Machine authoring guide

The core APIs and nested parameters used to define, implement, and run a machine, organized in authoring order.

5 sections 11 core APIs ./Machine

Define state topology

Declare the complete state tree and its schema-backed values before constructing the machine.

#

state

variable
Source
declare const state: StateConstructor

Defines root or nested state schemas while preserving the exact child topology.

Pass the root descriptor to make. Nested states can be declared inline or reused by mounting a descriptor in multiple places. Initial edges and value constructors belong in the handler tree.

Repeated compound state typescript
import { Machine } from "@typeonce/effect-machine"
import { Schema } from "effect"

const TradingState = Schema.TaggedUnion({
  InSession: {},
  Applying: {}
})
const TradingSlot = Machine.state({
  states: {
    Idle: {},
    InSession: TradingState.cases.InSession,
    Applying: TradingState.cases.Applying
  }
})

const States = Machine.state({
  states: {
    slot1: TradingSlot,
    slot2: TradingSlot
  }
})

Atomic and final states

Source

Configuration accepted for an atomic object state node.

Omit schema when the state owns no value. A schema-less final may still declare output.

annotations
Source
readonly annotations?: SchemaLessStateAnnotations

Descriptive metadata for a schema-less state.

output
Source
readonly output?: Schema.Top

Optional schema describing the terminal value produced by this final state.

schema
Source
readonly schema: TaggedSchema

Tagged schema that owns the state's decoded value.

type
Source
readonly type?: "active"
readonly type: "final"

Declares an ordinary active state. Omitted values default to "active".

Compound states

Source

Configuration accepted for a compound object state node. Omit schema when the compound state exists only to own control topology.

annotations
Source
readonly annotations?: SchemaLessStateAnnotations

Descriptive metadata for a schema-less state.

schema
Source
readonly schema: TaggedSchema

Tagged schema that owns the compound state's decoded value.

states
Source
readonly states: StateTree

Nested state nodes owned by this compound state.

type
Source
readonly type?: "active"

Compound states are ordinary active states.

Parallel states

Source

Configuration accepted for a parallel object state node. Omit schema when the parallel state exists only to own its regions.

annotations
Source
readonly annotations?: SchemaLessStateAnnotations

Descriptive metadata for a schema-less state.

output
Source
readonly output?: Schema.Top

Optional schema describing the value produced after every region completes.

schema
Source
readonly schema: TaggedSchema

Tagged schema that owns the parallel state's decoded value.

states
Source
readonly states: StateTree

Child regions that are entered and remain active simultaneously.

type
Source
readonly type: "parallel"

Selects parallel-region semantics for the node.

History states

Source

Pseudo-state that restores the last active configuration of its parent.

History nodes are transition targets only. They never become active and therefore do not declare a state value schema or lifecycle handlers. Both recorded history and a first-use default can rebuild inactive ancestors. A default is a complete root configuration containing the history owner, so its validity is independent of the transition source.

annotations
Source
readonly annotations?: SchemaLessStateAnnotations

Descriptive metadata used by visualization and documentation tooling.

history
Source
readonly history?: "shallow" | "deep"

Restores only the direct child for shallow history or the complete descendant configuration for deep history.

Default "shallow"
type
Source
readonly type: "history"

Selects history pseudo-state semantics.

Choice states

Source

Transient decision pseudo-state resolved immediately when targeted.

Choice nodes have no value and never belong to an active configuration. Their required choice implementation uses ordinary TypeScript or an Effect to select a typed target.

annotations
Source
readonly annotations?: SchemaLessStateAnnotations

Descriptive metadata used by visualization and documentation tooling.

type
Source
readonly type: "choice"

Selects transient choice pseudo-state semantics.

Annotations

Source

Descriptive annotations exposed for compiled state nodes.

Schema-backed states resolve their complete Effect Schema annotation map. Schema-less active states and pseudo-states accept only the descriptive fields below. Annotations never affect state identity, targeting, or runtime behavior.

description
Source
readonly description?: string

Short explanation of the state node's domain meaning.

documentation
Source
readonly documentation?: string

Longer documentation text associated with the state node.

title
Source
readonly title?: string

Human-readable label used by visualization and documentation tooling.

Since v0.15.0

Define event protocols

Describe public input, machine-local events, outward notifications, and parent ownership.

#

events

variable
Source
declare const events: <Cases extends Readonly<Record<string, Schema.Struct.Fields>>>(cases: Cases & ValidateEventFields<NoInfer<Cases>> & ValidateEventProtocolBuilder<"public", EventFieldsSchemas<Cases>>) => Machine.EventProtocol<"public", EventFieldsSchemas<Cases>>

Defines a public event protocol from tagged field records.

Constructors defer schema validation until delivery. Use eventsFromSchemas when importing existing tagged schemas or protocol descriptors.

Example typescript
const Events = Machine.events({ Increment: { by: Schema.Number }, Reset: {} })
const increment = Events.Increment({ by: 1 })
Since v0.32.0
#

internalEvents

variable
Source
declare const internalEvents: <Cases extends Readonly<Record<string, Schema.Struct.Fields>>>(cases: Cases & ValidateEventFields<NoInfer<Cases>> & ValidateEventProtocolBuilder<"internal", EventFieldsSchemas<Cases>>) => Machine.EventProtocol<"internal", EventFieldsSchemas<Cases>>

Defines an internal event protocol and returns deferred constructors for every statically finite configured event tag.

Use these constructors for raised events and other machine-local deliveries. Construction failures are reported through the owning machine's MachineSchemaDecodeError channel.

Example typescript
const Internal = Machine.internalEventsFromSchemas(
  Schema.TaggedUnion({
    Loaded: { value: Schema.String },
    Failed: { message: Schema.String }
  })
)
const machine = Machine.make({ internalEvents: Internal, ... })

// Inside a transition callback:
enqueue.raise(Internal.Loaded({ value }))
Since v0.10.0
#

emittedEvents

variable
Source
declare const emittedEvents: <Cases extends Readonly<Record<string, Schema.Struct.Fields>>>(cases: Cases & ValidateEventFields<NoInfer<Cases>> & ValidateEventProtocolBuilder<"emitted", EventFieldsSchemas<Cases>>) => Machine.EventProtocol<"emitted", EventFieldsSchemas<Cases>>

Defines the ephemeral notifications a machine may publish to external observers. Emitted events are separate from machine input and are never sent implicitly to a parent machine. Observe them through MachineRef.emissions or the AtomMachine emission stream adapters.

Example typescript
const Emitted = Machine.emittedEventsFromSchemas(
  Schema.TaggedUnion({
    Saved: { id: Schema.String }
  })
)
const machine = Machine.make({ emittedEvents: Emitted, ... })
Since v0.10.0
#

parent

variable
Source
declare const parent: <Events extends ReadonlyArray<Machine.TaggedSchema>>(events: Machine.EventProtocol<"public", Events>) => Parent<"required", Events>

Requires the machine to run as an owned child whose parent accepts the supplied public event protocol.

Required-parent machines expose a non-optional parent target in behavior contexts and are rejected by root execution APIs.

Since v0.17.0
#

optionalParent

variable
Source
declare const optionalParent: <Events extends ReadonlyArray<Machine.TaggedSchema>>(events: Machine.EventProtocol<"public", Events>) => Parent<"optional", Events>

Declares public events a machine may send to its owner while preserving the ability to run that machine as a root.

Optional-parent machines expose parent as a possibly absent target.

Since v0.17.0

Create the definition

Combine topology and protocols into a reusable machine definition with an explicit initial target.

#

make

variable
Source
declare const make: <Root extends StateNodeConfig, InputEvents extends readonly Array<TaggedSchema>, Emits extends readonly Array<TaggedSchema> = readonly [], Input extends Top = Void, InitialE = never, InitialR = never, InternalEvents extends readonly Array<TaggedSchema> = readonly [], ParentDeclaration extends Any | undefined = undefined, Effects extends Readonly<Record<string, Program<Effect<unknown, unknown, unknown>>>> = {}, Streams extends Readonly<Record<string, Program<Stream<unknown, unknown, unknown>>>> = {}, Timers extends Readonly<Record<string, Program<Input>>> = {}, Logics extends Readonly<Record<string, unknown>> = {}, Children extends Readonly<Record<string, Any>> = {}, Branches extends Readonly<Record<string, Readonly<Record<string, BranchDeclaration<NoInfer<Root>, RootSchemas<NoInfer<Root>>>>>>> = {}>(config: {
  readonly branches?: Branches & { [K in string | number | symbol]: ValidateTransitionBranchRecord<NoInfer<Branches[K]>> };
  readonly children?: Children;
  readonly effects?: Effects & ValidatePrograms<Effects>;
  readonly emittedEvents?: EventProtocol<"emitted", Emits>;
  readonly events: EventConstructors<InputEvents, "public"> & {
    readonly [EventProtocolTypeId]: {
      readonly kind: "public";
      readonly schemas: InputEvents;
    };
  } & ValidateInputEventProtocol<NoInfer<InputEvents>, DuplicateEventTag<NoInfer<InputEvents>, never>>;
  readonly id?: string;
  readonly input?: Input;
  readonly internalEvents?: EventConstructors<InternalEvents, "internal"> & {
    readonly [EventProtocolTypeId]: {
      readonly kind: "internal";
      readonly schemas: InternalEvents;
    };
  } & ValidateInternalEventProtocol<NoInfer<InputEvents>, NoInfer<InternalEvents>, DuplicateEventTag<NoInfer<InternalEvents>, never>, Extract<TagOf<NoInfer<InputEvents>[number]>, TagOf<NoInfer<InternalEvents>[number]>>>;
  readonly logic?: Logics & ValidatePrograms<Logics> & ValidateLogicSources<NoInfer<Logics>>;
  readonly parent?: ParentDeclaration;
  readonly root: {
    readonly ~effect/Machine/State: "~effect/Machine/State";
    readonly node: Root;
  } & ReservedRootName<NoInfer<Root>>;
  readonly streams?: Streams & ValidatePrograms<Streams>;
  readonly timers?: Timers & ValidatePrograms<Timers>;
} & UniqueSourceNames<NoInfer<Effects>, NoInfer<Streams>, NoInfer<Timers>, NoInfer<Logics>, NoInfer<Children>>) => MakeResult<Root, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents, ParentDeclaration, Effects, Streams, Timers, Logics, Children, Branches>

Creates a schema-first machine definition.

Details

State and event schemas provide runtime boundary validation while their decoded types drive handler, state, event, target, error, and service inference. State-tree validation is applied whether states comes from states or is passed inline. Call handle on the returned definition to implement state behavior with ordinary TypeScript control flow.

initial is a target-first callback. Its outer selector runs once while the definition is captured; an attached .resolve(...) callback remains lazy until initial planning. Return a bare selected state when its schema supports default construction.

Machine.events defines the public input protocol. Machine.internalEvents adds raised events and other machine-local deliveries. Machine.emittedEvents defines outward ephemeral notifications. The parent configuration accepts Machine.parent(events) for a required owner or Machine.optionalParent(events) for a root-capable machine. All descriptors expose deferred constructors while retaining their schemas opaquely for runtime validation. Public and internal tags must be disjoint.

Typed counter machine typescript
import { Machine } from "@typeonce/effect-machine"
import { Schema } from "effect"
class Count extends Schema.TaggedClass<Count>("Count")("Count", {
  value: Schema.Number
}) {
}
class Increment extends Schema.TaggedClass<Increment>("Increment")("Increment", {
  by: Schema.Number
}) {
}
const States = Machine.state({ states: { Count } })
const Events = Machine.eventsFromSchemas(Increment)
const counter = Machine.make({
  root: States,
  events: Events
}).handle({
  initial: {
    target: "Count",
    decoded: true,
    data: new Count({ value: 0 })
  },
  states: {
    Count: {
      on: {
        Increment: {
          update: "Count",
          decoded: true,
          data: ({ event, state }) => new Count({ value: state.value + event.by })
        }
      }
    }
  }
})

Configuration

Complete schema-first machine definition.

branches
Source
readonly branches?: Branches & { [K in string | number | symbol]: ValidateTransitionBranchRecord<NoInfer<Branches[K]>> }

Named groups of inspectable destinations used by transition resolvers.

children
Source
readonly children?: Children

Child machine descriptors registered for state-owned invocation.

effects
Source
readonly effects?: Effects & ValidatePrograms<Effects>

Lazy Effects or functions with one required input, invoked by registered name.

emittedEvents
Source
readonly emittedEvents?: EventProtocol<"emitted", Emits>

Ephemeral notifications that handlers may publish to observers.

events
Source
readonly events: EventConstructors<InputEvents, "public"> & {
  readonly [EventProtocolTypeId]: {
    readonly kind: "public";
    readonly schemas: InputEvents;
  };
} & ValidateInputEventProtocol<NoInfer<InputEvents>, DuplicateEventTag<NoInfer<InputEvents>, never>>

Public events accepted by independently running machine references.

id
Source
readonly id?: string

Stable definition identifier used by inspection and visualization.

input
Source
readonly input?: Input

Schema used to decode input before initial-state construction.

internalEvents
Source
readonly internalEvents?: EventConstructors<InternalEvents, "internal"> & {
  readonly [EventProtocolTypeId]: {
    readonly kind: "internal";
    readonly schemas: InternalEvents;
  };
} & ValidateInternalEventProtocol<NoInfer<InputEvents>, NoInfer<InternalEvents>, DuplicateEventTag<NoInfer<InternalEvents>, never>, Extract<TagOf<NoInfer<InputEvents>[number]>, TagOf<NoInfer<InternalEvents>[number]>>>

Machine-local events used by raised events and other internal deliveries.

logic
Source
readonly logic?: Logics & ValidatePrograms<Logics> & ValidateLogicSources<NoInfer<Logics>>

Logic values or functions of one required input; their Effect channels remain inferred.

parent
Source
readonly parent?: ParentDeclaration

Required or optional owning-machine protocol for this definition.

root
Source
readonly root: {
  readonly ~effect/Machine/State: "~effect/Machine/State";
  readonly node: Root;
} & ReservedRootName<NoInfer<Root>>

State topology and value schemas, captured by a Machine.state descriptor.

streams
Source
readonly streams?: Streams & ValidatePrograms<Streams>

Lazy Streams or functions with one required input, invoked by registered name.

timers
Source
readonly timers?: Timers & ValidatePrograms<Timers>

Cancellable delays, supplied as durations or functions of one required input.

See also
  • state for typed state-tree helpers.
Since v0.4.0

Implement state behavior

Attach state-local actions, transitions, output, and invoked lifecycles to the definition.

#

handle

method
Source
readonly handle: Handler<States, Events, Emits, Input, InitialE, InitialR, FinalStates, Output, InputEvents, ParentEvents, Registrations>

Adds typed state handlers and returns an independent machine implementation. Event dispatch maps and transition descriptors are captured by value, so later mutation of the supplied objects cannot alter the resulting machine.

Example typescript
const counter = definition.handle({ states: {
  Count: {
    on: {
      Increment: {
        update: "Count",
        decoded: ({ event, state }) => new Count({ value: state.value + event.by })
      }
    }
  }
} })

State handlers

Source

Handlers for a node of the declared root tree.

always
Source
readonly always?: Transition<S, Src, AlwaysContext<S, Ev, Em, Src, In, Pa>, Ev, Em, R, false, TransitionAcceptance>

Eventless transition evaluated during stabilization.

choice
Source
readonly choice: Transition<S, Src, ChoiceContext<S, Ev, Em, Src, In, Pa>, Ev, Em, R>

Required total transition for a transient choice state.

history
Source
readonly history?: HistoryDefaultConfig<..., ..., ..., ..., ...>

Restores the declared history reference, using its fallback on first entry.

input
Source
readonly input: RegisteredInput<R>["Type"]

Fresh machine input used by root construction and root initial callbacks.

invoke
Source
readonly invoke?: Invocation<S, Ev, Em, Src, In, Pa, R> | ReadonlyArray<...> & {
  readonly src?: ...;
}

One registered invocation or an array with distinct lifecycle identities.

on
Source
readonly on?: { [Tag in TagOf<Ev[number]>]: Transition<S, Src, HandlerContext<S, Ev, Em, Src, Tag, never, never, In, Pa>, Ev, Em, R, true, TransitionAcceptance> }

Event handlers keyed by the public or internal event tag.

onDone
Source
readonly onDone?: Transition<S, Src, DoneContext<S, Ev, Em, Src, In, Pa>, Ev, Em, R, false, TransitionAcceptance>

Handles successful invocation or state completion with its exact output type.

root
Source
readonly root: StateByIdentifier<S, Extract<"", StateIdentifier<S>>>

Root-owned data constructed before initial descendant values.

History defaults

Source

Fallback implementation for one direct history pseudo-state.

default
Source
readonly default: HistoryDefaultHandler<States, Events, Emits, ParentId>

Builds the complete fallback configuration used before history is first captured.

Inline transitions

Source

A transition with an inspectable destination and source-specific construction.

declinable
Source
readonly declinable?: "declinable" extends Acceptance ? boolean : false

Set to true when the resolver can explicitly return decline().

history
Source
readonly history: ReferenceUnion<S, HistoryIdentifier<S>>

Restores the declared history reference, using its fallback on first entry.

none
Source
readonly none: true

Accepts the event without selecting a new destination.

resolve
Source
readonly resolve?: (context: C & DeclineCapability, enqueue: Enqueue<EventOf<Ev>, EmittedEventOf<Em>>) => undefined | Declined

Selects one declared branch and may enqueue synchronous commands.

Named branch declarations

Source

A topology declaration; its state values are constructed by a resolver.

history
Source
readonly history: ReferenceUnion<S, HistoryIdentifier<S>>

Restores the declared history reference, using its fallback on first entry.

initialize
Source
readonly initialize: true

Reconstructs root and its initial children from fresh machine input supplied by the resolver.

none
Source
readonly none: true

Accepts the event without selecting a new destination.

target
Source
readonly target: ReferenceUnion<S, DestinationPath<S>>

Selects a declared descendant; its transition or bound branch constructor supplies required values.

title
Source
readonly title?: string

Optional presentation label for this named branch.

update
Source
readonly update?: ReferenceUnion<S, ValuedStateIdentifier<S>>
readonly update: ReferenceUnion<S, ValuedStateIdentifier<S>>

Replaces the complete value of a retained source or ancestor without replacing its active children.

Declinable transitions

Source

Context capability available only to explicitly declinable resolvers.

decline
Source
readonly decline: () => Declined

Declines this candidate and continues hierarchical transition selection.

Enqueued commands

Source

Synchronous commands available while a machine transition is being selected.

Enqueuing records statechart and machine operations for the selected transition. It never executes an Effect while the transition is evaluated.

emit
Source
readonly emit: (event: EmittedEventInput<Emits>) => void

Publishes an ephemeral notification to this machine's observers.

raise
Source
readonly raise: (event: EventInput<Events>) => void

Raises an event inside the current macrostep.

sendTo
Source
readonly sendTo: {
  <Event>(target: MachineTarget<Event>, event: Event): void;
  <Child extends Any>(child: Child, event: Event<Child>): void;
  <Address extends ChildAddress<never>>(child: Address, event: Event<Address>): void;
}

Sends an event to an invoked child after the transition is selected.

stop
Source
readonly stop: {
  <Child extends Any>(child: Child): void;
  <Event>(child: ChildAddress<Event>): void;
}

Stops an invoked child after the transition is selected.

Machine references

Source

Machine targets available while evaluating machine behavior.

parent
Source
readonly parent: MachineTarget<Machine.EventInputOf<ParentEvents>>
readonly parent: MachineTarget<Machine.EventInputOf<ParentEvents>> | undefined

Required target for the machine that owns this child.

self
Source
readonly self: MachineTarget<Machine.EventInputOf<InputEvents>>

Target for the current machine. Sending queues a later mailbox event.

Event handlers

Source

Context passed to a state/event handler.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: EventByTag<Events, EventTag>

Event that selected this handler, narrowed by its _tag.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete logical configuration captured at the start of this microstep.

state
Source
readonly state: StateByIdentifier<States, StateId>

Value owned by the state whose handler is running.

Entry and exit actions

Source

Context passed to an entry or exit state handler.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Event or initial-entry marker responsible for the lifecycle action.

state
Source
readonly state: StateByIdentifier<States, StateId>

Value owned by the state entering or exiting.

Eventless transitions

Source

Context passed to an eventless transition handler.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Lifecycle event retained while the eventless transition is evaluated.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete logical configuration captured at the start of this microstep.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state evaluating the eventless transition.

State completion

Source

Context passed to a state completion transition handler.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Lifecycle event retained while state completion is processed.

output
Source
readonly output: CompletionOutputByIdentifier<States, StateId>

Output produced by the completed final child or parallel regions.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete logical configuration captured at the start of this microstep.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state whose child configuration completed.

Choice resolution

Source

Context passed to a transient choice resolver. There is no state value.

ancestors
Source
readonly ancestors: { [Parent in Extract<ParentStateIdentifier<ChoiceId>, ValuedStateIdentifier<States>>]: StateByIdentifier<States, Parent> }

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: StateByIdentifier<States, Extract<ImmediateParentStateIdentifier<ChoiceId>, StateIdentifier<States>>>

Value owned by the choice node's immediate schema-backed parent.

event
Source
readonly event: LifecycleEvent<Events>

Lifecycle event that led to the transient choice.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

Final output

Source

Context passed to a final state output function.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Lifecycle event responsible for entering the final state.

state
Source
readonly state: StateByIdentifier<States, StateId>

Decoded value owned by the final state.

Parallel output

Source

Context passed to a parallel state output function.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Lifecycle event retained while parallel completion is processed.

outputs
Source
readonly outputs: ParallelOutputRegions<States, StateId>

Completion output from every direct parallel region.

state
Source
readonly state: StateByIdentifier<States, StateId>

Decoded value owned by the completed parallel state.

Invocation configuration

Source

A registered source invocation with its required input and reachable outcomes.

address
Source
readonly address: ChildAddress<LogicEventOf<InvokeResolvedSource<...>>>

Typed runtime address required for invoked logic; child descriptors carry their own address.

id
Source
readonly id: InvokeLifecycleId
readonly id?: InvokeLifecycleId

Lifecycle identifier; Effects, Streams, and timers default to their registered source name.

src
Source
readonly src: K

Name of the source registered in make.

Registered sources

Source

Source programs and named topology declarations captured by a machine definition.

branches
Source
readonly branches?: Readonly<Record<string, Readonly<Record<string, unknown>>>>

Named groups of inspectable destinations used by transition resolvers.

children
Source
readonly children?: Readonly<Record<string, Any>>

Child machine descriptors registered for state-owned invocation.

effects
Source
readonly effects?: Readonly<Record<string, Program<Effect<unknown, unknown, unknown>>>>

Lazy Effects or functions with one required input, invoked by registered name.

logic
Source
readonly logic?: Readonly<Record<string, unknown>>

Logic values or functions of one required input; their Effect channels remain inferred.

streams
Source
readonly streams?: Readonly<Record<string, Program<Stream<unknown, unknown, unknown>>>>

Lazy Streams or functions with one required input, invoked by registered name.

timers
Source
readonly timers?: Readonly<Record<string, Program<Input>>>

Cancellable delays, supplied as durations or functions of one required input.

Input mapper context

Source

Context passed to a function-valued invocation source.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

children
Source
readonly children: ChildOwner<EventOf<InputEvents>>

Process-owned child operations for dynamic child machine lifecycles.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

event
Source
readonly event: LifecycleEvent<Events>

Event or initial-entry marker responsible for starting the invocation.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

state
Source
readonly state: StateByIdentifier<States, StateId>

Value owned by the state that owns this invocation.

Completion context

Source

Context passed to an invocation's successful completion transition.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

id
Source
readonly id: string

Parent-local invocation identifier.

output
Source
readonly output: Output

Successful output produced by the invocation.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete owning-machine configuration captured for this transition.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state that owns the invocation.

Failure context

Source

Context passed to an invocation typed-failure transition.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

error
Source
readonly error: Error

Typed failure produced by the invocation.

id
Source
readonly id: string

Parent-local invocation identifier.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete owning-machine configuration captured for this transition.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state that owns the invocation.

Stream element context

Source

Context passed to a Stream invocation's element transition.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

element
Source
readonly element: Element

Next element emitted by the invoked Stream.

id
Source
readonly id: string

Parent-local invocation identifier.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Snapshot<States>

Complete owning-machine configuration captured for this transition.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state that owns the Stream invocation.

Child snapshot context

Source

Context passed to an invocation's active-snapshot transition.

ancestors
Source
readonly ancestors: ParentStateValues<States, StateId>

Schema-backed ancestor values keyed by their complete state paths.

containingState
Source
readonly containingState: ParentStateValue<States, StateId>

Value owned by the nearest schema-backed ancestor, when one exists.

id
Source
readonly id: string

Parent-local invocation identifier.

root
Source
readonly root: StateByIdentifier<States, Extract<"", StateIdentifier<States>>>

Value owned by the logical root.

snapshot
Source
readonly snapshot: Extract<RuntimeSnapshot<State, Error, Output>, {
  readonly status: "active";
}>

Latest active lifecycle snapshot published by the invoked logic or child.

state
Source
readonly state: StateByIdentifier<States, StateId>

Current value of the state that owns the invocation.

Since v0.4.0

Run and observe

Start or resume an executable machine and subscribe to its state over time.

#

start

variable
Source
declare const start: <States extends Machine.StateSchemas, Events extends ReadonlyArray<Machine.TaggedSchema>, Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [], Input extends Schema.Top = typeof Schema.Void, UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>, E = never, R = never, InitialE = never, InitialR = never, FinalStates extends Machine.StateIdentifier<States> = never, Output = never, OutputStates extends Machine.StateIdentifier<States> = never, InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events, ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []>(machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits, OutputStates, InputEvents, ParentEvents> & EnsureExecutable<States, UnhandledStates, OutputStates> & Machine.RootCompatible<ParentEvents>, ...args: [...Machine.InputArgs<Input>]) => Effect.Effect<MachineRef<Machine.Snapshot<States>, Machine.EventInputOf<InputEvents>, E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError, Output, Machine.EmittedEventOf<Emits>>, InitialE | E | ActionError<InitialR | R> | InfiniteTransitionError | MachineSchemaDecodeError | StartupError | StoppedError, ExcludeCompatibleRuntime<ExecutionServices<InitialR | R>, Machine.EventOf<Events>, Machine.EmittedEventOf<Emits>>>

Starts a machine.

When to use

Use when you want asynchronous event delivery, lifecycle snapshots, join, and machine-owned spawned or invoked children.

Details

For each accepted event the runtime plans the complete synchronous macrostep, executes closed machine commands, stops invokes for exited states, publishes the new state, delivers emitted events, and then starts invokes for entered states.

Gotchas

The returned handle's send operation only enqueues events. Transition failures are reported through the runtime snapshot, changes, and join rather than being returned by send. Sending after the machine reaches any terminal state fails immediately with StoppedError.

Example typescript
import { Machine } from "@typeonce/effect-machine"
import { Effect, Schema } from "effect"
class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {
}
const States = Machine.state({ states: { Idle } })
const machine = Machine.make({
  root: States,
  events: Machine.eventsFromSchemas()
}).handle({
  initial: {
    target: "Idle"
  },
  states: {
    Idle: {}
  }
})
const state = Effect.gen(function*() {
  const ref = yield* Machine.start(machine)
  return yield* ref.state
})
See also
  • plan for inspecting the same transition plan without executing it.
  • watch for classified terminal outcomes.
Since v0.4.0
#

resume

variable
Source
declare const resume: <States extends Machine.StateSchemas, Events extends ReadonlyArray<Machine.TaggedSchema>, Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [], Input extends Schema.Top = typeof Schema.Void, UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>, E = never, R = never, InitialE = never, InitialR = never, FinalStates extends Machine.StateIdentifier<States> = never, Output = never, OutputStates extends Machine.StateIdentifier<States> = never, InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events, ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []>(machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits, OutputStates, InputEvents, ParentEvents> & EnsureExecutable<States, UnhandledStates, OutputStates> & Machine.RootCompatible<ParentEvents>, snapshot: Machine.Snapshot<States>) => Effect.Effect<MachineRef<Machine.Snapshot<States>, Machine.EventInputOf<InputEvents>, E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError, Output, Machine.EmittedEventOf<Emits>>, MachineSchemaDecodeError, ExcludeCompatibleRuntime<ExecutionServices<R>, Machine.EventOf<Events>, Machine.EmittedEventOf<Emits>>>

Starts a fresh managed runtime from a decoded logical snapshot.

Details

resume validates and normalizes the supplied snapshot before publishing it as the first state. It does not call the machine's initial function, replay entry or transition actions, re-deliver raised or emitted events, or re-evaluate historical completion and eventless transitions. Active-state invokes start once in ancestor and document order with InitialEvent; timer invocations restart their complete duration and child-machine invocations start from their own initial state.

Only logical state, completion, and history metadata are resumed. Queues, scopes, subscriptions, fibers, spawned children, invoke progress, and prior runtime status are process-local and are not restored. A final snapshot immediately produces a completed ref with its current-machine output.

Decode encoded data explicitly with decodeSnapshot before calling this function. Stable snapshots are hosted as supplied; newly enabled eventless or completion transitions in a changed machine definition are not evaluated merely because the runtime was resumed; only ordinary subsequent transition planning can enter and stabilize states.

Example typescript
import { Machine } from "@typeonce/effect-machine"
import { Effect, Schema } from "effect"
class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {
}
const States = Machine.state({ states: { Idle } })
const machine = Machine.make({
  root: States,
  events: Machine.eventsFromSchemas()
}).handle({
  initial: {
    target: "Idle"
  },
  states: {
    Idle: {}
  }
})
const resumed = Effect.gen(function*() {
  const initial = yield* Machine.planInitial(machine)
  const encoded = yield* Machine.encodeSnapshot(machine, initial.state)
  const snapshot = yield* Machine.decodeSnapshot(machine, encoded)
  return yield* Machine.resume(machine, snapshot)
})
See also
  • decodeSnapshot for the schema and transport boundary.
  • start for ordinary initial startup.
Since v0.4.0
#

watch

variable
Source
declare const watch: <State, Event, Error = never, Output = never>(ref: MachineRef<State, Event, Error, Output>) => Stream.Stream<RuntimeOutcome<State, Error, Output>>

Returns a stream of terminal lifecycle outcomes for a running machine.

Since v0.4.0
Type at least two characters to search.