Skip to content

States

A state is a named, typed node in the machine’s graph. state("basicInfo")() creates one.

State is not data. Data lives in Context. State answers “where am I?”. Context answers “what do I know?”.

import { state } from "@mantaq/core";
const basicInfo = state("basicInfo")();
const submitting = state("submitting")();
basicInfo.name; // "basicInfo"
basicInfo.isFinal; // false
const success = state("success")().final();
success.isFinal; // true

Entering a final state fires "done" subscribers, sets snapshot().done to true, and stops the actor from accepting events.

States carry an optional payload, passed on entry, read by effects.

m.on(submitting, paymentFail, () => ({
state: error,
payload: { reason: "card declined" },
}));
m.effect(error, {
name: "logFailure",
fn: ({ state }) => {
console.log(state.payload.reason);
},
});

Sub-actors passed as regions to the Actor constructor. Child runs alongside parent. Snapshot nests.

import { checkout } from "../checkout.ts";
const fraudMonitor = new Actor({
inputs: [scanDone],
states: [scanning, cleared, flagged],
initial: scanning,
setup: (m) => {
m.on(scanning, scanDone, (event) => ({
state: event.payload.risky ? flagged : cleared,
}));
},
});
const checkout = new Actor({
// ...
regions: { fraud: fraudMonitor },
});

matches(checkout, "basicInfo.fraud.cleared") checks a child state.

Multiple regions run simultaneously:

regions: { fraud: fraudMonitor, analytics: analyticsMonitor }

Each is its own actor. Both run independently.