• Class decorator that adds finite state machine capabilities to a KOS model.

    This decorator eliminates manual state management boilerplate by:

    • Adding lifecycle-aware FSM initialization at configured phase (READY, ACTIVATE, etc.)
    • Managing state transitions automatically with validation
    • Providing observable state that integrates with

    Type Parameters

    • TState extends string
    • TEvent extends string

    Parameters

    Returns ClassDecorator

    A class decorator that modifies the target class prototype

    Kos Model

    reactive system

    • Supporting entry/exit handlers via

    Kos State Entry

    and

    Kos State Exit

    decorators

    • Enabling state guards via

    Kos State Guard

    decorator

    Two-Level State System

    Framework Lifecycle (Universal, Not Customizable):

    • CREATED → INIT → LOAD → READY → ACTIVATE → UNLOAD → DESTROY
    • Managed by KOS framework
    • Same for all models

    Application FSM (This Decorator):

    • Runs WITHIN an active model
    • Application-specific business logic
    • Different for each model type
    • Examples: Pour states, connection states, workflow states

    Lifecycle Integration

    The FSM initializes at the configured lifecycle phase:

    @kosStateMachine({
    initial: 'idle',
    initializeAt: DependencyLifecycle.READY, // Default
    states: { ... }
    })
    • INIT: FSM needs to be active during model initialization (rare)
    • READY: FSM operational as soon as data loaded (most common)
    • ACTIVATE: FSM only relevant when UI is active (UI-bound models)

    TypeScript Usage

    IMPORTANT: Use TypeScript interface merging to get proper type information:

    type MyState = 'idle' | 'active';
    type MyEvent = 'START' | 'STOP';

    interface MyModelImpl extends KosStateMachineAware<MyState, MyEvent> {}

    @kosStateMachine<MyState, MyEvent>({ ... })
    class MyModelImpl implements IKosDataModel {
    // All FSM properties are now available with full type safety
    }

    See

    Example

    // Basic FSM with default READY initialization
    type PourState = 'idle' | 'pouring' | 'complete';
    type PourEvent = 'START' | 'FINISH';

    interface PourModelImpl extends KosStateMachineAware<PourState, PourEvent> {}

    @kosModel({ modelTypeId: "pour-model" })
    @kosStateMachine<PourState, PourEvent>({
    initial: 'idle',
    states: {
    idle: { on: { START: 'pouring' } },
    pouring: { on: { FINISH: 'complete' } },
    complete: {}
    }
    })
    class PourModelImpl implements IKosDataModel {
    async ready(): Promise<void> {
    // After this completes, FSM is initialized to 'idle'
    }

    startPour(): void {
    this.transition('START'); // idle -> pouring
    }
    }

    Example

    // UI-bound FSM with ACTIVATE initialization
    type WorkflowState = 'draft' | 'review' | 'approved';
    type WorkflowEvent = 'SUBMIT' | 'APPROVE' | 'REJECT';

    interface DocumentModelImpl extends KosStateMachineAware<WorkflowState, WorkflowEvent> {}

    @kosModel({ modelTypeId: "document-model" })
    @kosStateMachine<WorkflowState, WorkflowEvent>({
    initial: 'draft',
    initializeAt: DependencyLifecycle.ACTIVATE, // UI-bound
    states: {
    draft: { on: { SUBMIT: 'review' } },
    review: { on: { APPROVE: 'approved', REJECT: 'draft' } },
    approved: {}
    }
    })
    class DocumentModelImpl implements IKosDataModel {
    // FSM only initializes when UI activates this model
    }

    Example

    // FSM with history tracking
    interface HistoryModelImpl extends KosStateMachineAware<'idle' | 'active', 'TOGGLE'> {}

    @kosStateMachine<'idle' | 'active', 'TOGGLE'>(
    {
    initial: 'idle',
    states: {
    idle: { on: { TOGGLE: 'active' } },
    active: { on: { TOGGLE: 'idle' } }
    }
    },
    {
    trackHistory: true,
    stateProperty: 'status'
    }
    )
    class HistoryModelImpl implements IKosDataModel {
    // Access via this.stateHistory
    }

    Since

    2.1.0