2.3 KiB
Capability Spec: fsm
Package: @suaveplan/fsm
Version: 0.0.0 (genesis)
Status: ADDED
ADDED Requirements
FSM-01 — Config validation
validateConfig(config) MUST reject machines with unknown target states, duplicate state ids, or cyclic hierarchical parents. Invalid configs MUST throw FSM.INVALID_CONFIG.
FSM-02 — Transition contract
StateMachine.send(event) MUST run each candidate transition's guards in declared order, halt on the first true, execute the transition's actions, and emit TransitionResult { fromState, toState, event, eventType: FsmEventType }. Guard rejection across all candidates MUST emit FSM.INVALID_TRANSITION.
FSM-03 — Async guards / actions
AsyncGuardFn MUST return Promise<boolean>; AsyncActionFn MUST return Promise<void>. send MUST await them in order. Concurrent send calls MUST be serialised by the machine (FIFO).
FSM-04 — Snapshot / restore
StateMachine.snapshot() MUST return MachineSnapshot serialisable via JSON.stringify. StateMachine.restore(snapshot) MUST restore the machine to that exact state + context. Snapshots from a different config.id MUST be rejected.
FSM-05 — Hierarchical semantics
HierarchicalStateMachine MUST resolve the deepest active leaf on entry. onEntry / onExit MUST fire in outer→inner / inner→outer order respectively.
FSM-06 — Parallel regions
ParallelStateMachine MUST evaluate transitions independently per RegionConfig. SyncPoint MUST block progress until every named region enters the configured state.
FSM-07 — History
HistoryType MUST be 'shallow' | 'deep'. HistoryStateManager MUST return the last active leaf on re-entry for deep, and the last active direct child for shallow. Empty history on onExit-before-onEntry paths MUST emit FSM.HISTORY_EMPTY.
FSM-08 — Deferred events
DeferredEventQueue MUST buffer events per StateDeferConfig and release them when the state exits. Overflow MUST surface as FSM.DEFER_OVERFLOW.
FSM-09 — Visualisation
toDot(config) MUST produce Graphviz DOT representing states + transitions. toMermaid(config) MUST produce Mermaid state-diagram syntax. Both MUST handle hierarchical + parallel configs.
FSM-10 — Observability
send MUST record fsm.transition.duration_ms histogram and fsm.transition.total{outcome} counter.