BehavioralFsm
Defined in: behavioral-fsm.ts:53
Defines FSM behavior (states + transitions) while tracking per-client state
in a WeakMap. A single BehavioralFsm instance can drive any number of
independent client objects simultaneously — each gets its own state,
deferred queue, and lifecycle.
Prefer createBehavioralFsm() over constructing this directly — the factory
infers all generic parameters from the config object.
All public methods silently no-op after dispose() is called.
Type Parameters
Section titled “Type Parameters”TClient
Section titled “TClient”TClient extends object
The client object type. Must be an object (non-primitive) so it can serve as a WeakMap key.
TStateNames
Section titled “TStateNames”TStateNames extends string
String literal union of valid state names.
TInputNames
Section titled “TInputNames”TInputNames extends string
String literal union of valid input names.
TBubbles
Section titled “TBubbles”TBubbles extends string = never
String literal union of inputs this FSM declares via
bubbles. Type-only — carried so BubblesOfInstance can extract it from
a constructed instance; nothing at runtime reads this generic.
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new BehavioralFsm<
TClient,TStateNames,TInputNames,TBubbles>(config):BehavioralFsm<TClient,TStateNames,TInputNames,TBubbles>
Defined in: behavioral-fsm.ts:80
Parameters
Section titled “Parameters”config
Section titled “config”FsmConfig<TClient, Record<string, Record<string, unknown>>>
Returns
Section titled “Returns”BehavioralFsm<TClient, TStateNames, TInputNames, TBubbles>
Properties
Section titled “Properties”[MACHINA_TYPE]
Section titled “[MACHINA_TYPE]”
readonly[MACHINA_TYPE]:"BehavioralFsm"
Defined in: behavioral-fsm.ts:63
readonlyid:string
Defined in: behavioral-fsm.ts:60
initialState
Section titled “initialState”
readonlyinitialState:TStateNames
Defined in: behavioral-fsm.ts:61
states
Section titled “states”
readonlystates:Record<string,Record<string,unknown>>
Defined in: behavioral-fsm.ts:67
Methods
Section titled “Methods”canHandle()
Section titled “canHandle()”canHandle(
client,inputName):boolean
Defined in: behavioral-fsm.ts:140
Returns true if the client’s current state has a handler for inputName
(or a catch-all "*" handler), or if the current state’s _child chain
can handle it — the check recurses to the same depth handle()’s
delegation can actually reach, so a grandchild-only input answers true
from the root. Does NOT initialize the client — no _onEnter, no
events, no side effects. Unseen clients are treated as if they were
already in initialState. Returns false when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
inputName
Section titled “inputName”string
Returns
Section titled “Returns”boolean
compositeState()
Section titled “compositeState()”compositeState(
client):string
Defined in: behavioral-fsm.ts:284
Returns the client’s state as a dot-delimited path including any active
child FSM states (e.g. "active.connecting.retrying"). Returns just the
current state name when no child is active. Returns "" for clients that
have never been initialized (unlike currentState() which returns undefined).
Parameters
Section titled “Parameters”client
Section titled “client”TClient
Returns
Section titled “Returns”string
currentState()
Section titled “currentState()”currentState(
client):TStateNames|undefined
Defined in: behavioral-fsm.ts:178
Returns the client’s current state, or undefined if the client has
never been initialized (i.e. handle(), transition(), or reset()
have never been called for it). Does NOT trigger initialization.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
Returns
Section titled “Returns”TStateNames | undefined
dispose()
Section titled “dispose()”dispose(
options?):void
Defined in: behavioral-fsm.ts:664
Permanently shut down this FSM. Irreversible — all subsequent method
calls become silent no-ops. Tears down child subscriptions, clears all
listeners, and cascades disposal to child FSMs (unless preserveChildren
is set). The same child appearing in multiple states is disposed once.
Parameters
Section titled “Parameters”options?
Section titled “options?”Returns
Section titled “Returns”void
emit()
Section titled “emit()”emit(
eventName,data?):void
Defined in: behavioral-fsm.ts:649
Emit a custom event through the FSM. Built-in lifecycle events are emitted automatically — this is for user-defined events from handlers. No-ops when disposed.
Parameters
Section titled “Parameters”eventName
Section titled “eventName”string
unknown
Returns
Section titled “Returns”void
handle()
Section titled “handle()”handle(
client,inputName, …args):void
Defined in: behavioral-fsm.ts:102
Dispatch an input to the given client’s current state handler.
Delegation order: if the current state has a _child FSM that can
handle the input, it is dispatched there. If the child emits nohandler,
the input bubbles up to this FSM’s local handler. If no handler exists
here either, nohandler is emitted on this FSM’s emitter.
No-ops silently when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
inputName
Section titled “inputName”TInputNames
…unknown[]
Returns
Section titled “Returns”void
Call Signature
Section titled “Call Signature”on<
K>(eventName,callback):Subscription
Defined in: behavioral-fsm.ts:632
Subscribe to a built-in lifecycle event or the wildcard.
Named overload: typed payload includes { client: TClient } so you can
identify which client the event pertains to. Wildcard ("*") receives
(eventName, data) for every event. Returns a no-op Subscription
when disposed.
Type Parameters
Section titled “Type Parameters”K extends "transitioning" | "transitioned" | "handling" | "handled" | "nohandler" | "invalidstate" | "deferred"
Parameters
Section titled “Parameters”eventName
Section titled “eventName”K
callback
Section titled “callback”(data) => void
Returns
Section titled “Returns”Call Signature
Section titled “Call Signature”on(
eventName,callback):Subscription
Defined in: behavioral-fsm.ts:636
Subscribe to a built-in lifecycle event or the wildcard.
Named overload: typed payload includes { client: TClient } so you can
identify which client the event pertains to. Wildcard ("*") receives
(eventName, data) for every event. Returns a no-op Subscription
when disposed.
Parameters
Section titled “Parameters”eventName
Section titled “eventName”"*"
callback
Section titled “callback”(eventName, data) => void
Returns
Section titled “Returns”rehydrate()
Section titled “rehydrate()”Call Signature
Section titled “Call Signature”rehydrate(
client,compositeState):void
Defined in: behavioral-fsm.ts:323
Silently place client at compositeState with no lifecycle activity —
no _onEnter, no _onExit, no transitioning/transitioned events.
Designed to work with compositeState(), which produces the dot-path
string that the string form consumes.
The snapshot form (pass a ClientSnapshot from dehydrate()) additionally
requeues each level’s pending deferred inputs, so a client resumes with the
same replay-on-next-transition behavior it had when dehydrated. Both forms
validate the ENTIRE hierarchy before writing anything — a throw at any level
leaves every level, including this one, unwritten.
Throws synchronously for unknown state names, missing _child at an inner
level, or Fsm children in the hierarchy (Fsm owns its own context; nothing
per-client to rehydrate there).
No-ops silently when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
compositeState
Section titled “compositeState”string
Returns
Section titled “Returns”void
Call Signature
Section titled “Call Signature”rehydrate(
client,snapshot):void
Defined in: behavioral-fsm.ts:324
Silently place client at compositeState with no lifecycle activity —
no _onEnter, no _onExit, no transitioning/transitioned events.
Designed to work with compositeState(), which produces the dot-path
string that the string form consumes.
The snapshot form (pass a ClientSnapshot from dehydrate()) additionally
requeues each level’s pending deferred inputs, so a client resumes with the
same replay-on-next-transition behavior it had when dehydrated. Both forms
validate the ENTIRE hierarchy before writing anything — a throw at any level
leaves every level, including this one, unwritten.
Throws synchronously for unknown state names, missing _child at an inner
level, or Fsm children in the hierarchy (Fsm owns its own context; nothing
per-client to rehydrate there).
No-ops silently when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
snapshot
Section titled “snapshot”Returns
Section titled “Returns”void
reset()
Section titled “reset()”reset(
client):void
Defined in: behavioral-fsm.ts:166
Transition the client back to initialState, firing _onEnter and
lifecycle events as if entering it fresh. No-ops when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
Returns
Section titled “Returns”void
transition()
Section titled “transition()”transition(
client,toState):void
Defined in: behavioral-fsm.ts:196
Directly transition client to toState, running the full lifecycle:
_onExit for the current state → transitioning event → update state →
_onEnter for new state → transitioned event → child reset → deferred
queue replay → bounce (if _onEnter returned a state name).
Same-state transitions are silently ignored. Transitions to unknown state
names emit invalidstate instead of throwing. Throws if the transition
depth exceeds MAX_TRANSITION_DEPTH (likely an _onEnter → transition loop).
No-ops when disposed.
Parameters
Section titled “Parameters”client
Section titled “client”TClient
toState
Section titled “toState”TStateNames
Returns
Section titled “Returns”void