once
Пропускает только первое срабатывание, остальные глотает — пока необязательный reset не взведёт его заново.
once(source);
once(source, { reset });Возвращает Event<T> — и для события-источника, и для стора.
Онбординг и разовые баннеры
import { once } from "@virentia/core/utils";
const firstOpen = once(appOpened);
reaction({ on: firstOpen, run: () => showOnboarding() });Флаг «уже было» внутри once — это стор: он живёт в своём скоупе и попадает в SSR-снапшот. Онбординг, показанный при серверном рендере, не мигнёт второй раз после гидрации. В этом весь смысл оператора: соблазнительный самодельный вариант с let fired = false на уровне модуля заводит флаг на весь процесс — SSR-запрос одного пользователя помечает «показано» сразу всем.
Аналитика первого использования
Событие «фичу попробовали» — ровно один раз на сессию:
const featureTried = once(exportClicked);
reaction({ on: featureTried, run: () => void trackFx("export-first-use") });Ленивый прогрев
Загрузить тяжёлые данные при первом открытии панели — и только при первом:
const panelFirstOpened = once(panelOpened);
reaction({ on: panelFirstOpened, run: () => void preloadHistoryFx() });Взвести заново
reset превращает «однажды» в «однажды за эпоху» — за сессию, за документ:
const greeted = once(sessionStarted, { reset: loggedOut });После loggedOut следующий sessionStarted в том же скоупе снова пройдёт.
Когда пригодится
- Всё, что показывается или отправляется только в первый раз: онбординг, подсказки, аналитика знакомства с фичей, прогрев данных.
- С
reset— «первый раз для каждой сущности или сессии»: перевзвод по выходу из аккаунта, смене документа, открытию новой записи.
Когда не подходит: если условие на самом деле состояние («пользователь прошёл настройку?») — заведите стор и computed. once — про сам факт первого раза, а не про долгоживущий булев флаг.
Поведение
- Флаг у каждого скоупа свой: скоуп A, поймавший первое срабатывание, не глушит скоуп B.
- Как стор, флаг участвует в сериализации скоупа — это сделано специально, см. случай с онбордингом.
- Dispose владельца снимает подписки оператора, как у любой реакции.