Core Concepts
The FSM class
FSM is the base class for all state machines, extending eventemitter3’s EventEmitter.
import { FSM } from 'afsm'
class MyFSM extends FSM { // your states and methods}
const obj = new MyFSM('my-fsm') // optional nameKey members
| Member | Description |
|---|---|
obj.state | Current state, type State (string or MiddleState) |
obj.stateDiagram | Auto-generated mermaid state diagram lines |
obj.name | Instance name (shown in DevTools) |
obj.groupName | Group name (defaults to class name) |
obj.on/off/emit | Inherited from EventEmitter |
FSM.STATECHANGED | State change event name, constant 'stateChanged' |
FSM.INIT | Initial state, constant '[*]' |
FSM.ON / FSM.OFF | Generic state constants 'on' / 'off' |
The State type
export type State = string | MiddleStateThere are two kinds of state:
- Stable states (strings) — e.g.
'idle','connected',FSM.INIT - Intermediate states (
MiddleStateinstances) — transient during async execution,toString()returns${action}ing
For example, calling @ChangeState('idle', 'done') async fetch():
- Enters intermediate state
fetching(aMiddleStateinstance) - On success becomes stable state
done - On failure rolls back to
idle
MiddleState
export class MiddleState { oldState: State newState: string action: string aborted: boolean toString() { return `${this.action}ing` } abort(fsm: IFSM): void}An intermediate state describes the transition “from oldState via action toward newState”. It can be aborted via abort() (see Abort & Interruption).
stateDiagram
stateDiagram is a getter that auto-generates mermaid syntax from decorator metadata. It’s memoized on the prototype after first access.
const obj = new MyFSM()console.log(obj.stateDiagram)// [// "[*] --> gotoState1ing : gotoState1",// "gotoState1ing --> state1 : gotoState1 🟢",// "gotoState1ing --> [*] : gotoState1 🔴",// ...// ]Drop this into a mermaid stateDiagram-v2 block to render. See Visualizing the Diagram.
Instance registries
FSM has two static registries used by the context composition pattern (see Composing FSMs):
FSM.instances: Map<string, IFSM>— string-keyed registryFSM.instances2: WeakMap<object, IFSM>— object-keyed registryFSM.get(context)— get or create the FSM associated with a contextFSM.getState(context)— directly fetch a context’s state
The IFSM interface
export interface IFSM extends FSM {}A self-referential interface for FSM, mainly used in decorator type signatures. In everyday use you just extends FSM.
Next steps
- @ChangeState — the transition decorator
- Event System — listening to
stateChangedand per-state events