- Name
type- Kind
- property
- Type
string- Requirement
- required
DocsAPI referenceStatechart
Statechart runtime
The lifecycle kernel and its optional authoring, scheduler, persistence and inspection entry points. Every section below is an importable public package path.
Lifecycle
Start a service, observe snapshots, send events, update input, batch work, and always release the subscription and service.
import { createService } from "@grassroot/statechart";import { switchMachine } from "@grassroot/ui-machines/switch"; const service = createService(switchMachine, { input: { defaultChecked: false } });const stop = service.subscribe((snapshot) => console.log(snapshot.value));service.start();service.send({ type: "PRESS", reason: "pointer" });service.setInput({ defaultChecked: true });service.batch(() => service.send({ type: "RESET" }));stop();service.stop();@grassroot/statechart
Core runtime
CommandObject
typetype CommandObject = { readonly type: string; readonly [key: string]: JsonValue;};typestringcreateService
functiondeclare function createService<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output = never>(machine: Machine<Input, Value, Context, Event, Command, Output>, options: { input: Input; runCommand?: (command: Command, tools: { send: (event: Event) => void; signal: AbortSignal; }) => void | (() => void); onDiagnostic?: (diagnostic: DiagnosticObject & { readonly machineId: string; }) => void; onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void;}): Service<Input, Value, Context, Event, Command, Output>;machineMachine<Input, Value, Context, Event, Command, Output>options{
input: Input;
runCommand?: (command: Command, tools: {
send: (event: Event) => void;
signal: AbortSignal;
}) => void | (() => void);
onDiagnostic?: (diagnostic: DiagnosticObject & {
readonly machineId: string;
}) => void;
onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void;
}returnService<Input, Value, Context, Event, Command, Output>- Name
machine- Kind
- parameter
- Type
Machine<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
options- Kind
- parameter
- Type
{ input: Input; runCommand?: (command: Command, tools: { send: (event: Event) => void; signal: AbortSignal; }) => void | (() => void); onDiagnostic?: (diagnostic: DiagnosticObject & { readonly machineId: string; }) => void; onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void; }- Requirement
- required
- Name
return- Kind
- return value
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- n/a
DiagnosticObject
typetype DiagnosticObject = { readonly code: string; readonly message: string; readonly severity: "warning" | "error"; readonly data?: JsonValue;};codestringdataJsonValuemessagestringseverity"warning" | "error"- Name
code- Kind
- property
- Type
string- Requirement
- required
- Name
data- Kind
- property
- Type
JsonValue- Requirement
- optional
- Name
message- Kind
- property
- Type
string- Requirement
- required
- Name
severity- Kind
- property
- Type
"warning" | "error"- Requirement
- required
EventObject
typetype EventObject = { readonly type: string;};typestring- Name
type- Kind
- property
- Type
string- Requirement
- required
JsonValue
typeThe low-level `@grassroot/statechart` contract, frozen in phase 0 of GRASSROOT_STATECHART_EXECUTION_PLAN.md. The shapes here are lifted verbatim from GRASSROOT_STATECHART_PLATFORM_PLAN.md ("Native statechart model"). Decision records: docs/decisions/statechart-api.md and docs/decisions/statechart-semantics.md. The authoring layer (phase 5) must compile to this contract with identical semantics. This file is types plus one declaration only — no runtime code ships in phase 0. `createService` is implemented in phase 1 (src/service.ts).
type JsonValue = null | boolean | number | string | readonly JsonValue[] | { readonly [key: string]: JsonValue;};Machine
interfaceinterface Machine<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject = never, Output = never> { readonly id: string; initial(input: Readonly<Input>): Transition<Value, Context, Command, Output>; transition(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>): Transition<Value, Context, Command, Output>; sync?(state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>): Transition<Value, Context, Command, Output>;}idstringinitial(input: Readonly<Input>) => Transition<Value, Context, Command, Output>sync((state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>) => Transition<Value, Context, Command, Output>) | undefinedtransition(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Name
id- Kind
- property
- Type
string- Requirement
- required
- Name
initial- Kind
- method
- Type
(input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Requirement
- required
- Name
sync- Kind
- method
- Type
((state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>) => Transition<Value, Context, Command, Output>) | undefined- Requirement
- optional
- Name
transition- Kind
- method
- Type
(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Requirement
- required
MachineState
interfaceinterface MachineState<Value extends StateValue, Context, Output = never> { readonly value: Value; readonly context: Readonly<Context>; readonly output?: Output;}contextReadonly<Context>outputOutputvalueValue- Name
context- Kind
- property
- Type
Readonly<Context>- Requirement
- required
- Name
output- Kind
- property
- Type
Output- Requirement
- optional
- Name
value- Kind
- property
- Type
Value- Requirement
- required
Service
interfaceinterface Service<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output = never> { start(): void; stop(): void; getSnapshot(): Snapshot<Value, Context, Output>; getInput(): Readonly<Input>; send(event: Event): Snapshot<Value, Context, Output>; setInput(next: Input): Snapshot<Value, Context, Output>; subscribe<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }): () => void; batch<Result>(work: () => Result): Result;}batch<Result>(work: () => Result) => ResultgetInput() => Readonly<Input>getSnapshot() => Snapshot<Value, Context, Output>send(event: Event) => Snapshot<Value, Context, Output>setInput(next: Input) => Snapshot<Value, Context, Output>start() => voidstop() => voidsubscribe<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }) => () => void- Name
batch- Kind
- method
- Type
<Result>(work: () => Result) => Result- Requirement
- required
- Name
getInput- Kind
- method
- Type
() => Readonly<Input>- Requirement
- required
- Name
getSnapshot- Kind
- method
- Type
() => Snapshot<Value, Context, Output>- Requirement
- required
- Name
send- Kind
- method
- Type
(event: Event) => Snapshot<Value, Context, Output>- Requirement
- required
- Name
setInput- Kind
- method
- Type
(next: Input) => Snapshot<Value, Context, Output>- Requirement
- required
- Name
start- Kind
- method
- Type
() => void- Requirement
- required
- Name
stop- Kind
- method
- Type
() => void- Requirement
- required
- Name
subscribe- Kind
- method
- Type
<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }) => () => void- Requirement
- required
ServiceError
interfaceinterface ServiceError<Value extends StateValue, Context, Event, Command, Output = never> { readonly phase: "start" | "transition" | "sync" | "diagnostic" | "command"; readonly cause: unknown; readonly machineId: string; readonly snapshot: Snapshot<Value, Context, Output>; readonly event?: Event; readonly diagnostic?: DiagnosticObject; readonly command?: Command;}causeunknowncommandCommanddiagnosticDiagnosticObjecteventEventmachineIdstringphase"start" | "transition" | "sync" | "diagnostic" | "command"snapshotSnapshot<Value, Context, Output>- Name
cause- Kind
- property
- Type
unknown- Requirement
- required
- Name
command- Kind
- property
- Type
Command- Requirement
- optional
- Name
diagnostic- Kind
- property
- Type
DiagnosticObject- Requirement
- optional
- Name
event- Kind
- property
- Type
Event- Requirement
- optional
- Name
machineId- Kind
- property
- Type
string- Requirement
- required
- Name
phase- Kind
- property
- Type
"start" | "transition" | "sync" | "diagnostic" | "command"- Requirement
- required
- Name
snapshot- Kind
- property
- Type
Snapshot<Value, Context, Output>- Requirement
- required
Snapshot
interfaceinterface Snapshot<Value extends StateValue, Context, Output = never> { readonly value: Value; readonly context: Readonly<Context>; readonly version: number; readonly status: "idle" | "active" | "done" | "stopped" | "error"; readonly output?: Output; readonly error?: unknown;}contextReadonly<Context>errorunknownoutputOutputstatus"idle" | "active" | "done" | "stopped" | "error"valueValueversionnumber- Name
context- Kind
- property
- Type
Readonly<Context>- Requirement
- required
- Name
error- Kind
- property
- Type
unknown- Requirement
- optional
- Name
output- Kind
- property
- Type
Output- Requirement
- optional
- Name
status- Kind
- property
- Type
"idle" | "active" | "done" | "stopped" | "error"- Requirement
- required
- Name
value- Kind
- property
- Type
Value- Requirement
- required
- Name
version- Kind
- property
- Type
number- Requirement
- required
StateValue
typetype StateValue = string | { readonly [region: string]: StateValue;};Transition
interfaceinterface Transition<Value extends StateValue, Context, Command extends CommandObject, Output = never> { readonly state: MachineState<Value, Context, Output>; readonly commands?: readonly Command[]; readonly diagnostics?: readonly DiagnosticObject[];}commandsreadonly Command[]diagnosticsreadonly DiagnosticObject[]stateMachineState<Value, Context, Output>- Name
commands- Kind
- property
- Type
readonly Command[]- Requirement
- optional
- Name
diagnostics- Kind
- property
- Type
readonly DiagnosticObject[]- Requirement
- optional
- Name
state- Kind
- property
- Type
MachineState<Value, Context, Output>- Requirement
- required
@grassroot/statechart/authoring
authoring
Action
typetype Action<C, E, I, Cmd extends CommandObject> = AssignAction<C, E, I> | CommandAction<C, E, I, Cmd> | BindingAction<any, C, E, I, Cmd>;ActionArgs
typetype ActionArgs<C, E, I> = { readonly context: C; readonly event: E; readonly input: I;};contextCeventEinputI- Name
context- Kind
- property
- Type
C- Requirement
- required
- Name
event- Kind
- property
- Type
E- Requirement
- required
- Name
input- Kind
- property
- Type
I- Requirement
- required
assign
functiondeclare function assign<C, E, I>(fn: (args: ActionArgs<C, E, I>) => Partial<C>): AssignAction<C, E, I>;fn(args: ActionArgs<C, E, I>) => Partial<C>returnAssignAction<C, E, I>- Name
fn- Kind
- parameter
- Type
(args: ActionArgs<C, E, I>) => Partial<C>- Requirement
- required
- Name
return- Kind
- return value
- Type
AssignAction<C, E, I>- Requirement
- n/a
AssignAction
interfaceinterface AssignAction<C, E, I> { readonly __kind: "assign"; readonly fn: (args: ActionArgs<C, E, I>) => Partial<C>;}__kind"assign"fn(args: ActionArgs<C, E, I>) => Partial<C>- Name
__kind- Kind
- property
- Type
"assign"- Requirement
- required
- Name
fn- Kind
- property
- Type
(args: ActionArgs<C, E, I>) => Partial<C>- Requirement
- required
bindable
functionOne binding = one controlled/uncontrolled field (S12). Two storage shapes: - context-backed (no `stateFor`/`valueOf`): committed value lives in `context[<binding key>]`. - state-backed (`stateFor`/`valueOf` provided): committed value IS the state value; `stateFor` maps a proposed value to a state name, `valueOf` maps a state name back to the binding's value type. The binding's key comes from where it is placed in `defineMachine`'s `bindings` map — `bindable()` itself is unnamed, `toMachine` resolves the name from that map by identity.
declare function bindable<V, C = unknown, E = unknown, I = unknown>(options: BindableOptions<V>): BindableSpec<V, C, E, I>;optionsBindableOptions<V>returnBindableSpec<V, C, E, I>- Name
options- Kind
- parameter
- Type
BindableOptions<V>- Requirement
- required
- Name
return- Kind
- return value
- Type
BindableSpec<V, C, E, I>- Requirement
- n/a
BindableOptions
typetype BindableOptions<V> = ContextBackedBindableOptions | StateBackedBindableOptions<V>;BindableSpec
interfaceinterface BindableSpec<V, C, E, I> { readonly __kind: "bindable"; readonly prop: string; readonly defaultProp: string; readonly stateFor?: (value: V) => string; readonly valueOf?: (state: string) => V; set<Cmd extends CommandObject>(fn: (args: ActionArgs<C, E, I> & { readonly current: V; }) => V, requestFactory: (value: V, context: C, event: E) => Cmd): BindingSetAction<V, C, E, I, Cmd>; reset(): BindingResetAction<V, C, E, I>;}__kind"bindable"defaultPropstringpropstringreset() => BindingResetAction<V, C, E, I>set<Cmd extends CommandObject>(fn: (args: ActionArgs<C, E, I> & { readonly current: V; }) => V, requestFactory: (value: V, context: C, event: E) => Cmd) => BindingSetAction<V, C, E, I, Cmd>stateFor(value: V) => stringvalueOf(state: string) => V- Name
__kind- Kind
- property
- Type
"bindable"- Requirement
- required
- Name
defaultProp- Kind
- property
- Type
string- Requirement
- required
- Name
prop- Kind
- property
- Type
string- Requirement
- required
- Name
reset- Kind
- method
- Type
() => BindingResetAction<V, C, E, I>- Requirement
- required
- Name
set- Kind
- method
- Type
<Cmd extends CommandObject>(fn: (args: ActionArgs<C, E, I> & { readonly current: V; }) => V, requestFactory: (value: V, context: C, event: E) => Cmd) => BindingSetAction<V, C, E, I, Cmd>- Requirement
- required
- Name
stateFor- Kind
- property
- Type
(value: V) => string- Requirement
- optional
- Name
valueOf- Kind
- property
- Type
(state: string) => V- Requirement
- optional
BindingAction
typetype BindingAction<V, C, E, I, Cmd extends CommandObject> = BindingSetAction<V, C, E, I, Cmd> | BindingResetAction<V, C, E, I>;BindingResetAction
interfaceinterface BindingResetAction<V, C, E, I> { readonly __kind: "binding"; readonly op: "reset"; readonly binding: BindableSpec<V, C, E, I>;}__kind"binding"bindingBindableSpec<V, C, E, I>op"reset"- Name
__kind- Kind
- property
- Type
"binding"- Requirement
- required
- Name
binding- Kind
- property
- Type
BindableSpec<V, C, E, I>- Requirement
- required
- Name
op- Kind
- property
- Type
"reset"- Requirement
- required
BindingSetAction
interfaceDeviation from the addendum, reported verbatim in the phase-5 return: the addendum's `binding.set(fn, requestFactory)` types `fn` as `({ context, event, input }) => V` and `requestFactory` as `(value, ctx) => CommandObject`. Neither signature can express the Switch fixture, which (a) toggles off the *current bound value* (state-backed — not present in `context` at all) and (b) puts `event.reason` (not anything derived from `context`) into the emitted command. Both are required for N4 trace-identity with the handwritten machine, so this layer extends both signatures additively: `fn` gains a `current` field (the binding's current resolved value, via `valueOf`/context lookup) and `requestFactory` gains a trailing `event` parameter. Existing two-arg callers are unaffected — extra fields/args are additive.
interface BindingSetAction<V, C, E, I, Cmd extends CommandObject> { readonly __kind: "binding"; readonly op: "set"; readonly binding: BindableSpec<V, C, E, I>; readonly fn: (args: ActionArgs<C, E, I> & { readonly current: V; }) => V; readonly requestFactory: (value: V, context: C, event: E) => Cmd;}__kind"binding"bindingBindableSpec<V, C, E, I>fn(args: ActionArgs<C, E, I> & {
readonly current: V;
}) => Vop"set"requestFactory(value: V, context: C, event: E) => Cmd- Name
__kind- Kind
- property
- Type
"binding"- Requirement
- required
- Name
binding- Kind
- property
- Type
BindableSpec<V, C, E, I>- Requirement
- required
- Name
fn- Kind
- property
- Type
(args: ActionArgs<C, E, I> & { readonly current: V; }) => V- Requirement
- required
- Name
op- Kind
- property
- Type
"set"- Requirement
- required
- Name
requestFactory- Kind
- property
- Type
(value: V, context: C, event: E) => Cmd- Requirement
- required
Candidate
interfaceinterface Candidate<I, C, E extends EventObject, Cmd extends CommandObject> { readonly guard?: (args: ActionArgs<C, E, I>) => boolean; readonly target?: string; readonly actions?: readonly Action<C, E, I, Cmd>[];}actionsreadonly Action<C, E, I, Cmd>[]guard(args: ActionArgs<C, E, I>) => booleantargetstring- Name
actions- Kind
- property
- Type
readonly Action<C, E, I, Cmd>[]- Requirement
- optional
- Name
guard- Kind
- property
- Type
(args: ActionArgs<C, E, I>) => boolean- Requirement
- optional
- Name
target- Kind
- property
- Type
string- Requirement
- optional
CANDIDATE_KEYS
valueexport declare const CANDIDATE_KEYS: ReadonlySet<string>;candidateList
functionThe one place a candidate entry (single or array) is normalized to a list.
declare function candidateList<I, C, E extends EventObject, Cmd extends CommandObject>(entry: Candidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]): readonly Candidate<I, C, E, Cmd>[];entryCandidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]returnreadonly Candidate<I, C, E, Cmd>[]- Name
entry- Kind
- parameter
- Type
Candidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]- Requirement
- required
- Name
return- Kind
- return value
- Type
readonly Candidate<I, C, E, Cmd>[]- Requirement
- n/a
collectDefinitionIssues
functionThe shared build-time validation core. Everything returned here is rejected by BOTH `toMachine` (throws) and `compileMachine` (throws with the compiler's `{ok, errors}` wording). Compiler-only lints (dead candidates, unreachable states) stay in the compiler package.
declare function collectDefinitionIssues(definition: MachineDefinition<any, any, any, any, any>): readonly DefinitionIssue[];definitionMachineDefinition<any, any, any, any, any>returnreadonly DefinitionIssue[]- Name
definition- Kind
- parameter
- Type
MachineDefinition<any, any, any, any, any>- Requirement
- required
- Name
return- Kind
- return value
- Type
readonly DefinitionIssue[]- Requirement
- n/a
command
functiondeclare function command<C, E, I, Cmd extends CommandObject>(fn: (args: ActionArgs<C, E, I>) => Cmd): CommandAction<C, E, I, Cmd>;fn(args: ActionArgs<C, E, I>) => CmdreturnCommandAction<C, E, I, Cmd>- Name
fn- Kind
- parameter
- Type
(args: ActionArgs<C, E, I>) => Cmd- Requirement
- required
- Name
return- Kind
- return value
- Type
CommandAction<C, E, I, Cmd>- Requirement
- n/a
CommandAction
interfaceinterface CommandAction<C, E, I, Cmd extends CommandObject> { readonly __kind: "command"; readonly fn: (args: ActionArgs<C, E, I>) => Cmd;}__kind"command"fn(args: ActionArgs<C, E, I>) => Cmd- Name
__kind- Kind
- property
- Type
"command"- Requirement
- required
- Name
fn- Kind
- property
- Type
(args: ActionArgs<C, E, I>) => Cmd- Requirement
- required
defineMachine
functionTyped authoring entry point. Unknown top-level, per-state and per-candidate keys are rejected both at the type level (TypeScript's excess-property check on the object literal argument) and here at runtime, so a definition that reaches a consumer through a non-literal path (spread, `as`, JS caller) still fails loudly instead of silently accepting an unsupported extension (nested/parallel states, history, entry/exit, etc. — see the addendum's "Not needed" list).
declare function defineMachine<I, V extends StateValue, C, E extends EventObject, Cmd extends CommandObject = never>(definition: MachineDefinition<I, V, C, E, Cmd>): MachineDefinition<I, V, C, E, Cmd>;definitionMachineDefinition<I, V, C, E, Cmd>returnMachineDefinition<I, V, C, E, Cmd>- Name
definition- Kind
- parameter
- Type
MachineDefinition<I, V, C, E, Cmd>- Requirement
- required
- Name
return- Kind
- return value
- Type
MachineDefinition<I, V, C, E, Cmd>- Requirement
- n/a
DefinitionIssue
interfaceinterface DefinitionIssue { readonly code: string; readonly message: string; readonly path: string;}codestringmessagestringpathstring- Name
code- Kind
- property
- Type
string- Requirement
- required
- Name
message- Kind
- property
- Type
string- Requirement
- required
- Name
path- Kind
- property
- Type
string- Requirement
- required
MACHINE_KEYS
valueexport declare const MACHINE_KEYS: ReadonlySet<string>;MachineDefinition
interfaceinterface MachineDefinition<I, V extends StateValue, C, E extends EventObject, Cmd extends CommandObject = never> { readonly id: string; readonly types?: { readonly input: I; readonly context: C; readonly events: E; readonly commands: Cmd; }; readonly bindings?: Readonly<Record<string, BindableSpec<any, C, E, I>>>; readonly context: (args: { readonly input: I; readonly bindings: Readonly<Record<string, unknown>>; }) => C; readonly initial: string | ((args: { readonly input: I; }) => string); readonly states: Readonly<Record<string, StateDefinition<I, C, E, Cmd>>>;}bindingsReadonly<Record<string, BindableSpec<any, C, E, I>>>context(args: {
readonly input: I;
readonly bindings: Readonly<Record<string, unknown>>;
}) => Cidstringinitialstring | ((args: {
readonly input: I;
}) => string)statesReadonly<Record<string, StateDefinition<I, C, E, Cmd>>>types{
readonly input: I;
readonly context: C;
readonly events: E;
readonly commands: Cmd;
}- Name
bindings- Kind
- property
- Type
Readonly<Record<string, BindableSpec<any, C, E, I>>>- Requirement
- optional
- Name
context- Kind
- property
- Type
(args: { readonly input: I; readonly bindings: Readonly<Record<string, unknown>>; }) => C- Requirement
- required
- Name
id- Kind
- property
- Type
string- Requirement
- required
- Name
initial- Kind
- property
- Type
string | ((args: { readonly input: I; }) => string)- Requirement
- required
- Name
states- Kind
- property
- Type
Readonly<Record<string, StateDefinition<I, C, E, Cmd>>>- Requirement
- required
- Name
types- Kind
- property
- Type
{ readonly input: I; readonly context: C; readonly events: E; readonly commands: Cmd; }- Requirement
- optional
STATE_KEYS
valueexport declare const STATE_KEYS: ReadonlySet<string>;StateDefinition
interfaceinterface StateDefinition<I, C, E extends EventObject, Cmd extends CommandObject> { readonly on?: Readonly<Record<string, Candidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]>>;}onReadonly<Record<string, Candidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]>>- Name
on- Kind
- property
- Type
Readonly<Record<string, Candidate<I, C, E, Cmd> | readonly Candidate<I, C, E, Cmd>[]>>- Requirement
- optional
toMachine
functionThe tree-shakable one-time normalizer: authored definition → low-level `Machine`. Implements N1–N4 from docs/decisions/statechart-api.md.
declare function toMachine<I, V extends StateValue, C, E extends EventObject, Cmd extends CommandObject = never>(definition: MachineDefinition<I, V, C, E, Cmd>): Machine<I, V, C, E, Cmd>;definitionMachineDefinition<I, V, C, E, Cmd>returnMachine<I, V, C, E, Cmd>- Name
definition- Kind
- parameter
- Type
MachineDefinition<I, V, C, E, Cmd>- Requirement
- required
- Name
return- Kind
- return value
- Type
Machine<I, V, C, E, Cmd>- Requirement
- n/a
@grassroot/statechart/inspect
inspect
attachInspector
functiondeclare function attachInspector<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machineId: string, emit: (record: InspectorRecord) => void, inspectorOptions?: InspectorOptions): () => void;serviceService<Input, Value, Context, Event, Command, Output>machineIdstringemit(record: InspectorRecord) => voidinspectorOptionsInspectorOptionsreturn() => void- Name
service- Kind
- parameter
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
machineId- Kind
- parameter
- Type
string- Requirement
- required
- Name
emit- Kind
- parameter
- Type
(record: InspectorRecord) => void- Requirement
- required
- Name
inspectorOptions- Kind
- parameter
- Type
InspectorOptions- Requirement
- optional
- Name
return- Kind
- return value
- Type
() => void- Requirement
- n/a
attachInspectorV2
functionAttach protocol-v2 observation to an already-created service. This post-construction path cannot observe commands or diagnostics, so its transition records contain empty arrays for those fields. Callers that own service construction can wrap those option channels separately.
declare function attachInspectorV2<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, meta: { readonly serviceId: string; readonly machineId: string;}, emit: (record: InspectorRecordV2) => void, options?: { readonly now?: () => number;}): () => void;serviceService<Input, Value, Context, Event, Command, Output>meta{
readonly serviceId: string;
readonly machineId: string;
}emit(record: InspectorRecordV2) => voidoptions{
readonly now?: () => number;
}return() => void- Name
service- Kind
- parameter
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
meta- Kind
- parameter
- Type
{ readonly serviceId: string; readonly machineId: string; }- Requirement
- required
- Name
emit- Kind
- parameter
- Type
(record: InspectorRecordV2) => void- Requirement
- required
- Name
options- Kind
- parameter
- Type
{ readonly now?: () => number; }- Requirement
- optional
- Name
return- Kind
- return value
- Type
() => void- Requirement
- n/a
DevtoolsHook
interfaceinterface DevtoolsHook extends DevtoolsRegistrationHook { unregister(serviceId: string): void; list(): readonly DevtoolsServiceMeta[]; subscribe(listener: (meta: DevtoolsServiceMeta, record: InspectorRecordV2) => void): () => void;}list() => readonly DevtoolsServiceMeta[]subscribe(listener: (meta: DevtoolsServiceMeta, record: InspectorRecordV2) => void) => () => voidunregister(serviceId: string) => void- Name
list- Kind
- method
- Type
() => readonly DevtoolsServiceMeta[]- Requirement
- required
- Name
subscribe- Kind
- method
- Type
(listener: (meta: DevtoolsServiceMeta, record: InspectorRecordV2) => void) => () => void- Requirement
- required
- Name
unregister- Kind
- method
- Type
(serviceId: string) => void- Requirement
- required
DevtoolsRegistrationHook
interfaceMinimal hook surface needed by framework adapters during registration.
interface DevtoolsRegistrationHook { readonly hookVersion: number; register<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">): () => void;}hookVersionnumberregister<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">) => () => void- Name
hookVersion- Kind
- property
- Type
number- Requirement
- required
- Name
register- Kind
- method
- Type
<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">) => () => void- Requirement
- required
DevtoolsServiceMeta
interfaceinterface DevtoolsServiceMeta { readonly serviceId: string; readonly machineId: string; readonly componentKey: string; readonly framework: "react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"; readonly scopeSeed: string; readonly mountedAt: number;}componentKeystringframework"react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"machineIdstringmountedAtnumberscopeSeedstringserviceIdstring- Name
componentKey- Kind
- property
- Type
string- Requirement
- required
- Name
framework- Kind
- property
- Type
"react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"- Requirement
- required
- Name
machineId- Kind
- property
- Type
string- Requirement
- required
- Name
mountedAt- Kind
- property
- Type
number- Requirement
- required
- Name
scopeSeed- Kind
- property
- Type
string- Requirement
- required
- Name
serviceId- Kind
- property
- Type
string- Requirement
- required
HOOK_GLOBAL_KEY
valueexport declare const HOOK_GLOBAL_KEY: "__GRASSROOT_DEVTOOLS_HOOK__";HOOK_VERSION
valueexport declare const HOOK_VERSION: 1;export declare const INSPECTOR_PROTOCOL_VERSION: 1;export declare const INSPECTOR_PROTOCOL_VERSION_2: 2;InspectorOptions
interfaceinterface InspectorOptions { now?: () => number;}now() => number- Name
now- Kind
- property
- Type
() => number- Requirement
- optional
InspectorRecord
typetype InspectorRecord = { protocol: 1; kind: "snapshot"; machineId: string; version: number; status: string; value: StateValue; at: number;} | { protocol: 1; kind: "command"; machineId: string; command: CommandObject; at: number;} | { protocol: 1; kind: "diagnostic"; machineId: string; diagnostic: DiagnosticObject; at: number;} | { protocol: 1; kind: "error"; machineId: string; phase: string; at: number;};InspectorRecordV2
typetype InspectorRecordV2 = (RecordBase & { readonly kind: "snapshot"; readonly version: number; readonly status: Snapshot<any, any, any>["status"]; readonly value: StateValue; readonly context: unknown;}) | (RecordBase & { readonly kind: "event"; readonly event: EventObject; readonly queuePosition: number; readonly source: "external" | "command" | "scheduled";}) | (RecordBase & { readonly kind: "transition"; readonly from: StateValue; readonly to: StateValue; readonly event: EventObject; readonly commands: readonly CommandObject[]; readonly diagnostics: readonly DiagnosticObject[]; readonly durationMs: number;}) | (RecordBase & { readonly kind: "input"; readonly prev: unknown; readonly next: unknown;}) | (RecordBase & { readonly kind: "lifecycle"; readonly phase: "start" | "stop";}) | (RecordBase & { readonly kind: "command"; readonly command: CommandObject;}) | (RecordBase & { readonly kind: "diagnostic"; readonly diagnostic: DiagnosticObject;}) | (RecordBase & { readonly kind: "error"; readonly phase: string;});RedactHook
typetype RedactHook = (path: readonly (string | number)[], value: unknown) => JsonValue | undefined;registerWithHook
functiondeclare function registerWithHook<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">): (() => void) | undefined;serviceService<Input, Value, Context, Event, Command, Output>machineMachine<Input, Value, Context, Event, Command, Output>metaOmit<DevtoolsServiceMeta, "mountedAt">return(() => void) | undefined- Name
service- Kind
- parameter
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
machine- Kind
- parameter
- Type
Machine<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
meta- Kind
- parameter
- Type
Omit<DevtoolsServiceMeta, "mountedAt">- Requirement
- required
- Name
return- Kind
- return value
- Type
(() => void) | undefined- Requirement
- n/a
serializeContext
functionConvert arbitrary context to JSON-safe data without ever throwing.
declare function serializeContext(context: unknown, redact?: RedactHook): JsonValue;contextunknownredactRedactHookreturnJsonValue- Name
context- Kind
- parameter
- Type
unknown- Requirement
- required
- Name
redact- Kind
- parameter
- Type
RedactHook- Requirement
- optional
- Name
return- Kind
- return value
- Type
JsonValue- Requirement
- n/a
withInspector
functiondeclare function withInspector<Opts extends ServiceOptionsConstraint>(machineId: string, options: Opts, emit: (record: InspectorRecord) => void, inspectorOptions?: InspectorOptions): Opts;machineIdstringoptionsOptsemit(record: InspectorRecord) => voidinspectorOptionsInspectorOptionsreturnOpts- Name
machineId- Kind
- parameter
- Type
string- Requirement
- required
- Name
options- Kind
- parameter
- Type
Opts- Requirement
- required
- Name
emit- Kind
- parameter
- Type
(record: InspectorRecord) => void- Requirement
- required
- Name
inspectorOptions- Kind
- parameter
- Type
InspectorOptions- Requirement
- optional
- Name
return- Kind
- return value
- Type
Opts- Requirement
- n/a
@grassroot/statechart/inspect/register
inspect/register
DevtoolsRegistrationHook
interfaceMinimal hook surface needed by framework adapters during registration.
interface DevtoolsRegistrationHook { readonly hookVersion: number; register<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">): () => void;}hookVersionnumberregister<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">) => () => void- Name
hookVersion- Kind
- property
- Type
number- Requirement
- required
- Name
register- Kind
- method
- Type
<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">) => () => void- Requirement
- required
DevtoolsServiceMeta
interfaceinterface DevtoolsServiceMeta { readonly serviceId: string; readonly machineId: string; readonly componentKey: string; readonly framework: "react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"; readonly scopeSeed: string; readonly mountedAt: number;}componentKeystringframework"react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"machineIdstringmountedAtnumberscopeSeedstringserviceIdstring- Name
componentKey- Kind
- property
- Type
string- Requirement
- required
- Name
framework- Kind
- property
- Type
"react" | "vue" | "solid" | "svelte" | "angular" | "vanilla"- Requirement
- required
- Name
machineId- Kind
- property
- Type
string- Requirement
- required
- Name
mountedAt- Kind
- property
- Type
number- Requirement
- required
- Name
scopeSeed- Kind
- property
- Type
string- Requirement
- required
- Name
serviceId- Kind
- property
- Type
string- Requirement
- required
HOOK_GLOBAL_KEY
valueexport declare const HOOK_GLOBAL_KEY: "__GRASSROOT_DEVTOOLS_HOOK__";HOOK_VERSION
valueexport declare const HOOK_VERSION: 1;registerWithHook
functiondeclare function registerWithHook<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output>(service: Service<Input, Value, Context, Event, Command, Output>, machine: Machine<Input, Value, Context, Event, Command, Output>, meta: Omit<DevtoolsServiceMeta, "mountedAt">): (() => void) | undefined;serviceService<Input, Value, Context, Event, Command, Output>machineMachine<Input, Value, Context, Event, Command, Output>metaOmit<DevtoolsServiceMeta, "mountedAt">return(() => void) | undefined- Name
service- Kind
- parameter
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
machine- Kind
- parameter
- Type
Machine<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
meta- Kind
- parameter
- Type
Omit<DevtoolsServiceMeta, "mountedAt">- Requirement
- required
- Name
return- Kind
- return value
- Type
(() => void) | undefined- Requirement
- n/a
@grassroot/statechart/persist
persist
migratePersistedSnapshot
functionv1 → v2 migration (DR-2). v1 had no `output` field; a v1 payload migrates by re-stamping the schema. Throws on payloads that are not v1-shaped enough to migrate (schema !== 1).
declare function migratePersistedSnapshot(data: unknown): PersistedSnapshot;dataunknownreturnPersistedSnapshot- Name
data- Kind
- parameter
- Type
unknown- Requirement
- required
- Name
return- Kind
- return value
- Type
PersistedSnapshot- Requirement
- n/a
PersistedSnapshot
interfaceinterface PersistedSnapshot { readonly schema: typeof SNAPSHOT_SCHEMA_VERSION; readonly machineId: string; readonly value: StateValue; readonly context: JsonValue; readonly version: number; readonly status: "idle" | "active" | "done" | "stopped" | "error"; readonly output?: JsonValue;}contextJsonValuemachineIdstringoutputJsonValueschematypeof SNAPSHOT_SCHEMA_VERSIONstatus"idle" | "active" | "done" | "stopped" | "error"valueStateValueversionnumber- Name
context- Kind
- property
- Type
JsonValue- Requirement
- required
- Name
machineId- Kind
- property
- Type
string- Requirement
- required
- Name
output- Kind
- property
- Type
JsonValue- Requirement
- optional
- Name
schema- Kind
- property
- Type
typeof SNAPSHOT_SCHEMA_VERSION- Requirement
- required
- Name
status- Kind
- property
- Type
"idle" | "active" | "done" | "stopped" | "error"- Requirement
- required
- Name
value- Kind
- property
- Type
StateValue- Requirement
- required
- Name
version- Kind
- property
- Type
number- Requirement
- required
restoreService
functiondeclare function restoreService(): never;returnnever- Name
return- Kind
- return value
- Type
never- Requirement
- n/a
serializeSnapshot
functiondeclare function serializeSnapshot(machineId: string, snapshot: Snapshot<any, any, any>): PersistedSnapshot;machineIdstringsnapshotSnapshot<any, any, any>returnPersistedSnapshot- Name
machineId- Kind
- parameter
- Type
string- Requirement
- required
- Name
snapshot- Kind
- parameter
- Type
Snapshot<any, any, any>- Requirement
- required
- Name
return- Kind
- return value
- Type
PersistedSnapshot- Requirement
- n/a
SNAPSHOT_SCHEMA_VERSION
valueexport declare const SNAPSHOT_SCHEMA_VERSION: 2;validatePersistedSnapshot
functiondeclare function validatePersistedSnapshot(machineId: string, data: unknown): { ok: true; snapshot: PersistedSnapshot;} | { ok: false; reason: "schema-version-mismatch" | "machine-mismatch" | "malformed"; detail: string;};machineIdstringdataunknownreturn{
ok: true;
snapshot: PersistedSnapshot;
} | {
ok: false;
reason: "schema-version-mismatch" | "machine-mismatch" | "malformed";
detail: string;
}- Name
machineId- Kind
- parameter
- Type
string- Requirement
- required
- Name
data- Kind
- parameter
- Type
unknown- Requirement
- required
- Name
return- Kind
- return value
- Type
{ ok: true; snapshot: PersistedSnapshot; } | { ok: false; reason: "schema-version-mismatch" | "machine-mismatch" | "malformed"; detail: string; }- Requirement
- n/a
@grassroot/statechart/scheduler
scheduler
CancelCommand
typeReserved command: cancel the pending timer under `key`; no-op if absent.
type CancelCommand = { readonly type: "statechart.cancel"; readonly key: string;};keystringtype"statechart.cancel"- Name
key- Kind
- property
- Type
string- Requirement
- required
- Name
type- Kind
- property
- Type
"statechart.cancel"- Requirement
- required
createNativeScheduler
functiondeclare function createNativeScheduler(): Scheduler;returnScheduler- Name
return- Kind
- return value
- Type
Scheduler- Requirement
- n/a
createScheduledEventRunner
functionDecorate `next` with scheduled-event support. Keys are scoped to this runner instance (one runner = one service): a same-key `schedule` replaces the pending timer, `cancel` clears it (no-op when absent), and a fired timer delivers its event through the ordinary `send` given to the command that scheduled it — joining the FIFO queue as an external event (S1). Every scheduling command's `AbortSignal` gets an abort listener that clears its timer; `stop()`/error (S4/S5) aborts every pending timer for the service, and the runner never calls `send` after abort.
declare function createScheduledEventRunner<Command extends CommandObject, Event extends EventObject>(scheduler: Scheduler, next?: RunCommand<Command, Event>): RunCommand<Command | ScheduledEventCommand<Event>, Event>;schedulerSchedulernextRunCommand<Command, Event>returnRunCommand<Command | ScheduledEventCommand<Event>, Event>- Name
scheduler- Kind
- parameter
- Type
Scheduler- Requirement
- required
- Name
next- Kind
- parameter
- Type
RunCommand<Command, Event>- Requirement
- optional
- Name
return- Kind
- return value
- Type
RunCommand<Command | ScheduledEventCommand<Event>, Event>- Requirement
- n/a
createVirtualScheduler
functiondeclare function createVirtualScheduler(): VirtualScheduler;returnVirtualScheduler- Name
return- Kind
- return value
- Type
VirtualScheduler- Requirement
- n/a
RunCommand
type`runCommand`-compatible function shape (same signature as `createService`'s `options.runCommand`).
type RunCommand<Command extends CommandObject, Event extends EventObject> = (command: Command, tools: RunCommandTools<Event>) => void | (() => void);RunCommandTools
interface`runCommand`-compatible tools, matching `createService`'s option shape.
interface RunCommandTools<Event extends EventObject> { readonly send: (event: Event) => void; readonly signal: AbortSignal;}send(event: Event) => voidsignalAbortSignal- Name
send- Kind
- property
- Type
(event: Event) => void- Requirement
- required
- Name
signal- Kind
- property
- Type
AbortSignal- Requirement
- required
ScheduleCommand
typeS13 — scheduled events (docs/decisions/statechart-semantics.md). `createScheduledEventRunner` is a `runCommand` decorator: it interprets two reserved command shapes over the given `Scheduler` and forwards every other command to `next` (the component's own runner) unchanged, with the same `tools`. Reserved command: schedule `send(event)` after `delayMs`. Same-key scheduling replaces the pending timer (cancel-then-schedule).
type ScheduleCommand<Event extends EventObject = EventObject> = { readonly type: "statechart.schedule"; readonly key: string; readonly event: Event; readonly delayMs: number;};delayMsnumbereventEventkeystringtype"statechart.schedule"- Name
delayMs- Kind
- property
- Type
number- Requirement
- required
- Name
event- Kind
- property
- Type
Event- Requirement
- required
- Name
key- Kind
- property
- Type
string- Requirement
- required
- Name
type- Kind
- property
- Type
"statechart.schedule"- Requirement
- required
Union of the two reserved command shapes this runner interprets.
type ScheduledEventCommand<Event extends EventObject = EventObject> = ScheduleCommand<Event> | CancelCommand;Scheduler
interfaceinterface Scheduler { now(): number; setTimeout(callback: () => void, delayMs: number): SchedulerHandle; clearTimeout(handle: SchedulerHandle): void;}clearTimeout(handle: SchedulerHandle) => voidnow() => numbersetTimeout(callback: () => void, delayMs: number) => SchedulerHandle- Name
clearTimeout- Kind
- method
- Type
(handle: SchedulerHandle) => void- Requirement
- required
- Name
now- Kind
- method
- Type
() => number- Requirement
- required
- Name
setTimeout- Kind
- method
- Type
(callback: () => void, delayMs: number) => SchedulerHandle- Requirement
- required
SchedulerHandle
typetype SchedulerHandle = { readonly __brand: "SchedulerHandle";};__brand"SchedulerHandle"- Name
__brand- Kind
- property
- Type
"SchedulerHandle"- Requirement
- required
export declare const VIRTUAL_SCHEDULER_MAX_TASKS_PER_RUN: 10000;VirtualScheduler
interfaceinterface VirtualScheduler extends Scheduler { advance(byMs: number): void; flush(): void; pendingCount(): number;}advance(byMs: number) => voidflush() => voidpendingCount() => number- Name
advance- Kind
- method
- Type
(byMs: number) => void- Requirement
- required
- Name
flush- Kind
- method
- Type
() => void- Requirement
- required
- Name
pendingCount- Kind
- method
- Type
() => number- Requirement
- required
@grassroot/statechart/service
service
createService
functiondeclare function createService<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output = never>(machine: Machine<Input, Value, Context, Event, Command, Output>, options: { input: Input; runCommand?: (command: Command, tools: { send: (event: Event) => void; signal: AbortSignal; }) => void | (() => void); onDiagnostic?: (diagnostic: DiagnosticObject & { readonly machineId: string; }) => void; onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void;}): Service<Input, Value, Context, Event, Command, Output>;machineMachine<Input, Value, Context, Event, Command, Output>options{
input: Input;
runCommand?: (command: Command, tools: {
send: (event: Event) => void;
signal: AbortSignal;
}) => void | (() => void);
onDiagnostic?: (diagnostic: DiagnosticObject & {
readonly machineId: string;
}) => void;
onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void;
}returnService<Input, Value, Context, Event, Command, Output>- Name
machine- Kind
- parameter
- Type
Machine<Input, Value, Context, Event, Command, Output>- Requirement
- required
- Name
options- Kind
- parameter
- Type
{ input: Input; runCommand?: (command: Command, tools: { send: (event: Event) => void; signal: AbortSignal; }) => void | (() => void); onDiagnostic?: (diagnostic: DiagnosticObject & { readonly machineId: string; }) => void; onError?: (error: ServiceError<Value, Context, Event, Command, Output>) => void; }- Requirement
- required
- Name
return- Kind
- return value
- Type
Service<Input, Value, Context, Event, Command, Output>- Requirement
- n/a
@grassroot/statechart/types
types
CommandObject
typetype CommandObject = { readonly type: string; readonly [key: string]: JsonValue;};typestring- Name
type- Kind
- property
- Type
string- Requirement
- required
DiagnosticObject
typetype DiagnosticObject = { readonly code: string; readonly message: string; readonly severity: "warning" | "error"; readonly data?: JsonValue;};codestringdataJsonValuemessagestringseverity"warning" | "error"- Name
code- Kind
- property
- Type
string- Requirement
- required
- Name
data- Kind
- property
- Type
JsonValue- Requirement
- optional
- Name
message- Kind
- property
- Type
string- Requirement
- required
- Name
severity- Kind
- property
- Type
"warning" | "error"- Requirement
- required
EventObject
typetype EventObject = { readonly type: string;};typestring- Name
type- Kind
- property
- Type
string- Requirement
- required
JsonValue
typeThe low-level `@grassroot/statechart` contract, frozen in phase 0 of GRASSROOT_STATECHART_EXECUTION_PLAN.md. The shapes here are lifted verbatim from GRASSROOT_STATECHART_PLATFORM_PLAN.md ("Native statechart model"). Decision records: docs/decisions/statechart-api.md and docs/decisions/statechart-semantics.md. The authoring layer (phase 5) must compile to this contract with identical semantics. This file is types plus one declaration only — no runtime code ships in phase 0. `createService` is implemented in phase 1 (src/service.ts).
type JsonValue = null | boolean | number | string | readonly JsonValue[] | { readonly [key: string]: JsonValue;};Machine
interfaceinterface Machine<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject = never, Output = never> { readonly id: string; initial(input: Readonly<Input>): Transition<Value, Context, Command, Output>; transition(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>): Transition<Value, Context, Command, Output>; sync?(state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>): Transition<Value, Context, Command, Output>;}idstringinitial(input: Readonly<Input>) => Transition<Value, Context, Command, Output>sync((state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>) => Transition<Value, Context, Command, Output>) | undefinedtransition(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Name
id- Kind
- property
- Type
string- Requirement
- required
- Name
initial- Kind
- method
- Type
(input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Requirement
- required
- Name
sync- Kind
- method
- Type
((state: MachineState<Value, Context, Output>, previous: Readonly<Input>, next: Readonly<Input>) => Transition<Value, Context, Command, Output>) | undefined- Requirement
- optional
- Name
transition- Kind
- method
- Type
(state: MachineState<Value, Context, Output>, event: Readonly<Event>, input: Readonly<Input>) => Transition<Value, Context, Command, Output>- Requirement
- required
MachineState
interfaceinterface MachineState<Value extends StateValue, Context, Output = never> { readonly value: Value; readonly context: Readonly<Context>; readonly output?: Output;}contextReadonly<Context>outputOutputvalueValue- Name
context- Kind
- property
- Type
Readonly<Context>- Requirement
- required
- Name
output- Kind
- property
- Type
Output- Requirement
- optional
- Name
value- Kind
- property
- Type
Value- Requirement
- required
Service
interfaceinterface Service<Input, Value extends StateValue, Context, Event extends EventObject, Command extends CommandObject, Output = never> { start(): void; stop(): void; getSnapshot(): Snapshot<Value, Context, Output>; getInput(): Readonly<Input>; send(event: Event): Snapshot<Value, Context, Output>; setInput(next: Input): Snapshot<Value, Context, Output>; subscribe<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }): () => void; batch<Result>(work: () => Result): Result;}batch<Result>(work: () => Result) => ResultgetInput() => Readonly<Input>getSnapshot() => Snapshot<Value, Context, Output>send(event: Event) => Snapshot<Value, Context, Output>setInput(next: Input) => Snapshot<Value, Context, Output>start() => voidstop() => voidsubscribe<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }) => () => void- Name
batch- Kind
- method
- Type
<Result>(work: () => Result) => Result- Requirement
- required
- Name
getInput- Kind
- method
- Type
() => Readonly<Input>- Requirement
- required
- Name
getSnapshot- Kind
- method
- Type
() => Snapshot<Value, Context, Output>- Requirement
- required
- Name
send- Kind
- method
- Type
(event: Event) => Snapshot<Value, Context, Output>- Requirement
- required
- Name
setInput- Kind
- method
- Type
(next: Input) => Snapshot<Value, Context, Output>- Requirement
- required
- Name
start- Kind
- method
- Type
() => void- Requirement
- required
- Name
stop- Kind
- method
- Type
() => void- Requirement
- required
- Name
subscribe- Kind
- method
- Type
<Selected>(selector: (snapshot: Snapshot<Value, Context, Output>) => Selected, listener: (value: Selected, previous: Selected) => void, options?: { equals?: (a: Selected, b: Selected) => boolean; immediate?: boolean; }) => () => void- Requirement
- required
ServiceError
interfaceinterface ServiceError<Value extends StateValue, Context, Event, Command, Output = never> { readonly phase: "start" | "transition" | "sync" | "diagnostic" | "command"; readonly cause: unknown; readonly machineId: string; readonly snapshot: Snapshot<Value, Context, Output>; readonly event?: Event; readonly diagnostic?: DiagnosticObject; readonly command?: Command;}causeunknowncommandCommanddiagnosticDiagnosticObjecteventEventmachineIdstringphase"start" | "transition" | "sync" | "diagnostic" | "command"snapshotSnapshot<Value, Context, Output>- Name
cause- Kind
- property
- Type
unknown- Requirement
- required
- Name
command- Kind
- property
- Type
Command- Requirement
- optional
- Name
diagnostic- Kind
- property
- Type
DiagnosticObject- Requirement
- optional
- Name
event- Kind
- property
- Type
Event- Requirement
- optional
- Name
machineId- Kind
- property
- Type
string- Requirement
- required
- Name
phase- Kind
- property
- Type
"start" | "transition" | "sync" | "diagnostic" | "command"- Requirement
- required
- Name
snapshot- Kind
- property
- Type
Snapshot<Value, Context, Output>- Requirement
- required
Snapshot
interfaceinterface Snapshot<Value extends StateValue, Context, Output = never> { readonly value: Value; readonly context: Readonly<Context>; readonly version: number; readonly status: "idle" | "active" | "done" | "stopped" | "error"; readonly output?: Output; readonly error?: unknown;}contextReadonly<Context>errorunknownoutputOutputstatus"idle" | "active" | "done" | "stopped" | "error"valueValueversionnumber- Name
context- Kind
- property
- Type
Readonly<Context>- Requirement
- required
- Name
error- Kind
- property
- Type
unknown- Requirement
- optional
- Name
output- Kind
- property
- Type
Output- Requirement
- optional
- Name
status- Kind
- property
- Type
"idle" | "active" | "done" | "stopped" | "error"- Requirement
- required
- Name
value- Kind
- property
- Type
Value- Requirement
- required
- Name
version- Kind
- property
- Type
number- Requirement
- required
StateValue
typetype StateValue = string | { readonly [region: string]: StateValue;};Transition
interfaceinterface Transition<Value extends StateValue, Context, Command extends CommandObject, Output = never> { readonly state: MachineState<Value, Context, Output>; readonly commands?: readonly Command[]; readonly diagnostics?: readonly DiagnosticObject[];}commandsreadonly Command[]diagnosticsreadonly DiagnosticObject[]stateMachineState<Value, Context, Output>- Name
commands- Kind
- property
- Type
readonly Command[]- Requirement
- optional
- Name
diagnostics- Kind
- property
- Type
readonly DiagnosticObject[]- Requirement
- optional
- Name
state- Kind
- property
- Type
MachineState<Value, Context, Output>- Requirement
- required