Skip to Content
👋 Добро пожаловать в документацию lite-fsm!

Глобальные эффекты

Глобальные эффекты в lite-fsm позволяют вынести резервную обработку событий в effect с ключом "*". Такой effect удобен для сквозной функциональности: логирования, аналитики или мониторинга состояния системы.

Концепция глобальных эффектов

Глобальный effect задаётся ключом "*" в объекте effects. Он запускается для обработанного события, если не был запущен более конкретный effect по имени нового state. При переходе без смены state конкретный state-effect не запускается, поэтому глобальный effect остаётся способом отреагировать на событие без смены состояния.

Создание глобальных эффектов

Для определения глобального эффекта используйте символ "*" в качестве ключа в объекте effects:

import { createMachine } from "@lite-fsm/core"; export const analytics = createMachine({ config: { IDLE: {}, }, initialState: "IDLE", initialContext: {}, effects: { "*": ({ action, getState, ym }) => { if (action.type === "LOGIN_RESOLVE") { const userId = getState().session.context.userId ?? -1; ym.reachGoal("auth", userId); } }, }, });

getState и сервис ym здесь — это пользовательские зависимости, которые мы передаём в менеджер через setDependencies({ getState: manager.getState, ym }). См. раздел Внедрение зависимостей.

Параметры глобальных эффектов

Глобальные эффекты получают те же параметры, что и обычные:

  • action — событие, которое привело к переходу;
  • transition(action) — отправить новое событие;
  • condition(predicate) — дождаться matching action;
  • любые пользовательские зависимости, переданные через setDependencies.
effects: { "*": ({ action, transition, logger, getState }) => { console.log(`Action: ${action.type}`, action.payload); console.log("Global state:", getState()); if (action.type === "CRITICAL_ERROR") { logger.error("Critical error occurred", action.payload); transition({ type: "SHOW_ERROR_DIALOG", payload: action.payload }); } }, }

Типичные сценарии использования

1. Отслеживание аналитики

Типичный сценарий для глобальных эффектов — отправка событий в систему аналитики:

const analyticsMachine = createMachine({ config: { IDLE: {}, }, initialState: "IDLE", initialContext: {}, effects: { "*": ({ action, analytics, getState }) => { try { if (action.type.startsWith("__")) return; const state = getState(); const userId = state.auth?.context?.userId; const sessionId = state.session?.context?.id; analytics.track({ eventName: action.type, properties: { ...action.payload, userId, sessionId, timestamp: new Date().toISOString(), }, }); } catch (error) { console.error("Analytics tracking error:", error); } }, }, });

2. Логирование состояний и переходов

Глобальные эффекты подходят для реализации логирования:

const loggingMachine = createMachine({ config: { IDLE: {}, }, initialState: "IDLE", initialContext: {}, effects: { "*": ({ action, getState }) => { if (process.env.NODE_ENV === "development") { const currentState = getState(); console.group(`📊 Action: ${action.type}`); console.log("Payload:", action.payload); console.log("Current State:", currentState); console.groupEnd(); } }, }, });

3. Мониторинг ошибок

Отслеживание и обработка ошибок на уровне FSM-событий:

const errorMonitorMachine = createMachine({ config: { IDLE: {}, }, initialState: "IDLE", initialContext: {}, effects: { "*": ({ action, errorMonitoring }) => { if (action.type.includes("ERROR") && action.payload?.error) { errorMonitoring.captureException(action.payload.error, { tags: { actionType: action.type }, extra: { payload: action.payload }, }); } }, }, });

Лучшие практики

  1. Держите глобальные effects наблюдателями: они не должны незаметно менять основной поток событий.
  2. Обрабатывайте ошибки: Оборачивайте код глобальных эффектов в try-catch, чтобы ошибки не нарушали работу основного приложения.
  3. Используйте для сквозной функциональности: Аналитика, логирование и мониторинг — хорошие кандидаты для глобальных эффектов.
  4. Ограничивайте вызовы переходов: Будьте осторожны с вызовом transition в глобальных эффектах, чтобы избежать бесконечных циклов.
  5. Разделяйте ответственность: выносите аналитику, логирование и мониторинг в отдельные машины, если они не принадлежат доменной машине.
  6. Ограничивайте работу по условию: выполняйте только нужные операции, чтобы глобальный effect не стал дорогой обработкой каждого события.
Last updated on