fn

useStateMachine

v0.2.0testeddemo

Reactive wrapper around the stdlib StateMachine: a type-safe finite state machine whose current state is exposed as a shallow ref, so templates and computeds can branch on state/matches/can. States, events, guards, and entry/exit hooks follow the stdlib createMachine config verbatim — this composable only adds reactivity.

Example

ts
const { state, send, can } = useStateMachine({
  initial: 'idle',
  states: {
    idle: { on: { FETCH: 'loading' } },
    loading: { on: { RESOLVE: 'idle', REJECT: 'failed' } },
    failed: { on: { RETRY: 'loading' } },
  },
});

send('FETCH'); // state.value === 'loading'
can('RETRY'); // false — reactive, usable in computeds/templates

Demo

Loading demo…

Signatures

ts
export function useStateMachine<
  const States extends Record<string, SyncStateNodeConfig<Context>>,
  Context,
>(config: {
  initial: NoInfer<ExtractStates<States>>;
  context: Context;
  states: States;
}): UseStateMachineReturn<ExtractStates<States>, ExtractEvents<States>, Context>;
ts
export function useStateMachine<
  const States extends Record<string, SyncStateNodeConfig<undefined>>,
>(config: {
  initial: NoInfer<ExtractStates<States>>;
  states: States;
}): UseStateMachineReturn<ExtractStates<States>, ExtractEvents<States>, undefined>;

Parameters

ParameterTypeDescription
config{ initial: string; context?: unknown; // Overload-implementation signature (mirrors stdlib `createMachine`): `any` // accepts every concrete `SyncStateNodeConfig<C>` — contravariant in `C` — // and `Context = undefined` keeps the invariant `StateMachine<..., Context>` // comparable with both public overloads. // eslint-disable-next-line @typescript-eslint/no-explicit-any states: Record<string, SyncStateNodeConfig<any>>; }Machine config: initial, optional context, and states

Returns

UseStateMachineReturn<string, string, undefined>Reactive state plus send/matches/can and the raw machine
PropertyTypeDescription
stateReadonly<ShallowRef<States>>Reactive current state of the machine.
send(event: Events) => StatesSend an event to the machine, potentially causing a transition. Returns the state the machine settled on (entry/exit hooks may themselves send events; the returned state is the final one).
matches(state: States) => booleanReactive check: is the machine currently in state?
can(event: Events) => booleanReactive check: can event cause a transition from the current state?
machineStateMachine<States, Events, Context>The underlying stdlib machine (context access, non-reactive escape hatch).