TopState
Abstract root class for every state in the hierarchy.
States are never constructed directly — the runtime binds one instance object whose
prototype moves along the class chain. Subclass TopState (or a child state), implement
your Protocol methods, and pass the root class to makeHsm.
Forwards State / Properties APIs and default StateEvents behavior.
Extended by
Type Parameters
Context
Context = Any
Protocol
Protocol extends { } | undefined = undefined
Implements
State<Context,Protocol>StateEvents<Context,Protocol>
Constructors
Constructor
new TopState<
Context,Protocol>():TopState<Context,Protocol>
Returns
TopState<Context, Protocol>
Properties
ctx
readonlyctx:Context
Domain context (injected by runtime — do not assign in constructors).
Implementation of
hsm
readonlyhsm:State<Context,Protocol>
Handler view of the machine (this inside methods delegates here for core operations).
Accessors
eventName
Get Signature
get eventName():
string
Name of the event or service currently being dispatched.
Matches the string passed to Base.post, Hsm.call, or State.postNow. Empty string when no handler is running.
Returns
string
Name of the event or service currently being dispatched.
Matches the string passed to Base.post, Hsm.call, or State.postNow. Empty string when no handler is running.
Implementation of
eventPayload
Get Signature
get eventPayload():
any[]
Arguments passed with the current dispatch, excluding injected resolve / reject
for Hsm.call services.
Empty array when idle. Typed as any[] at runtime; correlate with
EventPayload / ServiceRequest at compile time on the client.
Returns
any[]
Arguments passed with the current dispatch, excluding injected resolve / reject
for Hsm.call services.
Empty array when idle. Typed as any[] at runtime; correlate with
EventPayload / ServiceRequest at compile time on the client.
Implementation of
traceHeader
Get Signature
get traceHeader():
string
Prefix for nested trace domains, built from internal dispatch stack frames.
Empty at the top level; grows like domain|subdomain| during nested operations.
Handlers rarely need to read this directly — it is prepended automatically by
the default TraceWriter.
Returns
string
Prefix for nested trace domains, built from internal dispatch stack frames.
Empty at the top level; grows like domain|subdomain| during nested operations.
Handlers rarely need to read this directly — it is prepended automatically by
the default TraceWriter.
Implementation of
topState
Get Signature
get topState():
StateClass<Context,Protocol>
Constructor of the root state class supplied to makeHsm.
Constant for the lifetime of the instance unless you replace the entire machine.
Returns
StateClass<Context, Protocol>
Constructor of the root state class supplied to makeHsm.
Constant for the lifetime of the instance unless you replace the entire machine.
Implementation of
currentStateName
Get Signature
get currentStateName():
string
Human-readable name of currentState.
Sourced from defineStateName / registerStateNames when registered;
otherwise Class.name (unreliable under minification — register names in browser builds).
Returns
string
Human-readable name of currentState.
Sourced from defineStateName / registerStateNames when registered;
otherwise Class.name (unreliable under minification — register names in browser builds).
Implementation of
currentState
Get Signature
get currentState():
StateClass<Context,Protocol>
Constructor (Function) of the leaf state class currently executing.
Compare with topState, which is always the root composite passed to makeHsm. After a transition, this updates to the new leaf's constructor.
Returns
StateClass<Context, Protocol>
Constructor (Function) of the leaf state class currently executing.
Compare with topState, which is always the root composite passed to makeHsm. After a transition, this updates to the new leaf's constructor.
Implementation of
ctxTypeName
Get Signature
get ctxTypeName():
string
Runtime label derived from ctx constructor name, used as the first segment of
traceHeader in verbose traces.
Returns
string
Runtime label derived from ctx constructor name, used as the first segment of
traceHeader in verbose traces.
Implementation of
traceLevel
Get Signature
get traceLevel():
TraceLevel
Active trace verbosity; changing this swaps dispatch tracing behavior immediately.
Returns
Set Signature
set traceLevel(
value):void
Active trace verbosity; changing this swaps dispatch tracing behavior immediately.
Parameters
value
Returns
void
Active trace verbosity; changing this swaps dispatch tracing behavior immediately.
See
TraceLevel
Implementation of
topStateName
Get Signature
get topStateName():
string
Display name of topState (same naming rules as currentStateName).
Returns
string
Display name of topState (same naming rules as currentStateName).
Implementation of
traceWriter
Get Signature
get traceWriter():
TraceWriter
Destination for runtime and handler-initiated trace lines.
Replaceable at any time (e.g. swap in a test double before post/call).
Returns
Set Signature
set traceWriter(
value):void
Destination for runtime and handler-initiated trace lines.
Replaceable at any time (e.g. swap in a test double before post/call).
Parameters
value
Returns
void
Destination for runtime and handler-initiated trace lines.
Replaceable at any time (e.g. swap in a test double before post/call).
Implementation of
dispatchErrorCallback
Get Signature
get dispatchErrorCallback():
DispatchErrorCallback<Context,Protocol>
Last-resort error hook when StateEvents.onError / StateEvents.onUnhandled do not recover.
Returns
DispatchErrorCallback<Context, Protocol>
Set Signature
set dispatchErrorCallback(
value):void
Last-resort error hook when StateEvents.onError / StateEvents.onUnhandled do not recover.
Parameters
value
DispatchErrorCallback<Context, Protocol>
Returns
void
Last-resort error hook when StateEvents.onError / StateEvents.onUnhandled do not recover.
See
DispatchErrorCallback
Implementation of
Methods
transition()
transition(
nextState):void
Schedule an external transition to nextState after the current handler completes.
Does not run exit/entry immediately. When the handler returns successfully (including
after awaiting an async handler's Promise), the runtime:
- Computes the lowest common ancestor (LCA) on the class prototype chain
- Runs
onExit()from the current leaf up to (but not including) the LCA - Switches the instance prototype to
nextState(descending@InitialStatechains for composites) - Runs
onEntry()down from the LCA to the target leaf
Parameters
nextState
StateClass<Context, Protocol>
Destination state class constructor (not an instance)
Returns
void
Remarks
- Self-transition to the same leaf with unchanged initial descent: optimized to skip exit/entry
- Internal transition: omit
transition()— active class unchanged, no exit/entry transition()insideonEntry/onExit: scheduled transition is cleared when that lifecycle dispatch ends — use post fromonEntryfor follow-up work- Transition paths are cached per
From=>Topair for hot loops - Only the last
transition()call wins if invoked multiple times in one handler
Implementation of
unhandled()
unhandled():
never
Declare that the current event has no handler on this state (explicit super-call pattern).
Throws UnhandledEventError unless an ancestor's StateEvents.onUnhandled
catches it. Prefer omitting the method entirely when a state should inherit a parent's
handler — only call unhandled() when you intentionally defer to the error model.
Returns
never
never — always throws or redirects via onUnhandled
Remarks
Runtime dispatch already throws when no method exists on the prototype chain; unhandled()
is for handlers that exist but choose not to handle the event.
Implementation of
sleep()
sleep(
millis):Promise<void>
Pause the current handler without blocking the JavaScript event loop.
Returns a Promise resolved after millis milliseconds via setTimeout. The mailbox
remains locked to this handler until the Promise settles — other post/call jobs
queue but do not run.
Parameters
millis
number
Sleep duration in milliseconds (≥ 0)
Returns
Promise<void>
Promise that resolves (never rejects) when the delay elapses
Remarks
Use for simple delays inside handlers. For calendar-time deferral of new events,
prefer deferredPost. Composable with async handlers: await this.sleep(100).
Implementation of
post()
post<
EventName>(eventName, ...eventPayload):void
Enqueue a normal-priority event for later dispatch on the active state.
Returns immediately; the handler runs asynchronously when the mailbox reaches this job.
Dispatch walks the prototype chain from the current leaf upward until a method named
eventName is found.
Type Parameters
EventName
EventName extends string | number | symbol
Literal key of Protocol being posted
Parameters
eventName
PostedEvent<Protocol, EventName>
Event or service name. Must be keyof Protocol and must not collide
with reserved State method names (transition, post, ctx, …)
eventPayload
...EventPayload<Protocol, EventName>
Arguments tuple inferred from Protocol[eventName] handler parameters.
For events, pass every parameter except resolve / reject. For fire-and-forget
events, the handler return type must be void or Promise<void>
Returns
void
Remarks
Client usage: door.post('open') then await door.sync() to wait for completion.
Handler usage: this.post('tick') schedules work after the current handler returns
and after any State.transition it requested. Normal-priority posts run after all
State.postNow hi-priority jobs drained for the current turn.
Ordering: FIFO among normal-priority jobs. Multiple posts before one sync() are
processed in submission order.
Typing: With Protocol extends undefined, accepts any string and any[] (legacy mode).
Implementation of
deferredPost()
deferredPost<
EventName>(millis,eventName, ...eventPayload):void
Schedule a normal-priority post after a wall-clock delay.
Uses setTimeout internally; when the timer fires, the event is enqueued like an ordinary
post. Timers are not cancelled if the machine transitions or the scheduling handler throws.
Type Parameters
EventName
EventName extends string | number | symbol
Literal key of Protocol being scheduled
Parameters
millis
number
Delay in milliseconds before enqueueing (≥ 0). Subject to event-loop timer granularity
eventName
PostedEvent<Protocol, EventName>
Event name (same constraints as post)
eventPayload
...EventPayload<Protocol, EventName>
Handler arguments tuple (same as post)
Returns
void
Remarks
Available on State and Hsm. Typical pattern: handler schedules reminder,
client waits with await sleep(millis); await hsm.sync().
Does not block the calling handler — returns as soon as the timer is registered.
Implementation of
postNow()
postNow<
EventName>(eventName, ...eventPayload):void
Enqueue a hi-priority event processed before normal post jobs from the same turn.
Only valid inside a running handler (this.postNow). Clients must use post.
Hi-priority jobs drain immediately after the current handler and its transition complete,
before any normal-priority posts the handler enqueued (including chained this.post).
Type Parameters
EventName
EventName extends string | number | symbol
Literal key of Protocol
Parameters
eventName
PostedEvent<Protocol, EventName>
Event name (same typing rules as post)
eventPayload
...EventPayload<Protocol, EventName>
Handler arguments (same tuple as post)
Returns
void
Remarks
Models extended transitions: multiple internal steps (lock, capture, validate) that
must complete before deferred side effects. See tutorial 17-post-now.
Multiple postNow calls run in FIFO order within the hi-priority queue. You may need
an extra Hsm.sync after the first to drain postNow follow-ups.
Implementation of
onExit()
onExit():
void|Promise<void>
Invoked when leaving this state during an external transition.
Runs during the exit phase after the triggering handler completes and before the
prototype switches away. Async onExit is awaited before continuing up the LCA path.
Returns
void | Promise<void>
Remarks
Not called for internal transitions (handler returns without State.transition). Not called on Hsm.restore. Self-transitions may skip exit when optimized.
Implementation of
onEntry()
onEntry():
void|Promise<void>
Invoked when entering this state during initialization or an external transition.
Runs during the entry phase after the prototype points at this state. Async onEntry is
awaited before entering nested initial substates or running deeper onEntry hooks.
Returns
void | Promise<void>
Remarks
During makeHsm(..., initialize: true), onEntry runs from root down through each
@InitialState chain to the initial leaf. Schedule follow-up transitions via Base.post,
not State.transition, from within onEntry.
Implementation of
onError()
onError<
EventName>(error):void|Promise<void>
Recovery hook when an event handler throws EventHandlerError.
Type Parameters
EventName
EventName extends string | number | symbol
Correlated event key from Protocol
Parameters
error
RuntimeError<Context, Protocol, EventName>
Typed runtime error with RuntimeError.eventName, RuntimeError.eventPayload, HsmError.context, and HsmError.cause
Returns
void | Promise<void>
Remarks
Default TopState implementation rethrows. Override to log, transition to a safe state, or swallow. Uncaught errors invoke Properties.dispatchErrorCallback.
Implementation of
onUnhandled()
onUnhandled<
EventName>(error):void|Promise<void>
Recovery hook when dispatch would raise UnhandledEventError.
Type Parameters
EventName
EventName extends string | number | symbol
Correlated event key from Protocol
Parameters
error
UnhandledEventError<Context, Protocol, EventName>
Describes the unmatched event and active state
Returns
void | Promise<void>
Remarks
Override to implement catch-all handlers, auditing, or transition to an error state without defining every event on every leaf.