aifsmjs 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -196,6 +196,7 @@ function createRuntime(def, impl, opts = {}) {
196
196
  error: /* @__PURE__ */ new Set(),
197
197
  dispose: /* @__PURE__ */ new Set()
198
198
  };
199
+ const externalAbortCleanups = /* @__PURE__ */ new Set();
199
200
  function emit(type, payload) {
200
201
  for (const fn of eventListeners[type]) fn(payload);
201
202
  }
@@ -295,10 +296,24 @@ function createRuntime(def, impl, opts = {}) {
295
296
  };
296
297
  }
297
298
  target.add(wrapped);
298
- if (options?.signal) {
299
- options.signal.addEventListener("abort", () => target.delete(wrapped), { once: true });
299
+ let detachAbort;
300
+ const signal = options?.signal;
301
+ if (signal) {
302
+ const onAbort = () => {
303
+ target.delete(wrapped);
304
+ if (detachAbort) externalAbortCleanups.delete(detachAbort);
305
+ };
306
+ signal.addEventListener("abort", onAbort, { once: true });
307
+ detachAbort = () => signal.removeEventListener("abort", onAbort);
308
+ externalAbortCleanups.add(detachAbort);
300
309
  }
301
- return () => target.delete(wrapped);
310
+ return () => {
311
+ target.delete(wrapped);
312
+ if (detachAbort) {
313
+ detachAbort();
314
+ externalAbortCleanups.delete(detachAbort);
315
+ }
316
+ };
302
317
  }
303
318
  function dispose() {
304
319
  if (disposed) return;
@@ -307,6 +322,8 @@ function createRuntime(def, impl, opts = {}) {
307
322
  listeners.clear();
308
323
  emit("dispose", void 0);
309
324
  for (const set of Object.values(eventListeners)) set.clear();
325
+ for (const cleanup of externalAbortCleanups) cleanup();
326
+ externalAbortCleanups.clear();
310
327
  }
311
328
  return {
312
329
  getSnapshot: () => snapshot,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fsm/types.ts","../src/fsm/evaluator.ts","../src/effects/enqueuer.ts","../src/fsm/snapshot.ts","../src/fsm/updater.ts","../src/fsm/lifecycle.ts","../src/fsm/runtime.ts","../src/fsm/definition.ts","../src/fsm/resolver.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// All public types live here so AI agents and humans can read the entire\n// public surface in one file.\n\nexport type Effect = Readonly<{ type: string; payload?: unknown }>;\n\nexport type Enqueuer = Readonly<{\n effect: (type: string, payload?: unknown) => void;\n}>;\n\nexport type GuardArgs<Ctx, Evt> = Readonly<{\n context: Ctx;\n event: Evt;\n /**\n * Optional guard registry, threaded by `evalGuard` so combinators can resolve\n * string refs nested inside `and / or / not`. Inline user guards may safely\n * ignore this field — it is `undefined` when guards are evaluated outside of\n * `evalGuard` (e.g. in unit tests calling the function directly).\n */\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n /**\n * Current state value, threaded by `evalGuard` from the live snapshot. Used\n * by the `stateIn` combinator. `undefined` when guards are called outside of\n * a lifecycle evaluation.\n */\n value?: string;\n}>;\n\nexport type Guard<Ctx, Evt> = (args: GuardArgs<Ctx, Evt>) => boolean;\n\nexport type Action<Ctx, Evt> = (args: {\n context: Ctx;\n event: Evt;\n enqueue: Enqueuer;\n}) => Partial<Ctx> | void;\n\nexport type EffectHandler<Ctx, Evt> = (\n effect: Effect,\n args: { context: Ctx; event: Evt; signal: AbortSignal },\n) => void | Promise<void>;\n\nexport type GuardRef<Ctx, Evt> = string | Guard<Ctx, Evt>;\nexport type ActionRef<Ctx, Evt> = string | Action<Ctx, Evt>;\n\nexport type TransitionDef<Ctx, Evt, States extends string> = Readonly<{\n target?: States;\n guard?: GuardRef<Ctx, Evt>;\n actions?: readonly ActionRef<Ctx, Evt>[];\n}>;\n\nexport type StateDef<Ctx, Evt, States extends string> = Readonly<{\n on?: Readonly<\n Record<string, TransitionDef<Ctx, Evt, States> | readonly TransitionDef<Ctx, Evt, States>[]>\n >;\n entry?: readonly ActionRef<Ctx, Evt>[];\n exit?: readonly ActionRef<Ctx, Evt>[];\n final?: boolean;\n}>;\n\nexport type MachineDef<Ctx, Evt extends { type: string }, States extends string> = Readonly<{\n id: string;\n initial: States;\n context: Ctx;\n states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n}>;\n\nexport type Snapshot<Ctx, States extends string> = Readonly<{\n value: States;\n context: Ctx;\n status: \"active\" | \"final\";\n}>;\n\nexport type Implementations<Ctx, Evt> = Readonly<{\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n actions?: Readonly<Record<string, Action<Ctx, Evt>>>;\n effects?: Readonly<Record<string, EffectHandler<Ctx, Evt>>>;\n}>;\n\nexport type StepResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Sentinel event type that `Runtime.reset()` synthesises when the caller does\n * not pass an explicit event. Middleware receives it through\n * `MiddlewareContext.event`. Exposed so user code can discriminate.\n */\nexport const RESET_EVENT_TYPE = \"@@aifsmjs/RESET\" as const;\nexport type ResetEvent = Readonly<{ type: typeof RESET_EVENT_TYPE }>;\n\nexport type MiddlewareContext<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n /**\n * The triggering event. May be the user's `Evt` (from `send()` or an\n * explicit `reset(event)`) or the `ResetEvent` sentinel emitted by a\n * `reset()` with no event argument.\n */\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\nexport type Middleware<Ctx, Evt, States extends string> = (\n ctx: MiddlewareContext<Ctx, Evt, States>,\n next: () => void,\n) => void;\n\n/**\n * Payload of the `'transition'` runtime event — emitted after each `send()` or\n * `reset()` that actually changed the snapshot value.\n */\nexport type RuntimeTransitionEvent<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Payload of the `'error'` runtime event — currently emitted for async effect\n * handler rejections (which would otherwise become unhandled). Synchronous\n * throws from effect handlers and middleware still propagate to the caller of\n * `send()` / `reset()`.\n */\nexport type RuntimeErrorEvent<Evt> = Readonly<{\n error: unknown;\n event: Evt | ResetEvent | undefined;\n}>;\n\nexport type RuntimeEventMap<Ctx, Evt, States extends string> = {\n transition: RuntimeTransitionEvent<Ctx, Evt, States>;\n error: RuntimeErrorEvent<Evt>;\n dispose: void;\n};\n\nexport interface Runtime<Ctx, Evt extends { type: string }, States extends string> {\n getSnapshot(): Snapshot<Ctx, States>;\n /** Alias for `getSnapshot()`. */\n snapshot(): Snapshot<Ctx, States>;\n send(event: Evt): Snapshot<Ctx, States>;\n /**\n * Predict whether sending `event` would fire a transition. Reuses\n * `resolveTransitions` + `evalGuard` without applying any actions. Guards\n * are expected to be pure; `can` then matches `send` for the same input.\n */\n can(event: Evt): boolean;\n subscribe(listener: (snap: Snapshot<Ctx, States>) => void): () => void;\n /**\n * EventTarget-like typed listener API. Returns an unsubscribe function.\n * `options.signal` removes the listener when aborted; `options.once`\n * removes the listener after the first invocation. After `dispose()`,\n * `on()` is a no-op and returns a no-op unsubscribe.\n */\n on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void;\n /**\n * Re-initialise the runtime to the definition's initial snapshot. Triggers\n * subscribers but does NOT run entry actions (reset = re-birth, not\n * \"transition into initial\"). Throws RuntimeDisposedError if disposed.\n * If an `event` is supplied, middleware sees it as the trigger; otherwise\n * a sentinel `{ type: \"@@aifsmjs/RESET\" }` is synthesised.\n */\n reset(event?: Evt): Snapshot<Ctx, States>;\n /**\n * Tear down: abort the internal AbortController (effect handlers see signal\n * fire), clear listeners, and mark this runtime as disposed. Subsequent\n * send()/reset() calls throw RuntimeDisposedError. Idempotent.\n */\n dispose(): void;\n /**\n * True after `dispose()` has been called.\n */\n readonly disposed: boolean;\n /**\n * AbortSignal scoped to this runtime's lifetime. Fires once on dispose().\n * Threaded to every EffectHandler invocation; external integrations\n * (e.g. component teardown) can also attach `signal.addEventListener(\"abort\", ...)`.\n */\n readonly signal: AbortSignal;\n}\n\nexport type RuntimeOptions<Ctx, Evt, States extends string> = Readonly<{\n middleware?: readonly Middleware<Ctx, Evt, States>[];\n /**\n * If false, do not dispatch effects through the effect handler map.\n * Useful for replay / dry-run modes. Defaults to true.\n */\n dispatchEffects?: boolean;\n}>;\n","import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * this function does not catch async returns — TypeScript should already block\n * those at compile time.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n return fn(args);\n}\n","import type { Enqueuer } from \"../fsm/types.js\";\n\n/**\n * Build a closure-based Enqueuer that pushes effects into the supplied sink.\n * Each `step()` invocation creates one such enqueuer and discards it\n * afterwards; the sink is the effects array later returned to the caller.\n *\n * Lives in `effects/` because the Enqueuer concept is the effects-domain API\n * — `step()` imports it from here.\n */\nexport function createEnqueuer(sink: { type: string; payload?: unknown }[]): Enqueuer {\n return Object.freeze({\n effect(type: string, payload?: unknown) {\n if (payload === undefined) {\n sink.push(Object.freeze({ type }));\n } else {\n sink.push(Object.freeze({ type, payload }));\n }\n },\n });\n}\n","import type { Snapshot } from \"./types.js\";\n\nconst IS_DEV =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Object.isFrozen(value)) return value;\n Object.freeze(value);\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n } else if (isPlainObject(value)) {\n for (const key of Object.keys(value)) {\n deepFreeze((value as Record<string, unknown>)[key]);\n }\n }\n return value;\n}\n\n/**\n * Wrap a freshly built snapshot. In dev mode the whole tree is deep-frozen so\n * accidental mutation throws immediately. In production only the top object is\n * frozen, keeping the cost negligible.\n */\nexport function freezeSnapshot<C, S extends string>(snap: Snapshot<C, S>): Snapshot<C, S> {\n // IS_DEV is always true in vitest; the production branch (`Object.freeze`)\n // is exercised only when NODE_ENV === \"production\" and is intentionally\n // left out of the coverage threshold.\n return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);\n}\n\nexport function createSnapshot<C, S extends string>(args: {\n value: S;\n context: C;\n status?: \"active\" | \"final\";\n}): Snapshot<C, S> {\n return freezeSnapshot({\n value: args.value,\n context: args.context,\n status: args.status ?? \"active\",\n });\n}\n","import type { Action } from \"./types.js\";\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Build an Action that returns a Partial<Ctx> from a pure updater.\n * The partial is merged into the current context by `step()`.\n */\nexport function assign<Ctx, Evt>(\n updater: (args: { context: Ctx; event: Evt }) => Partial<Ctx>,\n): Action<Ctx, Evt> {\n return ({ context, event }) => updater({ context, event });\n}\n\n/**\n * Merge a partial context update into the current context. Plain-object\n * contexts get a shallow merge; non-object contexts get replaced wholesale.\n *\n * The function never mutates either argument.\n */\nexport function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx {\n if (patch === undefined || patch === null) return current;\n if (isPlainRecord(current) && isPlainRecord(patch)) {\n return { ...current, ...patch } as Ctx;\n }\n return patch as Ctx;\n}\n","import { createEnqueuer } from \"../effects/enqueuer.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Action,\n ActionRef,\n Effect,\n Implementations,\n MachineDef,\n Snapshot,\n StepResult,\n TransitionDef,\n} from \"./types.js\";\nimport { mergeContext } from \"./updater.js\";\n\nexport class UnknownActionError extends Error {\n readonly actionName: string;\n constructor(actionName: string) {\n super(`aifsmjs: action \"${actionName}\" not found in implementations.actions`);\n this.name = \"UnknownActionError\";\n this.actionName = actionName;\n }\n}\n\nfunction resolveAction<Ctx, Evt>(\n ref: ActionRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Action<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.actions?.[ref];\n if (!fn) throw new UnknownActionError(ref);\n return fn;\n}\n\nfunction runActions<Ctx, Evt>(\n refs: readonly ActionRef<Ctx, Evt>[] | undefined,\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n effectSink: Effect[],\n): Ctx {\n if (!refs || refs.length === 0) return ctx;\n const enqueue = createEnqueuer(effectSink as { type: string; payload?: unknown }[]);\n let current = ctx;\n for (const ref of refs) {\n const fn = resolveAction(ref, impl);\n const patch = fn({ context: current, event, enqueue });\n current = mergeContext(current, patch);\n }\n return current;\n}\n\nfunction pickTransition<Ctx, Evt, States extends string>(\n candidates: readonly TransitionDef<Ctx, Evt, States>[],\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value: States,\n): TransitionDef<Ctx, Evt, States> | undefined {\n for (const t of candidates) {\n if (!t.guard) return t;\n if (evalGuard(t.guard, ctx, event, impl, value)) return t;\n }\n return undefined;\n}\n\n/**\n * Compute the next snapshot and collected effects from a single event.\n *\n * Order is fixed and uninterruptible:\n * 1. resolve candidate transitions for (state, event.type)\n * 2. evaluate guards in declaration order; pick the first passing one\n * 3. if external (target defined), run exit actions of the old state\n * 4. run transition.actions in declaration order\n * 5. if external, run entry actions of the new state\n * 6. return { snapshot, effects, changed }\n *\n * The function is pure: it never dispatches effects and never mutates inputs.\n */\nexport function step<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n snapshot: Snapshot<Ctx, States>,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n): StepResult<Ctx, States> {\n // Final state is inert: it never reacts to events.\n if (snapshot.status === \"final\") {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const state = def.states[snapshot.value];\n /* v8 ignore next 3 — defensive: snapshot.value is always validated against def.states by defineMachine + initialSnapshot. */\n if (!state) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const candidates = state.on?.[event.type];\n const candidateList: readonly TransitionDef<Ctx, Evt, States>[] = candidates\n ? Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>]\n : [];\n\n const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);\n if (!chosen) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const isExternal = chosen.target !== undefined;\n const nextStateValue = (chosen.target ?? snapshot.value) as States;\n const nextState = def.states[nextStateValue];\n\n const effectSink: Effect[] = [];\n let ctx = snapshot.context as Ctx;\n\n if (isExternal) {\n ctx = runActions(state.exit, ctx, event, impl, effectSink);\n }\n ctx = runActions(chosen.actions, ctx, event, impl, effectSink);\n if (isExternal && nextState) {\n ctx = runActions(nextState.entry, ctx, event, impl, effectSink);\n }\n\n const status: \"active\" | \"final\" = nextState?.final === true ? \"final\" : \"active\";\n const nextSnapshot = freezeSnapshot({\n value: nextStateValue,\n context: ctx,\n status,\n });\n\n return Object.freeze({\n snapshot: nextSnapshot,\n effects: Object.freeze(effectSink.slice()) as readonly Effect[],\n changed: true,\n });\n}\n","import { initialSnapshot } from \"./definition.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { step } from \"./lifecycle.js\";\nimport { deepFreeze } from \"./snapshot.js\";\nimport {\n type Effect,\n type Implementations,\n type MachineDef,\n type Middleware,\n RESET_EVENT_TYPE,\n type ResetEvent,\n type Runtime,\n type RuntimeErrorEvent,\n type RuntimeEventMap,\n type RuntimeOptions,\n type RuntimeTransitionEvent,\n type Snapshot,\n type TransitionDef,\n} from \"./types.js\";\n\nexport class RuntimeDisposedError extends Error {\n constructor() {\n super(\"aifsmjs: runtime has been disposed; send()/reset() are not allowed\");\n this.name = \"RuntimeDisposedError\";\n }\n}\n\nconst RESET_EVENT: ResetEvent = Object.freeze({ type: RESET_EVENT_TYPE });\n\nfunction composeMiddleware<Ctx, Evt, States extends string>(\n middleware: readonly Middleware<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (ctx, finalNext) => {\n let index = -1;\n const dispatch = (i: number): void => {\n if (i <= index) throw new Error(\"aifsmjs: next() called multiple times in middleware\");\n index = i;\n const fn = middleware[i];\n if (!fn) {\n finalNext();\n return;\n }\n fn(ctx, () => dispatch(i + 1));\n };\n dispatch(0);\n };\n}\n\n/**\n * Build a thin stateful runtime around a machine. `send()` calls `step()`,\n * runs the read-only middleware pipeline, dispatches effects, and notifies\n * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it\n * and clears all state.\n */\nexport function createRuntime<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts: RuntimeOptions<Ctx, Evt, States> = {},\n): Runtime<Ctx, Evt, States> {\n let snapshot: Snapshot<Ctx, States> = initialSnapshot(def);\n const listeners = new Set<(snap: Snapshot<Ctx, States>) => void>();\n const middlewareChain =\n opts.middleware && opts.middleware.length > 0 ? composeMiddleware(opts.middleware) : undefined;\n const shouldDispatch = opts.dispatchEffects !== false;\n const controller = new AbortController();\n let disposed = false;\n\n // Typed event listeners for the EventTarget-like on() API.\n type EventListeners = {\n [K in keyof RuntimeEventMap<Ctx, Evt, States>]: Set<\n (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void\n >;\n };\n const eventListeners: EventListeners = {\n transition: new Set(),\n error: new Set(),\n dispose: new Set(),\n };\n\n function emit<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n payload: RuntimeEventMap<Ctx, Evt, States>[K],\n ): void {\n for (const fn of eventListeners[type]) fn(payload);\n }\n\n function notify() {\n for (const l of listeners) l(snapshot);\n }\n\n function runMiddleware(\n prev: Snapshot<Ctx, States>,\n event: Evt | ResetEvent,\n effects: readonly Effect[],\n changed: boolean,\n ) {\n if (!middlewareChain) return;\n const mwCtx = deepFreeze({\n prev,\n next: snapshot,\n event,\n effects,\n changed,\n });\n middlewareChain(mwCtx, () => {});\n }\n\n function dispatchEffects(\n effects: readonly Effect[],\n context: Ctx,\n event: Evt | ResetEvent,\n ): void {\n if (!impl.effects || effects.length === 0) return;\n for (const eff of effects) {\n const handler = impl.effects[eff.type];\n if (!handler) continue;\n // Sync throws still propagate to the caller of send(); async rejections\n // surface on the 'error' event channel instead of becoming unhandled.\n const r = handler(eff, { context, event: event as Evt, signal: controller.signal });\n if (r instanceof Promise) {\n r.catch((err: unknown) => {\n const payload: RuntimeErrorEvent<Evt> = { error: err, event };\n emit(\"error\", payload);\n });\n }\n }\n }\n\n function send(event: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n const result = step(def, prev, event, impl);\n snapshot = result.snapshot;\n\n runMiddleware(prev, event, result.effects, result.changed);\n\n if (shouldDispatch) {\n dispatchEffects(result.effects, snapshot.context, event);\n }\n\n if (result.changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event,\n effects: result.effects,\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function reset(event?: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n snapshot = initialSnapshot(def);\n const changed = prev.value !== snapshot.value;\n const triggerEvent: Evt | ResetEvent = event ?? RESET_EVENT;\n runMiddleware(prev, triggerEvent, [], changed);\n if (changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event: triggerEvent,\n effects: [],\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function can(event: Evt): boolean {\n if (disposed || snapshot.status === \"final\") return false;\n const state = def.states[snapshot.value];\n /* v8 ignore next — defensive: snapshot.value always corresponds to a declared state. */\n if (!state) return false;\n const candidates = state.on?.[event.type];\n if (!candidates) return false;\n const list: readonly TransitionDef<Ctx, Evt, States>[] = Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>];\n for (const t of list) {\n if (!t.guard) return true;\n if (evalGuard(t.guard, snapshot.context, event, impl, snapshot.value)) return true;\n }\n return false;\n }\n\n function on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void {\n if (disposed || options?.signal?.aborted) return () => {};\n const target = eventListeners[type];\n let wrapped: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void = listener;\n if (options?.once) {\n wrapped = (payload) => {\n target.delete(wrapped);\n listener(payload);\n };\n }\n target.add(wrapped);\n if (options?.signal) {\n options.signal.addEventListener(\"abort\", () => target.delete(wrapped), { once: true });\n }\n return () => target.delete(wrapped);\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n controller.abort();\n listeners.clear();\n emit(\"dispose\", undefined as RuntimeEventMap<Ctx, Evt, States>[\"dispose\"]);\n for (const set of Object.values(eventListeners)) set.clear();\n }\n\n return {\n getSnapshot: () => snapshot,\n snapshot: () => snapshot,\n send,\n can,\n reset,\n dispose,\n on,\n get disposed() {\n return disposed;\n },\n get signal() {\n return controller.signal;\n },\n subscribe(listener) {\n if (disposed) return () => {};\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { createRuntime } from \"./runtime.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Implementations,\n MachineDef,\n Runtime,\n RuntimeOptions,\n Snapshot,\n StateDef,\n} from \"./types.js\";\n\nexport class InvalidDefinitionError extends Error {\n constructor(message: string) {\n super(`aifsmjs: ${message}`);\n this.name = \"InvalidDefinitionError\";\n }\n}\n\nfunction validateDefinition<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): void {\n if (!def.id || typeof def.id !== \"string\") {\n throw new InvalidDefinitionError(\"definition must have a non-empty string `id`\");\n }\n /* v8 ignore next 3 — additional safety: TS prevents non-object `states`; this guards untyped JS callers. */\n if (!def.states || typeof def.states !== \"object\") {\n throw new InvalidDefinitionError(\"definition must have a `states` object\");\n }\n const stateKeys = Object.keys(def.states) as States[];\n if (stateKeys.length === 0) {\n throw new InvalidDefinitionError(\"`states` must declare at least one state\");\n }\n if (!def.initial || !stateKeys.includes(def.initial)) {\n throw new InvalidDefinitionError(\n `\\`initial\\` \"${String(def.initial)}\" is not declared in states (${stateKeys.join(\", \")})`,\n );\n }\n for (const [stateName, stateDef] of Object.entries(def.states) as [\n States,\n (typeof def.states)[States],\n ][]) {\n if (!stateDef.on) continue;\n for (const [evtType, entry] of Object.entries(stateDef.on)) {\n const transitions = Array.isArray(entry) ? entry : [entry];\n for (const t of transitions) {\n if (t.target !== undefined && !stateKeys.includes(t.target)) {\n throw new InvalidDefinitionError(\n `transition ${stateName} -[${evtType}]-> \"${String(t.target)}\" targets an unknown state`,\n );\n }\n }\n }\n }\n}\n\n/**\n * Validate a machine definition shape and return it. Same reference is\n * returned; no cloning happens. Validation is intentionally shallow.\n *\n * Two call forms:\n *\n * defineMachine<Ctx, Evt, States>({ ... })\n * Explicit generics. Use when you need full control (e.g. union event\n * types). Required because TypeScript cannot otherwise infer `Evt`.\n *\n * setup<Ctx, Evt>().defineMachine({ ... })\n * Curried form. Lets `States` be inferred from `keyof states`, so you\n * can omit it. Recommended for typical usage.\n */\nexport function defineMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): MachineDef<Ctx, Evt, States> {\n validateDefinition(def);\n return def;\n}\n\n/**\n * Curried builder so `States` can be inferred from `keyof states` without\n * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the\n * type arguments; pass the def to the returned `defineMachine`.\n *\n * const machine = setup<MyCtx, MyEvt>().defineMachine({\n * id: \"m\",\n * initial: \"a\",\n * context: { ... },\n * states: { a: {...}, b: {...} }, // States inferred as \"a\" | \"b\"\n * });\n */\nexport function setup<Ctx, Evt extends { type: string }>(): {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => MachineDef<Ctx, Evt, States>;\n} {\n return {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => {\n const cast = def as unknown as MachineDef<Ctx, Evt, States>;\n validateDefinition(cast);\n return cast;\n },\n };\n}\n\n/**\n * Build the initial snapshot for a machine.\n */\nexport function initialSnapshot<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): Snapshot<Ctx, States> {\n const isFinal = def.states[def.initial]?.final === true;\n return freezeSnapshot({\n value: def.initial,\n context: def.context,\n status: isFinal ? (\"final\" as const) : (\"active\" as const),\n });\n}\n\n/**\n * Convenience factory that composes `defineMachine` and `createRuntime` in\n * one call for the common case where you do not need to keep the machine\n * definition around for serialization or sharing.\n *\n * For type inference over `States` from `keyof states`, prefer\n * `setup<Ctx, Evt>().defineMachine(...)` then pass the result to\n * `createRuntime` separately. `createMachine` is the spec-style entry point\n * documented in the ai*js ecosystem review.\n */\nexport function createMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts?: RuntimeOptions<Ctx, Evt, States>,\n): Runtime<Ctx, Evt, States> {\n return createRuntime(defineMachine(def), impl, opts ?? {});\n}\n","import type { MachineDef, TransitionDef } from \"./types.js\";\n\n/**\n * Return all transition candidates for (state, eventType). Order is preserved\n * from the declaration so that guard fallthrough behaves predictably.\n *\n * If the event has no entry under the given state, an empty array is returned.\n */\nexport function resolveTransitions<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n stateValue: States,\n eventType: string,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n const state = def.states[stateValue];\n if (!state || !state.on) return [];\n const entry = state.on[eventType];\n if (!entry) return [];\n return Array.isArray(entry) ? entry : [entry as TransitionDef<Ctx, Evt, States>];\n}\n"]}
1
+ {"version":3,"sources":["../src/fsm/types.ts","../src/fsm/evaluator.ts","../src/effects/enqueuer.ts","../src/fsm/snapshot.ts","../src/fsm/updater.ts","../src/fsm/lifecycle.ts","../src/fsm/runtime.ts","../src/fsm/definition.ts","../src/fsm/resolver.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// All public types live here so AI agents and humans can read the entire\n// public surface in one file.\n\nexport type Effect = Readonly<{ type: string; payload?: unknown }>;\n\nexport type Enqueuer = Readonly<{\n effect: (type: string, payload?: unknown) => void;\n}>;\n\nexport type GuardArgs<Ctx, Evt> = Readonly<{\n context: Ctx;\n event: Evt;\n /**\n * Optional guard registry, threaded by `evalGuard` so combinators can resolve\n * string refs nested inside `and / or / not`. Inline user guards may safely\n * ignore this field — it is `undefined` when guards are evaluated outside of\n * `evalGuard` (e.g. in unit tests calling the function directly).\n */\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n /**\n * Current state value, threaded by `evalGuard` from the live snapshot. Used\n * by the `stateIn` combinator. `undefined` when guards are called outside of\n * a lifecycle evaluation.\n */\n value?: string;\n}>;\n\nexport type Guard<Ctx, Evt> = (args: GuardArgs<Ctx, Evt>) => boolean;\n\nexport type Action<Ctx, Evt> = (args: {\n context: Ctx;\n event: Evt;\n enqueue: Enqueuer;\n}) => Partial<Ctx> | void;\n\nexport type EffectHandler<Ctx, Evt> = (\n effect: Effect,\n args: { context: Ctx; event: Evt; signal: AbortSignal },\n) => void | Promise<void>;\n\nexport type GuardRef<Ctx, Evt> = string | Guard<Ctx, Evt>;\nexport type ActionRef<Ctx, Evt> = string | Action<Ctx, Evt>;\n\nexport type TransitionDef<Ctx, Evt, States extends string> = Readonly<{\n target?: States;\n guard?: GuardRef<Ctx, Evt>;\n actions?: readonly ActionRef<Ctx, Evt>[];\n}>;\n\nexport type StateDef<Ctx, Evt, States extends string> = Readonly<{\n on?: Readonly<\n Record<string, TransitionDef<Ctx, Evt, States> | readonly TransitionDef<Ctx, Evt, States>[]>\n >;\n entry?: readonly ActionRef<Ctx, Evt>[];\n exit?: readonly ActionRef<Ctx, Evt>[];\n final?: boolean;\n}>;\n\nexport type MachineDef<Ctx, Evt extends { type: string }, States extends string> = Readonly<{\n id: string;\n initial: States;\n context: Ctx;\n states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n}>;\n\nexport type Snapshot<Ctx, States extends string> = Readonly<{\n value: States;\n context: Ctx;\n status: \"active\" | \"final\";\n}>;\n\nexport type Implementations<Ctx, Evt> = Readonly<{\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n actions?: Readonly<Record<string, Action<Ctx, Evt>>>;\n effects?: Readonly<Record<string, EffectHandler<Ctx, Evt>>>;\n}>;\n\nexport type StepResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Sentinel event type that `Runtime.reset()` synthesises when the caller does\n * not pass an explicit event. Middleware receives it through\n * `MiddlewareContext.event`. Exposed so user code can discriminate.\n */\nexport const RESET_EVENT_TYPE = \"@@aifsmjs/RESET\" as const;\nexport type ResetEvent = Readonly<{ type: typeof RESET_EVENT_TYPE }>;\n\nexport type MiddlewareContext<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n /**\n * The triggering event. May be the user's `Evt` (from `send()` or an\n * explicit `reset(event)`) or the `ResetEvent` sentinel emitted by a\n * `reset()` with no event argument.\n */\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\nexport type Middleware<Ctx, Evt, States extends string> = (\n ctx: MiddlewareContext<Ctx, Evt, States>,\n next: () => void,\n) => void;\n\n/**\n * Payload of the `'transition'` runtime event — emitted after each `send()` or\n * `reset()` that actually changed the snapshot value.\n */\nexport type RuntimeTransitionEvent<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Payload of the `'error'` runtime event — currently emitted for async effect\n * handler rejections (which would otherwise become unhandled). Synchronous\n * throws from effect handlers and middleware still propagate to the caller of\n * `send()` / `reset()`.\n */\nexport type RuntimeErrorEvent<Evt> = Readonly<{\n error: unknown;\n event: Evt | ResetEvent | undefined;\n}>;\n\nexport type RuntimeEventMap<Ctx, Evt, States extends string> = {\n transition: RuntimeTransitionEvent<Ctx, Evt, States>;\n error: RuntimeErrorEvent<Evt>;\n dispose: void;\n};\n\nexport interface Runtime<Ctx, Evt extends { type: string }, States extends string> {\n getSnapshot(): Snapshot<Ctx, States>;\n /** Alias for `getSnapshot()`. */\n snapshot(): Snapshot<Ctx, States>;\n send(event: Evt): Snapshot<Ctx, States>;\n /**\n * Predict whether sending `event` would fire a transition. Reuses\n * `resolveTransitions` + `evalGuard` without applying any actions. Guards\n * are expected to be pure; `can` then matches `send` for the same input.\n */\n can(event: Evt): boolean;\n subscribe(listener: (snap: Snapshot<Ctx, States>) => void): () => void;\n /**\n * EventTarget-like typed listener API. Returns an unsubscribe function.\n * `options.signal` removes the listener when aborted; `options.once`\n * removes the listener after the first invocation. After `dispose()`,\n * `on()` is a no-op and returns a no-op unsubscribe.\n */\n on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void;\n /**\n * Re-initialise the runtime to the definition's initial snapshot. Triggers\n * subscribers but does NOT run entry actions (reset = re-birth, not\n * \"transition into initial\"). Throws RuntimeDisposedError if disposed.\n * If an `event` is supplied, middleware sees it as the trigger; otherwise\n * a sentinel `{ type: \"@@aifsmjs/RESET\" }` is synthesised.\n */\n reset(event?: Evt): Snapshot<Ctx, States>;\n /**\n * Tear down: abort the internal AbortController (effect handlers see signal\n * fire), clear listeners, and mark this runtime as disposed. Subsequent\n * send()/reset() calls throw RuntimeDisposedError. Idempotent.\n */\n dispose(): void;\n /**\n * True after `dispose()` has been called.\n */\n readonly disposed: boolean;\n /**\n * AbortSignal scoped to this runtime's lifetime. Fires once on dispose().\n * Threaded to every EffectHandler invocation; external integrations\n * (e.g. component teardown) can also attach `signal.addEventListener(\"abort\", ...)`.\n */\n readonly signal: AbortSignal;\n}\n\nexport type RuntimeOptions<Ctx, Evt, States extends string> = Readonly<{\n middleware?: readonly Middleware<Ctx, Evt, States>[];\n /**\n * If false, do not dispatch effects through the effect handler map.\n * Useful for replay / dry-run modes. Defaults to true.\n */\n dispatchEffects?: boolean;\n}>;\n","import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * this function does not catch async returns — TypeScript should already block\n * those at compile time.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n return fn(args);\n}\n","import type { Enqueuer } from \"../fsm/types.js\";\n\n/**\n * Build a closure-based Enqueuer that pushes effects into the supplied sink.\n * Each `step()` invocation creates one such enqueuer and discards it\n * afterwards; the sink is the effects array later returned to the caller.\n *\n * Lives in `effects/` because the Enqueuer concept is the effects-domain API\n * — `step()` imports it from here.\n */\nexport function createEnqueuer(sink: { type: string; payload?: unknown }[]): Enqueuer {\n return Object.freeze({\n effect(type: string, payload?: unknown) {\n if (payload === undefined) {\n sink.push(Object.freeze({ type }));\n } else {\n sink.push(Object.freeze({ type, payload }));\n }\n },\n });\n}\n","import type { Snapshot } from \"./types.js\";\n\nconst IS_DEV =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Object.isFrozen(value)) return value;\n Object.freeze(value);\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n } else if (isPlainObject(value)) {\n for (const key of Object.keys(value)) {\n deepFreeze((value as Record<string, unknown>)[key]);\n }\n }\n return value;\n}\n\n/**\n * Wrap a freshly built snapshot. In dev mode the whole tree is deep-frozen so\n * accidental mutation throws immediately. In production only the top object is\n * frozen, keeping the cost negligible.\n */\nexport function freezeSnapshot<C, S extends string>(snap: Snapshot<C, S>): Snapshot<C, S> {\n // IS_DEV is always true in vitest; the production branch (`Object.freeze`)\n // is exercised only when NODE_ENV === \"production\" and is intentionally\n // left out of the coverage threshold.\n return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);\n}\n\nexport function createSnapshot<C, S extends string>(args: {\n value: S;\n context: C;\n status?: \"active\" | \"final\";\n}): Snapshot<C, S> {\n return freezeSnapshot({\n value: args.value,\n context: args.context,\n status: args.status ?? \"active\",\n });\n}\n","import type { Action } from \"./types.js\";\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Build an Action that returns a Partial<Ctx> from a pure updater.\n * The partial is merged into the current context by `step()`.\n */\nexport function assign<Ctx, Evt>(\n updater: (args: { context: Ctx; event: Evt }) => Partial<Ctx>,\n): Action<Ctx, Evt> {\n return ({ context, event }) => updater({ context, event });\n}\n\n/**\n * Merge a partial context update into the current context. Plain-object\n * contexts get a shallow merge; non-object contexts get replaced wholesale.\n *\n * The function never mutates either argument.\n */\nexport function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx {\n if (patch === undefined || patch === null) return current;\n if (isPlainRecord(current) && isPlainRecord(patch)) {\n return { ...current, ...patch } as Ctx;\n }\n return patch as Ctx;\n}\n","import { createEnqueuer } from \"../effects/enqueuer.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Action,\n ActionRef,\n Effect,\n Implementations,\n MachineDef,\n Snapshot,\n StepResult,\n TransitionDef,\n} from \"./types.js\";\nimport { mergeContext } from \"./updater.js\";\n\nexport class UnknownActionError extends Error {\n readonly actionName: string;\n constructor(actionName: string) {\n super(`aifsmjs: action \"${actionName}\" not found in implementations.actions`);\n this.name = \"UnknownActionError\";\n this.actionName = actionName;\n }\n}\n\nfunction resolveAction<Ctx, Evt>(\n ref: ActionRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Action<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.actions?.[ref];\n if (!fn) throw new UnknownActionError(ref);\n return fn;\n}\n\nfunction runActions<Ctx, Evt>(\n refs: readonly ActionRef<Ctx, Evt>[] | undefined,\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n effectSink: Effect[],\n): Ctx {\n if (!refs || refs.length === 0) return ctx;\n const enqueue = createEnqueuer(effectSink as { type: string; payload?: unknown }[]);\n let current = ctx;\n for (const ref of refs) {\n const fn = resolveAction(ref, impl);\n const patch = fn({ context: current, event, enqueue });\n current = mergeContext(current, patch);\n }\n return current;\n}\n\nfunction pickTransition<Ctx, Evt, States extends string>(\n candidates: readonly TransitionDef<Ctx, Evt, States>[],\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value: States,\n): TransitionDef<Ctx, Evt, States> | undefined {\n for (const t of candidates) {\n if (!t.guard) return t;\n if (evalGuard(t.guard, ctx, event, impl, value)) return t;\n }\n return undefined;\n}\n\n/**\n * Compute the next snapshot and collected effects from a single event.\n *\n * Order is fixed and uninterruptible:\n * 1. resolve candidate transitions for (state, event.type)\n * 2. evaluate guards in declaration order; pick the first passing one\n * 3. if external (target defined), run exit actions of the old state\n * 4. run transition.actions in declaration order\n * 5. if external, run entry actions of the new state\n * 6. return { snapshot, effects, changed }\n *\n * The function is pure: it never dispatches effects and never mutates inputs.\n */\nexport function step<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n snapshot: Snapshot<Ctx, States>,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n): StepResult<Ctx, States> {\n // Final state is inert: it never reacts to events.\n if (snapshot.status === \"final\") {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const state = def.states[snapshot.value];\n /* v8 ignore next 3 — defensive: snapshot.value is always validated against def.states by defineMachine + initialSnapshot. */\n if (!state) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const candidates = state.on?.[event.type];\n const candidateList: readonly TransitionDef<Ctx, Evt, States>[] = candidates\n ? Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>]\n : [];\n\n const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);\n if (!chosen) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const isExternal = chosen.target !== undefined;\n const nextStateValue = (chosen.target ?? snapshot.value) as States;\n const nextState = def.states[nextStateValue];\n\n const effectSink: Effect[] = [];\n let ctx = snapshot.context;\n\n if (isExternal) {\n ctx = runActions(state.exit, ctx, event, impl, effectSink);\n }\n ctx = runActions(chosen.actions, ctx, event, impl, effectSink);\n if (isExternal && nextState) {\n ctx = runActions(nextState.entry, ctx, event, impl, effectSink);\n }\n\n const status: \"active\" | \"final\" = nextState?.final === true ? \"final\" : \"active\";\n const nextSnapshot = freezeSnapshot({\n value: nextStateValue,\n context: ctx,\n status,\n });\n\n return Object.freeze({\n snapshot: nextSnapshot,\n effects: Object.freeze(effectSink.slice()) as readonly Effect[],\n changed: true,\n });\n}\n","import { initialSnapshot } from \"./definition.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { step } from \"./lifecycle.js\";\nimport { deepFreeze } from \"./snapshot.js\";\nimport {\n type Effect,\n type Implementations,\n type MachineDef,\n type Middleware,\n RESET_EVENT_TYPE,\n type ResetEvent,\n type Runtime,\n type RuntimeErrorEvent,\n type RuntimeEventMap,\n type RuntimeOptions,\n type RuntimeTransitionEvent,\n type Snapshot,\n type TransitionDef,\n} from \"./types.js\";\n\nexport class RuntimeDisposedError extends Error {\n constructor() {\n super(\"aifsmjs: runtime has been disposed; send()/reset() are not allowed\");\n this.name = \"RuntimeDisposedError\";\n }\n}\n\nconst RESET_EVENT: ResetEvent = Object.freeze({ type: RESET_EVENT_TYPE });\n\nfunction composeMiddleware<Ctx, Evt, States extends string>(\n middleware: readonly Middleware<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (ctx, finalNext) => {\n let index = -1;\n const dispatch = (i: number): void => {\n if (i <= index) throw new Error(\"aifsmjs: next() called multiple times in middleware\");\n index = i;\n const fn = middleware[i];\n if (!fn) {\n finalNext();\n return;\n }\n fn(ctx, () => dispatch(i + 1));\n };\n dispatch(0);\n };\n}\n\n/**\n * Build a thin stateful runtime around a machine. `send()` calls `step()`,\n * runs the read-only middleware pipeline, dispatches effects, and notifies\n * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it\n * and clears all state.\n */\nexport function createRuntime<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts: RuntimeOptions<Ctx, Evt, States> = {},\n): Runtime<Ctx, Evt, States> {\n let snapshot: Snapshot<Ctx, States> = initialSnapshot(def);\n const listeners = new Set<(snap: Snapshot<Ctx, States>) => void>();\n const middlewareChain =\n opts.middleware && opts.middleware.length > 0 ? composeMiddleware(opts.middleware) : undefined;\n const shouldDispatch = opts.dispatchEffects !== false;\n const controller = new AbortController();\n let disposed = false;\n\n // Typed event listeners for the EventTarget-like on() API.\n type EventListeners = {\n [K in keyof RuntimeEventMap<Ctx, Evt, States>]: Set<\n (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void\n >;\n };\n const eventListeners: EventListeners = {\n transition: new Set(),\n error: new Set(),\n dispose: new Set(),\n };\n\n // Track detach functions for abort listeners we attach to external signals\n // in on({ signal }). dispose() removes them so the external signal does not\n // keep wrapped listeners alive past the runtime's lifetime.\n const externalAbortCleanups = new Set<() => void>();\n\n function emit<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n payload: RuntimeEventMap<Ctx, Evt, States>[K],\n ): void {\n for (const fn of eventListeners[type]) fn(payload);\n }\n\n function notify() {\n for (const l of listeners) l(snapshot);\n }\n\n function runMiddleware(\n prev: Snapshot<Ctx, States>,\n event: Evt | ResetEvent,\n effects: readonly Effect[],\n changed: boolean,\n ) {\n if (!middlewareChain) return;\n const mwCtx = deepFreeze({\n prev,\n next: snapshot,\n event,\n effects,\n changed,\n });\n middlewareChain(mwCtx, () => {});\n }\n\n function dispatchEffects(effects: readonly Effect[], context: Ctx, event: Evt): void {\n if (!impl.effects || effects.length === 0) return;\n for (const eff of effects) {\n const handler = impl.effects[eff.type];\n if (!handler) continue;\n // Sync throws still propagate to the caller of send(); async rejections\n // surface on the 'error' event channel instead of becoming unhandled.\n const r = handler(eff, { context, event, signal: controller.signal });\n if (r instanceof Promise) {\n r.catch((err: unknown) => {\n const payload: RuntimeErrorEvent<Evt> = { error: err, event };\n emit(\"error\", payload);\n });\n }\n }\n }\n\n function send(event: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n const result = step(def, prev, event, impl);\n snapshot = result.snapshot;\n\n runMiddleware(prev, event, result.effects, result.changed);\n\n if (shouldDispatch) {\n dispatchEffects(result.effects, snapshot.context, event);\n }\n\n if (result.changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event,\n effects: result.effects,\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function reset(event?: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n snapshot = initialSnapshot(def);\n const changed = prev.value !== snapshot.value;\n const triggerEvent: Evt | ResetEvent = event ?? RESET_EVENT;\n runMiddleware(prev, triggerEvent, [], changed);\n if (changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event: triggerEvent,\n effects: [],\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function can(event: Evt): boolean {\n if (disposed || snapshot.status === \"final\") return false;\n const state = def.states[snapshot.value];\n /* v8 ignore next — defensive: snapshot.value always corresponds to a declared state. */\n if (!state) return false;\n const candidates = state.on?.[event.type];\n if (!candidates) return false;\n const list: readonly TransitionDef<Ctx, Evt, States>[] = Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>];\n for (const t of list) {\n if (!t.guard) return true;\n if (evalGuard(t.guard, snapshot.context, event, impl, snapshot.value)) return true;\n }\n return false;\n }\n\n function on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void {\n if (disposed || options?.signal?.aborted) return () => {};\n const target = eventListeners[type];\n let wrapped: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void = listener;\n if (options?.once) {\n wrapped = (payload) => {\n target.delete(wrapped);\n listener(payload);\n };\n }\n target.add(wrapped);\n let detachAbort: (() => void) | undefined;\n const signal = options?.signal;\n if (signal) {\n const onAbort = () => {\n target.delete(wrapped);\n if (detachAbort) externalAbortCleanups.delete(detachAbort);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n detachAbort = () => signal.removeEventListener(\"abort\", onAbort);\n externalAbortCleanups.add(detachAbort);\n }\n return () => {\n target.delete(wrapped);\n if (detachAbort) {\n detachAbort();\n externalAbortCleanups.delete(detachAbort);\n }\n };\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n controller.abort();\n listeners.clear();\n emit(\"dispose\", undefined as RuntimeEventMap<Ctx, Evt, States>[\"dispose\"]);\n for (const set of Object.values(eventListeners)) set.clear();\n for (const cleanup of externalAbortCleanups) cleanup();\n externalAbortCleanups.clear();\n }\n\n return {\n getSnapshot: () => snapshot,\n snapshot: () => snapshot,\n send,\n can,\n reset,\n dispose,\n on,\n get disposed() {\n return disposed;\n },\n get signal() {\n return controller.signal;\n },\n subscribe(listener) {\n if (disposed) return () => {};\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { createRuntime } from \"./runtime.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Implementations,\n MachineDef,\n Runtime,\n RuntimeOptions,\n Snapshot,\n StateDef,\n} from \"./types.js\";\n\nexport class InvalidDefinitionError extends Error {\n constructor(message: string) {\n super(`aifsmjs: ${message}`);\n this.name = \"InvalidDefinitionError\";\n }\n}\n\nfunction validateDefinition<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): void {\n if (!def.id || typeof def.id !== \"string\") {\n throw new InvalidDefinitionError(\"definition must have a non-empty string `id`\");\n }\n /* v8 ignore next 3 — additional safety: TS prevents non-object `states`; this guards untyped JS callers. */\n if (!def.states || typeof def.states !== \"object\") {\n throw new InvalidDefinitionError(\"definition must have a `states` object\");\n }\n const stateKeys = Object.keys(def.states) as States[];\n if (stateKeys.length === 0) {\n throw new InvalidDefinitionError(\"`states` must declare at least one state\");\n }\n if (!def.initial || !stateKeys.includes(def.initial)) {\n throw new InvalidDefinitionError(\n `\\`initial\\` \"${String(def.initial)}\" is not declared in states (${stateKeys.join(\", \")})`,\n );\n }\n for (const [stateName, stateDef] of Object.entries(def.states) as [\n States,\n (typeof def.states)[States],\n ][]) {\n if (!stateDef.on) continue;\n for (const [evtType, entry] of Object.entries(stateDef.on)) {\n const transitions = Array.isArray(entry) ? entry : [entry];\n for (const t of transitions) {\n if (t.target !== undefined && !stateKeys.includes(t.target)) {\n throw new InvalidDefinitionError(\n `transition ${stateName} -[${evtType}]-> \"${String(t.target)}\" targets an unknown state`,\n );\n }\n }\n }\n }\n}\n\n/**\n * Validate a machine definition shape and return it. Same reference is\n * returned; no cloning happens. Validation is intentionally shallow.\n *\n * Two call forms:\n *\n * defineMachine<Ctx, Evt, States>({ ... })\n * Explicit generics. Use when you need full control (e.g. union event\n * types). Required because TypeScript cannot otherwise infer `Evt`.\n *\n * setup<Ctx, Evt>().defineMachine({ ... })\n * Curried form. Lets `States` be inferred from `keyof states`, so you\n * can omit it. Recommended for typical usage.\n */\nexport function defineMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): MachineDef<Ctx, Evt, States> {\n validateDefinition(def);\n return def;\n}\n\n/**\n * Curried builder so `States` can be inferred from `keyof states` without\n * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the\n * type arguments; pass the def to the returned `defineMachine`.\n *\n * const machine = setup<MyCtx, MyEvt>().defineMachine({\n * id: \"m\",\n * initial: \"a\",\n * context: { ... },\n * states: { a: {...}, b: {...} }, // States inferred as \"a\" | \"b\"\n * });\n */\nexport function setup<Ctx, Evt extends { type: string }>(): {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => MachineDef<Ctx, Evt, States>;\n} {\n return {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => {\n const cast = def as unknown as MachineDef<Ctx, Evt, States>;\n validateDefinition(cast);\n return cast;\n },\n };\n}\n\n/**\n * Build the initial snapshot for a machine.\n */\nexport function initialSnapshot<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): Snapshot<Ctx, States> {\n const isFinal = def.states[def.initial]?.final === true;\n return freezeSnapshot({\n value: def.initial,\n context: def.context,\n status: isFinal ? (\"final\" as const) : (\"active\" as const),\n });\n}\n\n/**\n * Convenience factory that composes `defineMachine` and `createRuntime` in\n * one call for the common case where you do not need to keep the machine\n * definition around for serialization or sharing.\n *\n * For type inference over `States` from `keyof states`, prefer\n * `setup<Ctx, Evt>().defineMachine(...)` then pass the result to\n * `createRuntime` separately. `createMachine` is the spec-style entry point\n * documented in the ai*js ecosystem review.\n */\nexport function createMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts?: RuntimeOptions<Ctx, Evt, States>,\n): Runtime<Ctx, Evt, States> {\n return createRuntime(defineMachine(def), impl, opts ?? {});\n}\n","import type { MachineDef, TransitionDef } from \"./types.js\";\n\n/**\n * Return all transition candidates for (state, eventType). Order is preserved\n * from the declaration so that guard fallthrough behaves predictably.\n *\n * If the event has no entry under the given state, an empty array is returned.\n */\nexport function resolveTransitions<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n stateValue: States,\n eventType: string,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n const state = def.states[stateValue];\n if (!state || !state.on) return [];\n const entry = state.on[eventType];\n if (!entry) return [];\n return Array.isArray(entry) ? entry : [entry as TransitionDef<Ctx, Evt, States>];\n}\n"]}
package/dist/index.js CHANGED
@@ -194,6 +194,7 @@ function createRuntime(def, impl, opts = {}) {
194
194
  error: /* @__PURE__ */ new Set(),
195
195
  dispose: /* @__PURE__ */ new Set()
196
196
  };
197
+ const externalAbortCleanups = /* @__PURE__ */ new Set();
197
198
  function emit(type, payload) {
198
199
  for (const fn of eventListeners[type]) fn(payload);
199
200
  }
@@ -293,10 +294,24 @@ function createRuntime(def, impl, opts = {}) {
293
294
  };
294
295
  }
295
296
  target.add(wrapped);
296
- if (options?.signal) {
297
- options.signal.addEventListener("abort", () => target.delete(wrapped), { once: true });
297
+ let detachAbort;
298
+ const signal = options?.signal;
299
+ if (signal) {
300
+ const onAbort = () => {
301
+ target.delete(wrapped);
302
+ if (detachAbort) externalAbortCleanups.delete(detachAbort);
303
+ };
304
+ signal.addEventListener("abort", onAbort, { once: true });
305
+ detachAbort = () => signal.removeEventListener("abort", onAbort);
306
+ externalAbortCleanups.add(detachAbort);
298
307
  }
299
- return () => target.delete(wrapped);
308
+ return () => {
309
+ target.delete(wrapped);
310
+ if (detachAbort) {
311
+ detachAbort();
312
+ externalAbortCleanups.delete(detachAbort);
313
+ }
314
+ };
300
315
  }
301
316
  function dispose() {
302
317
  if (disposed) return;
@@ -305,6 +320,8 @@ function createRuntime(def, impl, opts = {}) {
305
320
  listeners.clear();
306
321
  emit("dispose", void 0);
307
322
  for (const set of Object.values(eventListeners)) set.clear();
323
+ for (const cleanup of externalAbortCleanups) cleanup();
324
+ externalAbortCleanups.clear();
308
325
  }
309
326
  return {
310
327
  getSnapshot: () => snapshot,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fsm/types.ts","../src/fsm/evaluator.ts","../src/effects/enqueuer.ts","../src/fsm/snapshot.ts","../src/fsm/updater.ts","../src/fsm/lifecycle.ts","../src/fsm/runtime.ts","../src/fsm/definition.ts","../src/fsm/resolver.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// All public types live here so AI agents and humans can read the entire\n// public surface in one file.\n\nexport type Effect = Readonly<{ type: string; payload?: unknown }>;\n\nexport type Enqueuer = Readonly<{\n effect: (type: string, payload?: unknown) => void;\n}>;\n\nexport type GuardArgs<Ctx, Evt> = Readonly<{\n context: Ctx;\n event: Evt;\n /**\n * Optional guard registry, threaded by `evalGuard` so combinators can resolve\n * string refs nested inside `and / or / not`. Inline user guards may safely\n * ignore this field — it is `undefined` when guards are evaluated outside of\n * `evalGuard` (e.g. in unit tests calling the function directly).\n */\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n /**\n * Current state value, threaded by `evalGuard` from the live snapshot. Used\n * by the `stateIn` combinator. `undefined` when guards are called outside of\n * a lifecycle evaluation.\n */\n value?: string;\n}>;\n\nexport type Guard<Ctx, Evt> = (args: GuardArgs<Ctx, Evt>) => boolean;\n\nexport type Action<Ctx, Evt> = (args: {\n context: Ctx;\n event: Evt;\n enqueue: Enqueuer;\n}) => Partial<Ctx> | void;\n\nexport type EffectHandler<Ctx, Evt> = (\n effect: Effect,\n args: { context: Ctx; event: Evt; signal: AbortSignal },\n) => void | Promise<void>;\n\nexport type GuardRef<Ctx, Evt> = string | Guard<Ctx, Evt>;\nexport type ActionRef<Ctx, Evt> = string | Action<Ctx, Evt>;\n\nexport type TransitionDef<Ctx, Evt, States extends string> = Readonly<{\n target?: States;\n guard?: GuardRef<Ctx, Evt>;\n actions?: readonly ActionRef<Ctx, Evt>[];\n}>;\n\nexport type StateDef<Ctx, Evt, States extends string> = Readonly<{\n on?: Readonly<\n Record<string, TransitionDef<Ctx, Evt, States> | readonly TransitionDef<Ctx, Evt, States>[]>\n >;\n entry?: readonly ActionRef<Ctx, Evt>[];\n exit?: readonly ActionRef<Ctx, Evt>[];\n final?: boolean;\n}>;\n\nexport type MachineDef<Ctx, Evt extends { type: string }, States extends string> = Readonly<{\n id: string;\n initial: States;\n context: Ctx;\n states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n}>;\n\nexport type Snapshot<Ctx, States extends string> = Readonly<{\n value: States;\n context: Ctx;\n status: \"active\" | \"final\";\n}>;\n\nexport type Implementations<Ctx, Evt> = Readonly<{\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n actions?: Readonly<Record<string, Action<Ctx, Evt>>>;\n effects?: Readonly<Record<string, EffectHandler<Ctx, Evt>>>;\n}>;\n\nexport type StepResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Sentinel event type that `Runtime.reset()` synthesises when the caller does\n * not pass an explicit event. Middleware receives it through\n * `MiddlewareContext.event`. Exposed so user code can discriminate.\n */\nexport const RESET_EVENT_TYPE = \"@@aifsmjs/RESET\" as const;\nexport type ResetEvent = Readonly<{ type: typeof RESET_EVENT_TYPE }>;\n\nexport type MiddlewareContext<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n /**\n * The triggering event. May be the user's `Evt` (from `send()` or an\n * explicit `reset(event)`) or the `ResetEvent` sentinel emitted by a\n * `reset()` with no event argument.\n */\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\nexport type Middleware<Ctx, Evt, States extends string> = (\n ctx: MiddlewareContext<Ctx, Evt, States>,\n next: () => void,\n) => void;\n\n/**\n * Payload of the `'transition'` runtime event — emitted after each `send()` or\n * `reset()` that actually changed the snapshot value.\n */\nexport type RuntimeTransitionEvent<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Payload of the `'error'` runtime event — currently emitted for async effect\n * handler rejections (which would otherwise become unhandled). Synchronous\n * throws from effect handlers and middleware still propagate to the caller of\n * `send()` / `reset()`.\n */\nexport type RuntimeErrorEvent<Evt> = Readonly<{\n error: unknown;\n event: Evt | ResetEvent | undefined;\n}>;\n\nexport type RuntimeEventMap<Ctx, Evt, States extends string> = {\n transition: RuntimeTransitionEvent<Ctx, Evt, States>;\n error: RuntimeErrorEvent<Evt>;\n dispose: void;\n};\n\nexport interface Runtime<Ctx, Evt extends { type: string }, States extends string> {\n getSnapshot(): Snapshot<Ctx, States>;\n /** Alias for `getSnapshot()`. */\n snapshot(): Snapshot<Ctx, States>;\n send(event: Evt): Snapshot<Ctx, States>;\n /**\n * Predict whether sending `event` would fire a transition. Reuses\n * `resolveTransitions` + `evalGuard` without applying any actions. Guards\n * are expected to be pure; `can` then matches `send` for the same input.\n */\n can(event: Evt): boolean;\n subscribe(listener: (snap: Snapshot<Ctx, States>) => void): () => void;\n /**\n * EventTarget-like typed listener API. Returns an unsubscribe function.\n * `options.signal` removes the listener when aborted; `options.once`\n * removes the listener after the first invocation. After `dispose()`,\n * `on()` is a no-op and returns a no-op unsubscribe.\n */\n on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void;\n /**\n * Re-initialise the runtime to the definition's initial snapshot. Triggers\n * subscribers but does NOT run entry actions (reset = re-birth, not\n * \"transition into initial\"). Throws RuntimeDisposedError if disposed.\n * If an `event` is supplied, middleware sees it as the trigger; otherwise\n * a sentinel `{ type: \"@@aifsmjs/RESET\" }` is synthesised.\n */\n reset(event?: Evt): Snapshot<Ctx, States>;\n /**\n * Tear down: abort the internal AbortController (effect handlers see signal\n * fire), clear listeners, and mark this runtime as disposed. Subsequent\n * send()/reset() calls throw RuntimeDisposedError. Idempotent.\n */\n dispose(): void;\n /**\n * True after `dispose()` has been called.\n */\n readonly disposed: boolean;\n /**\n * AbortSignal scoped to this runtime's lifetime. Fires once on dispose().\n * Threaded to every EffectHandler invocation; external integrations\n * (e.g. component teardown) can also attach `signal.addEventListener(\"abort\", ...)`.\n */\n readonly signal: AbortSignal;\n}\n\nexport type RuntimeOptions<Ctx, Evt, States extends string> = Readonly<{\n middleware?: readonly Middleware<Ctx, Evt, States>[];\n /**\n * If false, do not dispatch effects through the effect handler map.\n * Useful for replay / dry-run modes. Defaults to true.\n */\n dispatchEffects?: boolean;\n}>;\n","import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * this function does not catch async returns — TypeScript should already block\n * those at compile time.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n return fn(args);\n}\n","import type { Enqueuer } from \"../fsm/types.js\";\n\n/**\n * Build a closure-based Enqueuer that pushes effects into the supplied sink.\n * Each `step()` invocation creates one such enqueuer and discards it\n * afterwards; the sink is the effects array later returned to the caller.\n *\n * Lives in `effects/` because the Enqueuer concept is the effects-domain API\n * — `step()` imports it from here.\n */\nexport function createEnqueuer(sink: { type: string; payload?: unknown }[]): Enqueuer {\n return Object.freeze({\n effect(type: string, payload?: unknown) {\n if (payload === undefined) {\n sink.push(Object.freeze({ type }));\n } else {\n sink.push(Object.freeze({ type, payload }));\n }\n },\n });\n}\n","import type { Snapshot } from \"./types.js\";\n\nconst IS_DEV =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Object.isFrozen(value)) return value;\n Object.freeze(value);\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n } else if (isPlainObject(value)) {\n for (const key of Object.keys(value)) {\n deepFreeze((value as Record<string, unknown>)[key]);\n }\n }\n return value;\n}\n\n/**\n * Wrap a freshly built snapshot. In dev mode the whole tree is deep-frozen so\n * accidental mutation throws immediately. In production only the top object is\n * frozen, keeping the cost negligible.\n */\nexport function freezeSnapshot<C, S extends string>(snap: Snapshot<C, S>): Snapshot<C, S> {\n // IS_DEV is always true in vitest; the production branch (`Object.freeze`)\n // is exercised only when NODE_ENV === \"production\" and is intentionally\n // left out of the coverage threshold.\n return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);\n}\n\nexport function createSnapshot<C, S extends string>(args: {\n value: S;\n context: C;\n status?: \"active\" | \"final\";\n}): Snapshot<C, S> {\n return freezeSnapshot({\n value: args.value,\n context: args.context,\n status: args.status ?? \"active\",\n });\n}\n","import type { Action } from \"./types.js\";\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Build an Action that returns a Partial<Ctx> from a pure updater.\n * The partial is merged into the current context by `step()`.\n */\nexport function assign<Ctx, Evt>(\n updater: (args: { context: Ctx; event: Evt }) => Partial<Ctx>,\n): Action<Ctx, Evt> {\n return ({ context, event }) => updater({ context, event });\n}\n\n/**\n * Merge a partial context update into the current context. Plain-object\n * contexts get a shallow merge; non-object contexts get replaced wholesale.\n *\n * The function never mutates either argument.\n */\nexport function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx {\n if (patch === undefined || patch === null) return current;\n if (isPlainRecord(current) && isPlainRecord(patch)) {\n return { ...current, ...patch } as Ctx;\n }\n return patch as Ctx;\n}\n","import { createEnqueuer } from \"../effects/enqueuer.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Action,\n ActionRef,\n Effect,\n Implementations,\n MachineDef,\n Snapshot,\n StepResult,\n TransitionDef,\n} from \"./types.js\";\nimport { mergeContext } from \"./updater.js\";\n\nexport class UnknownActionError extends Error {\n readonly actionName: string;\n constructor(actionName: string) {\n super(`aifsmjs: action \"${actionName}\" not found in implementations.actions`);\n this.name = \"UnknownActionError\";\n this.actionName = actionName;\n }\n}\n\nfunction resolveAction<Ctx, Evt>(\n ref: ActionRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Action<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.actions?.[ref];\n if (!fn) throw new UnknownActionError(ref);\n return fn;\n}\n\nfunction runActions<Ctx, Evt>(\n refs: readonly ActionRef<Ctx, Evt>[] | undefined,\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n effectSink: Effect[],\n): Ctx {\n if (!refs || refs.length === 0) return ctx;\n const enqueue = createEnqueuer(effectSink as { type: string; payload?: unknown }[]);\n let current = ctx;\n for (const ref of refs) {\n const fn = resolveAction(ref, impl);\n const patch = fn({ context: current, event, enqueue });\n current = mergeContext(current, patch);\n }\n return current;\n}\n\nfunction pickTransition<Ctx, Evt, States extends string>(\n candidates: readonly TransitionDef<Ctx, Evt, States>[],\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value: States,\n): TransitionDef<Ctx, Evt, States> | undefined {\n for (const t of candidates) {\n if (!t.guard) return t;\n if (evalGuard(t.guard, ctx, event, impl, value)) return t;\n }\n return undefined;\n}\n\n/**\n * Compute the next snapshot and collected effects from a single event.\n *\n * Order is fixed and uninterruptible:\n * 1. resolve candidate transitions for (state, event.type)\n * 2. evaluate guards in declaration order; pick the first passing one\n * 3. if external (target defined), run exit actions of the old state\n * 4. run transition.actions in declaration order\n * 5. if external, run entry actions of the new state\n * 6. return { snapshot, effects, changed }\n *\n * The function is pure: it never dispatches effects and never mutates inputs.\n */\nexport function step<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n snapshot: Snapshot<Ctx, States>,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n): StepResult<Ctx, States> {\n // Final state is inert: it never reacts to events.\n if (snapshot.status === \"final\") {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const state = def.states[snapshot.value];\n /* v8 ignore next 3 — defensive: snapshot.value is always validated against def.states by defineMachine + initialSnapshot. */\n if (!state) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const candidates = state.on?.[event.type];\n const candidateList: readonly TransitionDef<Ctx, Evt, States>[] = candidates\n ? Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>]\n : [];\n\n const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);\n if (!chosen) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const isExternal = chosen.target !== undefined;\n const nextStateValue = (chosen.target ?? snapshot.value) as States;\n const nextState = def.states[nextStateValue];\n\n const effectSink: Effect[] = [];\n let ctx = snapshot.context as Ctx;\n\n if (isExternal) {\n ctx = runActions(state.exit, ctx, event, impl, effectSink);\n }\n ctx = runActions(chosen.actions, ctx, event, impl, effectSink);\n if (isExternal && nextState) {\n ctx = runActions(nextState.entry, ctx, event, impl, effectSink);\n }\n\n const status: \"active\" | \"final\" = nextState?.final === true ? \"final\" : \"active\";\n const nextSnapshot = freezeSnapshot({\n value: nextStateValue,\n context: ctx,\n status,\n });\n\n return Object.freeze({\n snapshot: nextSnapshot,\n effects: Object.freeze(effectSink.slice()) as readonly Effect[],\n changed: true,\n });\n}\n","import { initialSnapshot } from \"./definition.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { step } from \"./lifecycle.js\";\nimport { deepFreeze } from \"./snapshot.js\";\nimport {\n type Effect,\n type Implementations,\n type MachineDef,\n type Middleware,\n RESET_EVENT_TYPE,\n type ResetEvent,\n type Runtime,\n type RuntimeErrorEvent,\n type RuntimeEventMap,\n type RuntimeOptions,\n type RuntimeTransitionEvent,\n type Snapshot,\n type TransitionDef,\n} from \"./types.js\";\n\nexport class RuntimeDisposedError extends Error {\n constructor() {\n super(\"aifsmjs: runtime has been disposed; send()/reset() are not allowed\");\n this.name = \"RuntimeDisposedError\";\n }\n}\n\nconst RESET_EVENT: ResetEvent = Object.freeze({ type: RESET_EVENT_TYPE });\n\nfunction composeMiddleware<Ctx, Evt, States extends string>(\n middleware: readonly Middleware<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (ctx, finalNext) => {\n let index = -1;\n const dispatch = (i: number): void => {\n if (i <= index) throw new Error(\"aifsmjs: next() called multiple times in middleware\");\n index = i;\n const fn = middleware[i];\n if (!fn) {\n finalNext();\n return;\n }\n fn(ctx, () => dispatch(i + 1));\n };\n dispatch(0);\n };\n}\n\n/**\n * Build a thin stateful runtime around a machine. `send()` calls `step()`,\n * runs the read-only middleware pipeline, dispatches effects, and notifies\n * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it\n * and clears all state.\n */\nexport function createRuntime<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts: RuntimeOptions<Ctx, Evt, States> = {},\n): Runtime<Ctx, Evt, States> {\n let snapshot: Snapshot<Ctx, States> = initialSnapshot(def);\n const listeners = new Set<(snap: Snapshot<Ctx, States>) => void>();\n const middlewareChain =\n opts.middleware && opts.middleware.length > 0 ? composeMiddleware(opts.middleware) : undefined;\n const shouldDispatch = opts.dispatchEffects !== false;\n const controller = new AbortController();\n let disposed = false;\n\n // Typed event listeners for the EventTarget-like on() API.\n type EventListeners = {\n [K in keyof RuntimeEventMap<Ctx, Evt, States>]: Set<\n (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void\n >;\n };\n const eventListeners: EventListeners = {\n transition: new Set(),\n error: new Set(),\n dispose: new Set(),\n };\n\n function emit<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n payload: RuntimeEventMap<Ctx, Evt, States>[K],\n ): void {\n for (const fn of eventListeners[type]) fn(payload);\n }\n\n function notify() {\n for (const l of listeners) l(snapshot);\n }\n\n function runMiddleware(\n prev: Snapshot<Ctx, States>,\n event: Evt | ResetEvent,\n effects: readonly Effect[],\n changed: boolean,\n ) {\n if (!middlewareChain) return;\n const mwCtx = deepFreeze({\n prev,\n next: snapshot,\n event,\n effects,\n changed,\n });\n middlewareChain(mwCtx, () => {});\n }\n\n function dispatchEffects(\n effects: readonly Effect[],\n context: Ctx,\n event: Evt | ResetEvent,\n ): void {\n if (!impl.effects || effects.length === 0) return;\n for (const eff of effects) {\n const handler = impl.effects[eff.type];\n if (!handler) continue;\n // Sync throws still propagate to the caller of send(); async rejections\n // surface on the 'error' event channel instead of becoming unhandled.\n const r = handler(eff, { context, event: event as Evt, signal: controller.signal });\n if (r instanceof Promise) {\n r.catch((err: unknown) => {\n const payload: RuntimeErrorEvent<Evt> = { error: err, event };\n emit(\"error\", payload);\n });\n }\n }\n }\n\n function send(event: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n const result = step(def, prev, event, impl);\n snapshot = result.snapshot;\n\n runMiddleware(prev, event, result.effects, result.changed);\n\n if (shouldDispatch) {\n dispatchEffects(result.effects, snapshot.context, event);\n }\n\n if (result.changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event,\n effects: result.effects,\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function reset(event?: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n snapshot = initialSnapshot(def);\n const changed = prev.value !== snapshot.value;\n const triggerEvent: Evt | ResetEvent = event ?? RESET_EVENT;\n runMiddleware(prev, triggerEvent, [], changed);\n if (changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event: triggerEvent,\n effects: [],\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function can(event: Evt): boolean {\n if (disposed || snapshot.status === \"final\") return false;\n const state = def.states[snapshot.value];\n /* v8 ignore next — defensive: snapshot.value always corresponds to a declared state. */\n if (!state) return false;\n const candidates = state.on?.[event.type];\n if (!candidates) return false;\n const list: readonly TransitionDef<Ctx, Evt, States>[] = Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>];\n for (const t of list) {\n if (!t.guard) return true;\n if (evalGuard(t.guard, snapshot.context, event, impl, snapshot.value)) return true;\n }\n return false;\n }\n\n function on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void {\n if (disposed || options?.signal?.aborted) return () => {};\n const target = eventListeners[type];\n let wrapped: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void = listener;\n if (options?.once) {\n wrapped = (payload) => {\n target.delete(wrapped);\n listener(payload);\n };\n }\n target.add(wrapped);\n if (options?.signal) {\n options.signal.addEventListener(\"abort\", () => target.delete(wrapped), { once: true });\n }\n return () => target.delete(wrapped);\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n controller.abort();\n listeners.clear();\n emit(\"dispose\", undefined as RuntimeEventMap<Ctx, Evt, States>[\"dispose\"]);\n for (const set of Object.values(eventListeners)) set.clear();\n }\n\n return {\n getSnapshot: () => snapshot,\n snapshot: () => snapshot,\n send,\n can,\n reset,\n dispose,\n on,\n get disposed() {\n return disposed;\n },\n get signal() {\n return controller.signal;\n },\n subscribe(listener) {\n if (disposed) return () => {};\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { createRuntime } from \"./runtime.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Implementations,\n MachineDef,\n Runtime,\n RuntimeOptions,\n Snapshot,\n StateDef,\n} from \"./types.js\";\n\nexport class InvalidDefinitionError extends Error {\n constructor(message: string) {\n super(`aifsmjs: ${message}`);\n this.name = \"InvalidDefinitionError\";\n }\n}\n\nfunction validateDefinition<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): void {\n if (!def.id || typeof def.id !== \"string\") {\n throw new InvalidDefinitionError(\"definition must have a non-empty string `id`\");\n }\n /* v8 ignore next 3 — additional safety: TS prevents non-object `states`; this guards untyped JS callers. */\n if (!def.states || typeof def.states !== \"object\") {\n throw new InvalidDefinitionError(\"definition must have a `states` object\");\n }\n const stateKeys = Object.keys(def.states) as States[];\n if (stateKeys.length === 0) {\n throw new InvalidDefinitionError(\"`states` must declare at least one state\");\n }\n if (!def.initial || !stateKeys.includes(def.initial)) {\n throw new InvalidDefinitionError(\n `\\`initial\\` \"${String(def.initial)}\" is not declared in states (${stateKeys.join(\", \")})`,\n );\n }\n for (const [stateName, stateDef] of Object.entries(def.states) as [\n States,\n (typeof def.states)[States],\n ][]) {\n if (!stateDef.on) continue;\n for (const [evtType, entry] of Object.entries(stateDef.on)) {\n const transitions = Array.isArray(entry) ? entry : [entry];\n for (const t of transitions) {\n if (t.target !== undefined && !stateKeys.includes(t.target)) {\n throw new InvalidDefinitionError(\n `transition ${stateName} -[${evtType}]-> \"${String(t.target)}\" targets an unknown state`,\n );\n }\n }\n }\n }\n}\n\n/**\n * Validate a machine definition shape and return it. Same reference is\n * returned; no cloning happens. Validation is intentionally shallow.\n *\n * Two call forms:\n *\n * defineMachine<Ctx, Evt, States>({ ... })\n * Explicit generics. Use when you need full control (e.g. union event\n * types). Required because TypeScript cannot otherwise infer `Evt`.\n *\n * setup<Ctx, Evt>().defineMachine({ ... })\n * Curried form. Lets `States` be inferred from `keyof states`, so you\n * can omit it. Recommended for typical usage.\n */\nexport function defineMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): MachineDef<Ctx, Evt, States> {\n validateDefinition(def);\n return def;\n}\n\n/**\n * Curried builder so `States` can be inferred from `keyof states` without\n * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the\n * type arguments; pass the def to the returned `defineMachine`.\n *\n * const machine = setup<MyCtx, MyEvt>().defineMachine({\n * id: \"m\",\n * initial: \"a\",\n * context: { ... },\n * states: { a: {...}, b: {...} }, // States inferred as \"a\" | \"b\"\n * });\n */\nexport function setup<Ctx, Evt extends { type: string }>(): {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => MachineDef<Ctx, Evt, States>;\n} {\n return {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => {\n const cast = def as unknown as MachineDef<Ctx, Evt, States>;\n validateDefinition(cast);\n return cast;\n },\n };\n}\n\n/**\n * Build the initial snapshot for a machine.\n */\nexport function initialSnapshot<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): Snapshot<Ctx, States> {\n const isFinal = def.states[def.initial]?.final === true;\n return freezeSnapshot({\n value: def.initial,\n context: def.context,\n status: isFinal ? (\"final\" as const) : (\"active\" as const),\n });\n}\n\n/**\n * Convenience factory that composes `defineMachine` and `createRuntime` in\n * one call for the common case where you do not need to keep the machine\n * definition around for serialization or sharing.\n *\n * For type inference over `States` from `keyof states`, prefer\n * `setup<Ctx, Evt>().defineMachine(...)` then pass the result to\n * `createRuntime` separately. `createMachine` is the spec-style entry point\n * documented in the ai*js ecosystem review.\n */\nexport function createMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts?: RuntimeOptions<Ctx, Evt, States>,\n): Runtime<Ctx, Evt, States> {\n return createRuntime(defineMachine(def), impl, opts ?? {});\n}\n","import type { MachineDef, TransitionDef } from \"./types.js\";\n\n/**\n * Return all transition candidates for (state, eventType). Order is preserved\n * from the declaration so that guard fallthrough behaves predictably.\n *\n * If the event has no entry under the given state, an empty array is returned.\n */\nexport function resolveTransitions<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n stateValue: States,\n eventType: string,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n const state = def.states[stateValue];\n if (!state || !state.on) return [];\n const entry = state.on[eventType];\n if (!entry) return [];\n return Array.isArray(entry) ? entry : [entry as TransitionDef<Ctx, Evt, States>];\n}\n"]}
1
+ {"version":3,"sources":["../src/fsm/types.ts","../src/fsm/evaluator.ts","../src/effects/enqueuer.ts","../src/fsm/snapshot.ts","../src/fsm/updater.ts","../src/fsm/lifecycle.ts","../src/fsm/runtime.ts","../src/fsm/definition.ts","../src/fsm/resolver.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// All public types live here so AI agents and humans can read the entire\n// public surface in one file.\n\nexport type Effect = Readonly<{ type: string; payload?: unknown }>;\n\nexport type Enqueuer = Readonly<{\n effect: (type: string, payload?: unknown) => void;\n}>;\n\nexport type GuardArgs<Ctx, Evt> = Readonly<{\n context: Ctx;\n event: Evt;\n /**\n * Optional guard registry, threaded by `evalGuard` so combinators can resolve\n * string refs nested inside `and / or / not`. Inline user guards may safely\n * ignore this field — it is `undefined` when guards are evaluated outside of\n * `evalGuard` (e.g. in unit tests calling the function directly).\n */\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n /**\n * Current state value, threaded by `evalGuard` from the live snapshot. Used\n * by the `stateIn` combinator. `undefined` when guards are called outside of\n * a lifecycle evaluation.\n */\n value?: string;\n}>;\n\nexport type Guard<Ctx, Evt> = (args: GuardArgs<Ctx, Evt>) => boolean;\n\nexport type Action<Ctx, Evt> = (args: {\n context: Ctx;\n event: Evt;\n enqueue: Enqueuer;\n}) => Partial<Ctx> | void;\n\nexport type EffectHandler<Ctx, Evt> = (\n effect: Effect,\n args: { context: Ctx; event: Evt; signal: AbortSignal },\n) => void | Promise<void>;\n\nexport type GuardRef<Ctx, Evt> = string | Guard<Ctx, Evt>;\nexport type ActionRef<Ctx, Evt> = string | Action<Ctx, Evt>;\n\nexport type TransitionDef<Ctx, Evt, States extends string> = Readonly<{\n target?: States;\n guard?: GuardRef<Ctx, Evt>;\n actions?: readonly ActionRef<Ctx, Evt>[];\n}>;\n\nexport type StateDef<Ctx, Evt, States extends string> = Readonly<{\n on?: Readonly<\n Record<string, TransitionDef<Ctx, Evt, States> | readonly TransitionDef<Ctx, Evt, States>[]>\n >;\n entry?: readonly ActionRef<Ctx, Evt>[];\n exit?: readonly ActionRef<Ctx, Evt>[];\n final?: boolean;\n}>;\n\nexport type MachineDef<Ctx, Evt extends { type: string }, States extends string> = Readonly<{\n id: string;\n initial: States;\n context: Ctx;\n states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n}>;\n\nexport type Snapshot<Ctx, States extends string> = Readonly<{\n value: States;\n context: Ctx;\n status: \"active\" | \"final\";\n}>;\n\nexport type Implementations<Ctx, Evt> = Readonly<{\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n actions?: Readonly<Record<string, Action<Ctx, Evt>>>;\n effects?: Readonly<Record<string, EffectHandler<Ctx, Evt>>>;\n}>;\n\nexport type StepResult<Ctx, States extends string> = Readonly<{\n snapshot: Snapshot<Ctx, States>;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Sentinel event type that `Runtime.reset()` synthesises when the caller does\n * not pass an explicit event. Middleware receives it through\n * `MiddlewareContext.event`. Exposed so user code can discriminate.\n */\nexport const RESET_EVENT_TYPE = \"@@aifsmjs/RESET\" as const;\nexport type ResetEvent = Readonly<{ type: typeof RESET_EVENT_TYPE }>;\n\nexport type MiddlewareContext<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n /**\n * The triggering event. May be the user's `Evt` (from `send()` or an\n * explicit `reset(event)`) or the `ResetEvent` sentinel emitted by a\n * `reset()` with no event argument.\n */\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\nexport type Middleware<Ctx, Evt, States extends string> = (\n ctx: MiddlewareContext<Ctx, Evt, States>,\n next: () => void,\n) => void;\n\n/**\n * Payload of the `'transition'` runtime event — emitted after each `send()` or\n * `reset()` that actually changed the snapshot value.\n */\nexport type RuntimeTransitionEvent<Ctx, Evt, States extends string> = Readonly<{\n prev: Snapshot<Ctx, States>;\n next: Snapshot<Ctx, States>;\n event: Evt | ResetEvent;\n effects: readonly Effect[];\n changed: boolean;\n}>;\n\n/**\n * Payload of the `'error'` runtime event — currently emitted for async effect\n * handler rejections (which would otherwise become unhandled). Synchronous\n * throws from effect handlers and middleware still propagate to the caller of\n * `send()` / `reset()`.\n */\nexport type RuntimeErrorEvent<Evt> = Readonly<{\n error: unknown;\n event: Evt | ResetEvent | undefined;\n}>;\n\nexport type RuntimeEventMap<Ctx, Evt, States extends string> = {\n transition: RuntimeTransitionEvent<Ctx, Evt, States>;\n error: RuntimeErrorEvent<Evt>;\n dispose: void;\n};\n\nexport interface Runtime<Ctx, Evt extends { type: string }, States extends string> {\n getSnapshot(): Snapshot<Ctx, States>;\n /** Alias for `getSnapshot()`. */\n snapshot(): Snapshot<Ctx, States>;\n send(event: Evt): Snapshot<Ctx, States>;\n /**\n * Predict whether sending `event` would fire a transition. Reuses\n * `resolveTransitions` + `evalGuard` without applying any actions. Guards\n * are expected to be pure; `can` then matches `send` for the same input.\n */\n can(event: Evt): boolean;\n subscribe(listener: (snap: Snapshot<Ctx, States>) => void): () => void;\n /**\n * EventTarget-like typed listener API. Returns an unsubscribe function.\n * `options.signal` removes the listener when aborted; `options.once`\n * removes the listener after the first invocation. After `dispose()`,\n * `on()` is a no-op and returns a no-op unsubscribe.\n */\n on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void;\n /**\n * Re-initialise the runtime to the definition's initial snapshot. Triggers\n * subscribers but does NOT run entry actions (reset = re-birth, not\n * \"transition into initial\"). Throws RuntimeDisposedError if disposed.\n * If an `event` is supplied, middleware sees it as the trigger; otherwise\n * a sentinel `{ type: \"@@aifsmjs/RESET\" }` is synthesised.\n */\n reset(event?: Evt): Snapshot<Ctx, States>;\n /**\n * Tear down: abort the internal AbortController (effect handlers see signal\n * fire), clear listeners, and mark this runtime as disposed. Subsequent\n * send()/reset() calls throw RuntimeDisposedError. Idempotent.\n */\n dispose(): void;\n /**\n * True after `dispose()` has been called.\n */\n readonly disposed: boolean;\n /**\n * AbortSignal scoped to this runtime's lifetime. Fires once on dispose().\n * Threaded to every EffectHandler invocation; external integrations\n * (e.g. component teardown) can also attach `signal.addEventListener(\"abort\", ...)`.\n */\n readonly signal: AbortSignal;\n}\n\nexport type RuntimeOptions<Ctx, Evt, States extends string> = Readonly<{\n middleware?: readonly Middleware<Ctx, Evt, States>[];\n /**\n * If false, do not dispatch effects through the effect handler map.\n * Useful for replay / dry-run modes. Defaults to true.\n */\n dispatchEffects?: boolean;\n}>;\n","import type { Guard, GuardRef, Implementations } from \"./types.js\";\n\nexport class UnknownGuardError extends Error {\n readonly guardName: string;\n constructor(guardName: string) {\n super(`aifsmjs: guard \"${guardName}\" not found in implementations.guards`);\n this.name = \"UnknownGuardError\";\n this.guardName = guardName;\n }\n}\n\n/**\n * Resolve a guard ref to a Guard function. String refs are looked up in the\n * implementations map; inline functions are returned as-is.\n */\nexport function resolveGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Guard<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.guards?.[ref];\n if (!fn) throw new UnknownGuardError(ref);\n return fn;\n}\n\n/**\n * Evaluate a guard ref against (context, event). Guards must be sync and pure;\n * this function does not catch async returns — TypeScript should already block\n * those at compile time.\n *\n * The optional `value` argument is the current state value, threaded so the\n * `stateIn` combinator and similar predicates can introspect it.\n */\nexport function evalGuard<Ctx, Evt>(\n ref: GuardRef<Ctx, Evt>,\n context: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value?: string,\n): boolean {\n const fn = resolveGuard(ref, impl);\n // Build args while honouring exactOptionalPropertyTypes: omit fields that\n // would otherwise be assigned `undefined`.\n type Args = {\n context: Ctx;\n event: Evt;\n guards?: Readonly<Record<string, Guard<Ctx, Evt>>>;\n value?: string;\n };\n const args: Args = { context, event };\n const guardsMap = impl.guards;\n if (guardsMap) args.guards = guardsMap;\n if (value !== undefined) args.value = value;\n return fn(args);\n}\n","import type { Enqueuer } from \"../fsm/types.js\";\n\n/**\n * Build a closure-based Enqueuer that pushes effects into the supplied sink.\n * Each `step()` invocation creates one such enqueuer and discards it\n * afterwards; the sink is the effects array later returned to the caller.\n *\n * Lives in `effects/` because the Enqueuer concept is the effects-domain API\n * — `step()` imports it from here.\n */\nexport function createEnqueuer(sink: { type: string; payload?: unknown }[]): Enqueuer {\n return Object.freeze({\n effect(type: string, payload?: unknown) {\n if (payload === undefined) {\n sink.push(Object.freeze({ type }));\n } else {\n sink.push(Object.freeze({ type, payload }));\n }\n },\n });\n}\n","import type { Snapshot } from \"./types.js\";\n\nconst IS_DEV =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.NODE_ENV !== \"production\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Object.isFrozen(value)) return value;\n Object.freeze(value);\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n } else if (isPlainObject(value)) {\n for (const key of Object.keys(value)) {\n deepFreeze((value as Record<string, unknown>)[key]);\n }\n }\n return value;\n}\n\n/**\n * Wrap a freshly built snapshot. In dev mode the whole tree is deep-frozen so\n * accidental mutation throws immediately. In production only the top object is\n * frozen, keeping the cost negligible.\n */\nexport function freezeSnapshot<C, S extends string>(snap: Snapshot<C, S>): Snapshot<C, S> {\n // IS_DEV is always true in vitest; the production branch (`Object.freeze`)\n // is exercised only when NODE_ENV === \"production\" and is intentionally\n // left out of the coverage threshold.\n return IS_DEV ? deepFreeze(snap) : Object.freeze(snap);\n}\n\nexport function createSnapshot<C, S extends string>(args: {\n value: S;\n context: C;\n status?: \"active\" | \"final\";\n}): Snapshot<C, S> {\n return freezeSnapshot({\n value: args.value,\n context: args.context,\n status: args.status ?? \"active\",\n });\n}\n","import type { Action } from \"./types.js\";\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\") return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Build an Action that returns a Partial<Ctx> from a pure updater.\n * The partial is merged into the current context by `step()`.\n */\nexport function assign<Ctx, Evt>(\n updater: (args: { context: Ctx; event: Evt }) => Partial<Ctx>,\n): Action<Ctx, Evt> {\n return ({ context, event }) => updater({ context, event });\n}\n\n/**\n * Merge a partial context update into the current context. Plain-object\n * contexts get a shallow merge; non-object contexts get replaced wholesale.\n *\n * The function never mutates either argument.\n */\nexport function mergeContext<Ctx>(current: Ctx, patch: Partial<Ctx> | void): Ctx {\n if (patch === undefined || patch === null) return current;\n if (isPlainRecord(current) && isPlainRecord(patch)) {\n return { ...current, ...patch } as Ctx;\n }\n return patch as Ctx;\n}\n","import { createEnqueuer } from \"../effects/enqueuer.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Action,\n ActionRef,\n Effect,\n Implementations,\n MachineDef,\n Snapshot,\n StepResult,\n TransitionDef,\n} from \"./types.js\";\nimport { mergeContext } from \"./updater.js\";\n\nexport class UnknownActionError extends Error {\n readonly actionName: string;\n constructor(actionName: string) {\n super(`aifsmjs: action \"${actionName}\" not found in implementations.actions`);\n this.name = \"UnknownActionError\";\n this.actionName = actionName;\n }\n}\n\nfunction resolveAction<Ctx, Evt>(\n ref: ActionRef<Ctx, Evt>,\n impl: Implementations<Ctx, Evt>,\n): Action<Ctx, Evt> {\n if (typeof ref === \"function\") return ref;\n const fn = impl.actions?.[ref];\n if (!fn) throw new UnknownActionError(ref);\n return fn;\n}\n\nfunction runActions<Ctx, Evt>(\n refs: readonly ActionRef<Ctx, Evt>[] | undefined,\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n effectSink: Effect[],\n): Ctx {\n if (!refs || refs.length === 0) return ctx;\n const enqueue = createEnqueuer(effectSink as { type: string; payload?: unknown }[]);\n let current = ctx;\n for (const ref of refs) {\n const fn = resolveAction(ref, impl);\n const patch = fn({ context: current, event, enqueue });\n current = mergeContext(current, patch);\n }\n return current;\n}\n\nfunction pickTransition<Ctx, Evt, States extends string>(\n candidates: readonly TransitionDef<Ctx, Evt, States>[],\n ctx: Ctx,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n value: States,\n): TransitionDef<Ctx, Evt, States> | undefined {\n for (const t of candidates) {\n if (!t.guard) return t;\n if (evalGuard(t.guard, ctx, event, impl, value)) return t;\n }\n return undefined;\n}\n\n/**\n * Compute the next snapshot and collected effects from a single event.\n *\n * Order is fixed and uninterruptible:\n * 1. resolve candidate transitions for (state, event.type)\n * 2. evaluate guards in declaration order; pick the first passing one\n * 3. if external (target defined), run exit actions of the old state\n * 4. run transition.actions in declaration order\n * 5. if external, run entry actions of the new state\n * 6. return { snapshot, effects, changed }\n *\n * The function is pure: it never dispatches effects and never mutates inputs.\n */\nexport function step<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n snapshot: Snapshot<Ctx, States>,\n event: Evt,\n impl: Implementations<Ctx, Evt>,\n): StepResult<Ctx, States> {\n // Final state is inert: it never reacts to events.\n if (snapshot.status === \"final\") {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const state = def.states[snapshot.value];\n /* v8 ignore next 3 — defensive: snapshot.value is always validated against def.states by defineMachine + initialSnapshot. */\n if (!state) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const candidates = state.on?.[event.type];\n const candidateList: readonly TransitionDef<Ctx, Evt, States>[] = candidates\n ? Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>]\n : [];\n\n const chosen = pickTransition(candidateList, snapshot.context, event, impl, snapshot.value);\n if (!chosen) {\n return Object.freeze({ snapshot, effects: [] as readonly Effect[], changed: false });\n }\n\n const isExternal = chosen.target !== undefined;\n const nextStateValue = (chosen.target ?? snapshot.value) as States;\n const nextState = def.states[nextStateValue];\n\n const effectSink: Effect[] = [];\n let ctx = snapshot.context;\n\n if (isExternal) {\n ctx = runActions(state.exit, ctx, event, impl, effectSink);\n }\n ctx = runActions(chosen.actions, ctx, event, impl, effectSink);\n if (isExternal && nextState) {\n ctx = runActions(nextState.entry, ctx, event, impl, effectSink);\n }\n\n const status: \"active\" | \"final\" = nextState?.final === true ? \"final\" : \"active\";\n const nextSnapshot = freezeSnapshot({\n value: nextStateValue,\n context: ctx,\n status,\n });\n\n return Object.freeze({\n snapshot: nextSnapshot,\n effects: Object.freeze(effectSink.slice()) as readonly Effect[],\n changed: true,\n });\n}\n","import { initialSnapshot } from \"./definition.js\";\nimport { evalGuard } from \"./evaluator.js\";\nimport { step } from \"./lifecycle.js\";\nimport { deepFreeze } from \"./snapshot.js\";\nimport {\n type Effect,\n type Implementations,\n type MachineDef,\n type Middleware,\n RESET_EVENT_TYPE,\n type ResetEvent,\n type Runtime,\n type RuntimeErrorEvent,\n type RuntimeEventMap,\n type RuntimeOptions,\n type RuntimeTransitionEvent,\n type Snapshot,\n type TransitionDef,\n} from \"./types.js\";\n\nexport class RuntimeDisposedError extends Error {\n constructor() {\n super(\"aifsmjs: runtime has been disposed; send()/reset() are not allowed\");\n this.name = \"RuntimeDisposedError\";\n }\n}\n\nconst RESET_EVENT: ResetEvent = Object.freeze({ type: RESET_EVENT_TYPE });\n\nfunction composeMiddleware<Ctx, Evt, States extends string>(\n middleware: readonly Middleware<Ctx, Evt, States>[],\n): Middleware<Ctx, Evt, States> {\n return (ctx, finalNext) => {\n let index = -1;\n const dispatch = (i: number): void => {\n if (i <= index) throw new Error(\"aifsmjs: next() called multiple times in middleware\");\n index = i;\n const fn = middleware[i];\n if (!fn) {\n finalNext();\n return;\n }\n fn(ctx, () => dispatch(i + 1));\n };\n dispatch(0);\n };\n}\n\n/**\n * Build a thin stateful runtime around a machine. `send()` calls `step()`,\n * runs the read-only middleware pipeline, dispatches effects, and notifies\n * subscribers. The runtime owns an `AbortController`; `dispose()` aborts it\n * and clears all state.\n */\nexport function createRuntime<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts: RuntimeOptions<Ctx, Evt, States> = {},\n): Runtime<Ctx, Evt, States> {\n let snapshot: Snapshot<Ctx, States> = initialSnapshot(def);\n const listeners = new Set<(snap: Snapshot<Ctx, States>) => void>();\n const middlewareChain =\n opts.middleware && opts.middleware.length > 0 ? composeMiddleware(opts.middleware) : undefined;\n const shouldDispatch = opts.dispatchEffects !== false;\n const controller = new AbortController();\n let disposed = false;\n\n // Typed event listeners for the EventTarget-like on() API.\n type EventListeners = {\n [K in keyof RuntimeEventMap<Ctx, Evt, States>]: Set<\n (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void\n >;\n };\n const eventListeners: EventListeners = {\n transition: new Set(),\n error: new Set(),\n dispose: new Set(),\n };\n\n // Track detach functions for abort listeners we attach to external signals\n // in on({ signal }). dispose() removes them so the external signal does not\n // keep wrapped listeners alive past the runtime's lifetime.\n const externalAbortCleanups = new Set<() => void>();\n\n function emit<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n payload: RuntimeEventMap<Ctx, Evt, States>[K],\n ): void {\n for (const fn of eventListeners[type]) fn(payload);\n }\n\n function notify() {\n for (const l of listeners) l(snapshot);\n }\n\n function runMiddleware(\n prev: Snapshot<Ctx, States>,\n event: Evt | ResetEvent,\n effects: readonly Effect[],\n changed: boolean,\n ) {\n if (!middlewareChain) return;\n const mwCtx = deepFreeze({\n prev,\n next: snapshot,\n event,\n effects,\n changed,\n });\n middlewareChain(mwCtx, () => {});\n }\n\n function dispatchEffects(effects: readonly Effect[], context: Ctx, event: Evt): void {\n if (!impl.effects || effects.length === 0) return;\n for (const eff of effects) {\n const handler = impl.effects[eff.type];\n if (!handler) continue;\n // Sync throws still propagate to the caller of send(); async rejections\n // surface on the 'error' event channel instead of becoming unhandled.\n const r = handler(eff, { context, event, signal: controller.signal });\n if (r instanceof Promise) {\n r.catch((err: unknown) => {\n const payload: RuntimeErrorEvent<Evt> = { error: err, event };\n emit(\"error\", payload);\n });\n }\n }\n }\n\n function send(event: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n const result = step(def, prev, event, impl);\n snapshot = result.snapshot;\n\n runMiddleware(prev, event, result.effects, result.changed);\n\n if (shouldDispatch) {\n dispatchEffects(result.effects, snapshot.context, event);\n }\n\n if (result.changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event,\n effects: result.effects,\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function reset(event?: Evt): Snapshot<Ctx, States> {\n if (disposed) throw new RuntimeDisposedError();\n const prev = snapshot;\n snapshot = initialSnapshot(def);\n const changed = prev.value !== snapshot.value;\n const triggerEvent: Evt | ResetEvent = event ?? RESET_EVENT;\n runMiddleware(prev, triggerEvent, [], changed);\n if (changed) {\n notify();\n const payload: RuntimeTransitionEvent<Ctx, Evt, States> = {\n prev,\n next: snapshot,\n event: triggerEvent,\n effects: [],\n changed: true,\n };\n emit(\"transition\", payload);\n }\n return snapshot;\n }\n\n function can(event: Evt): boolean {\n if (disposed || snapshot.status === \"final\") return false;\n const state = def.states[snapshot.value];\n /* v8 ignore next — defensive: snapshot.value always corresponds to a declared state. */\n if (!state) return false;\n const candidates = state.on?.[event.type];\n if (!candidates) return false;\n const list: readonly TransitionDef<Ctx, Evt, States>[] = Array.isArray(candidates)\n ? candidates\n : [candidates as TransitionDef<Ctx, Evt, States>];\n for (const t of list) {\n if (!t.guard) return true;\n if (evalGuard(t.guard, snapshot.context, event, impl, snapshot.value)) return true;\n }\n return false;\n }\n\n function on<K extends keyof RuntimeEventMap<Ctx, Evt, States>>(\n type: K,\n listener: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void,\n options?: { signal?: AbortSignal; once?: boolean },\n ): () => void {\n if (disposed || options?.signal?.aborted) return () => {};\n const target = eventListeners[type];\n let wrapped: (payload: RuntimeEventMap<Ctx, Evt, States>[K]) => void = listener;\n if (options?.once) {\n wrapped = (payload) => {\n target.delete(wrapped);\n listener(payload);\n };\n }\n target.add(wrapped);\n let detachAbort: (() => void) | undefined;\n const signal = options?.signal;\n if (signal) {\n const onAbort = () => {\n target.delete(wrapped);\n if (detachAbort) externalAbortCleanups.delete(detachAbort);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n detachAbort = () => signal.removeEventListener(\"abort\", onAbort);\n externalAbortCleanups.add(detachAbort);\n }\n return () => {\n target.delete(wrapped);\n if (detachAbort) {\n detachAbort();\n externalAbortCleanups.delete(detachAbort);\n }\n };\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n controller.abort();\n listeners.clear();\n emit(\"dispose\", undefined as RuntimeEventMap<Ctx, Evt, States>[\"dispose\"]);\n for (const set of Object.values(eventListeners)) set.clear();\n for (const cleanup of externalAbortCleanups) cleanup();\n externalAbortCleanups.clear();\n }\n\n return {\n getSnapshot: () => snapshot,\n snapshot: () => snapshot,\n send,\n can,\n reset,\n dispose,\n on,\n get disposed() {\n return disposed;\n },\n get signal() {\n return controller.signal;\n },\n subscribe(listener) {\n if (disposed) return () => {};\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import { createRuntime } from \"./runtime.js\";\nimport { freezeSnapshot } from \"./snapshot.js\";\nimport type {\n Implementations,\n MachineDef,\n Runtime,\n RuntimeOptions,\n Snapshot,\n StateDef,\n} from \"./types.js\";\n\nexport class InvalidDefinitionError extends Error {\n constructor(message: string) {\n super(`aifsmjs: ${message}`);\n this.name = \"InvalidDefinitionError\";\n }\n}\n\nfunction validateDefinition<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): void {\n if (!def.id || typeof def.id !== \"string\") {\n throw new InvalidDefinitionError(\"definition must have a non-empty string `id`\");\n }\n /* v8 ignore next 3 — additional safety: TS prevents non-object `states`; this guards untyped JS callers. */\n if (!def.states || typeof def.states !== \"object\") {\n throw new InvalidDefinitionError(\"definition must have a `states` object\");\n }\n const stateKeys = Object.keys(def.states) as States[];\n if (stateKeys.length === 0) {\n throw new InvalidDefinitionError(\"`states` must declare at least one state\");\n }\n if (!def.initial || !stateKeys.includes(def.initial)) {\n throw new InvalidDefinitionError(\n `\\`initial\\` \"${String(def.initial)}\" is not declared in states (${stateKeys.join(\", \")})`,\n );\n }\n for (const [stateName, stateDef] of Object.entries(def.states) as [\n States,\n (typeof def.states)[States],\n ][]) {\n if (!stateDef.on) continue;\n for (const [evtType, entry] of Object.entries(stateDef.on)) {\n const transitions = Array.isArray(entry) ? entry : [entry];\n for (const t of transitions) {\n if (t.target !== undefined && !stateKeys.includes(t.target)) {\n throw new InvalidDefinitionError(\n `transition ${stateName} -[${evtType}]-> \"${String(t.target)}\" targets an unknown state`,\n );\n }\n }\n }\n }\n}\n\n/**\n * Validate a machine definition shape and return it. Same reference is\n * returned; no cloning happens. Validation is intentionally shallow.\n *\n * Two call forms:\n *\n * defineMachine<Ctx, Evt, States>({ ... })\n * Explicit generics. Use when you need full control (e.g. union event\n * types). Required because TypeScript cannot otherwise infer `Evt`.\n *\n * setup<Ctx, Evt>().defineMachine({ ... })\n * Curried form. Lets `States` be inferred from `keyof states`, so you\n * can omit it. Recommended for typical usage.\n */\nexport function defineMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): MachineDef<Ctx, Evt, States> {\n validateDefinition(def);\n return def;\n}\n\n/**\n * Curried builder so `States` can be inferred from `keyof states` without\n * `initial` collapsing it to a single literal. Pass `Ctx` and `Evt` as the\n * type arguments; pass the def to the returned `defineMachine`.\n *\n * const machine = setup<MyCtx, MyEvt>().defineMachine({\n * id: \"m\",\n * initial: \"a\",\n * context: { ... },\n * states: { a: {...}, b: {...} }, // States inferred as \"a\" | \"b\"\n * });\n */\nexport function setup<Ctx, Evt extends { type: string }>(): {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => MachineDef<Ctx, Evt, States>;\n} {\n return {\n defineMachine: <const States extends string>(def: {\n readonly id: string;\n readonly initial: NoInfer<States>;\n readonly context: Ctx;\n readonly states: Readonly<Record<States, StateDef<Ctx, Evt, States>>>;\n }) => {\n const cast = def as unknown as MachineDef<Ctx, Evt, States>;\n validateDefinition(cast);\n return cast;\n },\n };\n}\n\n/**\n * Build the initial snapshot for a machine.\n */\nexport function initialSnapshot<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n): Snapshot<Ctx, States> {\n const isFinal = def.states[def.initial]?.final === true;\n return freezeSnapshot({\n value: def.initial,\n context: def.context,\n status: isFinal ? (\"final\" as const) : (\"active\" as const),\n });\n}\n\n/**\n * Convenience factory that composes `defineMachine` and `createRuntime` in\n * one call for the common case where you do not need to keep the machine\n * definition around for serialization or sharing.\n *\n * For type inference over `States` from `keyof states`, prefer\n * `setup<Ctx, Evt>().defineMachine(...)` then pass the result to\n * `createRuntime` separately. `createMachine` is the spec-style entry point\n * documented in the ai*js ecosystem review.\n */\nexport function createMachine<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n impl: Implementations<Ctx, Evt>,\n opts?: RuntimeOptions<Ctx, Evt, States>,\n): Runtime<Ctx, Evt, States> {\n return createRuntime(defineMachine(def), impl, opts ?? {});\n}\n","import type { MachineDef, TransitionDef } from \"./types.js\";\n\n/**\n * Return all transition candidates for (state, eventType). Order is preserved\n * from the declaration so that guard fallthrough behaves predictably.\n *\n * If the event has no entry under the given state, an empty array is returned.\n */\nexport function resolveTransitions<Ctx, Evt extends { type: string }, States extends string>(\n def: MachineDef<Ctx, Evt, States>,\n stateValue: States,\n eventType: string,\n): readonly TransitionDef<Ctx, Evt, States>[] {\n const state = def.states[stateValue];\n if (!state || !state.on) return [];\n const entry = state.on[eventType];\n if (!entry) return [];\n return Array.isArray(entry) ? entry : [entry as TransitionDef<Ctx, Evt, States>];\n}\n"]}
@@ -274,6 +274,7 @@ function createRuntime(def, impl, opts = {}) {
274
274
  error: /* @__PURE__ */ new Set(),
275
275
  dispose: /* @__PURE__ */ new Set()
276
276
  };
277
+ const externalAbortCleanups = /* @__PURE__ */ new Set();
277
278
  function emit(type, payload) {
278
279
  for (const fn of eventListeners[type]) fn(payload);
279
280
  }
@@ -373,10 +374,24 @@ function createRuntime(def, impl, opts = {}) {
373
374
  };
374
375
  }
375
376
  target.add(wrapped);
376
- if (options?.signal) {
377
- options.signal.addEventListener("abort", () => target.delete(wrapped), { once: true });
377
+ let detachAbort;
378
+ const signal = options?.signal;
379
+ if (signal) {
380
+ const onAbort = () => {
381
+ target.delete(wrapped);
382
+ if (detachAbort) externalAbortCleanups.delete(detachAbort);
383
+ };
384
+ signal.addEventListener("abort", onAbort, { once: true });
385
+ detachAbort = () => signal.removeEventListener("abort", onAbort);
386
+ externalAbortCleanups.add(detachAbort);
378
387
  }
379
- return () => target.delete(wrapped);
388
+ return () => {
389
+ target.delete(wrapped);
390
+ if (detachAbort) {
391
+ detachAbort();
392
+ externalAbortCleanups.delete(detachAbort);
393
+ }
394
+ };
380
395
  }
381
396
  function dispose() {
382
397
  if (disposed) return;
@@ -385,6 +400,8 @@ function createRuntime(def, impl, opts = {}) {
385
400
  listeners.clear();
386
401
  emit("dispose", void 0);
387
402
  for (const set of Object.values(eventListeners)) set.clear();
403
+ for (const cleanup of externalAbortCleanups) cleanup();
404
+ externalAbortCleanups.clear();
388
405
  }
389
406
  return {
390
407
  getSnapshot: () => snapshot,