Skip to content

Machine

Machine: object

Defined in: Core/Machine.ts:180

interpret: <States, Events, BusEvents>(machine, options) => MachineActor<States, Events>

Starts an actor that stores state and runs its entry and exit effects.

Manages active state lifecycles:

  • Runs entry effects on state entry, providing an AbortSignal and guarded send.
  • Automatically aborts active controllers and executes cleanup disposers when exiting a state.
  • Suppresses stale async dispatches from previously active states.
  • Queues re-entrant send calls to preserve sequential transition semantics.
  • Optionally synchronizes with an EventBus.
  • Propagates synchronous callback errors after completing the active transition or cleanup.

States extends WithKind<string> & object

Events extends Record<string, unknown>

BusEvents extends Record<string, unknown> = Events

Machine<States, Events>

MachineInterpretOptions<States, Events, BusEvents> & CompatibleBus<Events, BusEvents>

MachineActor<States, Events>

Machine.transition for pure stateless transitions.

const actor = Machine.interpret(authMachine, { initial: Machine.state("loggedOut") });

const unsubscribe = actor.subscribe((state) => {
  console.log("Current state:", state.kind);
});

actor.send({ kind: "SUBMIT", value: { email: "dev@example.com" } });

is: <K>(kind) => <S>(state) => state is Extract<S, { kind: K }>

Curried type guard that refines a state to a specific variant kind.

K extends string

K

<S>(state) => state is Extract<S, { kind: K }>

if (Machine.is("authenticating")(state)) {
  console.log(state.value.email);
}

make: <States, Events>(states) => Machine<States, Events>

Creates a state machine definition from state configurations and event handlers.

States extends WithKind<string> & object

Events extends Record<string, unknown>

MachineTransitionTable<States, Events>

Machine<States, Events>

type AuthState =
  | Machine.State<"loggedOut", void, "authenticating">
  | Machine.State<"authenticating", { readonly email: string }, "authenticated" | "failed">
  | Machine.State<"authenticated", { readonly token: string }, "loggedOut">
  | Machine.State<"failed", { readonly error: string }, "authenticating" | "loggedOut">;

type AuthEvents = {
  SUBMIT: { readonly email: string };
  RESOLVE: { readonly token: string };
  REJECT: { readonly error: string };
  LOGOUT: void;
};

const authMachine = Machine.make<AuthState, AuthEvents>({
  loggedOut: {
    on: {
      SUBMIT: (_state, { email }) => Machine.state("authenticating", { email }),
    },
  },
  authenticating: {
    on: {
      RESOLVE: (_state, { token }) => Machine.state("authenticated", { token }),
      REJECT: (_state, { error }) => Machine.state("failed", { error }),
    },
  },
  authenticated: {
    on: {
      LOGOUT: () => Machine.state("loggedOut"),
    },
  },
  failed: {
    on: {
      SUBMIT: (_state, { email }) => Machine.state("authenticating", { email }),
      LOGOUT: () => Machine.state("loggedOut"),
    },
  },
});

match: {<States, R>(cases): (state) => R; <States, Cases>(state, cases): HandlerReturn<Cases[keyof Cases]>; } = matchMachine

Exhaustive pattern matcher across all state variants of a machine.

The data-first form infers state payloads and the union of branch return values. The curried form remains available for pipe, but requires explicit state and return type arguments.

<States, R>(cases): (state) => R

States extends WithKind<string> & object

R

{ readonly [K in string]: (state: Extract<States, { kind: K }>) => R }

(state) => R

<States, Cases>(state, cases): HandlerReturn<Cases[keyof Cases]>

States extends WithKind<string> & object

Cases extends MachineMatchCases<States>

States

Cases

HandlerReturn<Cases[keyof Cases]>

const title = Machine.match(actor.getState(), {
  loggedOut: () => "Please Sign In",
  authenticating: ({ value }) => `Verifying ${value.email}...`,
  authenticated: ({ value }) => `Logged in with token ${value.token}`,
  failed: ({ value }) => `Error: ${value.error}`,
});

state: {<Kind>(kind): WithKind<Kind> & object; <Kind, Data>(kind, value): MachineState<Kind, Data, string>; } = makeState

Constructs a state variant without requiring manual type assertions.

<Kind>(kind): WithKind<Kind> & object

Kind extends string

Kind

WithKind<Kind> & object

<Kind, Data>(kind, value): MachineState<Kind, Data, string>

Kind extends string

Data

Kind

Data

MachineState<Kind, Data, string>

const idle = Machine.state("idle");
const active = Machine.state("active", { count: 1 });

to: object

Converters to standard external runtime structures.

reducer: <States, Events>(machine) => (state, event) => States

Converts a state machine into an uncurried reducer function (state, event) => nextState directly compatible with React useReducer.

States extends WithKind<string> & object

Events extends Record<string, unknown>

Machine<States, Events>

(state, event) => States

Machine.transition for pure, curried data-last pipeline transitions.

// In React:
const [state, dispatch] = useReducer(
  Machine.to.reducer(checkoutMachine),
  Machine.state("cart"),
);

transition: <States, Events>(machine, event) => (state) => States

Pure, data-last transition function. Evaluates a transition on the provided state and returns the next state without executing lifecycle side effects.

If the state does not handle the event, the current state is returned unchanged. State kinds and event kinds must be declared machine members; external data must be validated before it enters a machine (garbage-in-garbage-out — a prototype-named kind through a contract violation is treated as an inherited property, not a member).

States extends WithKind<string> & object

Events extends Record<string, unknown>

Machine<States, Events>

MachineEventMessage<Events>

(state) => States

Machine.interpret to run a stateful actor with async lifecycle effects.

const nextState = pipe(
  currentState,
  Machine.transition(authMachine, { kind: "SUBMIT", value: { email: "dev@example.com" } }),
);