Factory Machines
What are Factory Machines?
Section titled “What are Factory Machines?”Factory Machines combine state factories with transitions to create complete state machines with type-safe operations. They extend the Matchbox pattern to provide:
- Type-safe state creation with proper parameter inference
- Type-safe transitions with smart parameter types
- State data preservation when transitioning between states
- Lifecycle hooks for intercepting and reacting to state changes
const {(getState, send)} = fsm(states, transitions, initialState)
Creating Factory Machines and Using matchina
Section titled “Creating Factory Machines and Using matchina”To create a state machine, always start by defining your states using defineStates
:
const states = defineStates({ S1: () => ({}), S2: () => ({}),});
You can then create and use a machine in several ways:
// Basic factory machineconst { getState, send } = createMachine( states, { S1: { e1: "S2" }, S2: { e2: "S1" } }, states.S1());
// With matchina (zen wrapper for ergonomic API)const { getState, send, e1, e2 } = matchina( states, { S1: { e1: "S2" }, S2: { e2: "S1" } }, states.S1());
// Or, equivalently, assignEventApi-wrapped factory machineconst { getState, send, e1, e2 } = assignEventApi( createMachine(states, { S1: { e1: "S2" }, S2: { e2: "S1" } }, states.S1()));
createMachine
gives you.getState()
and.send(type, ...params)
.matchina
(orassignEventApi(createMachine(...))
) gives you.getState()
,.send(type, ...params)
, and direct methods for each event (e.g..e1()
,.e2()
).- The APIs are otherwise equivalent;
matchina
is just a convenience wrapper.
Transition Types & Data Propagation
Section titled “Transition Types & Data Propagation”Transition logic determines:
- Which exit states are possible for each entry state and event
- What parameters are required to send those events
- How state data is propagated or explicitly created during transitions
A transition handler can take one of these forms:
- String state key: If your transition does not accept parameters, simply return the destination state key as a string. Data is preserved automatically if compatible.
search: "Loading";
- Function with parameters: If your transition accepts parameters, return a state instance or a function that creates a state instance based on the event.
- Return a state instance directly:
search: (query: string) => TaskStates.Loading(query);
- Or, for advanced cases, return a function that receives the event object (
{ type, from, to }
) and returns a state instance:success: (results: string[]) => (event) =>TaskStates.Success(event.from.data.query, results);
- Return a state instance directly:
Summary Table:
Form | Example | Use Case |
---|---|---|
String (state key) | pause: "Paused" | No params, simple state change |
Function | search: (q) => TaskStates.Loading(q) | Accepts params, returns state instance |
Event function | success: (r) => (ev) => ... | Needs event context for state creation |
Using Factory Machines and matchina
Section titled “Using Factory Machines and matchina”-
With
createMachine
, trigger transitions by calling:machine.send(type, ...params); -
With
matchina
orassignEventApi
, you can also call event methods directly:machine.e1(...params); -
type
is the event name (string) -
...params
are the parameters for the transition (if any)
Getting Current State
Section titled “Getting Current State”Get the current state for inspection:
const state = machine.getState();console.log(state.key); // Current state key
Pattern Matching
Section titled “Pattern Matching”Pattern matching on state is only available if your state factory supports it (e.g. if you used a matchbox factory). For more, see the matchbox documentation.
Next Steps
Section titled “Next Steps”Now that you understand Factory Machines and matchina, explore these related guides:
- Lifecycle & Hooks - Add hooks for intercepting state changes
- Effects - Manage side effects with the effects system
- Promise Machines - Handle async operations with state machines
- React Integration - Use state machines with React