Middleware
Подключаемый наблюдатель, прицепленный к каждому триггеру в рантайме. Семь хуков срабатывают в предсказуемых точках вокруг диспатча — три из них (onFire, onSkip, onError) часто складываются в полный аудит-трейл; остальные (onBeforeMatch, onActionStart, onActionEnd, onCascade) — для трассировки, метрик и devtools.
Все хуки необязательные. Исключение, выброшенное в хуке, ловится и логируется рантаймом, но не прерывает запуск — middleware не должен быть load-bearing.
Определение
Заголовок раздела «Определение»name — string
Заголовок раздела «name — string»Стабильный id middleware. Обязателен. Полезен в сообщениях об ошибках и в панелях devtools.
onFire(ctx) -> void | { cancel: true; reason: string }
Заголовок раздела «onFire(ctx) -> void | { cancel: true; reason: string }»Вызывается один раз на каждый fire(eventName, payload) верхнего уровня (или каскадный) перед тем, как сматчится любой триггер. Возврат { cancel: true, reason } прерывает весь диспатч — триггеры не запускаются, и запись в стиле 'overflow' не пишется. Это единственный хук с коротким замыканием.
Поле FireContext | Описание |
|---|---|
eventName | Диспатчируемое событие. |
payload | Полезная нагрузка, непрозрачная для middleware. |
cascadeDepth | 0 для срабатываний верхнего уровня; n внутри каскада. |
parentRunId? | Установлен, если fire происходит внутри работающего обработчика. |
parentTriggerId? | То же — id upstream-триггера. |
parentContext? | Непрозрачная ссылка-связный список для детекта циклов. |
onBeforeMatch(ctx) -> void
Заголовок раздела «onBeforeMatch(ctx) -> void»Вызывается на каждую пару (event, trigger) сразу после того, как диспатч достал триггер из индекса событий — до любой concurrency-gate или проверки required. Чисто наблюдательный; полезен для «какие триггеры были рассмотрены для этого события» без инструментирования onSkip и onActionStart по отдельности.
onSkip(ctx) -> void
Заголовок раздела «onSkip(ctx) -> void»Вызывается, когда триггер сматчился, но был пропущен. reason — один из 'disabled', 'required-missing', 'concurrency-take-first', 'aborted', 'cycle', 'overflow' и т. д. Используй для отслеживания «почему мой триггер не запустился».
onActionStart(ctx) -> void
Заголовок раздела «onActionStart(ctx) -> void»Вызывается прямо перед тем, как обработчик вызовет действие. actionName и payload — аргументы. Используй для трассировки по действиям.
onActionEnd(ctx & { durationMs; result? }) -> void
Заголовок раздела «onActionEnd(ctx & { durationMs; result? }) -> void»Вызывается, когда действие вернёт значение (или его промис разрешится). durationMs — wall-clock-время от onActionStart до onActionEnd. Рантайм замеряет это только когда есть хотя бы один слушатель — без миддлвэров с таймингом затрат нет.
onError(ctx & { error }) -> void
Заголовок раздела «onError(ctx & { error }) -> void»Вызывается, когда действие выбрасывает исключение или его промис реджектится. Паря с onActionStart, обрамляет полную попытку. Ошибки также записываются в снепшот инспектора со status: 'errored'.
onCascade(ctx) -> void
Заголовок раздела «onCascade(ctx) -> void»Вызывается, когда каскадное событие подавлено — kind: 'overflow' (cascadeDepth превысил maxCascadeDepth) или kind: 'cycle' (триггер появляется в своей же цепочке предков).