Events
Both Fsm and BehavioralFsm emit lifecycle events throughout the input-handling and transition cycle. Subscribe with on(), which returns a { off() } subscription object.
Subscribing
Section titled “Subscribing”on() is safe to call multiple times with the same callback — the underlying Set deduplicates. The returned Subscription is the only way to remove a specific listener; there’s no off(eventName, callback) API.
Built-in events
Section titled “Built-in events”| Event | Payload | Fired when |
|---|---|---|
transitioning | { fromState, toState } | A transition is about to occur |
transitioned | { fromState, toState } | A transition completed |
handling | { inputName } | An input is about to be dispatched |
handled | { inputName } | An input was successfully handled |
nohandler | { inputName, args } | No handler found in current state |
invalidstate | { stateName } | Transition targeted a nonexistent state |
deferred | { inputName } | An input was deferred |
Events follow a grammatical pattern: present participle (transitioning, handling) means “about to happen”; past participle (transitioned, handled) means “just happened”.
BehavioralFsm events
Section titled “BehavioralFsm events”BehavioralFsm shares the same event names, but every payload is intersected with a client field identifying which client the event pertains to:
This is necessary because a single BehavioralFsm instance manages many independent clients — without client in the payload you’d have no idea whose event just fired.
Wildcard subscriber
Section titled “Wildcard subscriber”Subscribe to "*" to receive every event. The callback signature differs from named subscriptions: the first argument is the event name, the second is the payload.
Wildcard listeners fire before named listeners for the same event. This is intentional — it lets relay listeners observe all events before specific subscribers react.
Custom events
Section titled “Custom events”Handlers can emit custom events via the emit argument on the handler args object. Built-in lifecycle events are emitted automatically by the engine; emit is for user-defined events.
Custom events are received by on() subscribers the same way as built-in events. The wildcard "*" subscription catches them too.
TypeScript
Section titled “TypeScript”The built-in event payloads are fully typed via FsmEventMap and BehavioralFsmEventMap. You won’t normally need to reference these directly — on() is already typed through the FSM instance — but they’re exported if you need them for callbacks defined outside the on() call.
Custom events emitted via emit() are untyped — they flow through as unknown on the wildcard path. If you need typed custom events, narrow them at the subscriber.