@state-flow/core 1.0.0
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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/flow.d.ts +49 -0
- package/dist/flow.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1507 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1458 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logger.d.ts +45 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/package-json.d.ts +8 -0
- package/dist/package-json.d.ts.map +1 -0
- package/dist/result.d.ts +60 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/signal.d.ts +19 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/state.d.ts +56 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/symbols.d.ts +9 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/package-json.ts","../src/flow.ts","../src/logger.ts","../src/symbols.ts","../src/utils.ts","../src/result.ts","../src/state.ts","../src/signal.ts"],"sourcesContent":["import packageJson from \"./package-json\";\n\n// `dispatch` is a deprecated escape hatch — prefer `lock()` + `send()`. It stays exported\n// only for synchronous teardown / pre-lock bootstrap (see its JSDoc); all other code should\n// acquire a lock so signals queue instead of throwing under a held lock / active transition.\nexport { applyFlow, DispatchFn, dispatch, disposeFlow, lock, observe, StateManager, sync } from \"./flow\";\nexport {\n addGlobalLogHandler,\n consoleLogHandler,\n StateFlowLogEntry,\n StateFlowLogHandler,\n setConsoleLogSilenced,\n setGlobalDispatchContextProvider,\n} from \"./logger\";\nexport { Result, ResultCollector, ResultKind } from \"./result\";\nexport { defineSignal, Signal, StateSignal } from \"./signal\";\nexport { defineFlow, defineState, isState, StateResult, StateVariant, stateVar } from \"./state\";\nexport { PARSER, SIGNALS, STRING_REPR, VARIANT } from \"./symbols\";\nexport { Infer, StateFlowError, serializeDebug } from \"./utils\";\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __STATE_FLOW__: { version: string };\n}\n\n// Exposes the running version on the global object so it can be inspected from the\n// browser/node console without importing the package — e.g. `globalThis.__STATE_FLOW__.version`.\nglobalThis.__STATE_FLOW__ ??= {\n version: `${packageJson.version} (${packageJson.branch} <${packageJson.commit}>)`,\n};\n","export default { name: \"@state-flow/core\", version: \"1.0.0\", commit: \"6b8863c9d96e7ff65eaf983b247f122628b986d5\", branch: \"HEAD\" };\n","/**\n * Contains structs for dispatching signals and controlling states\n *\n * @example ```ts\n * const mediaCtrl = {\n * audio: { volume: 0.5 },\n * el: document.createElement('video'),\n * };\n *\n * applyFlow(mediaCtrl, [audio], (sm) => {\n * sm.addEnterHandler(audio.muted, muteEl);\n * sm.addExitHandler(audio.muted, unmuteEl);\n * sm.addUpdateHandler(audio.unmuted, changeVolumeEl);\n * });\n *\n * function muteEl(state: audio): Result {\n * if (mediaCtrl.el.muted) {\n * return Result.ignore(\"already muted\");\n * }\n *\n * mediaCtrl.el.muted = true;\n * return Result.ok();\n * }\n *\n * function unmuteEl(state: audio): Result {\n * if (!mediaCtrl.el.muted) {\n * return Result.ignore(\"not muted\");\n * }\n *\n * mediaCtrl.el.muted = false;\n * return Result.ok();\n * }\n *\n * function changeVolumeEl(state: audio): Result {\n * if (state.volume < 0 || state volume > 1) {\n * return Result.reject(\"incorrect volume\");\n * }\n * mediaCtrl.el.volume = state.volume;\n * }\n * ```\n */\nimport { EventEmitter } from \"events\";\n\nimport {\n consoleLogHandler,\n emitGrouped,\n getGlobalDispatchContext,\n type StateFlowLogEntry,\n type StateFlowLogHandler,\n withGlobalLogHandlers,\n} from \"./logger\";\nimport { mergeResults, Result, ResultCollector, ResultKind } from \"./result\";\nimport type { Signal } from \"./signal\";\nimport {\n type ArrayToRecord,\n getInitialState,\n getName,\n handleSignal,\n isStateDef,\n type StateDefinition,\n type StateInstance,\n type StateVariant,\n stateAccepts,\n} from \"./state\";\nimport { DEF, VARIANT } from \"./symbols\";\nimport { buildName, StateFlowError } from \"./utils\";\n\nconst managementStateMap = new WeakMap<object, StateFlowMeta>();\nconst observersMap = new WeakMap<ObserverHandler<any>, Array<ObserverComparer<any>>>();\nconst currentRC = {\n ref: null as ResultCollector | null,\n set(rc: ResultCollector) {\n this.ref = rc;\n },\n clear() {\n this.ref = null;\n },\n};\n\n//#region Helper Types\n\ntype EventKind = \"enter\" | \"update\" | \"exit\" | \"rollback\";\n\nexport type StateFlowMeta = {\n emitter: EventEmitter;\n transitioning: Promise<Result> | true | null;\n lockHolder: symbol | null;\n /** FIFO waiters. Each carries its OWN lock id so dispose() can hand ownership\n * over directly (set lockHolder = next.id) with no null-gap window. */\n lockQueue: Array<{ id: symbol; resolve: () => void }>;\n states: Array<StateDefinition>;\n name: string;\n logHandlers: StateFlowLogHandler[];\n /** Active labeled-lock log group. While set, each dispatched entry is buffered here instead of\n * being emitted immediately, then flushed together (under one console group) when the lock\n * releases. Null when no labeled lock is held. `context` is the dispatch-context provider's\n * snapshot captured at `lock()` CALL time (null without a provider — the default).\n * See `lock(target, label)` and `emitGrouped`. */\n logGroup: { label: string; pending: Array<Promise<StateFlowLogEntry>>; context: string | null } | null;\n};\n\nexport interface FlowConfig {\n logHandlers?: StateFlowLogHandler[];\n}\n\ntype ProcessResult = {\n snapshot: Record<string, StateInstance>;\n} & {\n // [ the state , description ]\n [K in EventKind]: Array<[StateInstance, string]>;\n};\n\ntype StateHandler<TProps> = (state: StateInstance<TProps>, context: unknown) => Result;\n\ntype ObserverHandler<TProps = unknown> = (state: StateInstance<TProps>) => void;\ntype ObserverComparer<TProps = unknown> = (a: StateInstance<TProps>, b: StateInstance<TProps>) => void;\ntype ObserverComparerFn<TProps = unknown> = (a: TProps, b: TProps) => boolean;\n\ntype Disposer = {\n [Symbol.dispose](): void;\n};\n\nexport interface StateManager {\n addEnterHandler<TProps>(state: StateVariant<TProps>, cb: StateHandler<TProps>, context?: unknown): void;\n\n addExitHandler<TProps>(state: StateVariant<TProps>, cb: StateHandler<TProps>, context?: unknown): void;\n\n addUpdateHandler<TProps>(state: StateVariant<TProps>, cb: StateHandler<TProps>, context?: unknown): void;\n\n addRollbackHandler<TProps>(state: StateVariant<TProps>, cb: StateHandler<TProps>, context?: unknown): void;\n}\n\ntype StateManagerCallback = (sm: StateManager) => void;\n\nexport type DispatchFn = ((signal: Signal, mute?: boolean) => Result) & {\n [Symbol.asyncDispose](): Promise<void>;\n};\n\n//#endregion\n\n//#region Helper Functions\n\n/**\n * Builds a key for event emitter\n */\nfunction eventKey(kind: EventKind | \"observe\", state: string): string {\n return `${kind}:${state}`;\n}\n\n/**\n * @throws StateFlowError if target is not state flow object\n */\nfunction stateMeta(target: object): StateFlowMeta {\n const meta = managementStateMap.get(target);\n if (meta == null) {\n throw new StateFlowError(`${buildName(target)} doesn't contains state flows`);\n }\n return meta;\n}\n\n//#endregion\n\n/**\n * Watches for state changes of the specified group.\n * Returns a function to stop watching.\n */\nfunction addStateHandler(\n emitter: EventEmitter,\n kind: EventKind,\n stateVar: StateVariant,\n cb: StateHandler<any>,\n ctx?: unknown,\n): void {\n const wrapper = (\n state: StateInstance,\n snapshot: Record<string, StateInstance>,\n stateUpd: string,\n collector?: ResultCollector,\n ): void => {\n const handlerName = buildName(ctx, cb);\n try {\n const res = cb.apply(ctx, [state, snapshot]);\n if (!(res instanceof Result)) {\n throw new StateFlowError(`Handler '${handlerName}' returned not result`);\n }\n collector?.logHandler(String(stateVar[DEF]), kind, handlerName, res);\n collector?.push(res.withHandlerName(handlerName).withStateUpdating(stateUpd));\n } catch (err) {\n collector?.logHandler(String(stateVar[DEF]), kind, handlerName, err);\n collector?.push(Result.error(err).withHandlerName(handlerName).withStateUpdating(stateUpd));\n }\n };\n\n emitter.on(eventKey(kind, String(stateVar)), wrapper);\n}\n\n/**\n * Initializes a state management system on a target object by applying state definitions\n * and configuring event handlers.\n *\n * @param target - The object that will hold the state values and receive state updates\n * @param states - Array of state definitions that define the possible states and transitions\n * @param initializer - Callback function to set up state change handlers\n * @param config - State Flow configuration\n * @throws StateFlowError if state definitions are invalid or state objects are not found on target\n *\n * @example\n * ```ts\n * const mediaController = {\n * audioState: { volume: 0.5 },\n * videoState: { playing: false }\n * };\n *\n * applyFlow(mediaController, [audioState, videoState], (sm) => {\n * sm.addEnterHandler(audioState.muted, handleMute);\n * sm.addExitHandler(videoState.playing, handlePause);\n * });\n * ```\n */\nexport function applyFlow<TStates extends Array<object>>(\n target: ArrayToRecord<TStates>,\n states: TStates,\n initializer: StateManagerCallback,\n config: FlowConfig = {},\n): void {\n for (const def of states) {\n if (!isStateDef(def)) {\n throw new StateFlowError(\"Incorrect state definition\");\n }\n const name = getName(def);\n\n const st = target[name];\n if (st == null) {\n throw new StateFlowError(`State object ${name} not found`);\n }\n\n Object.defineProperty(target, name, { value: getInitialState(def)(st) });\n }\n\n const logHandlers = config.logHandlers?.length ? config.logHandlers : [consoleLogHandler];\n\n const emitter = new EventEmitter();\n managementStateMap.set(target, {\n emitter,\n logHandlers,\n states: states as StateDefinition[],\n transitioning: null,\n lockHolder: null,\n lockQueue: [],\n logGroup: null,\n name: String(Symbol.toStringTag in target ? target[Symbol.toStringTag] : target.constructor.name),\n });\n\n initializer({\n addEnterHandler: addStateHandler.bind(null, emitter, \"enter\"),\n addUpdateHandler: addStateHandler.bind(null, emitter, \"update\"),\n addExitHandler: addStateHandler.bind(null, emitter, \"exit\"),\n addRollbackHandler: addStateHandler.bind(null, emitter, \"rollback\"),\n });\n}\n\nfunction prepareSnapshot(target: object): Record<string, StateInstance> {\n const meta = managementStateMap.get(target);\n if (meta == null) {\n return {};\n }\n\n return Object.fromEntries(\n meta.states.map((s) => [s[Symbol.toStringTag], Reflect.get(target, s[Symbol.toStringTag])]),\n ) as Record<string, StateInstance>;\n}\n\n/**\n * Dispatches a signal to trigger state transitions in the target object.\n *\n * @deprecated Prefer `await using send = await lock(target); await send(sig).expect(...).done()`.\n * Bare `dispatch()` throws under a held lock / active transition (see the guards below);\n * only use it for synchronous teardown or pre-lock bootstrap. Every other caller should\n * acquire a lock so signals queue behind any in-flight transition instead of throwing.\n *\n * @param target - Object containing the states to be updated\n * @param signal - Signal object that triggers state transitions\n * @param mute - Do not emit log for that\n * @returns Result object indicating success, failure, or transition status\n * @throws StateFlowError if a lock is held or states are transitioning\n *\n * @example\n * ```ts\n * // Preferred: acquire a lock so dispatches queue instead of throwing.\n * await using send = await lock(player);\n * await send(signals.play()).expect(ResultKind.OK, ResultKind.Ignored).done();\n * await send(signals.seek({ time: 50 })).done();\n * // lock released automatically at scope exit\n *\n * // Escape hatch only — synchronous teardown or pre-lock bootstrap, where an async\n * // lock cannot be awaited (e.g. page-unload, or a constructor before any lock exists):\n * dispatch(player, signals.dispose({ reason: \"page unloaded\" }));\n * ```\n */\nexport function dispatch(target: object, signal: Signal, mute = false): Result {\n const meta = stateMeta(target);\n\n if (meta.lockHolder != null) {\n throw new StateFlowError(\"Lock is held. Use `await using send = lock(target)` for queued access\");\n }\n if (meta.transitioning != null) {\n throw new StateFlowError(\"States are in transitioning. Use `await sync(obj)` or await a previous result\");\n }\n\n const chainSnapshot = prepareSnapshot(target);\n const result = dispatchCore(target, signal, meta, mute);\n return processEnqueueChain(target, result, meta, chainSnapshot, mute);\n}\n\n/**\n * Acquires an exclusive lock on the target for dispatching multiple signals.\n * Use with `await using` for automatic cleanup.\n *\n * @param target - Object containing the states to lock\n * @param label - Optional short label for the critical section. When given, every entry logged\n * inside the lock is buffered and flushed together under one `console.group(label)` on release,\n * so a multi-signal operation reads as a single unit (see `emitGrouped`). Because entries are\n * buffered, a labeled lock's logs appear together at release rather than one-by-one in real time\n * — that delay is what makes correct nesting possible. Omit the label for unchanged, immediate\n * per-entry logging.\n * @returns A callable DispatchFn that dispatches signals while holding the lock\n *\n * @example\n * ```ts\n * await using send = await lock(player, \"player play request\");\n * await send(signals.play()).done();\n * await send(signals.seek({ time: 50 })).done();\n * // lock released automatically at scope exit; the two signals log under one \"player play request\" group\n * ```\n */\nexport async function lock(target: object, label?: string): Promise<DispatchFn> {\n const meta = stateMeta(target);\n const id = Symbol(\"lock\");\n\n // Captured SYNCHRONOUSLY at call time — an async function body runs in the caller's stack\n // up to its first await, so for UI-triggered locks this still executes inside the\n // interaction event's synchronous propagation (the whole point: by the time `send()` runs,\n // microtask hops have long left that stack). Null without a provider — the default.\n const dispatchContext = label != null ? getGlobalDispatchContext() : null;\n const lockRequestedAt = dispatchContext != null ? Date.now() : 0;\n\n // Claim ownership. If the lock is held OR anyone is already queued, wait our\n // FIFO turn; otherwise take it immediately. This claim is SYNCHRONOUS (no await\n // between the check and the assignment), so two concurrent lock() calls can never\n // both take it. dispose() hands ownership DIRECTLY to the next waiter (sets\n // lockHolder = next.id before resolving), so there is no window where lockHolder\n // is null while a waiter is about to resume — which previously let a racing\n // lock() slip in front of a woken waiter and invalidate its handle\n // (\"Lock has been released\").\n if (meta.lockHolder != null || meta.lockQueue.length > 0) {\n await new Promise<void>((resolve) => meta.lockQueue.push({ id, resolve }));\n // resumed: dispose() has already set meta.lockHolder = id for us\n } else {\n meta.lockHolder = id;\n }\n\n // We now hold the lock exclusively; drain any in-flight async transition before\n // the caller dispatches. (The previous holder's dispose already awaited its own\n // transition before handing off, so this is normally a no-op.)\n await sync(target);\n\n // Start buffering this critical section's log entries so they flush as one labeled group on\n // release. Set AFTER sync() so entries drained from a previous holder don't join this group.\n if (label != null) {\n // The wait between requesting and holding the lock (queue + transition drain) is the\n // window in which a user gesture's transient activation can expire — surface it when\n // it is long enough to matter.\n const lockWaitMs = dispatchContext != null ? Date.now() - lockRequestedAt : 0;\n const context =\n dispatchContext != null && lockWaitMs >= 5 ? `${dispatchContext} [lock ${lockWaitMs}ms]` : dispatchContext;\n meta.logGroup = { label, pending: [], context };\n }\n\n let chainSnapshot: Record<string, StateInstance> | null = null;\n\n const dispose = async (): Promise<void> => {\n if (meta.lockHolder !== id) {\n return;\n }\n\n // wait for any pending async transition before releasing\n if (meta.transitioning instanceof Promise) {\n await meta.transitioning;\n }\n\n chainSnapshot = null;\n\n // Flush this lock's buffered entries as one grouped console block before handing off, so a\n // following lock's signals never interleave with ours. We still hold the lock here, so no\n // other dispatch can add to the group. allSettled keeps a rejected finish from dropping the\n // rest of the group.\n const group = meta.logGroup;\n if (group != null) {\n meta.logGroup = null;\n const settled = await Promise.allSettled(group.pending);\n const entries: StateFlowLogEntry[] = [];\n for (const outcome of settled) {\n if (outcome.status === \"fulfilled\") {\n entries.push(outcome.value);\n }\n }\n emitGrouped(withGlobalLogHandlers(meta.logHandlers), group.label, entries, group.context);\n }\n\n // Hand ownership directly to the next waiter (no null-gap), else free the lock.\n const next = meta.lockQueue.shift();\n if (next) {\n meta.lockHolder = next.id;\n next.resolve();\n } else {\n meta.lockHolder = null;\n }\n };\n\n const send: DispatchFn = Object.assign(\n (signal: Signal, mute = false): Result => {\n if (meta.lockHolder !== id) {\n throw new StateFlowError(\"Lock has been released\");\n }\n\n // capture chain snapshot on first dispatch within this lock\n if (chainSnapshot == null) {\n chainSnapshot = prepareSnapshot(target);\n }\n\n const result = dispatchCore(target, signal, meta, mute);\n return processEnqueueChain(target, result, meta, chainSnapshot, mute);\n },\n { [Symbol.asyncDispose]: dispose },\n );\n\n return send;\n}\n\n/**\n * Core dispatch logic — processes a single signal through the state machine.\n * Does not check lock or transitioning state — callers must do that.\n */\nfunction dispatchCore(target: object, signal: Signal, meta: StateFlowMeta, mute: boolean): Result {\n const st = new Error().stack;\n\n // for collecting results from all handlers; an unresolved transition at this\n // point means this dispatch runs against PRE-commit variants (legal under a\n // held lock) — flag it so the log exposes the stale-read window.\n const collector = new ResultCollector(meta.name, signal, meta.transitioning != null);\n let result: Result = Result.ignore(\"\");\n let snapshot = prepareSnapshot(target);\n\n try {\n // at first, we need to make the flow is not rejecting\n // this signal and get sorted states\n result = prepareStatesAfterSignal(target, signal, meta.states, collector);\n\n // no need to continue in that case\n if (!result.in(ResultKind.OK) || result.data == null) {\n return result.withSignal(signal).withStacktrace(st ?? null);\n }\n\n const processResult = result.data as ProcessResult;\n snapshot = processResult.snapshot;\n\n // handle all event kinds\n // order matters!\n for (const kind of [\"exit\", \"update\", \"enter\"] as const) {\n processHandlers(kind, meta.emitter, processResult[kind], snapshot, collector);\n\n // getting final result based on all handlers\n result = collector.merge();\n\n if (result.in(ResultKind.Rejected, ResultKind.Error)) {\n // rollback in case of error\n processHandlers(\"rollback\", meta.emitter, processResult.rollback, prepareSnapshot(target), collector);\n return result.withSignal(signal).withStacktrace(st ?? null);\n }\n }\n // to turn 'ignored' into 'ok'\n result = result.merge(Result.ok());\n\n // log enqueued signals from handlers\n for (const enqueued of result.enqueuedSignals) {\n collector.logEnqueue(String(enqueued), result.message ?? \"handler\");\n }\n\n // DEV warning (warn-only guard): the BLESSED enqueue pattern is the\n // self-terminating same-target record chain — exactly ONE enqueued signal per\n // dispatch cycle (the nested re-loop in processEnqueueChain re-dispatches each\n // signal in its own cycle, so a legitimate chain never accumulates >1 here).\n // More than one enqueued signal in a SINGLE cycle means two DIFFERENT handlers\n // co-enqueued — the genuinely-forbidden case. We do NOT reject it; we only warn\n // so the chain stays intact while the misuse surfaces in the dev console.\n if (result.enqueuedSignals.length > 1) {\n console.warn(\n `[SF/${meta.name}] ${String(signal)}: ${result.enqueuedSignals.length} signals were enqueued in a single ` +\n `dispatch cycle by different handlers (${result.enqueuedSignals.map(String).join(\", \")}). ` +\n \"Only ONE enqueue per cycle (the self-terminating record chain) is supported; \" +\n \"co-enqueuing from multiple handlers is unsupported and may not behave as expected.\",\n );\n }\n\n if (result.kind !== ResultKind.InTransition) {\n meta.transitioning = true;\n // sync result — apply state immediately\n applyState(target, snapshot, collector);\n } else {\n // async — defer state application until transition completes.\n // meta.transitioning is the FULL processing chain: await executors → apply state\n // → process enqueued signals. This ensures .done() returns the final result\n // including any rejections from enqueued signals.\n meta.transitioning = result\n .withMeta(meta)\n .waitAll()\n .then((res) => {\n meta.transitioning = null;\n\n if (res.kind === ResultKind.OK) {\n // Capture pre-apply snapshot for rollback if enqueued signals fail.\n const preTransitionSnap = res.enqueuedSignals.length > 0 ? prepareSnapshot(target) : null;\n\n applyState(target, snapshot, collector);\n\n // Process enqueued signals from the resolved transition.\n // This enables Result.enqueue() inside Result.transition() callbacks.\n if (preTransitionSnap && res.enqueuedSignals.length > 0) {\n const enqResult = processEnqueueChain(target, res, meta, preTransitionSnap, mute);\n if (enqResult.in(ResultKind.Rejected, ResultKind.Error)) {\n return enqResult;\n }\n }\n } else if (res.in(ResultKind.Rejected, ResultKind.Error)) {\n processHandlers(\"rollback\", meta.emitter, processResult.rollback, prepareSnapshot(target), collector);\n }\n return res;\n });\n }\n\n return result\n .withMeta(meta)\n .withSignal(signal)\n .withStacktrace(st ?? null);\n } finally {\n if (meta.transitioning === true) {\n meta.transitioning = null;\n }\n\n if (!mute) {\n const finished = collector.finish(snapshot, result);\n const group = meta.logGroup;\n if (group != null) {\n // Under a labeled lock: buffer the entry; lock dispose() flushes the whole group.\n group.pending.push(finished);\n } else {\n finished\n .then((entry) => {\n withGlobalLogHandlers(meta.logHandlers).forEach((handler) => {\n handler(entry);\n });\n })\n .catch(() => {});\n }\n }\n }\n}\n\n/**\n * Processes enqueued signals from a dispatch result.\n * Each enqueued signal is dispatched in sequence within the same lock.\n * If any enqueued dispatch fails, rolls back all state to the chain snapshot.\n */\nfunction processEnqueueChain(\n target: object,\n result: Result,\n meta: StateFlowMeta,\n chainSnapshot: Record<string, StateInstance>,\n mute: boolean,\n): Result {\n let current = result;\n\n while (current.enqueuedSignals.length > 0) {\n const signals = [...current.enqueuedSignals];\n\n for (const signal of signals) {\n const enqResult = dispatchCore(target, signal as Signal, meta, mute);\n\n if (enqResult.in(ResultKind.Rejected, ResultKind.Error)) {\n // full rollback to pre-chain state\n rollbackToSnapshot(target, chainSnapshot);\n return enqResult;\n }\n\n current = enqResult;\n }\n }\n\n return current;\n}\n\n/**\n * Restores all states on target from a snapshot.\n */\nfunction rollbackToSnapshot(target: object, snapshot: Record<string, StateInstance>): void {\n for (const [key, value] of Object.entries(snapshot)) {\n Reflect.set(target, key, value);\n }\n}\n\n/**\n * Collect new states after the signal flow\n * If noting was handled the signal then it returns \"ignored\" result\n * If at least one handler was failed, it returns \"error\" or \"rejected\" result\n * Otherwise, it returns snapshot with new states and lists of sorted states\n * for further handling\n */\nfunction prepareStatesAfterSignal(\n target: object,\n signal: Signal,\n states: Array<StateDefinition>,\n collector: ResultCollector,\n): Result<ProcessResult> {\n const processResult: ProcessResult = {\n snapshot: Object.fromEntries(states.map((s) => [s[Symbol.toStringTag], s(target)])),\n enter: [],\n update: [],\n exit: [],\n rollback: [],\n };\n\n const results: Result[] = [];\n // Variants that declare NO handler for this signal — kept so a full-miss\n // dispatch can report WHICH states were active instead of a bare \"Ignored\".\n const unhandled: string[] = [];\n\n // collect new states after signal flow\n for (const def of states) {\n const name = getName(def);\n const oldState = def(target);\n\n if (!stateAccepts(oldState, signal[Symbol.toStringTag])) {\n unhandled.push(String(oldState[Symbol.toStringTag]));\n }\n\n const result = handleSignal(oldState, signal, processResult.snapshot);\n switch (result.kind) {\n // state was successfully changed\n case ResultKind.OK: {\n const newState = result.data as StateInstance;\n const desc = `'${oldState}->${newState}'`;\n processResult.snapshot[name] = newState;\n collector.logStateChange(def[Symbol.toStringTag], oldState, newState);\n\n if (newState[VARIANT] === oldState[VARIANT]) {\n processResult.update.push([newState, `update ${desc}`]);\n } else {\n processResult.enter.push([newState, `enter to ${desc}`]);\n processResult.exit.push([oldState, `exit from ${desc}`]);\n }\n processResult.rollback.push([oldState, `rollback ${desc}`]);\n\n break;\n }\n\n // the signal was ignored completely\n case ResultKind.Ignored:\n processResult.snapshot[name] = oldState;\n break;\n\n // got incorrect result\n case ResultKind.InTransition:\n // stop handling the signal immediately\n // because there is no point to continue with an error\n return Result.error<ProcessResult>(new StateFlowError(\"Transition is not allowed in flow handlers\")).withSignal(\n signal,\n );\n\n // Error or Rejected are left\n default:\n // stop handling the signal immediately either\n // by the same reason\n return result as Result<any>;\n }\n\n results.push(result);\n }\n\n const final = mergeResults(results);\n if (final.kind !== ResultKind.OK) {\n // A signal that NO active variant handles dies as Ignored with an empty\n // message — historically the hardest log entry to interpret (is the state\n // wrong, or the signal?). Name the active variants so the log answers it.\n if (final.kind === ResultKind.Ignored && final.message == null && unhandled.length === states.length) {\n return Result.ignore(`no handler in ${unhandled.join(\", \")}`) as Result<ProcessResult>;\n }\n return final as Result<ProcessResult>;\n }\n return Result.ok(processResult);\n}\n\nfunction applyState(target: object, snapshot: Record<string, StateInstance>, rc: ResultCollector): void {\n const meta = stateMeta(target);\n\n currentRC.set(rc);\n for (const [key, value] of Object.entries(snapshot)) {\n if (value !== Reflect.get(target, key)) {\n meta.emitter.emit(eventKey(\"observe\", String(value[VARIANT])), Reflect.get(target, key), value);\n Reflect.set(target, key, value);\n }\n }\n currentRC.clear();\n}\n\nfunction processHandlers(\n kind: EventKind,\n emitter: EventEmitter,\n states: Array<[StateInstance, string]>,\n snapshot: Record<string, StateInstance>,\n collector?: ResultCollector,\n): void {\n // handle states\n for (const [state, desc] of states) {\n const key = eventKey(kind, String(state[VARIANT]));\n emitter.emit(key, snapshot[state[VARIANT][DEF][Symbol.toStringTag]], snapshot, desc, collector);\n }\n}\n\n/**\n * Waits for all pending state transitions to complete on the target object.\n *\n * @param target - Object containing states that may be transitioning\n * @returns Promise that resolves when all transitions are complete\n * @throws StateFlowError if target object is not initialized with applyFlow\n *\n * @example\n * ```ts\n * async function play() {\n * await sync(player);\n *\n * dispatch(player, signals.play()); // Now safe to dispatch new signals\n * }\n * ```\n */\nexport async function sync(target: object): Promise<void> {\n const meta = stateMeta(target);\n const transitioning = meta.transitioning;\n if (transitioning instanceof Promise) {\n return new Promise((r) => {\n const wait = () => {\n if (meta.transitioning == null) {\n r();\n return;\n }\n\n transitioning.finally(() => setTimeout(wait, 0)).catch(() => {});\n };\n\n wait();\n });\n }\n}\n\n/**\n * Creates an observer that watches for changes in specific state variants.\n * The observer is automatically cleaned up when the returned Disposer is disposed.\n *\n * @param target - Object containing the states to observe\n * @param stateVariants - Array of state variants to watch for changes\n * @param handlerFn - Callback function executed when observed states change\n * @param compareFn - Optional function to determine if states are different\n * @param ctx\n * @returns Disposer object that cleans up the observer when disposed\n *\n * @example\n * ```ts\n * using observer = observe(\n * player,\n * [audioState.muted, audioState.playing],\n * (state) => console.log(`Audio state changed: ${state}`),\n * (prev, curr) => prev.volume !== curr.volume\n * );\n * ```\n */\nexport function observe<T>(\n target: object,\n stateVariants: StateVariant<T>[],\n handlerFn: ObserverHandler<T>,\n compareFn: ObserverComparerFn<T> = (a, b) => a !== b,\n ctx?: object,\n): Disposer {\n const meta = stateMeta(target);\n\n for (const stateVar of stateVariants) {\n subscribe(meta.emitter, stateVar, compareFn, handlerFn, ctx);\n }\n\n return {\n [Symbol.dispose]: () => {\n for (const stateVar of stateVariants) {\n unsubscribe(meta.emitter, stateVar, handlerFn);\n }\n },\n };\n}\n\nfunction subscribe<T>(\n emitter: EventEmitter,\n stateVar: StateVariant,\n cmpFn: ObserverComparerFn<T>,\n hdlFn: ObserverHandler<T>,\n ctx?: object,\n) {\n const key = eventKey(\"observe\", String(stateVar));\n const cb: ObserverComparer<T> = (a, b) => {\n const needObserve = cmpFn(a, b);\n currentRC.ref?.logObserver(String(stateVar[DEF]), buildName(ctx, hdlFn), needObserve);\n if (needObserve) {\n setTimeout(() => hdlFn(b), 0);\n }\n };\n emitter.on(key, cb);\n observersMap.set(hdlFn, [...(observersMap.get(hdlFn) ?? []), cb]);\n}\n\nfunction unsubscribe<T>(emitter: EventEmitter, stateVar: StateVariant, hdlFn: ObserverHandler<T>) {\n const key = eventKey(\"observe\", String(stateVar));\n const cbs = observersMap.get(hdlFn);\n cbs?.forEach((cb) => {\n emitter.off(key, cb);\n });\n}\n\nexport function disposeFlow(target: object): void {\n const meta = stateMeta(target);\n meta.emitter.removeAllListeners();\n Reflect.deleteProperty(meta, \"emitter\");\n for (const state of meta.states) {\n Reflect.deleteProperty(target, state[Symbol.toStringTag]);\n }\n}\n","import type { CompactStackTrace } from \"./utils\";\n\n// will be replaced to lively domain after deploying stacktrace-viewer\nconst STACKTRACE_VIEWER_URL = \"https://stacktrace.pirogov.dev/\";\n\nexport interface StateFlowLogEntry {\n // Flow identification\n flowName: string;\n signal: string;\n isAsync: boolean;\n startTime: number;\n duration?: number; // Present for completed async transitions\n /** Monotonic per-page dispatch-START order, shared across ALL flows. Entries are\n * delivered (and recorded) in FINISH order; sort by this to reconstruct the true\n * dispatch timeline, including same-millisecond ties. The engine always sets it on\n * fresh entries; it is optional because hand-built entries (fixtures, replay tooling)\n * and recordings from older builds predate the field. */\n dispatchOrder?: number;\n /** Set when this dispatch STARTED while the flow still had an unresolved async\n * transition: it ran against PRE-commit state variants (a held lock permits this).\n * The classic stale-read race signature — an Ignored/unexpected result here usually\n * means the signal raced the previous transition's commit. */\n duringTransition?: boolean;\n message: string; // Formatted message suitable for logging\n\n // States\n finalStates: Record<string, string>;\n\n // State changes or attempts\n stateChanges: Array<{\n newState: string;\n oldState: string;\n stateName: string;\n }>;\n\n // Handler executions\n handlerResults: Array<{\n type: \"enter\" | \"exit\" | \"update\" | \"rollback\";\n handlerName: string;\n stateName: string;\n result: string;\n }>;\n\n observers: Array<{\n observerName: string;\n stateName: string;\n needObserve: boolean;\n }>;\n\n // Enqueued signal chain\n enqueuedSignals: Array<{\n signal: string;\n fromHandler: string;\n }>;\n\n stacktrace: CompactStackTrace | null;\n\n // Final result\n finalResult: string;\n\n /** Set when the entry was emitted under a labeled `lock(target, label)`. Lets non-console\n * handlers group related signals; the console handler is grouped for you via `emitGrouped`. */\n groupLabel?: string;\n\n /** The dispatch-context provider's snapshot, captured SYNCHRONOUSLY when the section's\n * `lock(target, label)` was CALLED — i.e. still inside the caller's stack, which for\n * UI-triggered locks is the interaction event's synchronous propagation. When the lock was\n * CONTENDED for >= 5ms, `lock()` appends ` [lock <wait>ms]` to the snapshot before stamping\n * it. Set on every entry of the labeled section at flush. Absent when no provider is\n * registered (the default), for unlabeled locks, and on entries from older builds. */\n dispatchContext?: string;\n}\n\nexport type StateFlowLogHandler = (entry: StateFlowLogEntry) => void;\n\n// Global dispatch-context provider. Same additive-hook pattern as the global log handlers:\n// `lock(target, label)` calls it synchronously in its prologue and stamps the returned string\n// onto the section's group + entries. With no provider registered (the default) the cost is a\n// null check and behavior is byte-identical — entries gain no field, console output unchanged.\nlet dispatchContextProvider: (() => string | null) | null = null;\n\n/**\n * Registers the provider whose return value becomes `dispatchContext` on every entry of a\n * labeled lock section, captured synchronously at `lock()` call time. Returns an unsubscribe\n * function. One provider at a time (last registration wins). Debug-tooling hook: a throwing\n * or null-returning provider leaves entries and console output exactly as without one.\n */\nexport function setGlobalDispatchContextProvider(provider: () => string | null): () => void {\n dispatchContextProvider = provider;\n return () => {\n if (dispatchContextProvider === provider) {\n dispatchContextProvider = null;\n }\n };\n}\n\n/** @internal The provider's current value, or null (no provider / provider threw). */\nexport function getGlobalDispatchContext(): string | null {\n if (dispatchContextProvider == null) {\n return null;\n }\n try {\n return dispatchContextProvider();\n } catch {\n return null;\n }\n}\n\n// Global log-handler registry. Handlers registered here receive EVERY flow's entries in addition\n// to each flow's own `logHandlers`. Purely additive: with no handler registered the delivery path\n// is exactly the per-flow handler list. Intended for debug tooling (e.g. the core SDK's StateFlow\n// log recorder) so it can observe all flows without touching production `applyFlow` call sites.\nconst globalLogHandlers = new Set<StateFlowLogHandler>();\n\n/**\n * Registers a handler that receives every log entry from every flow, in addition to the per-flow\n * `logHandlers`. Returns an unsubscribe function. Debug-tooling hook: it does not change console\n * output or any per-flow handler behavior.\n */\nexport function addGlobalLogHandler(handler: StateFlowLogHandler): () => void {\n globalLogHandlers.add(handler);\n return () => {\n globalLogHandlers.delete(handler);\n };\n}\n\n/** @internal Per-flow handlers plus the globally registered taps (the per-flow array when none). */\nexport function withGlobalLogHandlers(handlers: StateFlowLogHandler[]): StateFlowLogHandler[] {\n if (globalLogHandlers.size === 0) {\n return handlers;\n }\n return [...handlers, ...globalLogHandlers];\n}\n\n// StateFlow's built-in console logging is noise during test runs, so it is silenced by default\n// under vitest (which sets process.env.VITEST). Structured/custom handlers are unaffected — only\n// the console output of `consoleLogHandler` and the `emitGrouped` group wrapper are suppressed.\nlet consoleSilencedOverride: boolean | null = null;\n\nfunction isConsoleSilenced(): boolean {\n if (consoleSilencedOverride !== null) {\n return consoleSilencedOverride;\n }\n return typeof process !== \"undefined\" && process.env?.VITEST != null;\n}\n\n/**\n * Force StateFlow's built-in console logging on (`false`) or off (`true`), or pass `null` to\n * restore the default (silenced under vitest, on otherwise). Affects `consoleLogHandler` and the\n * `emitGrouped` console grouping; structured handlers always receive their entries.\n */\nexport function setConsoleLogSilenced(silenced: boolean | null): void {\n consoleSilencedOverride = silenced;\n}\n\nexport const consoleLogHandler: StateFlowLogHandler = (entry: StateFlowLogEntry) => {\n if (isConsoleSilenced()) {\n return;\n }\n\n const logs: Record<string, Array<string>> = {};\n entry.stateChanges.reduce((l, r) => {\n l[r.stateName] ??= [];\n l[r.stateName].push(`State: ${r.oldState} => ${r.newState}`);\n return l;\n }, logs);\n\n entry.handlerResults.reduce((l, r) => {\n l[r.stateName] ??= [];\n l[r.stateName].push(`\\t${r.type} ${r.handlerName}() => ${r.result}`);\n return l;\n }, logs);\n\n entry.observers.reduce((l, r) => {\n l[r.stateName] ??= [];\n l[r.stateName].push(`\\tobserved by ${r.observerName}() => ${r.needObserve}`);\n return l;\n }, logs);\n\n console.groupCollapsed(entry.message);\n\n for (const [, rows] of Object.entries(logs)) {\n for (const row of rows) {\n console.log(row);\n }\n }\n\n if (entry.enqueuedSignals.length > 0) {\n console.log(\"\\nEnqueued Signals:\");\n for (const enq of entry.enqueuedSignals) {\n console.log(`\\t${enq.signal} (from ${enq.fromHandler})`);\n }\n }\n\n console.log(\"\\nFinal States:\");\n Object.entries(entry.finalStates).forEach(([name, state]) => {\n console.debug(`\\t${name}: ${state}`);\n });\n\n if (entry.stacktrace != null) {\n console.log(\"\\nStacktrace:\");\n console.log(`${STACKTRACE_VIEWER_URL}#${btoa(JSON.stringify(entry.stacktrace))}`);\n }\n\n console.groupEnd();\n};\n\n/**\n * Flushes a labeled lock's buffered entries as one console group.\n *\n * A `lock(target, label)` collects every entry dispatched inside the critical section and emits\n * them here on release, wrapping the per-signal (collapsed) groups in one expanded\n * `console.group(label)` so related signals read as a single unit:\n *\n * ▼ player play request\n * ▶ [SF/player] play - OK\n * ▶ [SF/driver] activate - OK\n *\n * Grouping is a console-presentation concern, so the `console.group`/`console.groupEnd` pair is\n * emitted for the label regardless of the configured handlers (the default sink is the console).\n * Each entry is also tagged with `groupLabel` so non-console handlers can group however they like.\n */\nexport function emitGrouped(\n handlers: StateFlowLogHandler[],\n label: string,\n entries: StateFlowLogEntry[],\n context: string | null = null,\n): void {\n if (entries.length === 0) {\n return;\n }\n\n if (isConsoleSilenced()) {\n // No console group when silenced (e.g. under vitest), but still deliver every entry to the\n // handlers so structured/custom log sinks keep receiving them.\n for (const entry of entries) {\n entry.groupLabel = label;\n if (context != null) {\n entry.dispatchContext = context;\n }\n for (const handler of handlers) {\n handler(entry);\n }\n }\n return;\n }\n\n // groupLabel stays the RAW label (consumers assert on it); the interaction context only\n // decorates the console header and rides the entries as the separate dispatchContext field.\n console.group(context != null ? `${label} ⟵ ${context}` : label);\n try {\n for (const entry of entries) {\n entry.groupLabel = label;\n if (context != null) {\n entry.dispatchContext = context;\n }\n for (const handler of handlers) {\n handler(entry);\n }\n }\n } finally {\n console.groupEnd();\n }\n}\n","export const SIGNAL = Symbol.for(\"SIGNAL\");\nexport const DEF = Symbol.for(\"DEF\");\nexport const IS_INITIAL = Symbol.for(\"IS_INITIAL\");\nexport const VARIANT = Symbol.for(\"VARIANT\");\nexport const SIGNALS = Symbol.for(\"SIGNALS\");\nexport const HANDLERS = Symbol.for(\"HANDLERS\");\nexport const STRING_REPR = Symbol.for(\"STRING_REPR\");\nexport const PARSER = Symbol.for(\"PARSER\");\n\n// small polyfill\nif (typeof Symbol.dispose === \"undefined\") {\n Object.defineProperty(Symbol, \"dispose\", { value: Symbol.for(\"dispose\") });\n}\n\nif (typeof Symbol.asyncDispose === \"undefined\") {\n Object.defineProperty(Symbol, \"asyncDispose\", { value: Symbol.for(\"asyncDispose\") });\n}\n","import type { SignalDefinition } from \"./signal\";\nimport type { StateDefinition, StateVariant } from \"./state\";\nimport { VARIANT } from \"./symbols\";\n\n// Compact stacktrace format types\n\n// URL array element in compact format\nexport type CompactUrlArray = string[];\n\n// Single frame in compact format [urlIndex, line, column]\nexport type CompactFrame = [number, number, number];\n\n// Array of compact frames\nexport type CompactFrameArray = CompactFrame[];\n\n// Complete compact stacktrace format\nexport type CompactStackTrace = [CompactUrlArray, CompactFrameArray];\n\nexport type Infer<T> =\n T extends StateDefinition<infer TProps, \"\", unknown, string>\n ? TProps\n : T extends StateVariant<infer TProps, \"\", unknown, string>\n ? TProps\n : T extends SignalDefinition<infer TArgs>\n ? TArgs\n : never;\n\nexport function truncate(key: PropertyKey, value: unknown): unknown {\n if (typeof value === \"string\" && value.length > 15) {\n return `${value.substring(0, 15)}...`;\n }\n\n if (Array.isArray(value) && value.length > 3) {\n return `[array: ${value.length}] items]`;\n }\n\n if (typeof value === \"object\" && value != null && Object.keys(value).length > 5) {\n return `[object: ${Object.keys(value).length} props]`;\n }\n return value;\n}\n\n// biome-ignore lint/complexity/noBannedTypes: Utility function accepts any function type\nexport function buildName(ctx: unknown, func?: Function): string {\n let fnName: unknown = null;\n let ctxName: unknown = null;\n\n if (func != null) {\n fnName =\n Symbol.toStringTag in func && func[Symbol.toStringTag] !== \"AsyncFunction\" ? func[Symbol.toStringTag] : func.name;\n }\n\n if (ctx != null && typeof ctx === \"object\") {\n ctxName = Symbol.toStringTag in ctx ? ctx[Symbol.toStringTag] : ctx.constructor.name;\n }\n\n if (ctxName == null) {\n return String(fnName);\n } else if (fnName == null) {\n return String(ctxName);\n }\n\n if (String(fnName).startsWith(String(ctxName))) {\n return String(fnName);\n }\n return `${ctxName}.${fnName}`;\n}\n\nexport class StateFlowError extends Error {\n constructor(message: string, inner: Error | null = null) {\n super(message);\n this.name = \"StateFlowError\";\n\n if (inner != null) {\n this.stack = inner.stack;\n }\n }\n}\n\n// URL regex - captures file URL, line number, and column number\nconst urlRegex = /(https?:\\/\\/[^:]+(?::\\d+)?(?:\\/[^:]*)*?):(\\d+):(\\d+)/g;\n/**\n * Simplified function that converts a standard stacktrace to a compact format\n * using direct regex parsing instead of adapters\n *\n * @example Input: \"Error: Something went wrong\\n at https://localhost:8899/static/js/bundle.js:12124:33\"\n * @example Output: [[\"https://localhost:8899/static/js/bundle.js\"], [[0, 12124, 33]]]\n */\nexport function parseCompactStacktrace(stacktrace: string | null): CompactStackTrace | null {\n if (stacktrace == null) {\n return null;\n }\n\n // Extract unique URLs and their frames\n const urlMap = new Map<string, number>();\n const urls: string[] = [];\n const compactFrames: CompactFrame[] = [];\n\n // Find all matches in the stacktrace\n const matches = stacktrace.matchAll(urlRegex);\n\n for (const match of matches) {\n const [, url, lineStr, columnStr] = match;\n\n // Add URL to the list if it's not already there\n if (!urlMap.has(url)) {\n urlMap.set(url, urls.length);\n urls.push(url);\n }\n\n // Create a compact frame\n // biome-ignore lint/style/noNonNullAssertion: the `if (!urlMap.has(url))` block directly above sets url in urlMap when absent, so by this line urlMap always has url and get() returns a defined index.\n const urlIndex = urlMap.get(url)!;\n const line = parseInt(lineStr, 10);\n const column = parseInt(columnStr, 10);\n\n compactFrames.push([urlIndex, line, column]);\n }\n\n if (compactFrames.length === 0) {\n return null;\n }\n\n return [urls, compactFrames];\n}\nconst maxArrayItems = 10;\nconst maxStringLen = 25;\nconst abbreviate = true;\nconst inlineSingleArrays = true;\nconst maxDepth = 3;\n\ninterface FlattenResult {\n path: string[];\n value: unknown;\n}\n\nconst SPACES_REGEX = /\\s/;\nconst BRACKETS_REGEX = /[{}[\\]=]/;\n\nfunction isObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === \"object\" && !Array.isArray(val);\n}\n\nfunction isPlainObject(val: unknown): val is object {\n if (!isObject(val)) {\n return false;\n }\n\n const proto = Object.getPrototypeOf(val);\n return proto === null || proto === Object.prototype;\n}\n\nfunction getClassName(val: object): string {\n const proto = Object.getPrototypeOf(val);\n if (proto?.constructor?.name != null) {\n return proto.constructor.name;\n }\n return \"Object\";\n}\n\nfunction flattenPath(val: unknown, path: string[] = [], depthBudget: number = maxDepth): FlattenResult {\n if (isPlainObject(val) && depthBudget > 0) {\n const keys = Reflect.ownKeys(val).filter((k): k is string => typeof k === \"string\");\n if (keys.length === 1) {\n const key = keys[0];\n if (key !== undefined) {\n const nextVal = Reflect.get(val, key);\n return flattenPath(nextVal, [...path, key], depthBudget - 1);\n }\n }\n }\n return { path, value: val };\n}\n\nfunction serializeValue(val: unknown, depth: number = 0): string {\n // Null/undefined\n if (val === null) {\n return abbreviate ? \"N\" : \"null\";\n }\n if (val === undefined) {\n return abbreviate ? \"U\" : \"undefined\";\n }\n\n // Boolean\n if (typeof val === \"boolean\") {\n return abbreviate ? (val ? \"T\" : \"F\") : String(val);\n }\n\n // Number\n if (typeof val === \"number\") {\n return String(val);\n }\n\n // String\n if (typeof val === \"string\") {\n let str = val;\n\n // Truncate if too long\n if (maxStringLen && str.length > maxStringLen) {\n str = `${str.slice(0, maxStringLen)}…`;\n }\n\n // Check if needs quotes - use single quotes for strings with spaces\n const hasSpaces = SPACES_REGEX.test(str);\n const hasSpecialChars = BRACKETS_REGEX.test(str);\n\n if (hasSpaces || hasSpecialChars) {\n // Use single quotes, escape single quotes inside\n return `'${str.replace(/'/g, \"\\\\'\")}'`;\n }\n\n return str;\n }\n\n // Array\n if (Array.isArray(val)) {\n // Inline single primitive values\n if (inlineSingleArrays && val.length === 1) {\n const first = val[0];\n if (\n first === null ||\n first === undefined ||\n typeof first === \"number\" ||\n typeof first === \"boolean\" ||\n typeof first === \"string\"\n ) {\n return serializeValue(first, depth + 1);\n }\n }\n\n let items: unknown[] = val;\n let truncated = false;\n\n // Truncate long arrays\n if (maxArrayItems && val.length > maxArrayItems) {\n items = val.slice(0, maxArrayItems);\n truncated = true;\n }\n\n const serialized = items.map((item) => {\n if (isPlainObject(item)) {\n // Check depth limit\n if (depth >= maxDepth) {\n return \"{...}\";\n }\n\n const depthBudget = maxDepth - depth - 1;\n const entries = Reflect.ownKeys(item)\n .filter((k): k is string => typeof k === \"string\")\n .map((k) => {\n const v = Reflect.get(item as object, k);\n const { path, value } = flattenPath(v, [], depthBudget);\n const fullPath = path.length > 0 ? `${k}.${path.join(\".\")}` : k;\n return `${fullPath}=${serializeValue(value, depth + 1 + path.length)}`;\n });\n return entries.length === 1 ? entries[0] : `{${entries.join(\" \")}}`;\n }\n return serializeValue(item, depth + 1);\n });\n\n // Use space separator in arrays\n const result = serialized.join(\" \");\n return `[${result}${truncated ? ` …+${val.length - maxArrayItems}` : \"\"}]`;\n }\n\n // Object\n if (isObject(val)) {\n // Check if it's a Date\n if (val instanceof Date) {\n return val.toISOString();\n }\n\n // Check for Symbol.toPrimitive BEFORE plain object check\n if (Reflect.has(val, Symbol.toPrimitive) && !Reflect.has(val, VARIANT)) {\n return String(val);\n }\n\n // Native containers/objects — previously collapsed to an opaque {ClassName}.\n if (val instanceof Map) {\n if (depth >= maxDepth) {\n return `Map(${val.size}){...}`;\n }\n let entries = [...val.entries()];\n const dropped = maxArrayItems ? entries.length - maxArrayItems : 0;\n if (dropped > 0) {\n entries = entries.slice(0, maxArrayItems);\n }\n const body = entries.map(([k, v]) => `${serializeValue(k, depth + 1)}=${serializeValue(v, depth + 1)}`);\n return `Map(${val.size}){${body.join(\" \")}${dropped > 0 ? ` …+${dropped}` : \"\"}}`;\n }\n\n if (val instanceof Set) {\n if (depth >= maxDepth) {\n return `Set(${val.size}){...}`;\n }\n let items = [...val.values()];\n const dropped = maxArrayItems ? items.length - maxArrayItems : 0;\n if (dropped > 0) {\n items = items.slice(0, maxArrayItems);\n }\n const body = items.map((item) => serializeValue(item, depth + 1));\n return `Set(${val.size}){${body.join(\" \")}${dropped > 0 ? ` …+${dropped}` : \"\"}}`;\n }\n\n if (val instanceof Error) {\n // name(message) with the standard string truncation; parens already delimit,\n // so the message is not re-quoted.\n let message = val.message;\n if (maxStringLen && message.length > maxStringLen) {\n message = `${message.slice(0, maxStringLen)}…`;\n }\n return `${val.name}(${message})`;\n }\n\n if (val instanceof RegExp) {\n return String(val);\n }\n\n if (val instanceof ArrayBuffer) {\n return `ArrayBuffer(${val.byteLength})`;\n }\n\n if (ArrayBuffer.isView(val)) {\n const length = (val as { length?: number }).length ?? val.byteLength;\n return `${getClassName(val)}(${length})`;\n }\n\n // DOM Event duck-check: state-flow compiles DOM-lib-free, so no instanceof\n // Event — a string `type` plus an *Event constructor name identifies one.\n if (typeof (val as { type?: unknown }).type === \"string\" && getClassName(val).endsWith(\"Event\")) {\n return `${getClassName(val)}(${(val as { type: string }).type})`;\n }\n\n // URL duck-check (same DOM-free constraint): constructor name + href.\n if (getClassName(val) === \"URL\" && typeof (val as { href?: unknown }).href === \"string\") {\n return serializeValue((val as { href: string }).href, depth);\n }\n\n // Check if it's a plain object or a custom class instance\n if (!isPlainObject(val)) {\n // Custom class - show {ClassName}\n const className = getClassName(val);\n return `{${className}}`;\n }\n\n // Check depth limit for plain objects\n if (depth >= maxDepth) {\n return \"{...}\";\n }\n\n // Plain object - serialize properties\n const depthBudget = maxDepth - depth - 1;\n const entries = Reflect.ownKeys(val)\n .filter((k): k is string => typeof k === \"string\")\n .map((k) => {\n const v = Reflect.get(val as object, k);\n const { path, value } = flattenPath(v, [], depthBudget);\n const fullPath = path.length > 0 ? `${k}.${path.join(\".\")}` : k;\n return `${fullPath}=${serializeValue(value, depth + 1 + path.length)}`;\n });\n\n // Use space separator for all objects\n return depth === 0 ? entries.join(\" \") : `{${entries.join(\" \")}}`;\n }\n\n // Fallback for other types\n return String(val);\n}\n\nexport function serializeDebug(obj: unknown): string {\n if (obj == null) {\n return \"\";\n }\n\n return serializeValue(obj);\n}\n","/**\n * Contains classes for handling and merging multiple results.\n * Merging process follows the rules:\n *\n * - if at least one result is `Error`, then the final result is `Error`\n * - if at least one result is `Rejected`, then the final result is `Rejected`\n * - if a result is `InTransition`, then the final result will be gathered\n * when transition is finished\n * - if all results are `Ignored`, then the final result is `Ignored`\n * - otherwise, the final result is `Handled`\n *\n * @example ```ts\n * // returns 'ok' result with new state\n * return Result.state(audio.unmuted({volume: 0.7}));\n *\n * // returns 'ok' result without data\n * return Result.ok();\n *\n * // ignore signal/handling\n * return Result.ignore(\"explanation message why it was ignored\");\n *\n * // reject signal/handling\n * return Result.reject(\"explanation message why it was rejected\");\n *\n * // result containing error\n * try {\n * // ...\n * } catch(err) {\n * return Result.error(err);\n * }\n *\n * ```\n */\n\nimport type { StateFlowMeta } from \"./flow\";\nimport type { StateFlowLogEntry } from \"./logger\";\nimport type { Signal, StateSignal } from \"./signal\";\nimport type { StateInstance } from \"./state\";\nimport { type CompactStackTrace, parseCompactStacktrace, StateFlowError } from \"./utils\";\n\nexport enum ResultKind {\n /**\n * At least one handler handled the signal and no errors were thrown.\n */\n OK,\n\n /**\n * All handlers and groups ignored the signal or didn't exist.\n */\n Ignored,\n\n /**\n * At least one handler is in transition and no errors were thrown yet.\n */\n InTransition,\n\n /**\n * At least one handler rejected the signal.\n */\n Rejected,\n\n /**\n * At least one handler threw an error.\n */\n Error,\n}\n\n/**\n * Represents the result of signal handling or state transition.\n */\nexport class Result<TData = unknown> {\n // a list of transitioning result promises\n readonly #executors: Array<Promise<Result>> = [];\n\n // signals to dispatch after this result completes successfully\n #enqueued: StateSignal[] = [];\n\n // cached promise for current result\n #promise: Promise<Result> | null = null;\n\n // kinds the caller asserted via expect() on an InTransition result.\n // The assertion is deferred to the FINAL resolved result and enforced in done().\n #expectedKinds: ResultKind[] | null = null;\n\n // contexts for logging purposes\n #timestamps: [number, number] = [Date.now(), Date.now()];\n #signal: Signal | null = null;\n #handler: string | null = null;\n #state: string | null = null;\n #stacktrace: CompactStackTrace | null = null;\n #meta: StateFlowMeta | null = null;\n\n /**\n * Internal constructor of Result\n *\n * @param kind\n * @param data\n * @param msg\n * @param ts\n * @private\n * @internal\n */\n private constructor(\n readonly kind: ResultKind,\n readonly data: TData | null,\n private readonly msg: string | Error,\n ts: number = Date.now(),\n ) {\n this.#timestamps = [ts, ts];\n\n if (kind === ResultKind.InTransition) {\n this.#executors.push(data as Promise<Result>);\n }\n // immutable object\n Object.freeze(this);\n }\n\n get startedAt(): number {\n return this.#timestamps[0];\n }\n\n get finishedAt(): number {\n return this.#timestamps[1];\n }\n\n get stacktrace(): CompactStackTrace | null {\n return this.#stacktrace;\n }\n\n in(...args: ResultKind[]): boolean {\n return args.includes(this.kind);\n }\n\n /**\n * Returns a promise with result\n * Useful for `InTransition` kind results\n * For all other kinds it wraps \"this\" object\n */\n async done(): Promise<Result> {\n // For InTransition results with meta, use the full processing chain\n // which includes state application and enqueue processing.\n // Check BEFORE calling waitAll() — the processing chain sets\n // meta.transitioning = null on completion, so checking after await\n // would always miss it.\n if (\n this.kind === ResultKind.InTransition &&\n this.#meta?.transitioning != null &&\n typeof this.#meta.transitioning !== \"boolean\"\n ) {\n return this.#assertExpected(await this.#meta.transitioning);\n }\n const result = await this.waitAll();\n if (this.#meta?.transitioning != null) {\n await this.#meta.transitioning;\n }\n return this.#assertExpected(result);\n }\n\n /**\n * Error object for `Error` results\n * Or null for all other kinds of results\n */\n get error(): Error | null {\n if (this.msg instanceof Error) {\n return this.msg;\n }\n return null;\n }\n\n /**\n * Message string for `Ignored` or `Rejected` kinds\n * Or null for all other kinds of results\n */\n get message(): string | null {\n if (typeof this.msg === \"string\" && this.msg !== \"\") {\n return this.msg;\n }\n return null;\n }\n\n /**\n * Signals enqueued for dispatch after this result completes successfully\n */\n get enqueuedSignals(): readonly StateSignal[] {\n return this.#enqueued;\n }\n\n /**\n * @internal\n * @private\n */\n waitAll(): Promise<Result> {\n // cache the promise if we haven't already\n // that allows to not use the promise if we don't need to\n // (probably most of the time)\n if (this.#promise == null) {\n if (this.kind === ResultKind.InTransition) {\n // so for in transition, we need to wait for all the executors to finish\n // and then merge the results\n this.#promise = Promise.all(this.#executors)\n .then(mergeResults)\n // A transition whose asyncFn resolved to ANOTHER InTransition (a nested transition, or a\n // send() returned without .done()) must keep resolving to its concrete final — otherwise the\n // result stays InTransition forever: it logs as \"InTransition\" (never the resolved\n // message), .done() returns InTransition so callers see kind !== OK, and dispatchCore neither\n // commits nor rolls back. Each level has its own withTimeout, so recursion always terminates.\n .then((res) => (res.kind === ResultKind.InTransition ? res.waitAll() : res))\n .then((res) => res.withTimestamps(...this.#timestamps, Date.now()));\n } else {\n // but for everything else, we can just resolve in the next tick\n this.#promise = Promise.resolve(this);\n }\n }\n return this.#promise;\n }\n\n /**\n * Creates `Ignored` result with explanation message\n *\n * @param message explanation message\n */\n static ignore<T>(message: string): Result<T> {\n return new Result<T>(ResultKind.Ignored, null, message);\n }\n\n /**\n * Creates `Ok` result without any messages\n */\n static ok<T = null>(data: T = null as T): Result<T> {\n return new Result(ResultKind.OK, data, \"\");\n }\n\n /**\n * Creates `Ok` result with a new state\n * Used in a flow handlers\n *\n * @param data a new state\n */\n static state<T extends StateInstance>(data: T): Result<T> {\n return new Result(ResultKind.OK, data, \"\");\n }\n\n /**\n * Creates `Ok` result that enqueues a follow-up signal for dispatch\n * after the current dispatch completes successfully.\n * If the enqueued signal fails, the entire chain is rolled back.\n *\n * @param signal - Signal to dispatch after current dispatch succeeds\n */\n static enqueue<T = null>(signal: StateSignal): Result<T> {\n const result = new Result<T>(ResultKind.OK, null as T, \"\");\n result.#enqueued = [signal];\n return result;\n }\n\n /**\n * Creates a new `InTransition` result with using async callback\n * and timeout for executing it.\n *\n * @param asyncFn\n * @param timeout\n */\n static transition<T>(asyncFn: () => Promise<Result<T>>, timeout = 500): Result<Promise<Result<T>>> {\n const ts = Date.now();\n return new Result(\n ResultKind.InTransition,\n withTimeout(\n asyncFn().catch((err) => Result.error(err)),\n timeout,\n ),\n \"\",\n ts,\n );\n }\n\n /**\n * Creates a new `Rejected` result with explanation message\n *\n * @param message\n */\n static reject<T>(message: string): Result<T> {\n return new Result<T>(ResultKind.Rejected, null, message);\n }\n\n static error<T>(error: unknown): Result<T> {\n if (error instanceof Error) {\n return new Result<T>(ResultKind.Error, null, error);\n }\n return new Result<T>(ResultKind.Error, null, new Error(String(error)));\n }\n\n expect(...kinds: ResultKind[]): this {\n if (this.kind === ResultKind.InTransition) {\n // Defer the assertion to the FINAL resolved result. We do NOT park a\n // side-promise here (that previously leaked an unhandled rejection and\n // was orphaned by done(), which returns meta.transitioning without ever\n // reading it). done() applies #expectedKinds to whatever the transition\n // resolves to, so `.expect(...).done()` composes in any order.\n this.#expectedKinds = kinds;\n return this;\n }\n\n if (!kinds.includes(this.kind)) {\n throw new StateFlowError(\n buildErrorMessages(this.kind, this.error, this.message, this.#signal, this.#handler, this.#state),\n this.error,\n );\n }\n return this;\n }\n\n /**\n * Applies a previously-stored expect() assertion (from an InTransition\n * result) to the FINAL resolved result. Throws if the final kind is not\n * allowed. No-op when no expectation was registered.\n * @internal\n */\n #assertExpected(final: Result): Result {\n if (this.#expectedKinds == null) {\n return final;\n }\n if (!this.#expectedKinds.includes(final.kind)) {\n throw new StateFlowError(\n buildErrorMessages(\n final.kind,\n final.error,\n final.message,\n final.#signal ?? this.#signal,\n final.#handler ?? this.#handler,\n final.#state ?? this.#state,\n ),\n final.error,\n );\n }\n return final;\n }\n\n /**\n * @internal\n */\n withTimestamps(...ts: number[]): this {\n this.#timestamps = [Math.min(...ts), Math.max(...ts)];\n return this;\n }\n\n /**\n * @internal\n * @param signal\n */\n withSignal(signal: Signal | null): this {\n this.#signal = signal;\n return this;\n }\n\n /**\n * @internal\n * @param name\n */\n withHandlerName(name: string | null): this {\n this.#handler = name;\n return this;\n }\n\n withStacktrace(stack: CompactStackTrace | string | null): this {\n this.#stacktrace = Array.isArray(stack) ? stack : parseCompactStacktrace(stack);\n return this;\n }\n\n /**\n * @internal\n * @param state\n */\n withStateUpdating(state: string | null): this {\n this.#state = state;\n return this;\n }\n\n withMeta(meta: StateFlowMeta): this {\n this.#meta = meta;\n return this;\n }\n\n /**\n * @internal\n */\n withEnqueued(signals: StateSignal[]): this {\n this.#enqueued = signals;\n return this;\n }\n\n /**\n * @internal\n * @param other\n */\n merge<T>(other: Result<T>): Result<TData | T> {\n const combinedEnqueued = [...this.#enqueued, ...other.#enqueued];\n\n // when both results are the same...\n if (this.kind === other.kind) {\n switch (this.kind) {\n case ResultKind.Ignored:\n // merge the messages\n return Result.ignore<TData>(mergeStrings(this.msg, other.msg))\n .withTimestamps(...this.#timestamps, ...other.#timestamps)\n .withSignal(this.#signal)\n .withHandlerName(this.#handler)\n .withStateUpdating(this.#state)\n .withStacktrace(this.#stacktrace)\n .withEnqueued(combinedEnqueued);\n case ResultKind.OK:\n // it doesn't matter which state we return here\n // because they are the same\n return this.withTimestamps(...this.#timestamps, ...other.#timestamps).withEnqueued(combinedEnqueued);\n case ResultKind.InTransition:\n // combine the executors\n this.#executors.push(...other.#executors);\n this.#enqueued = combinedEnqueued;\n return this;\n case ResultKind.Rejected:\n // don't care about other rejected results\n // matters only the fact that this result is rejected\n return this.withTimestamps(...this.#timestamps, ...other.#timestamps).withEnqueued(combinedEnqueued);\n case ResultKind.Error: {\n // return merged error which contains both errors\n const msg = [this.data, other.data]\n .filter((m) => m !== \"\")\n .map((e) => String(e))\n .filter((m) => m !== \"\")\n .join(\"; \");\n return Result.error<TData>(new StateFlowError(msg))\n .withTimestamps(...this.#timestamps, ...other.#timestamps)\n .withSignal(this.#signal)\n .withHandlerName(this.#handler)\n .withStateUpdating(this.#state)\n .withStacktrace(this.#stacktrace)\n .withEnqueued(combinedEnqueued);\n }\n default:\n throw new Error(`unknown state result: ${this.kind}`);\n }\n }\n\n const choose = <A, B>(a: Result<A>, b: Result<B>): Result<A | B> | null => {\n // we need to decide which result is more important here\n switch (a.kind) {\n case ResultKind.Ignored:\n // no need to merge here, because Ignored is the least important result\n return b;\n case ResultKind.InTransition:\n // just add the other result to the executors\n // so that it will be merged later\n a.#executors.push(b.waitAll());\n return a;\n case ResultKind.Rejected:\n case ResultKind.Error:\n // if this result is an error or rejected, then it is the most important\n // we don't care about the other results\n return a;\n default:\n return null;\n }\n };\n\n return (choose(this, other) ?? choose(other, this) ?? this)\n .withTimestamps(...this.#timestamps, ...other.#timestamps)\n .withSignal(this.#signal)\n .withHandlerName(this.#handler)\n .withStateUpdating(this.#state)\n .withStacktrace(this.#stacktrace)\n .withEnqueued(combinedEnqueued);\n }\n\n [Symbol.toStringTag](): string {\n if (this.#enqueued.length > 0) {\n return `Result.Enqueue(${this.#enqueued.map(String).join(\", \")})`;\n }\n return `Result.${ResultKind[this.kind]}()`;\n }\n\n [Symbol.toPrimitive](): string {\n if (this.#enqueued.length > 0) {\n return `Enqueue(${this.#enqueued.map(String).join(\", \")})`;\n }\n\n if (this.kind === ResultKind.Error) {\n return this.error != null ? String(this.error) : ResultKind[this.kind];\n }\n\n return `${ResultKind[this.kind]}${this.message != null ? `: ${this.message}` : \"\"}`;\n }\n}\n\nfunction mergeStrings(a?: unknown, b?: unknown): string {\n if (a == null && b == null) {\n return \"\";\n }\n\n if (a == null || a === \"\") {\n return String(b);\n }\n if (b == null || b === \"\") {\n return String(a);\n }\n return `${a}; ${b}`;\n}\n\nfunction withTimeout<T>(promise: Promise<Result<T>>, timeout: number): Promise<Result<T>> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n resolve(Result.error(new Error(\"timeout\")) as Result<T>);\n }, timeout);\n\n promise.then(\n (res) => {\n clearTimeout(timer);\n resolve(res);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n}\n\nfunction buildErrorMessages(\n got: ResultKind,\n error: Error | null,\n message: string | null,\n signal: Signal | null = null,\n handler: string | null = null,\n stateUpd: string | null = null,\n): string {\n let msg: string;\n\n if (signal != null) {\n msg = `[SF] Signal '${String(signal)}' `;\n } else {\n msg = \"[SF] Result \";\n }\n\n if (handler != null) {\n msg += `in handler '${handler}()' `;\n }\n\n switch (got) {\n case ResultKind.Rejected:\n msg += \"was rejected\";\n break;\n case ResultKind.Error:\n msg += \"thrown an error\";\n break;\n case ResultKind.InTransition:\n msg += \"was in transition\";\n break;\n case ResultKind.OK:\n msg += \"was ok\";\n break;\n default:\n msg += \"was ignored\";\n }\n\n if (stateUpd != null) {\n msg += ` while tried to ${stateUpd}`;\n }\n\n if (error != null) {\n msg += `: ${error}`;\n }\n\n if (message != null) {\n msg += `: Message: ${message}`;\n }\n return msg;\n}\n\n// Global dispatch-start counter shared by ALL flows on the page: entries carry a\n// total order at dispatch START, which delivery-ordered logs (async entries are\n// appended on finish) and same-millisecond startTime ties cannot provide.\nlet dispatchCounter = 0;\n\nexport class ResultCollector {\n private results: Result[] = [];\n private readonly entry: StateFlowLogEntry;\n\n constructor(flowName: string, signal: unknown, duringTransition = false) {\n this.entry = {\n message: \"\",\n flowName,\n signal: String(signal),\n isAsync: false,\n startTime: Date.now(),\n dispatchOrder: ++dispatchCounter,\n finalStates: {},\n stateChanges: [],\n handlerResults: [],\n observers: [],\n enqueuedSignals: [],\n stacktrace: null,\n finalResult: \"\",\n };\n if (duringTransition) {\n this.entry.duringTransition = true;\n }\n }\n\n merge(): Result {\n if (this.results.length === 1 && this.results[0] != null) {\n return this.results[0];\n }\n\n const final = mergeResults(this.results);\n this.results = [final];\n return final;\n }\n\n push(val: unknown): void {\n const res = val instanceof Result ? val : Result.error(val);\n this.results.push(res);\n }\n\n logStateChange(stateName: string, oldState: StateInstance, newState: StateInstance) {\n this.entry.stateChanges.push({\n stateName,\n oldState: String(oldState),\n newState: String(newState),\n });\n }\n\n logHandler(\n stateName: string,\n type: \"enter\" | \"exit\" | \"update\" | \"rollback\",\n handlerName: string,\n result: unknown,\n ): void {\n this.entry.handlerResults.push({\n type,\n handlerName,\n stateName,\n result: String(result),\n });\n }\n\n logEnqueue(signal: string, handlerName: string) {\n this.entry.enqueuedSignals.push({ signal, fromHandler: handlerName });\n }\n\n logObserver(stateName: string, observerName: string, needObserve: boolean) {\n this.entry.observers.push({\n stateName,\n observerName,\n needObserve,\n });\n }\n\n async finish(snapshot: Record<string, StateInstance>, result: Result): Promise<StateFlowLogEntry> {\n this.entry.stacktrace = result.stacktrace;\n\n let finalResult = result;\n if (result.kind === ResultKind.InTransition) {\n const startTime = this.entry.startTime;\n finalResult = await result.waitAll();\n this.entry.isAsync = true;\n this.entry.duration = Date.now() - startTime;\n }\n\n this.entry.finalStates = Object.fromEntries(Object.entries(snapshot).map(([k, v]) => [k, String(v)]));\n this.entry.finalResult = String(finalResult);\n\n const timing = this.entry.duration != null ? `[${this.entry.duration}ms] ` : \"\";\n const stale = this.entry.duringTransition ? \"(during transition) \" : \"\";\n\n this.entry.message = `[SF/${this.entry.flowName}] ${this.entry.signal} - ${\n this.entry.isAsync ? \"async \" : \"\"\n }${timing}${stale}${this.entry.finalResult}`;\n return this.entry;\n }\n}\n\nexport function mergeResults(results: Result[], ignoreMessage = \"\"): Result {\n return results.reduce((l, r) => r.merge(l), Result.ignore(ignoreMessage));\n}\n","/**\n * Contains tools for defining states\n *\n * @example ```ts\n *\n * const audio = defineState<{volume: number}>(\"audio\")\n * .signals(signals)\n * .variant(\"unmuted\")\n * .variant(\"muted\")\n * .variant(\"forbidden\")\n * .stringRepr(s => `vol=${s.volume}`)\n * .build();\n *\n * defineFlow(audio.unmuted, {\n * mute: (s) => audio.muted(s),\n * volume: (s, args) => audio.unmuted({ volume: args.volume }),\n * });\n *\n * defineFlow(audio.muted, {\n * unmute: (s) => audio.unmuted(s),\n * });\n *\n * defineFlow(audio.forbidden, {\n * unmute: (s) => Result.reject(\"not allowed\"),\n * mute: (s) => Result.reject(\"not allowed\"),\n * userInteraction: (s) => s.volume > 0 ? audio.unMuted(s) : audio.muted(s);\n * });\n *\n * ```\n */\n\nimport { Result } from \"./result\";\nimport type { Signal, SignalHandler, SignalHandlers } from \"./signal\";\nimport { DEF, HANDLERS, IS_INITIAL, PARSER, SIGNALS, STRING_REPR, VARIANT } from \"./symbols\";\nimport { type Infer, StateFlowError, serializeDebug } from \"./utils\";\n\n//#region Helper Types\n\nexport type ExtractVariants<T> =\n T extends StateDefinition<any, infer TVariants, any, any>\n ? TVariants\n : T extends StateVariant<any, infer TVariants, any, any>\n ? TVariants\n : never;\n\nexport type ExtractSignals<T> =\n T extends StateDefinition<any, \"\", infer TSignals, any>\n ? TSignals\n : T extends StateVariant<any, \"\", infer TSignals, any>\n ? TSignals\n : never;\n\nexport type ExtractName<T> =\n T extends StateDefinition<any, \"\", any, infer TName>\n ? TName\n : T extends StateVariant<any, \"\", any, infer TName>\n ? TName\n : never;\n\nexport type ArrayToRecord<T extends readonly unknown[]> = {\n [K in T[number] as ExtractName<K>]: Readonly<Infer<K>>;\n};\n\nexport type StateResult<TProps> = TProps | StateInstance<TProps> | Result;\n\ntype Parser<T> = (val: object) => T;\n\ntype StringRepr<TProps, TVariants extends PropertyKey, TSignals> = (\n val: StateInstance<TProps, TVariants, TSignals>,\n) => string;\n\n//#endregion\n\n//#region State Types\n\n/**\n * Represents a state type. Contains all possible\n * state values as a hashmap\n */\nexport type StateDefinition<\n TProps = any,\n TVariants extends PropertyKey = string,\n TSignals = unknown,\n TName extends string = \"\",\n> = {\n (x: unknown): StateInstance<TProps>;\n readonly [Symbol.toStringTag]: TName;\n readonly [SIGNALS]: TSignals;\n readonly [PARSER]: Parser<TProps>;\n readonly [STRING_REPR]: StringRepr<TProps, TVariants, TSignals>;\n} & {\n readonly [K in TVariants]: StateVariant<TProps, TVariants, TSignals>;\n};\n\n/**\n * Represents one of possible value for the state\n * Can be constructed by calling it as a function\n */\nexport type StateVariant<\n TProps = any,\n TVariants extends PropertyKey = string,\n TSignals = unknown,\n TName extends string = \"\",\n> = {\n readonly [Symbol.toStringTag]: string;\n readonly [DEF]: StateDefinition<TProps, \"\", TSignals, TName>;\n readonly [HANDLERS]: SignalHandlers<TProps, TSignals>;\n readonly [IS_INITIAL]: boolean;\n\n (props: TProps): StateInstance<TProps, TVariants, TSignals>;\n};\n\n/**\n * Represents an instance of specific state.\n * Contains all required props.\n */\nexport type StateInstance<\n TProps = unknown,\n TVariants extends PropertyKey = string,\n TSignals = unknown,\n TName extends string = \"\",\n> = {\n readonly [Symbol.toStringTag]: string;\n readonly [VARIANT]: StateVariant<TProps, TVariants, TSignals, TName>;\n} & {\n readonly [K in keyof TProps]: TProps[K];\n};\n\n//#endregion\n\n//#region Helper Functions\n\nexport function isState(state: unknown): state is StateInstance {\n return typeof state === \"object\" && state != null && VARIANT in state;\n}\n\nexport function isStateDef(obj: unknown): obj is StateDefinition {\n return obj != null && typeof obj === \"function\" && SIGNALS in obj;\n}\n\nfunction isStateInstance<TProps, TVariants extends PropertyKey, TSignals>(\n obj: unknown,\n name: string,\n): obj is StateInstance<TProps, TVariants, TSignals> {\n if (obj == null || typeof obj !== \"object\" || !(VARIANT in obj) || !(Symbol.toStringTag in obj)) {\n return false;\n }\n return String(obj[Symbol.toStringTag]).startsWith(name);\n}\n\n/**\n * Returns true if the group accepts the signal.\n */\nexport function stateAccepts<TProps, TSignals>(\n state: StateInstance<TProps, string, TSignals>,\n signalName: PropertyKey,\n): signalName is keyof TSignals {\n return signalName in state[VARIANT][HANDLERS];\n}\n\nexport function stateVar<T>(obj: StateInstance<T> | T): StateVariant<T> {\n if (obj == null || typeof obj !== \"object\" || !(VARIANT in obj)) {\n throw new StateFlowError(\"Not a state\");\n }\n\n return obj[VARIANT] as StateVariant<T>;\n}\n\nexport function getInitialState<TProps>(def: StateDefinition<TProps>): StateVariant<TProps> {\n const svar = Object.values(def).find((x) => x[IS_INITIAL]);\n if (svar == null) {\n throw new StateFlowError(\"Initial state variant not found\");\n }\n return svar;\n}\n\nexport function getName<T extends StateDefinition>(def: T): ExtractName<T> {\n return def[Symbol.toStringTag] as ExtractName<T>;\n}\n\n//#endregion\n\n/**\n * Builds a new immutable state instance\n *\n * @param value\n * @param props\n */\nfunction factory<TProps, TVariants extends PropertyKey, TSignals>(\n value: StateVariant<TProps, TVariants, TSignals>,\n props: TProps | StateInstance<TProps, TVariants, TSignals>,\n): StateInstance<TProps, TVariants, TSignals> {\n const name = String(value);\n const inst = value[DEF][PARSER](props as object) as StateInstance<TProps, TVariants, TSignals>;\n\n Object.defineProperties(inst, {\n [Symbol.toStringTag]: { value: name, writable: false, configurable: false, enumerable: false },\n [Symbol.toPrimitive]: {\n value: () => `${name}(${value[DEF][STRING_REPR](inst)})`,\n writable: false,\n configurable: false,\n enumerable: false,\n },\n [VARIANT]: { value, writable: false, configurable: false, enumerable: false },\n });\n\n return Object.freeze(inst);\n}\n\nfunction extract<TProps, TVariants extends PropertyKey, TSignals>(\n name: string,\n ctx: unknown,\n): StateInstance<TProps, TVariants, TSignals> {\n if (ctx == null || typeof ctx !== \"object\" || !(name in ctx)) {\n throw new StateFlowError(\"State Flow object not found\");\n }\n const state = Reflect.get(ctx, name);\n if (!isStateInstance<TProps, TVariants, TSignals>(state, name)) {\n throw new StateFlowError(`State not found: ${name}`);\n }\n\n return state;\n}\n\nclass StateBuilder<TProps, TVariants extends PropertyKey, TSignals, TName extends string> {\n #signals?: TSignals;\n\n readonly #variants: Array<[TVariants, boolean]> = [];\n\n #parser: Parser<TProps> = (v: object) => ({ ...v }) as TProps;\n\n #stringRepr: StringRepr<TProps, TVariants, TSignals> = (v) => serializeDebug(v);\n\n #name: TName = \"\" as TName;\n\n name<TNewName extends string>(name: TNewName): StateBuilder<TProps, TVariants, TSignals, TNewName> {\n const self = this as unknown as StateBuilder<TProps, TVariants, TSignals, TNewName>;\n self.#name = name;\n return self;\n }\n\n signals<TArgSignals>(signals: TArgSignals): StateBuilder<TProps, TVariants, TArgSignals, TName> {\n const self = this as unknown as StateBuilder<TProps, TVariants, TArgSignals, TName>;\n self.#signals = signals;\n return self;\n }\n\n variant<TVariant extends PropertyKey>(\n variant: TVariant,\n isInitial = false,\n ): StateBuilder<TProps, TVariants | TVariant, TSignals, TName> {\n const self = this as StateBuilder<TProps, TVariants | TVariant, TSignals, TName>;\n if (isInitial && self.#variants.some(([_, i]) => i)) {\n throw new StateFlowError(\"Only one initial state variant is allowed\");\n }\n self.#variants.push([variant, isInitial]);\n return self;\n }\n\n parser(func: (val: object) => TProps): this {\n this.#parser = func;\n return this;\n }\n\n stringRepr(func: (val: StateInstance<TProps, TVariants, TSignals>) => string): this {\n this.#stringRepr = func;\n return this;\n }\n\n build(): StateDefinition<TProps, TVariants, TSignals, TName> {\n const signals = this.#signals;\n const name = this.#name;\n if (signals == null) {\n throw new StateFlowError(\"Signals were not provided\");\n }\n\n if (name === \"\") {\n throw new StateFlowError(\"Name was not provided\");\n }\n\n if (this.#variants.length === 0) {\n throw new StateFlowError(\"No state variants are defined\");\n }\n\n const def = extract.bind(null, name) as unknown as StateDefinition<TProps, TVariants, TSignals, TName>;\n Object.assign(def, Object.fromEntries(this.#variants.map(([v, i]) => this.buildFactories(def, v, i))));\n\n Object.defineProperties(def, {\n [Symbol.toStringTag]: { value: this.#name, enumerable: false, configurable: false, writable: false },\n [Symbol.toPrimitive]: { value: () => this.#name, enumerable: false, configurable: false, writable: false },\n [SIGNALS]: { value: signals, enumerable: false, configurable: false, writable: false },\n [PARSER]: { value: this.#parser, enumerable: false, configurable: false, writable: false },\n [STRING_REPR]: { value: this.#stringRepr, enumerable: false, configurable: false, writable: false },\n });\n\n return Object.freeze(def);\n }\n\n private buildFactories(\n def: StateDefinition<TProps, TVariants, TSignals, TName>,\n variant: TVariants,\n isInitial: boolean,\n ): [PropertyKey, StateVariant<TProps, TVariants, TSignals>] {\n const fn = Object.defineProperties(\n function stateFactory(props) {\n return factory<TProps, TVariants, TSignals>(fn, props);\n } as StateVariant<TProps, TVariants, TSignals>,\n {\n [Symbol.toStringTag]: { value: variant, enumerable: false, writable: false, configurable: false },\n [Symbol.toPrimitive]: {\n value: () => `${String(def)}.${String(variant)}`,\n enumerable: false,\n writable: false,\n configurable: false,\n },\n [DEF]: { value: def, enumerable: false, writable: false, configurable: false },\n [HANDLERS]: { value: {}, enumerable: false, writable: false, configurable: false },\n [IS_INITIAL]: { value: isInitial, enumerable: false, writable: false, configurable: false },\n },\n );\n\n return [variant, fn];\n }\n}\n\n/**\n * Defines a new state type with associated variants and properties.\n *\n * @returns StateBuilder instance for fluent configuration of the state\n *\n * @example\n * ```ts\n * const audioState = defineState<{volume: number}>()\n * .name(\"audio\")\n * .signals(audioSignals)\n * .variant(\"playing\", true)\n * .variant(\"paused\")\n * .stringRepr(s => `vol=${s.volume}`)\n * .build();\n * ```\n */\nexport function defineState<TProps>(): StateBuilder<TProps, \"\", unknown, \"\"> {\n return new StateBuilder<TProps, \"\", unknown, \"\">();\n}\n\n/**\n * Configures state transition handlers for a specific state variant.\n *\n * @param state - State variant to define handlers for\n * @param handlers - Object mapping signal names to handler functions\n * @throws StateFlowError if handlers are already defined for the state variant\n *\n * @example\n * ```ts\n * defineFlow(audioState.playing, {\n * pause: (state) => audioState.paused(state),\n * volume: (state, args) => audioState.playing({ ...state, volume: args.volume })\n * });\n * ```\n */\nexport function defineFlow<TVariant extends StateVariant<any, any, any>>(\n state: TVariant,\n handlers: SignalHandlers<Infer<TVariant>, ExtractSignals<TVariant>>,\n): void {\n if (Object.isFrozen(state[HANDLERS])) {\n throw new StateFlowError(`Flow is already defined: ${String(state)}`);\n }\n Object.assign(state[HANDLERS], handlers);\n Object.freeze(state[HANDLERS]);\n}\n\n/**\n * Handles the signal in current state.\n */\nexport function handleSignal<TProps, TState extends StateInstance<TProps, string, TSignals>, TSignals>(\n state: TState,\n signal: Signal<TProps>,\n ctx: object,\n): Result<TState> {\n const signalName = signal[Symbol.toStringTag];\n if (!stateAccepts(state, signalName)) {\n return Result.ignore(\"\");\n }\n\n const handler = state[VARIANT][HANDLERS][signalName] as SignalHandler<TProps>;\n\n try {\n const result = handler(state, signal, ctx);\n if (result instanceof Result) {\n return result as Result<TState>;\n }\n\n if (isState(result)) {\n return Result.state(result) as Result<TState>;\n }\n\n return Result.state(state[VARIANT](result) as any);\n } catch (err) {\n return Result.error(err);\n }\n}\n","/**\n * Contains types and interfaces for the signal system.\n *\n * @example ```ts\n * const signals = {\n * mute: defineSignal(\"mute\"),\n * unmute: defineSignal(\"unmute\"),\n * volume: defineSignal<{volume: number}>(\"volume\"),\n * };\n *\n * // ...\n *\n * // immediate result\n * const res1 = dispatch(target, signals.unmute());\n *\n * // or if you need to await transition\n * const res2 = await dispatch(target, signals.volume({volume: 0.7})).done();\n * ```\n */\n\nimport type { StateResult } from \"./state\";\nimport { SIGNAL } from \"./symbols\";\nimport { type Infer, serializeDebug } from \"./utils\";\n\nexport interface StateSignal {\n [SIGNAL]: true;\n [Symbol.toStringTag]: string;\n}\n\nexport type Signal<TArgs = unknown> = StateSignal & TArgs;\n\nexport type SignalDefinition<TArgs = void> =\n TArgs extends Record<string, unknown>\n ? { [Symbol.toStringTag]: string } & ((props: TArgs) => StateSignal & TArgs)\n : { [Symbol.toStringTag]: string } & (() => StateSignal);\n\n/**\n * Creates a new signal definition that can trigger state transitions.\n *\n * @param name - Identifier for the signal\n * @param stringRepr\n * @returns Function to create signal instances, optionally with parameters\n *\n * @example\n * ```ts\n * const signals = {\n * play: defineSignal(\"play\"),\n * seek: defineSignal<{time: number}>(\"seek\"),\n * volume: defineSignal<{level: number}>(\"volume\")\n * };\n * ```\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: `void` is the intended \"no payload\" marker for parameterless signals.\nexport function defineSignal<TArgs extends Record<string, unknown> | void = void>(\n name: string,\n stringRepr = (args: TArgs) => serializeDebug(args),\n): SignalDefinition<TArgs> {\n const fn = (p?: Record<string, unknown>) => {\n // console.groupCollapsed(`[dispatch:] ${name}{${stringRepr(p as TArgs)}}`);\n // console.trace(name);\n // console.groupEnd();\n return Object.freeze({\n ...p,\n [SIGNAL]: true,\n [Symbol.toStringTag]: name,\n [Symbol.toPrimitive]: () => `${name}{${stringRepr(p as TArgs)}}`,\n });\n };\n Reflect.defineProperty(fn, Symbol.toStringTag, {\n value: name,\n writable: false,\n configurable: false,\n enumerable: false,\n });\n return fn as unknown as SignalDefinition<TArgs>;\n}\n\nexport type SignalHandler<TProps = unknown, TArgs = unknown> = (\n state: TProps,\n signal: TArgs,\n ctx: unknown,\n) => StateResult<TProps>;\n\nexport type SignalHandlers<TProps, TSignals> = Partial<{\n readonly [K in keyof TSignals]: SignalHandler<TProps, Infer<TSignals[K]>>;\n}>;\n"],"mappings":"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","names":["entries","ResultKind","stateVar"]}
|