@camcima/finita 4.2.0 → 4.3.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/CHANGELOG.md +141 -0
- package/dist/index.cjs +144 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -10
- package/dist/index.d.ts +69 -10
- package/dist/index.js +143 -49
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Event.ts","../src/internal/InternalConstruction.ts","../src/error/FinitaError.ts","../src/error/StateNotFoundError.ts","../src/StateCollection.ts","../src/Process.ts","../src/error/StateEventNotFoundError.ts","../src/State.ts","../src/Transition.ts","../src/error/DuplicateStateError.ts","../src/error/ProcessFinalizedError.ts","../src/error/GraphValidationError.ts","../src/error/DuplicateTransitionError.ts","../src/ProcessBuilder.ts","../src/error/AmbiguousTransitionError.ts","../src/selector/OneOrNoneActiveTransition.ts","../src/mutex/NullMutex.ts","../src/internal/OperationQueue.ts","../src/filter/ActiveTransitionFilter.ts","../src/error/WrongEventForStateError.ts","../src/error/LockCanNotBeAcquiredError.ts","../src/error/LockCanNotBeReleasedError.ts","../src/error/AutomaticTransitionCycleError.ts","../src/error/ReentrancyError.ts","../src/error/QueueLimitExceededError.ts","../src/Statemachine.ts","../src/condition/Tautology.ts","../src/condition/Contradiction.ts","../src/condition/CallbackCondition.ts","../src/error/InvalidSubjectError.ts","../src/condition/Timeout.ts","../src/condition/CompositeCondition.ts","../src/condition/AndComposite.ts","../src/condition/OrComposite.ts","../src/condition/Not.ts","../src/observer/CallbackObserver.ts","../src/observer/StatefulStatusChanger.ts","../src/observer/OnEnterObserver.ts","../src/util/index.ts","../src/observer/TransitionLogger.ts","../src/filter/FilterStateByEvent.ts","../src/filter/FilterStateByTransition.ts","../src/filter/FilterStateByFinalState.ts","../src/filter/FilterTransitionByEvent.ts","../src/selector/ScoreTransition.ts","../src/selector/WeightTransition.ts","../src/mutex/LockAdapterMutex.ts","../src/mutex/MutexFactory.ts","../src/factory/Factory.ts","../src/factory/SingleProcessDetector.ts","../src/error/ProcessNotFoundError.ts","../src/factory/AbstractNamedProcessDetector.ts","../src/factory/StatefulStateNameDetector.ts","../src/graph/GraphBuilder.ts"],"sourcesContent":["import type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { Observer } from \"./interfaces/Observer.js\";\n\nexport class Event implements EventInterface {\n private readonly name: string;\n private readonly observers: Set<Observer> = new Set();\n private readonly metadata: Map<string, unknown> = new Map();\n constructor(name: string) {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n /**\n * @deprecated Always returns []. Invoke args are now passed directly to\n * Observer.update — reading them from the event was racy when one\n * Process served multiple Statemachines.\n */\n getInvokeArgs(): unknown[] {\n return [];\n }\n\n async invoke(...args: unknown[]): Promise<void> {\n await this.notify(args);\n }\n\n attach(observer: Observer): void {\n this.observers.add(observer);\n }\n\n detach(observer: Observer): void {\n this.observers.delete(observer);\n }\n\n async notify(args?: readonly unknown[]): Promise<void> {\n // Forward args as-is. invoke() always supplies a concrete array (empty when\n // called with no args), whereas a bare notify() passes undefined — letting\n // observers distinguish \"invoked with zero args\" ([]) from \"no args\n // supplied\" (undefined), e.g. CallbackObserver's legacy update(subject).\n for (const observer of [...this.observers]) {\n await observer.update(this, args);\n }\n }\n\n /** Snapshot — detaching later does not change an already-returned list,\n * and mutating it does not change the event's registrations. */\n getObservers(): Iterable<Observer> {\n return [...this.observers];\n }\n\n getMetadata(): Record<string, unknown> {\n return Object.fromEntries(this.metadata);\n }\n\n getMetadataValue(key: string): unknown {\n return this.metadata.get(key);\n }\n\n setMetadataValue(key: string, value: unknown): void {\n this.metadata.set(key, value);\n }\n\n hasMetadataValue(key: string): boolean {\n return this.metadata.has(key);\n }\n\n deleteMetadataValue(key: string): void {\n this.metadata.delete(key);\n }\n}\n","/**\n * Symbol-based construction guard for State / Transition / Process.\n *\n * These classes' constructors require this symbol as the first argument.\n * Only ProcessBuilder imports it, ensuring only the builder can instantiate\n * the graph. User code receives an opaque type error if it tries to call\n * `new State(...)` directly.\n */\nexport const INTERNAL_CONSTRUCTION_KEY: unique symbol = Symbol(\n \"@camcima/finita/InternalConstruction\",\n);\nexport type InternalConstructionKey = typeof INTERNAL_CONSTRUCTION_KEY;\n","export abstract class FinitaError extends Error {\n abstract readonly code: string;\n\n constructor(message?: string) {\n super(message);\n if (new.target === FinitaError) {\n throw new TypeError(\n \"FinitaError is abstract and cannot be instantiated directly\",\n );\n }\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class StateNotFoundError extends FinitaError {\n readonly code = \"stateNotFound\";\n readonly stateName: string;\n readonly availableStates: readonly string[];\n\n constructor(stateName: string, availableStates: Iterable<string>) {\n const list = Array.from(availableStates);\n const display =\n list.length > 0 ? list.map((n) => `\"${n}\"`).join(\", \") : \"(none)\";\n super(`State \"${stateName}\" not found. Available: ${display}`);\n this.name = \"StateNotFoundError\";\n this.stateName = stateName;\n this.availableStates = Object.freeze([...list]);\n }\n}\n","import type { StateCollectionInterface } from \"./interfaces/StateCollectionInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport { StateNotFoundError } from \"./error/StateNotFoundError.js\";\n\nexport class StateCollection implements StateCollectionInterface {\n private readonly states: ReadonlyMap<string, StateInterface>;\n\n constructor(states: Iterable<StateInterface>) {\n const map = new Map<string, StateInterface>();\n for (const s of states) {\n map.set(s.getName(), s);\n }\n this.states = map;\n }\n\n getStates(): Iterable<StateInterface> {\n return this.states.values();\n }\n\n getState(name: string): StateInterface {\n const s = this.states.get(name);\n if (!s) {\n throw new StateNotFoundError(name, this.states.keys());\n }\n return s;\n }\n\n hasState(name: string): boolean {\n return this.states.has(name);\n }\n}\n","import type { ProcessInterface } from \"./interfaces/ProcessInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { StateCollection } from \"./StateCollection.js\";\n\nexport class Process implements ProcessInterface {\n private readonly name: string;\n private readonly initialState: StateInterface;\n private readonly states: StateCollection;\n\n constructor(\n key: InternalConstructionKey,\n name: string,\n initialState: StateInterface,\n states: Iterable<StateInterface>,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"Process is not user-constructible; use ProcessBuilder.\");\n }\n this.name = name;\n this.initialState = initialState;\n this.states = new StateCollection(states);\n Object.freeze(this);\n }\n\n getName(): string {\n return this.name;\n }\n\n getInitialState(): StateInterface {\n return this.initialState;\n }\n\n getStates(): Iterable<StateInterface> {\n return this.states.getStates();\n }\n\n getState(name: string): StateInterface {\n return this.states.getState(name);\n }\n\n hasState(name: string): boolean {\n return this.states.hasState(name);\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class StateEventNotFoundError extends FinitaError {\n readonly code = \"stateEventNotFound\";\n readonly stateName: string;\n readonly eventName: string;\n\n constructor(stateName: string, eventName: string) {\n super(`State \"${stateName}\" has no event \"${eventName}\"`);\n this.name = \"StateEventNotFoundError\";\n this.stateName = stateName;\n this.eventName = eventName;\n }\n}\n","import type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { Event } from \"./Event.js\";\nimport { StateEventNotFoundError } from \"./error/StateEventNotFoundError.js\";\n\nexport class State implements StateInterface {\n private readonly name: string;\n private _transitions: ReadonlySet<TransitionInterface> | null = null;\n private readonly events: ReadonlyMap<string, EventInterface>;\n private readonly metadata: ReadonlyMap<string, unknown>;\n\n constructor(\n key: InternalConstructionKey,\n name: string,\n eventNames: Iterable<string>,\n metadata: ReadonlyMap<string, unknown>,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"State is not user-constructible; use ProcessBuilder.\");\n }\n this.name = name;\n const events = new Map<string, EventInterface>();\n for (const en of eventNames) {\n events.set(en, new Event(en));\n }\n this.events = events;\n this.metadata = new Map(metadata);\n }\n\n /**\n * Internal: populate transitions after State construction.\n * May only be called once and only with the construction key.\n * Used by ProcessBuilder to break the cycle: State must exist before\n * Transitions can target it, but State needs its transitions to be useful.\n */\n _initTransitions(\n key: InternalConstructionKey,\n transitions: Iterable<TransitionInterface>,\n ): void {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"_initTransitions is internal\");\n }\n if (this._transitions !== null) {\n throw new Error(`State \"${this.name}\" transitions already set`);\n }\n this._transitions = new Set(transitions);\n Object.freeze(this);\n }\n\n getName(): string {\n return this.name;\n }\n\n getTransitions(): Iterable<TransitionInterface> {\n if (this._transitions === null) {\n return [];\n }\n return this._transitions;\n }\n\n getEventNames(): string[] {\n return Array.from(this.events.keys());\n }\n\n hasEvent(name: string): boolean {\n return this.events.has(name);\n }\n\n getEvent(name: string): EventInterface {\n const event = this.events.get(name);\n if (!event) {\n throw new StateEventNotFoundError(this.name, name);\n }\n return event;\n }\n\n getMetadata(): Record<string, unknown> {\n return Object.fromEntries(this.metadata);\n }\n\n getMetadataValue(key: string): unknown {\n return this.metadata.get(key);\n }\n\n hasMetadataValue(key: string): boolean {\n return this.metadata.has(key);\n }\n}\n","import type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { ConditionInterface } from \"./interfaces/ConditionInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\n\nexport class Transition<\n TSubject = unknown,\n> implements TransitionInterface<TSubject> {\n private readonly targetState: StateInterface;\n private readonly eventName: string | null;\n private readonly condition: ConditionInterface<TSubject> | null;\n private readonly weight: number;\n\n constructor(\n key: InternalConstructionKey,\n targetState: StateInterface,\n eventName: string | null,\n condition: ConditionInterface<TSubject> | null,\n weight: number,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\n \"Transition is not user-constructible; use ProcessBuilder.\",\n );\n }\n this.targetState = targetState;\n this.eventName = eventName;\n this.condition = condition;\n this.weight = weight;\n Object.freeze(this);\n }\n\n getTargetState(): StateInterface {\n return this.targetState;\n }\n\n getEventName(): string | null {\n return this.eventName;\n }\n\n getConditionName(): string | null {\n return this.condition ? this.condition.getName() : null;\n }\n\n getCondition(): ConditionInterface<TSubject> | null {\n return this.condition;\n }\n\n async isActive(\n subject: TSubject,\n context: Map<string, unknown>,\n event?: EventInterface,\n ): Promise<boolean> {\n let active: boolean;\n if (event) {\n active = event.getName() === this.eventName;\n } else {\n active = this.eventName === null;\n }\n if (this.condition && active) {\n active = await this.condition.checkCondition(subject, context);\n }\n return active;\n }\n\n getWeight(): number {\n return this.weight;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class DuplicateStateError extends FinitaError {\n readonly code = \"duplicateState\";\n readonly stateName: string;\n\n constructor(stateName: string) {\n super(\n `There is already a different state with name \"${stateName}\" in this collection`,\n );\n this.name = \"DuplicateStateError\";\n this.stateName = stateName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ProcessFinalizedError extends FinitaError {\n readonly code = \"processFinalized\";\n readonly processName: string;\n\n constructor(processName: string) {\n super(\n `Process \"${processName}\" has already been built; ProcessBuilder.build() may only be called once`,\n );\n this.name = \"ProcessFinalizedError\";\n this.processName = processName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport type GraphValidationCode =\n | \"unknownTarget\"\n | \"unknownSource\"\n | \"missingInitialState\"\n | \"multipleInitialStates\"\n | \"invalidStateName\"\n | \"invalidEventName\"\n | \"invalidConditionName\"\n | \"invalidTransitionWeight\"\n | \"orphanState\";\n\nexport class GraphValidationError extends FinitaError {\n readonly code: GraphValidationCode;\n readonly details: Readonly<Record<string, unknown>>;\n\n constructor(\n code: GraphValidationCode,\n message: string,\n details: Record<string, unknown> = {},\n ) {\n super(`[${code}] ${message}`);\n this.name = \"GraphValidationError\";\n this.code = code;\n this.details = Object.freeze({ ...details });\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport interface DuplicateTransitionConflict {\n fromState: string;\n toState: string;\n eventName: string | null;\n existingConditionName: string | null;\n newConditionName: string | null;\n existingWeight?: number;\n newWeight?: number;\n}\n\nexport class DuplicateTransitionError extends FinitaError {\n readonly code = \"duplicateTransition\";\n readonly conflict: Readonly<DuplicateTransitionConflict>;\n\n constructor(conflict: DuplicateTransitionConflict) {\n const eventLabel = conflict.eventName ?? \"<automatic>\";\n const existing = conflict.existingConditionName ?? \"<no condition>\";\n const incoming = conflict.newConditionName ?? \"<no condition>\";\n const weightInfo =\n conflict.existingWeight !== undefined &&\n conflict.newWeight !== undefined &&\n conflict.existingWeight !== conflict.newWeight\n ? `, existing weight ${conflict.existingWeight} vs new weight ${conflict.newWeight}`\n : \"\";\n super(\n `Conflicting transition declarations from \"${conflict.fromState}\" to \"${conflict.toState}\" on event \"${eventLabel}\": existing condition \"${existing}\" vs new condition \"${incoming}\"${weightInfo}`,\n );\n this.name = \"DuplicateTransitionError\";\n this.conflict = Object.freeze({ ...conflict });\n }\n}\n","import type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { ConditionInterface } from \"./interfaces/ConditionInterface.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { Process } from \"./Process.js\";\nimport { State } from \"./State.js\";\nimport { Transition } from \"./Transition.js\";\nimport { DuplicateStateError } from \"./error/DuplicateStateError.js\";\nimport { ProcessFinalizedError } from \"./error/ProcessFinalizedError.js\";\nimport { GraphValidationError } from \"./error/GraphValidationError.js\";\nimport { DuplicateTransitionError } from \"./error/DuplicateTransitionError.js\";\n\ninterface StateSpec {\n name: string;\n initial: boolean;\n metadata: Map<string, unknown>;\n}\n\ninterface TransitionSpec<TSubject = unknown> {\n fromState: string;\n toState: string;\n eventName: string | null;\n condition: ConditionInterface<TSubject> | null;\n weight: number;\n}\n\nexport interface AddStateOptions {\n initial?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AddTransitionOptions<TSubject = unknown> {\n event?: string;\n condition?: ConditionInterface<TSubject>;\n weight?: number;\n}\n\nexport interface BuildOptions {\n /**\n * When true, orphan/unreachable states cause GraphValidationError.\n * When false (default), orphan states are silently allowed.\n */\n strictOrphans?: boolean;\n}\n\nexport class ProcessBuilder<TSubject = unknown> {\n private readonly processName: string;\n private readonly stateSpecs: Map<string, StateSpec> = new Map();\n private readonly transitionSpecs: TransitionSpec<TSubject>[] = [];\n private built = false;\n\n constructor(processName: string) {\n this.processName = processName;\n }\n\n addState(name: string, options: AddStateOptions = {}): this {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n if (this.stateSpecs.has(name)) {\n throw new DuplicateStateError(name);\n }\n this.validateName(\"invalidStateName\", name, `addState(\"${name}\")`, {\n stateName: name,\n });\n this.stateSpecs.set(name, {\n name,\n initial: options.initial === true,\n metadata: new Map(Object.entries(options.metadata ?? {})),\n });\n return this;\n }\n\n addTransition(\n fromState: string,\n toState: string,\n options: AddTransitionOptions<TSubject> = {},\n ): this {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n let eventName: string | null = null;\n if (options.event !== undefined) {\n this.validateName(\n \"invalidEventName\",\n options.event,\n `addTransition called with an invalid event name from \"${fromState}\" to \"${toState}\"`,\n { fromState, toState, eventName: options.event },\n );\n eventName = options.event;\n }\n if (options.condition) {\n const conditionName = options.condition.getName();\n this.validateName(\n \"invalidConditionName\",\n conditionName,\n `addTransition called with an invalid condition name from \"${fromState}\" to \"${toState}\"`,\n { fromState, toState, conditionName },\n );\n }\n const weight = options.weight ?? 1;\n if (!Number.isFinite(weight)) {\n throw new GraphValidationError(\n \"invalidTransitionWeight\",\n `addTransition from \"${fromState}\" to \"${toState}\": weight must be a finite number; got ${String(weight)}`,\n { fromState, toState, eventName, weight },\n );\n }\n this.transitionSpecs.push({\n fromState,\n toState,\n eventName,\n condition: options.condition ?? null,\n weight,\n });\n return this;\n }\n\n build(options: BuildOptions = {}): Process {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n\n this.validateInitialState();\n this.validateTransitionEndpoints();\n this.validateNoConflictingDuplicates();\n\n const initialName = this.findInitialStateName();\n const eventNamesByState = this.collectEventNamesByState();\n\n // Two-phase construction: create all State instances first (with no\n // transitions), then build Transitions targeting those instances and attach\n // them. Identity holds by construction for any graph topology.\n const finalStates = this.buildAllStates(eventNamesByState);\n\n if (options.strictOrphans) {\n this.validateOrphans(finalStates, initialName);\n }\n\n const initialState = finalStates.get(initialName)!;\n this.built = true;\n return new Process(\n INTERNAL_CONSTRUCTION_KEY,\n this.processName,\n initialState,\n finalStates.values(),\n );\n }\n\n // --- private helpers ---\n\n /** One name rule for every named entity: non-empty, no leading/trailing whitespace. */\n private validateName(\n code: \"invalidStateName\" | \"invalidEventName\" | \"invalidConditionName\",\n raw: string,\n description: string,\n details: Record<string, unknown>,\n ): void {\n if (raw.trim() === \"\" || raw !== raw.trim()) {\n throw new GraphValidationError(\n code,\n `${description}: name ${JSON.stringify(raw)} is empty or whitespace-padded`,\n details,\n );\n }\n }\n\n private validateInitialState(): void {\n const initials = Array.from(this.stateSpecs.values()).filter(\n (s) => s.initial,\n );\n if (initials.length === 0) {\n throw new GraphValidationError(\n \"missingInitialState\",\n `Process \"${this.processName}\" has no state declared with { initial: true }`,\n { processName: this.processName },\n );\n }\n if (initials.length > 1) {\n throw new GraphValidationError(\n \"multipleInitialStates\",\n `Process \"${this.processName}\" declares multiple initial states: ${initials.map((s) => `\"${s.name}\"`).join(\", \")}`,\n {\n processName: this.processName,\n initialStates: initials.map((s) => s.name),\n },\n );\n }\n }\n\n private findInitialStateName(): string {\n return Array.from(this.stateSpecs.values()).find((s) => s.initial)!.name;\n }\n\n private validateTransitionEndpoints(): void {\n for (const t of this.transitionSpecs) {\n if (!this.stateSpecs.has(t.fromState)) {\n throw new GraphValidationError(\n \"unknownSource\",\n `Transition source state \"${t.fromState}\" was not declared with addState`,\n {\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n },\n );\n }\n if (!this.stateSpecs.has(t.toState)) {\n throw new GraphValidationError(\n \"unknownTarget\",\n `Transition target state \"${t.toState}\" was not declared with addState`,\n {\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n },\n );\n }\n }\n }\n\n /** Transition identity: (fromState, eventName, toState). Used by both the\n * conflict check and the build-time dedup — keep them in lockstep. */\n private static transitionKey(t: {\n fromState: string;\n eventName: string | null;\n toState: string;\n }): string {\n return `${t.fromState}\\x00${t.eventName ?? \"\"}\\x00${t.toState}`;\n }\n\n private validateNoConflictingDuplicates(): void {\n // Identity key: (fromState, eventName, toState).\n // Same condition reference AND same weight → dedup (idempotent\n // re-declaration). Anything else → conflict. We cannot introspect\n // callable bodies to compare logic, so different object identity is\n // treated as different logic.\n const seen = new Map<string, TransitionSpec<TSubject>>();\n for (const t of this.transitionSpecs) {\n const key = ProcessBuilder.transitionKey(t);\n const existing = seen.get(key);\n if (!existing) {\n seen.set(key, t);\n continue;\n }\n if (existing.condition !== t.condition || existing.weight !== t.weight) {\n throw new DuplicateTransitionError({\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n existingConditionName: existing.condition\n ? existing.condition.getName()\n : null,\n newConditionName: t.condition ? t.condition.getName() : null,\n existingWeight: existing.weight,\n newWeight: t.weight,\n });\n }\n // Same identity, same condition instance, same weight → dedup silently.\n }\n }\n\n private collectEventNamesByState(): Map<string, string[]> {\n const out = new Map<string, Set<string>>();\n for (const t of this.transitionSpecs) {\n if (t.eventName === null) continue;\n let bucket = out.get(t.fromState);\n if (!bucket) {\n bucket = new Set();\n out.set(t.fromState, bucket);\n }\n bucket.add(t.eventName);\n }\n return new Map(\n Array.from(out.entries()).map(([k, v]) => [k, Array.from(v)]),\n );\n }\n\n /**\n * Two-phase construction:\n * Phase 1 — create all final State instances with no transitions.\n * Phase 2 — build Transitions targeting the Phase-1 States, then attach\n * them via State._initTransitions.\n *\n * Because every Transition is created after every State exists, target\n * identity holds by construction for any graph topology (acyclic, cyclic,\n * self-loop).\n */\n private buildAllStates(\n eventNamesByState: Map<string, string[]>,\n ): Map<string, StateInterface> {\n const built = new Map<string, StateInterface>();\n\n // Phase 1: create all States with no transitions.\n for (const spec of this.stateSpecs.values()) {\n built.set(\n spec.name,\n new State(\n INTERNAL_CONSTRUCTION_KEY,\n spec.name,\n eventNamesByState.get(spec.name) ?? [],\n spec.metadata,\n ),\n );\n }\n\n // Phase 2: build Transitions targeting Phase-1 States, then attach.\n // validateNoConflictingDuplicates already guaranteed that specs sharing\n // the identity key are exact duplicates, so a plain key dedup suffices.\n const dedupSeen = new Set<string>();\n const transitionsByState = new Map<\n string,\n TransitionInterface<TSubject>[]\n >();\n for (const spec of this.stateSpecs.values()) {\n transitionsByState.set(spec.name, []);\n }\n for (const tSpec of this.transitionSpecs) {\n const dedupKey = ProcessBuilder.transitionKey(tSpec);\n if (dedupSeen.has(dedupKey)) continue;\n dedupSeen.add(dedupKey);\n const targetState = built.get(tSpec.toState)!;\n const transition = new Transition<TSubject>(\n INTERNAL_CONSTRUCTION_KEY,\n targetState,\n tSpec.eventName,\n tSpec.condition,\n tSpec.weight,\n );\n transitionsByState.get(tSpec.fromState)!.push(transition);\n }\n\n for (const [name, transitions] of transitionsByState) {\n (built.get(name) as State)._initTransitions(\n INTERNAL_CONSTRUCTION_KEY,\n transitions,\n );\n }\n\n return built;\n }\n\n private validateOrphans(\n states: Map<string, StateInterface>,\n initialName: string,\n ): void {\n const reachable = new Set<string>();\n const queue: string[] = [initialName];\n while (queue.length > 0) {\n const name = queue.shift()!;\n if (reachable.has(name)) continue;\n reachable.add(name);\n const s = states.get(name)!;\n for (const t of s.getTransitions()) {\n queue.push(t.getTargetState().getName());\n }\n }\n const orphans: string[] = [];\n for (const name of states.keys()) {\n if (!reachable.has(name)) orphans.push(name);\n }\n if (orphans.length > 0) {\n throw new GraphValidationError(\n \"orphanState\",\n `Process \"${this.processName}\" has unreachable states: ${orphans.map((n) => `\"${n}\"`).join(\", \")}`,\n { processName: this.processName, orphanStates: orphans },\n );\n }\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\n/** One of the simultaneously-active transitions that caused the ambiguity. */\nexport interface AmbiguousTransitionCandidate {\n targetStateName: string;\n eventName: string | null;\n conditionName: string | null;\n weight: number;\n}\n\nexport class AmbiguousTransitionError extends FinitaError {\n readonly code = \"ambiguousTransition\";\n readonly activeCount: number;\n /** The competing transitions — what you need to resolve the ambiguity. */\n readonly candidates: readonly Readonly<AmbiguousTransitionCandidate>[];\n\n constructor(\n activeCount: number,\n candidates: Iterable<AmbiguousTransitionCandidate> = [],\n ) {\n const list = Array.from(candidates, (c) => Object.freeze({ ...c }));\n const detail =\n list.length > 0\n ? ` Candidates: ${list.map(describeCandidate).join(\"; \")}.`\n : \"\";\n super(\n `More than one transition is active! (active count: ${activeCount})${detail}`,\n );\n this.name = \"AmbiguousTransitionError\";\n this.activeCount = activeCount;\n this.candidates = Object.freeze(list);\n }\n}\n\nfunction describeCandidate(candidate: AmbiguousTransitionCandidate): string {\n const parts = [`-> \"${candidate.targetStateName}\"`];\n parts.push(\n candidate.eventName === null\n ? \"on <automatic>\"\n : `on event \"${candidate.eventName}\"`,\n );\n if (candidate.conditionName !== null) {\n parts.push(`if ${candidate.conditionName}`);\n }\n parts.push(`weight ${candidate.weight}`);\n return parts.join(\" \");\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { AmbiguousTransitionError } from \"../error/AmbiguousTransitionError.js\";\n\nexport class OneOrNoneActiveTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n const arr = Array.from(transitions);\n switch (arr.length) {\n case 0:\n return null;\n case 1:\n return arr[0];\n default:\n throw new AmbiguousTransitionError(\n arr.length,\n arr.map((transition) => ({\n targetStateName: transition.getTargetState().getName(),\n eventName: transition.getEventName(),\n conditionName: transition.getConditionName(),\n weight: transition.getWeight(),\n })),\n );\n }\n }\n}\n","import type { MutexInterface } from \"../interfaces/MutexInterface.js\";\n\nexport class NullMutex implements MutexInterface {\n private acquired = false;\n\n acquireLock(): boolean {\n this.acquired = true;\n return true;\n }\n\n releaseLock(): boolean {\n this.acquired = false;\n return true;\n }\n\n isAcquired(): boolean {\n return this.acquired;\n }\n\n isLocked(): boolean {\n return false;\n }\n}\n","export interface QueuedOperation {\n /** Event name for triggerEvent operations; null for checkTransitions. */\n eventName: string | null;\n context: Map<string, unknown>;\n /** When set, the op is silently skipped unless the machine is still in this state when the op is dispatched (top of runOperation). */\n ifStateName?: string;\n resolve: () => void;\n reject: (err: unknown) => void;\n}\n\n/**\n * FIFO queue of pending top-level Statemachine operations.\n *\n * Holds the deferred resolvers so that callers' promises can be settled\n * by the engine when their operation runs. Has no side effects beyond\n * push/shift; the Statemachine drives execution.\n */\nexport class OperationQueue {\n private readonly items: QueuedOperation[] = [];\n\n enqueue(op: QueuedOperation): void {\n this.items.push(op);\n }\n\n dequeue(): QueuedOperation | undefined {\n return this.items.shift();\n }\n\n isEmpty(): boolean {\n return this.items.length === 0;\n }\n\n size(): number {\n return this.items.length;\n }\n}\n","import type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport type { EventInterface } from \"../interfaces/EventInterface.js\";\n\nexport class ActiveTransitionFilter {\n static async filter<TSubject = unknown>(\n transitions: Iterable<TransitionInterface<TSubject>>,\n subject: TSubject,\n context: Map<string, unknown>,\n event?: EventInterface,\n /**\n * Optional wrapper run around each individual isActive() evaluation. The\n * Statemachine passes its re-entrancy guard here so that every condition —\n * not just the first — is evaluated with the guard active; without per-item\n * wrapping a re-entrant condition on a later transition would deadlock.\n */\n wrap?: <T>(fn: () => T) => T,\n ): Promise<TransitionInterface<TSubject>[]> {\n const run = wrap ?? (<T>(fn: () => T): T => fn());\n const active: TransitionInterface<TSubject>[] = [];\n for (const transition of transitions) {\n if (await run(() => transition.isActive(subject, context, event))) {\n active.push(transition);\n }\n }\n return active;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class WrongEventForStateError extends FinitaError {\n readonly code = \"wrongEventForState\";\n readonly stateName: string;\n readonly eventName: string;\n\n constructor(stateName: string, eventName: string) {\n super(`Current state \"${stateName}\" doesn't have event \"${eventName}\"`);\n this.name = \"WrongEventForStateError\";\n this.stateName = stateName;\n this.eventName = eventName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class LockCanNotBeAcquiredError extends FinitaError {\n readonly code = \"lockCanNotBeAcquired\";\n\n constructor(message = \"Lock can not be acquired!\") {\n super(message);\n this.name = \"LockCanNotBeAcquiredError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\n/**\n * The mutex reported a failed release by returning false, as\n * LockAdapterInterface specifies (e.g. a PostgreSQL advisory unlock that\n * returns false, or a Redis DEL that removed nothing).\n *\n * The lock must be assumed to still be held: the engine surfaces this so a\n * failed release can never be mistaken for a successful one, which would let\n * every later operation piggyback on — and never release — a stuck lock.\n */\nexport class LockCanNotBeReleasedError extends FinitaError {\n readonly code = \"lockCanNotBeReleased\";\n\n constructor(\n message = \"Lock can not be released! releaseLock() returned false; the lock may still be held.\",\n ) {\n super(message);\n this.name = \"LockCanNotBeReleasedError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class AutomaticTransitionCycleError extends FinitaError {\n readonly code = \"automaticTransitionCycle\";\n readonly stateName: string;\n readonly hopLimit: number;\n\n constructor(stateName: string, hopLimit: number) {\n super(\n `Automatic transitions exceeded ${hopLimit} hops without reaching a quiescent state ` +\n `(last target: \"${stateName}\") — the graph is likely looping forever. ` +\n `Raise maxAutomaticHops if the loop is legitimate and bounded. ` +\n `Transitions committed before this error are NOT rolled back.`,\n );\n this.name = \"AutomaticTransitionCycleError\";\n this.stateName = stateName;\n this.hopLimit = hopLimit;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ReentrancyError extends FinitaError {\n readonly code = \"reentrancy\";\n\n constructor(operation: string) {\n super(\n `${operation} was called from inside an observer or condition of the same Statemachine. ` +\n `Awaiting it would deadlock: the machine runs one operation at a time and the runner ` +\n `is blocked on your callback. Where applicable, use the EnqueueContext passed to ` +\n `after-observers to chain events instead; from other callbacks, defer the call out of ` +\n `the synchronous path, e.g. queueMicrotask(() => sm.triggerEvent(...)).`,\n );\n this.name = \"ReentrancyError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class QueueLimitExceededError extends FinitaError {\n readonly code = \"queueLimitExceeded\";\n\n constructor(limit: number, eventName: string | null) {\n super(\n `${eventName === null ? \"checkTransitions()\" : `triggerEvent(\"${eventName}\")`} rejected: ` +\n `the operation queue already holds ${limit} pending operation(s) (maxQueueLength = ${limit}).`,\n );\n this.name = \"QueueLimitExceededError\";\n }\n}\n","import type { StatemachineInterface } from \"./interfaces/StatemachineInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { ProcessInterface } from \"./interfaces/ProcessInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { MutexInterface } from \"./interfaces/MutexInterface.js\";\nimport type { TransitionSelectorInterface } from \"./interfaces/TransitionSelectorInterface.js\";\nimport type { BeforeTransitionObserver } from \"./interfaces/BeforeTransitionObserverInterface.js\";\nimport type {\n AfterTransitionObserver,\n EnqueueContext,\n} from \"./interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"./interfaces/TransitionFrameInterface.js\";\nimport type { StatemachineOptions } from \"./interfaces/StatemachineOptions.js\";\nimport { OneOrNoneActiveTransition } from \"./selector/OneOrNoneActiveTransition.js\";\nimport { NullMutex } from \"./mutex/NullMutex.js\";\nimport { OperationQueue } from \"./internal/OperationQueue.js\";\nimport type { QueuedOperation } from \"./internal/OperationQueue.js\";\nimport { ActiveTransitionFilter } from \"./filter/ActiveTransitionFilter.js\";\nimport { WrongEventForStateError } from \"./error/WrongEventForStateError.js\";\nimport { LockCanNotBeAcquiredError } from \"./error/LockCanNotBeAcquiredError.js\";\nimport { LockCanNotBeReleasedError } from \"./error/LockCanNotBeReleasedError.js\";\nimport { AutomaticTransitionCycleError } from \"./error/AutomaticTransitionCycleError.js\";\nimport { ReentrancyError } from \"./error/ReentrancyError.js\";\nimport { QueueLimitExceededError } from \"./error/QueueLimitExceededError.js\";\n\nexport class Statemachine<\n TSubject = unknown,\n> implements StatemachineInterface<TSubject> {\n private readonly subject: TSubject;\n private readonly process: ProcessInterface;\n private readonly transitionSelector: TransitionSelectorInterface<TSubject>;\n private readonly mutex: MutexInterface;\n\n private currentState: StateInterface;\n private lastState: StateInterface | null = null;\n\n private autoreleaseLock: boolean;\n private readonly maxAutomaticHops: number;\n private readonly maxQueueLength: number;\n\n private readonly queue = new OperationQueue();\n private running = false;\n private idleWaiters: Array<() => void> = [];\n private inSyncCallback = false;\n\n private readonly beforeObservers: BeforeTransitionObserver<TSubject>[] = [];\n private readonly afterObservers: AfterTransitionObserver<TSubject>[] = [];\n\n private readonly onChainedOperationError?: (\n error: unknown,\n info: { eventName: string },\n ) => void;\n private readonly onReleaseError?: (error: unknown) => void;\n\n constructor(\n subject: TSubject,\n process: ProcessInterface,\n options: StatemachineOptions<TSubject> = {},\n ) {\n this.subject = subject;\n this.process = process;\n this.currentState =\n options.initialStateName !== undefined\n ? process.getState(options.initialStateName)\n : process.getInitialState();\n this.transitionSelector =\n options.transitionSelector ?? new OneOrNoneActiveTransition<TSubject>();\n this.mutex = options.mutex ?? new NullMutex();\n this.autoreleaseLock = options.autoreleaseLock ?? true;\n const hops = options.maxAutomaticHops ?? 100;\n if (!Number.isInteger(hops) || hops < 1) {\n throw new RangeError(\n `maxAutomaticHops must be a positive integer; got ${String(options.maxAutomaticHops)}`,\n );\n }\n this.maxAutomaticHops = hops;\n const maxQueue = options.maxQueueLength ?? Infinity;\n if (\n maxQueue !== Infinity &&\n (!Number.isInteger(maxQueue) || maxQueue < 1)\n ) {\n throw new RangeError(\n `maxQueueLength must be a positive integer; got ${String(options.maxQueueLength)}`,\n );\n }\n this.maxQueueLength = maxQueue;\n this.onChainedOperationError = options.onChainedOperationError;\n this.onReleaseError = options.onReleaseError;\n }\n\n // --- public getters ---\n\n getCurrentState(): StateInterface {\n return this.currentState;\n }\n\n getLastState(): StateInterface | null {\n return this.lastState;\n }\n\n getSubject(): TSubject {\n return this.subject;\n }\n\n getProcess(): ProcessInterface {\n return this.process;\n }\n\n // --- public observer attach/detach ---\n\n attachBefore(observer: BeforeTransitionObserver<TSubject>): void {\n if (this.beforeObservers.includes(observer)) return;\n this.beforeObservers.push(observer);\n }\n\n detachBefore(observer: BeforeTransitionObserver<TSubject>): void {\n const idx = this.beforeObservers.indexOf(observer);\n if (idx >= 0) this.beforeObservers.splice(idx, 1);\n }\n\n /** Snapshot — detaching later does not change an already-returned list,\n * and mutating it does not change the machine's registrations. */\n getBeforeObservers(): Iterable<BeforeTransitionObserver<TSubject>> {\n return [...this.beforeObservers];\n }\n\n attachAfter(observer: AfterTransitionObserver<TSubject>): void {\n if (this.afterObservers.includes(observer)) return;\n this.afterObservers.push(observer);\n }\n\n detachAfter(observer: AfterTransitionObserver<TSubject>): void {\n const idx = this.afterObservers.indexOf(observer);\n if (idx >= 0) this.afterObservers.splice(idx, 1);\n }\n\n /** Snapshot — see getBeforeObservers. */\n getAfterObservers(): Iterable<AfterTransitionObserver<TSubject>> {\n return [...this.afterObservers];\n }\n\n // --- public locking ---\n\n async acquireLock(): Promise<boolean> {\n return this.mutex.acquireLock();\n }\n\n /**\n * Releases the mutex. A failed release — whether the mutex throws or\n * returns false — is reported to the onReleaseError hook; it is not thrown,\n * so manual lock management keeps its existing control flow. Inspect\n * isLockAcquired() (or the hook) to learn whether the lock was actually\n * freed.\n */\n async releaseLock(): Promise<void> {\n await this.releaseMutex();\n }\n\n isLockAcquired(): boolean {\n return this.mutex.isAcquired();\n }\n\n isAutoreleaseLock(): boolean {\n return this.autoreleaseLock;\n }\n\n setAutoreleaseLock(autorelease: boolean): void {\n this.autoreleaseLock = autorelease;\n }\n\n // --- public top-level operations ---\n\n triggerEvent(name: string, context?: Map<string, unknown>): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.assertNotReentrant(`triggerEvent(\"${name}\")`);\n this.enqueueOperation(name, context, resolve, reject);\n });\n }\n\n checkTransitions(context?: Map<string, unknown>): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.assertNotReentrant(\"checkTransitions()\");\n this.enqueueOperation(null, context, resolve, reject);\n });\n }\n\n /**\n * Resolves once the operation queue is empty and the runner is idle —\n * i.e. every operation enqueued so far, including operations chained via\n * EnqueueContext.enqueue(), has completed. Resolves immediately if the\n * machine is already idle. Note this is a quiescence point, not a\n * receipt: work scheduled later (e.g. from a timer) starts a new drain.\n *\n * Like triggerEvent/checkTransitions, this may not be called from inside an\n * observer or condition of the same machine: the machine cannot reach idle\n * while the runner is blocked on that very callback, so awaiting it there\n * always deadlocks.\n */\n whenIdle(): Promise<void> {\n this.assertNotReentrant(\"whenIdle()\");\n if (!this.running && this.queue.isEmpty()) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleWaiters.push(resolve);\n });\n }\n\n /** Runs fn with the re-entrancy flag set for its SYNCHRONOUS portion only:\n * the flag is cleared as soon as fn returns (before any promise it returned\n * is awaited), so concurrent external callers are never affected. This\n * catches triggerEvent/checkTransitions calls made before a callback's first\n * await; calls made after a prior await are not detectable without\n * AsyncLocalStorage (Node-only) and will still deadlock — a documented gap. */\n private guardSync<T>(fn: () => T): T {\n this.inSyncCallback = true;\n try {\n return fn();\n } finally {\n this.inSyncCallback = false;\n }\n }\n\n private assertNotReentrant(operation: string): void {\n if (this.inSyncCallback) {\n throw new ReentrancyError(operation);\n }\n }\n\n /** Single entry point to the operation queue — every enqueue kicks the runner. */\n private enqueueOperation(\n eventName: string | null,\n context: Map<string, unknown> | undefined,\n resolve: () => void,\n reject: (err: unknown) => void,\n ifStateName?: string,\n ): void {\n if (this.queue.size() >= this.maxQueueLength) {\n throw new QueueLimitExceededError(this.maxQueueLength, eventName);\n }\n this.queue.enqueue({\n eventName,\n context: context ?? new Map(),\n ifStateName,\n resolve,\n reject,\n });\n void this.runIfIdle();\n }\n\n // --- internal runner ---\n\n private async runIfIdle(): Promise<void> {\n if (this.running) return;\n this.running = true;\n try {\n while (!this.queue.isEmpty()) {\n const op = this.queue.dequeue()!;\n await this.runOperation(op);\n }\n } finally {\n this.running = false;\n // The drain loop only exits when the queue is empty, but guard anyway:\n // waiters must never be released while work is pending.\n if (this.queue.isEmpty() && this.idleWaiters.length > 0) {\n const waiters = this.idleWaiters;\n this.idleWaiters = [];\n for (const waiter of waiters) waiter();\n }\n }\n }\n\n private async runOperation(op: QueuedOperation): Promise<void> {\n if (\n op.ifStateName !== undefined &&\n this.currentState.getName() !== op.ifStateName\n ) {\n // Stale chained op — the machine moved on before it was dequeued.\n op.resolve();\n return;\n }\n\n // If the caller has already acquired the mutex (e.g. manual lock\n // management with autoreleaseLock: false), don't reacquire — many\n // mutex implementations (database advisory locks, redis SET NX, etc.)\n // are not idempotent and will fail on the second acquire. We only\n // release in this method if we acquired in this method.\n //\n // The caller's promise settles only AFTER the release completes, so\n // `await sm.triggerEvent(...)` guarantees the lock is free again.\n let acquiredHere = false;\n let failure: { err: unknown } | null = null;\n try {\n if (!this.mutex.isAcquired()) {\n if (!(await this.mutex.acquireLock())) {\n throw new LockCanNotBeAcquiredError(\"Lock can not be acquired!\");\n }\n acquiredHere = true;\n }\n\n const event =\n op.eventName !== null ? this.resolveEvent(op.eventName) : null;\n\n await this.processOperation(event, op.context);\n } catch (err) {\n failure = { err };\n } finally {\n if (acquiredHere && this.autoreleaseLock) {\n const releaseFailure = await this.releaseMutex();\n // A release failure must not mask an operation error, but when the\n // operation succeeded the caller must learn the lock may still be\n // held — otherwise every later operation silently piggybacks on\n // (and never releases) the stuck lock.\n if (releaseFailure && !failure) failure = releaseFailure;\n }\n }\n if (failure) {\n op.reject(failure.err);\n } else {\n op.resolve();\n }\n }\n\n /**\n * Releases the mutex, normalizing its two failure modes into one result: a\n * thrown error, and a false return — the failure signal MutexInterface /\n * LockAdapterInterface define (a PostgreSQL advisory unlock that returns\n * false, a Redis DEL that removed nothing). A false return means the lock\n * may still be held, so it must never be mistaken for a successful release.\n *\n * Every failure is surfaced through the diagnostic hook — when the\n * operation also failed, the rejection carries the operation error and this\n * hook is the only place the release error appears.\n *\n * @returns null on success, or the failure wrapped for the caller to raise.\n */\n private async releaseMutex(): Promise<{ err: unknown } | null> {\n let failure: { err: unknown } | null = null;\n try {\n if (!(await this.mutex.releaseLock())) {\n failure = { err: new LockCanNotBeReleasedError() };\n }\n } catch (err) {\n failure = { err };\n }\n if (failure) {\n try {\n this.onReleaseError?.(failure.err);\n } catch {\n /* a throwing hook must not mask engine errors */\n }\n }\n return failure;\n }\n\n private resolveEvent(name: string): EventInterface {\n if (!this.currentState.hasEvent(name)) {\n throw new WrongEventForStateError(this.currentState.getName(), name);\n }\n return this.currentState.getEvent(name);\n }\n\n /**\n * Drive transitions starting from the current state, following automatic\n * transitions until quiescent. The first iteration may use the supplied\n * event; subsequent iterations are automatic.\n */\n private async processOperation(\n initialEvent: EventInterface | null,\n context: Map<string, unknown>,\n ): Promise<void> {\n let event = initialEvent;\n let automaticHops = 0;\n\n // Fire event-attached observers (imperative commands attached via\n // event.attach()) when the user-supplied event is resolved, regardless\n // of whether a transition fires. Runs once per triggerEvent call —\n // automatic transitions in the iteration loop have event=null and don't\n // re-trigger this dispatch.\n if (event) {\n const userEvent = event; // const capture for the closure (event is a mutable let)\n // Dispatch event-attached observers individually so each observer's\n // synchronous portion runs under the re-entrancy guard. Calling\n // invoke()/notify() wholesale would guard only the FIRST observer: the\n // notify loop awaits between observers, and guardSync clears the flag the\n // moment the first observer's update() yields. Iterate a snapshot so an\n // observer that detaches during dispatch can't shift the live set.\n const invokeArgs: readonly unknown[] = [this.subject, context];\n for (const observer of [...userEvent.getObservers()]) {\n await this.guardSync(() => observer.update(userEvent, invokeArgs));\n }\n }\n\n while (true) {\n const transitions = this.currentState.getTransitions();\n // Pass the guard per-transition: filter() awaits each isActive() call in\n // sequence, so a single guardSync around the whole call would protect\n // only the first condition. Wrapping each evaluation keeps a re-entrant\n // condition on a LATER transition detectable instead of deadlocking.\n const active = await ActiveTransitionFilter.filter(\n transitions,\n this.subject,\n context,\n event ?? undefined,\n (fn) => this.guardSync(fn),\n );\n const selected = this.guardSync(() =>\n this.transitionSelector.selectTransition(active),\n );\n\n if (!selected) {\n return;\n }\n\n const target = selected.getTargetState();\n\n if (selected.getEventName() === null) {\n automaticHops += 1;\n if (automaticHops > this.maxAutomaticHops) {\n throw new AutomaticTransitionCycleError(\n target.getName(),\n this.maxAutomaticHops,\n );\n }\n }\n\n if (this.currentState !== target) {\n const frame: TransitionFrame<TSubject> = Object.freeze({\n subject: this.subject,\n fromState: this.currentState,\n toState: target,\n transition: selected,\n event,\n condition: selected.getCondition(),\n context: this.readonlyContext(context),\n timestamp: Date.now(),\n machineName: this.process.getName(),\n });\n\n // Before phase — first observer to throw aborts. Iterate a snapshot\n // so observers that detach (themselves or others) during notify\n // can't shift the live array under the iterator.\n for (const observer of [...this.beforeObservers]) {\n await this.guardSync(() => observer.notify(frame));\n }\n\n // Commit.\n this.lastState = this.currentState;\n this.currentState = target;\n\n // After phase — collect errors, notify all, then rethrow.\n const enqueueCtx: EnqueueContext = {\n enqueue: (chainedEventName, chainedCtx, ifStateName) => {\n this.enqueueOperation(\n chainedEventName,\n chainedCtx,\n () => {\n /* chained ops are not awaited by the original caller */\n },\n (err) => {\n // Chained errors do not propagate to the original caller;\n // surface them through the optional sink instead. The sink\n // must never throw into the drain loop.\n try {\n this.onChainedOperationError?.(err, {\n eventName: chainedEventName,\n });\n } catch {\n /* swallow hook failures */\n }\n },\n ifStateName,\n );\n },\n };\n\n const errors: unknown[] = [];\n for (const observer of [...this.afterObservers]) {\n try {\n await this.guardSync(() => observer.notify(frame, enqueueCtx));\n } catch (err) {\n errors.push(err);\n }\n }\n if (errors.length === 1) {\n throw errors[0];\n }\n if (errors.length > 1) {\n throw new AggregateError(\n errors,\n `${errors.length} after-transition observer(s) threw`,\n );\n }\n }\n\n // Auto-follow-on: continue with no event.\n event = null;\n }\n }\n\n private readonlyContext(\n ctx: Map<string, unknown>,\n ): ReadonlyMap<string, unknown> {\n // Wrap to discourage mutation. We don't deep-freeze the values themselves —\n // keys removed from the wrapper map don't affect the underlying ctx, so\n // a thin wrapper suffices.\n return new Map(ctx);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport class Tautology implements ConditionInterface {\n private readonly name: string;\n\n constructor(name = \"Tautology\") {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(_subject: unknown, _context: Map<string, unknown>): boolean {\n return true;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport class Contradiction implements ConditionInterface {\n private readonly name: string;\n\n constructor(name = \"Contradiction\") {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(_subject: unknown, _context: Map<string, unknown>): boolean {\n return false;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\n\nexport type ConditionCallbackFn<TSubject = unknown> = (\n subject: TSubject,\n context: Map<string, unknown>,\n) => MaybePromise<boolean>;\n\nexport class CallbackCondition<\n TSubject = unknown,\n> implements ConditionInterface<TSubject> {\n private readonly name: string;\n private readonly callable: ConditionCallbackFn<TSubject>;\n\n constructor(name: string, callable: ConditionCallbackFn<TSubject>) {\n this.name = name;\n this.callable = callable;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean> {\n return this.callable(subject, context);\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class InvalidSubjectError extends FinitaError {\n readonly code = \"invalidSubject\";\n readonly expectedInterface: string;\n readonly missingMembers: readonly string[];\n\n constructor(expectedInterface: string, missingMembers: Iterable<string>) {\n const members = Array.from(missingMembers);\n const memberList = members.map((m) => `\"${m}\"`).join(\", \");\n super(\n `Subject does not satisfy ${expectedInterface}; missing member(s): ${memberList || \"(unknown)\"}`,\n );\n this.name = \"InvalidSubjectError\";\n this.expectedInterface = expectedInterface;\n this.missingMembers = Object.freeze([...members]);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { LastStateHasChangedDateInterface } from \"../interfaces/LastStateHasChangedDateInterface.js\";\nimport { InvalidSubjectError } from \"../error/InvalidSubjectError.js\";\n\nfunction isLastStateHasChangedDate(\n obj: unknown,\n): obj is LastStateHasChangedDateInterface {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getLastStateHasChangedDate\" in obj &&\n typeof (obj as LastStateHasChangedDateInterface)\n .getLastStateHasChangedDate === \"function\"\n );\n}\n\nexport class Timeout implements ConditionInterface {\n private readonly timeoutMs: number;\n private readonly label: string;\n\n constructor(timeoutMs: number, label?: string) {\n this.timeoutMs = timeoutMs;\n this.label = label ?? `${timeoutMs}ms`;\n }\n\n getName(): string {\n return `Timeout: ${this.label}`;\n }\n\n protected getLastStateHasChangedDate(\n subject: unknown,\n _context: Map<string, unknown>,\n ): Date {\n if (isLastStateHasChangedDate(subject)) {\n return subject.getLastStateHasChangedDate();\n }\n throw new InvalidSubjectError(\"LastStateHasChangedDateInterface\", [\n \"getLastStateHasChangedDate\",\n ]);\n }\n\n checkCondition(subject: unknown, context: Map<string, unknown>): boolean {\n return (\n this.getLastStateHasChangedDate(subject, context).getTime() +\n this.timeoutMs <=\n Date.now()\n );\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport abstract class CompositeCondition<\n TSubject = unknown,\n> implements ConditionInterface<TSubject> {\n protected readonly conditions: ConditionInterface<TSubject>[] = [];\n private readonly joinWord: string;\n\n constructor(joinWord: string, condition: ConditionInterface<TSubject>) {\n this.joinWord = joinWord;\n this.conditions.push(condition);\n }\n\n protected addCondition(condition: ConditionInterface<TSubject>): this {\n this.conditions.push(condition);\n return this;\n }\n\n getName(): string {\n const names = this.conditions.map((c) => c.getName());\n return `(${names.join(` ${this.joinWord} `)})`;\n }\n\n abstract checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): Promise<boolean>;\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport { CompositeCondition } from \"./CompositeCondition.js\";\n\nexport class AndComposite<\n TSubject = unknown,\n> extends CompositeCondition<TSubject> {\n constructor(condition: ConditionInterface<TSubject>) {\n super(\"and\", condition);\n }\n\n addAnd(condition: ConditionInterface<TSubject>): this {\n return this.addCondition(condition);\n }\n\n async checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): Promise<boolean> {\n for (const condition of this.conditions) {\n if (!(await condition.checkCondition(subject, context))) {\n return false;\n }\n }\n return true;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport { CompositeCondition } from \"./CompositeCondition.js\";\n\nexport class OrComposite<\n TSubject = unknown,\n> extends CompositeCondition<TSubject> {\n constructor(condition: ConditionInterface<TSubject>) {\n super(\"or\", condition);\n }\n\n addOr(condition: ConditionInterface<TSubject>): this {\n return this.addCondition(condition);\n }\n\n async checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): Promise<boolean> {\n for (const condition of this.conditions) {\n if (await condition.checkCondition(subject, context)) {\n return true;\n }\n }\n return false;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport class Not<TSubject = unknown> implements ConditionInterface<TSubject> {\n private readonly condition: ConditionInterface<TSubject>;\n\n constructor(condition: ConditionInterface<TSubject>) {\n this.condition = condition;\n }\n\n getName(): string {\n return `not ( ${this.condition.getName()} )`;\n }\n\n async checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): Promise<boolean> {\n return !(await this.condition.checkCondition(subject, context));\n }\n}\n","import type { Observer, ObservableSubject } from \"../interfaces/Observer.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\n\n/**\n * Observer for Event observers (commands attached to specific events).\n *\n * This is not a Statemachine observer. To run a callback after every\n * transition, implement AfterTransitionObserver directly or compose a small\n * wrapper.\n */\nexport class CallbackObserver implements Observer {\n private readonly callback: (...args: unknown[]) => MaybePromise<void>;\n\n constructor(callback: (...args: unknown[]) => MaybePromise<void>) {\n this.callback = callback;\n }\n\n update(\n subject: ObservableSubject,\n args?: readonly unknown[],\n ): MaybePromise<void> {\n // Event-invoked path: args is the invoke argument list — spread it into\n // the callback. An empty list means the event was invoked with zero args,\n // so the callback receives zero args (matching pre-v3.1 behavior).\n if (args !== undefined) {\n return this.callback(...args);\n }\n // Direct/legacy path: update(subject) with no args — pass the subject.\n return this.callback(subject);\n }\n}\n","import type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\nimport type { StatefulInterface } from \"../interfaces/StatefulInterface.js\";\n\nexport class StatefulStatusChanger<\n TSubject extends StatefulInterface,\n> implements AfterTransitionObserver<TSubject> {\n private readonly subject: TSubject | null;\n\n /**\n * @param subject Optional explicit subject to write to. When omitted\n * (recommended), the observer writes to frame.subject — the subject of\n * whichever machine fired the transition — so a single instance can be\n * shared safely across every machine a Factory creates.\n */\n constructor(subject?: TSubject) {\n // null sentinel lets `?? frame.subject` in notify() distinguish\n // \"no subject pinned\" from any valid subject value.\n this.subject = subject ?? null;\n }\n\n notify(frame: TransitionFrame<TSubject>): void {\n (this.subject ?? frame.subject).setCurrentStateName(\n frame.toState.getName(),\n );\n }\n}\n","import type {\n AfterTransitionObserver,\n EnqueueContext,\n} from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\n\n/**\n * After-transition observer that fires an event named DEFAULT_EVENT_NAME\n * (or a custom name) when entering any state that has that event declared.\n *\n * The chained event is *enqueued*, not invoked inline: it runs as its own\n * top-level operation after the current operation completes. Other\n * after-observers registered after OnEnterObserver still see the original\n * frame, not the chained one.\n *\n * The chained event only fires if the machine is still in the entered state\n * when the queue drains — states passed through transiently by automatic\n * transitions do not fire onEnter.\n */\nexport class OnEnterObserver<\n TSubject = unknown,\n> implements AfterTransitionObserver<TSubject> {\n static readonly DEFAULT_EVENT_NAME = \"onEnter\";\n\n private readonly eventName: string;\n\n constructor(eventName: string = OnEnterObserver.DEFAULT_EVENT_NAME) {\n this.eventName = eventName;\n }\n\n notify(frame: TransitionFrame<TSubject>, ctx: EnqueueContext): void {\n if (frame.toState.hasEvent(this.eventName)) {\n ctx.enqueue(\n this.eventName,\n new Map(frame.context),\n frame.toState.getName(),\n );\n }\n }\n}\n","import type { Named } from \"../interfaces/Named.js\";\n\nexport function isNamed(obj: unknown): obj is Named {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getName\" in obj &&\n typeof (obj as Named).getName === \"function\"\n );\n}\n\n/** Render any value by its getName() when present, String(value) otherwise. */\nexport function nameOrString(obj: unknown): string {\n if (isNamed(obj)) return obj.getName();\n return String(obj);\n}\n","import type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\nimport type { LoggerInterface } from \"../interfaces/LoggerInterface.js\";\nimport { nameOrString } from \"../util/index.js\";\n\nexport class TransitionLogger<\n TSubject = unknown,\n> implements AfterTransitionObserver<TSubject> {\n private readonly logger: LoggerInterface;\n private readonly loggerLevel: string;\n\n constructor(logger: LoggerInterface, loggerLevel = \"info\") {\n this.logger = logger;\n this.loggerLevel = loggerLevel;\n }\n\n notify(frame: TransitionFrame<TSubject>): void {\n let message = \"Transition\";\n\n message += ` from \"${nameOrString(frame.fromState)}\" to \"${nameOrString(frame.toState)}\"`;\n\n const eventName = frame.event ? frame.event.getName() : null;\n const conditionName = frame.condition ? frame.condition.getName() : null;\n if (eventName || conditionName) {\n message += \" with\";\n if (eventName) message += ` event \"${eventName}\"`;\n if (conditionName) message += ` condition \"${conditionName}\"`;\n }\n\n // frame.subject is intentionally omitted from the log context — callers\n // who need subject identity attach a custom observer that closes over it.\n this.logger.log(this.loggerLevel, message, {\n fromState: frame.fromState,\n toState: frame.toState,\n event: frame.event,\n transition: frame.transition,\n machineName: frame.machineName,\n });\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\nexport class FilterStateByEvent {\n static *filter(\n states: Iterable<StateInterface>,\n eventName: string,\n ): Iterable<StateInterface> {\n for (const state of states) {\n if (state.hasEvent(eventName)) {\n yield state;\n }\n }\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\n/**\n * Filters states that have at least one automatic transition (no event name).\n */\nexport class FilterStateByTransition {\n static *filter(states: Iterable<StateInterface>): Iterable<StateInterface> {\n for (const state of states) {\n for (const transition of state.getTransitions()) {\n if (!transition.getEventName()) {\n yield state;\n break;\n }\n }\n }\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\nexport class FilterStateByFinalState {\n static *filter(states: Iterable<StateInterface>): Iterable<StateInterface> {\n for (const state of states) {\n let count = 0;\n for (const _transition of state.getTransitions()) {\n count++;\n break;\n }\n if (count === 0) {\n yield state;\n }\n }\n }\n}\n","import type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\n\nexport class FilterTransitionByEvent {\n static *filter(\n transitions: Iterable<TransitionInterface>,\n eventName: string,\n ): Iterable<TransitionInterface> {\n for (const transition of transitions) {\n if (transition.getEventName() === eventName) {\n yield transition;\n }\n }\n }\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { OneOrNoneActiveTransition } from \"./OneOrNoneActiveTransition.js\";\n\nexport class ScoreTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n private readonly innerSelector: TransitionSelectorInterface<TSubject>;\n\n constructor(innerSelector?: TransitionSelectorInterface<TSubject>) {\n this.innerSelector =\n innerSelector ?? new OneOrNoneActiveTransition<TSubject>();\n }\n\n protected calculateScore(transition: TransitionInterface<TSubject>): number {\n let score = 0;\n if (transition.getEventName()) {\n score += 2;\n }\n if (transition.getConditionName()) {\n score += 1;\n }\n return score;\n }\n\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n let bestTransitions: TransitionInterface<TSubject>[] = [];\n let bestScore = -1;\n for (const transition of transitions) {\n const score = this.calculateScore(transition);\n if (score > bestScore) {\n bestScore = score;\n bestTransitions = [transition];\n } else if (score === bestScore) {\n bestTransitions.push(transition);\n }\n }\n return this.innerSelector.selectTransition(bestTransitions);\n }\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { OneOrNoneActiveTransition } from \"./OneOrNoneActiveTransition.js\";\n\nexport class WeightTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n private readonly innerSelector: TransitionSelectorInterface<TSubject>;\n private readonly epsilon: number;\n\n constructor(\n innerSelector?: TransitionSelectorInterface<TSubject>,\n epsilon = 0.001,\n ) {\n if (!Number.isFinite(epsilon) || epsilon <= 0) {\n throw new RangeError(\n `WeightTransition epsilon must be a finite number greater than 0; got ${String(epsilon)}`,\n );\n }\n this.innerSelector =\n innerSelector ?? new OneOrNoneActiveTransition<TSubject>();\n this.epsilon = epsilon;\n }\n\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n const all = Array.from(transitions);\n let maxWeight = Number.NEGATIVE_INFINITY;\n for (const transition of all) {\n const weight = transition.getWeight();\n if (!Number.isFinite(weight)) {\n throw new RangeError(\n `WeightTransition: transition weights must be finite numbers; got ${String(weight)}`,\n );\n }\n if (weight > maxWeight) maxWeight = weight;\n }\n const best = all.filter(\n (transition) => maxWeight - transition.getWeight() < this.epsilon,\n );\n return this.innerSelector.selectTransition(best);\n }\n}\n","import type { MutexInterface } from \"../interfaces/MutexInterface.js\";\nimport type { LockAdapterInterface } from \"../interfaces/LockAdapterInterface.js\";\n\nexport class LockAdapterMutex implements MutexInterface {\n private readonly lockAdapter: LockAdapterInterface;\n private readonly resourceName: string;\n private acquired = false;\n private pendingAcquire: Promise<boolean> | null = null;\n\n constructor(lockAdapter: LockAdapterInterface, resourceName: string) {\n this.lockAdapter = lockAdapter;\n this.resourceName = resourceName;\n }\n\n /**\n * Overlapping calls share one underlying acquire: the `acquired` flag is\n * only set after the adapter resolves, so without this both callers would\n * pass the check and acquire twice on a non-idempotent adapter (database\n * advisory locks, redis SET NX). The pending promise is cleared once it\n * settles, so a failed acquire can still be retried.\n */\n async acquireLock(): Promise<boolean> {\n if (this.acquired) {\n return true;\n }\n this.pendingAcquire ??= (async () => {\n try {\n this.acquired = await this.lockAdapter.acquireLock(this.resourceName);\n return this.acquired;\n } finally {\n this.pendingAcquire = null;\n }\n })();\n return this.pendingAcquire;\n }\n\n async releaseLock(): Promise<boolean> {\n if (this.acquired) {\n const result = await this.lockAdapter.releaseLock(this.resourceName);\n if (result) {\n this.acquired = false;\n }\n return result;\n }\n return false;\n }\n\n isAcquired(): boolean {\n return this.acquired;\n }\n\n async isLocked(): Promise<boolean> {\n return this.lockAdapter.isLocked(this.resourceName);\n }\n}\n","import type { MutexFactoryInterface } from \"../interfaces/MutexFactoryInterface.js\";\nimport type { MutexInterface } from \"../interfaces/MutexInterface.js\";\nimport type { LockAdapterInterface } from \"../interfaces/LockAdapterInterface.js\";\nimport { LockAdapterMutex } from \"./LockAdapterMutex.js\";\n\nexport type StringConverter<TSubject = unknown> = (subject: TSubject) => string;\n\nexport class MutexFactory<\n TSubject = unknown,\n> implements MutexFactoryInterface<TSubject> {\n private readonly lockAdapter: LockAdapterInterface;\n private readonly stringConverter: StringConverter<TSubject>;\n\n constructor(\n lockAdapter: LockAdapterInterface,\n stringConverter: StringConverter<TSubject>,\n ) {\n this.lockAdapter = lockAdapter;\n this.stringConverter = stringConverter;\n }\n\n createMutex(subject: TSubject): MutexInterface {\n return new LockAdapterMutex(\n this.lockAdapter,\n this.stringConverter(subject),\n );\n }\n}\n","import type { FactoryInterface } from \"../interfaces/FactoryInterface.js\";\nimport type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { StateNameDetectorInterface } from \"../interfaces/StateNameDetectorInterface.js\";\nimport type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { MutexFactoryInterface } from \"../interfaces/MutexFactoryInterface.js\";\nimport type { StatemachineInterface } from \"../interfaces/StatemachineInterface.js\";\nimport type { BeforeTransitionObserver } from \"../interfaces/BeforeTransitionObserverInterface.js\";\nimport type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { StatemachineOptions } from \"../interfaces/StatemachineOptions.js\";\nimport { Statemachine } from \"../Statemachine.js\";\n\n/**\n * Engine options applied to every machine the factory creates.\n *\n * `initialStateName`, `mutex` and `transitionSelector` are excluded: the\n * factory derives them per subject from the state-name detector, the mutex\n * factory and setTransitionSelector, so a template value could only\n * contradict them.\n */\nexport type FactoryStatemachineOptions<TSubject = unknown> = Omit<\n StatemachineOptions<TSubject>,\n \"initialStateName\" | \"mutex\" | \"transitionSelector\"\n>;\n\nexport class Factory<TSubject = unknown> implements FactoryInterface<TSubject> {\n private readonly processDetector: ProcessDetectorInterface<TSubject>;\n private readonly stateNameDetector: StateNameDetectorInterface<TSubject> | null;\n private readonly beforeObservers: Set<BeforeTransitionObserver<TSubject>> =\n new Set();\n private readonly afterObservers: Set<AfterTransitionObserver<TSubject>> =\n new Set();\n private transitionSelector: TransitionSelectorInterface<TSubject> | null =\n null;\n private mutexFactory: MutexFactoryInterface<TSubject> | null = null;\n private readonly options: FactoryStatemachineOptions<TSubject>;\n\n /**\n * @param options Engine options applied to every machine this factory\n * creates — back-pressure (maxQueueLength), the automatic-hop bound, lock\n * autorelease, and the onChainedOperationError / onReleaseError diagnostic\n * sinks. Without them, factory-created machines would silently run on\n * defaults, which is precisely where those sinks matter most.\n */\n constructor(\n processDetector: ProcessDetectorInterface<TSubject>,\n stateNameDetector?: StateNameDetectorInterface<TSubject> | null,\n options: FactoryStatemachineOptions<TSubject> = {},\n ) {\n this.processDetector = processDetector;\n this.stateNameDetector = stateNameDetector ?? null;\n this.options = { ...options };\n }\n\n setMutexFactory(factory: MutexFactoryInterface<TSubject> | null): void {\n this.mutexFactory = factory;\n }\n\n setTransitionSelector(selector: TransitionSelectorInterface<TSubject>): void {\n this.transitionSelector = selector;\n }\n\n attachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void {\n this.beforeObservers.add(observer);\n }\n\n detachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void {\n this.beforeObservers.delete(observer);\n }\n\n attachAfterObserver(observer: AfterTransitionObserver<TSubject>): void {\n this.afterObservers.add(observer);\n }\n\n detachAfterObserver(observer: AfterTransitionObserver<TSubject>): void {\n this.afterObservers.delete(observer);\n }\n\n async createStatemachine(\n subject: TSubject,\n ): Promise<StatemachineInterface<TSubject>> {\n const process = this.processDetector.detectProcess(subject);\n const stateName = this.stateNameDetector\n ? this.stateNameDetector.detectCurrentStateName(subject)\n : undefined;\n const mutex = this.mutexFactory\n ? await this.mutexFactory.createMutex(subject)\n : undefined;\n\n const sm = new Statemachine<TSubject>(subject, process, {\n ...this.options,\n initialStateName: stateName ?? undefined,\n transitionSelector: this.transitionSelector ?? undefined,\n mutex: mutex ?? undefined,\n });\n\n for (const o of this.beforeObservers) sm.attachBefore(o);\n for (const o of this.afterObservers) sm.attachAfter(o);\n\n return sm;\n }\n}\n","import type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { ProcessInterface } from \"../interfaces/ProcessInterface.js\";\n\nexport class SingleProcessDetector<\n TSubject = unknown,\n> implements ProcessDetectorInterface<TSubject> {\n private readonly process: ProcessInterface;\n\n constructor(process: ProcessInterface) {\n this.process = process;\n }\n\n detectProcess(_subject: TSubject): ProcessInterface {\n return this.process;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ProcessNotFoundError extends FinitaError {\n readonly code = \"processNotFound\";\n readonly processName: string;\n readonly availableProcesses: readonly string[];\n\n constructor(processName: string, availableProcesses: Iterable<string>) {\n const list = Array.from(availableProcesses);\n const display =\n list.length > 0 ? list.map((n) => `\"${n}\"`).join(\", \") : \"(none)\";\n super(`Process \"${processName}\" not found. Available: ${display}`);\n this.name = \"ProcessNotFoundError\";\n this.processName = processName;\n this.availableProcesses = Object.freeze([...list]);\n }\n}\n","import type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { ProcessInterface } from \"../interfaces/ProcessInterface.js\";\nimport { ProcessNotFoundError } from \"../error/ProcessNotFoundError.js\";\n\nexport abstract class AbstractNamedProcessDetector<\n TSubject = unknown,\n> implements ProcessDetectorInterface<TSubject> {\n private readonly processes: Map<string, ProcessInterface> = new Map();\n\n protected abstract detectProcessName(subject: TSubject): string;\n\n addProcess(process: ProcessInterface): void {\n this.processes.set(process.getName(), process);\n }\n\n hasProcess(name: string): boolean {\n return this.processes.has(name);\n }\n\n detectProcess(subject: TSubject): ProcessInterface {\n const name = this.detectProcessName(subject);\n const process = this.processes.get(name);\n if (!process) {\n throw new ProcessNotFoundError(name, this.processes.keys());\n }\n return process;\n }\n}\n","import type { StateNameDetectorInterface } from \"../interfaces/StateNameDetectorInterface.js\";\nimport type { StatefulInterface } from \"../interfaces/StatefulInterface.js\";\nimport { InvalidSubjectError } from \"../error/InvalidSubjectError.js\";\n\nfunction isStateful(obj: unknown): obj is StatefulInterface {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getCurrentStateName\" in obj &&\n typeof (obj as StatefulInterface).getCurrentStateName === \"function\"\n );\n}\n\nexport class StatefulStateNameDetector implements StateNameDetectorInterface<StatefulInterface> {\n detectCurrentStateName(subject: StatefulInterface): string | null {\n if (isStateful(subject)) {\n return subject.getCurrentStateName();\n }\n throw new InvalidSubjectError(\"StatefulInterface\", [\"getCurrentStateName\"]);\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport type { StateCollectionInterface } from \"../interfaces/StateCollectionInterface.js\";\nimport { nameOrString } from \"../util/index.js\";\n\nexport interface GraphNode {\n id: string;\n label: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface GraphEdge {\n source: string;\n target: string;\n label: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface Graph {\n nodes: GraphNode[];\n edges: GraphEdge[];\n}\n\nfunction escapeDotString(str: string): string {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction toMermaidId(name: string): string {\n return (\n \"s_\" +\n name.replace(\n /[^a-zA-Z0-9]/g,\n (ch) => `_${ch.charCodeAt(0).toString(16).padStart(4, \"0\")}`,\n )\n );\n}\n\nfunction escapeMermaidLabel(str: string): string {\n return str.replace(/\\\\/g, \"#92;\").replace(/\"/g, \"#quot;\");\n}\n\nexport type GraphDirection = \"TB\" | \"BT\" | \"LR\" | \"RL\";\n\nconst VALID_DIRECTIONS: ReadonlySet<string> = new Set([\"TB\", \"BT\", \"LR\", \"RL\"]);\n\nfunction assertDirection(value: string, optionName: string): void {\n if (!VALID_DIRECTIONS.has(value)) {\n throw new RangeError(\n `${optionName} must be one of \"TB\", \"BT\", \"LR\", \"RL\"; got ${JSON.stringify(value)}`,\n );\n }\n}\n\nexport interface DotOptions {\n rankdir?: GraphDirection;\n}\n\nexport interface MermaidOptions {\n direction?: GraphDirection;\n}\n\nexport class GraphBuilder {\n private readonly nodes: Map<string, GraphNode> = new Map();\n private readonly edges: GraphEdge[] = [];\n private readonly statesWithEdges: Set<string> = new Set();\n\n private getOrCreateNode(state: StateInterface): GraphNode {\n const name = state.getName();\n let node = this.nodes.get(name);\n if (!node) {\n node = { id: name, label: name, metadata: state.getMetadata() };\n this.nodes.set(name, node);\n }\n return node;\n }\n\n protected getTransitionLabel(\n state: StateInterface,\n transition: TransitionInterface,\n ): string {\n const parts: string[] = [];\n const eventName = transition.getEventName();\n if (eventName) {\n parts.push(`E: ${eventName}`);\n if (state.hasEvent(eventName)) {\n const event = state.getEvent(eventName);\n const observerNames: string[] = [];\n for (const observer of event.getObservers()) {\n observerNames.push(nameOrString(observer));\n }\n if (observerNames.length > 0) {\n parts.push(`C: ${observerNames.join(\", \")}`);\n }\n }\n }\n const conditionName = transition.getConditionName();\n if (conditionName) {\n parts.push(`IF: ${conditionName}`);\n }\n parts.push(`W: ${transition.getWeight()}`);\n return parts.join(\"\\n\");\n }\n\n addState(state: StateInterface): void {\n this.getOrCreateNode(state);\n const name = state.getName();\n if (this.statesWithEdges.has(name)) return;\n this.statesWithEdges.add(name);\n for (const transition of state.getTransitions()) {\n const sourceNode = this.getOrCreateNode(state);\n const targetNode = this.getOrCreateNode(transition.getTargetState());\n const label = this.getTransitionLabel(state, transition);\n const metadata: Record<string, unknown> = {};\n const eventName = transition.getEventName();\n if (eventName && state.hasEvent(eventName)) {\n Object.assign(metadata, state.getEvent(eventName).getMetadata());\n }\n this.edges.push({\n source: sourceNode.id,\n target: targetNode.id,\n label,\n metadata,\n });\n }\n }\n\n addStates(states: Iterable<StateInterface>): void {\n for (const state of states) {\n this.addState(state);\n }\n }\n\n addStateCollection(stateCollection: StateCollectionInterface): void {\n this.addStates(stateCollection.getStates());\n }\n\n getGraph(): Graph {\n return {\n nodes: Array.from(this.nodes.values()),\n edges: [...this.edges],\n };\n }\n\n toDot(options?: DotOptions): string {\n const graph = this.getGraph();\n const rankdir = options?.rankdir ?? \"LR\";\n assertDirection(rankdir, \"rankdir\");\n const lines: string[] = [];\n lines.push(\"digraph {\");\n lines.push(` rankdir=${rankdir};`);\n for (const node of graph.nodes) {\n const label = escapeDotString(node.label);\n lines.push(` \"${label}\" [label=\"${label}\"];`);\n }\n for (const edge of graph.edges) {\n const source = escapeDotString(edge.source);\n const target = escapeDotString(edge.target);\n const label = escapeDotString(edge.label);\n lines.push(` \"${source}\" -> \"${target}\" [label=\"${label}\"];`);\n }\n lines.push(\"}\");\n return lines.join(\"\\n\");\n }\n\n toMermaid(options?: MermaidOptions): string {\n const graph = this.getGraph();\n const direction = options?.direction ?? \"LR\";\n assertDirection(direction, \"direction\");\n const lines: string[] = [];\n lines.push(`stateDiagram-v2`);\n lines.push(` direction ${direction}`);\n const declared = new Set<string>();\n for (const node of graph.nodes) {\n const id = toMermaidId(node.id);\n if (!declared.has(id)) {\n declared.add(id);\n const label = escapeMermaidLabel(node.label);\n lines.push(` ${id} : \"${label}\"`);\n }\n }\n for (const edge of graph.edges) {\n const source = toMermaidId(edge.source);\n const target = toMermaidId(edge.target);\n const label = escapeMermaidLabel(edge.label.replace(/\\n/g, \" / \"));\n lines.push(` ${source} --> ${target} : ${label}`);\n }\n return lines.join(\"\\n\");\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/Event.ts","../src/internal/InternalConstruction.ts","../src/error/FinitaError.ts","../src/error/StateNotFoundError.ts","../src/StateCollection.ts","../src/Process.ts","../src/error/StateEventNotFoundError.ts","../src/State.ts","../src/Transition.ts","../src/error/DuplicateStateError.ts","../src/error/ProcessFinalizedError.ts","../src/error/GraphValidationError.ts","../src/error/DuplicateTransitionError.ts","../src/ProcessBuilder.ts","../src/error/AmbiguousTransitionError.ts","../src/selector/OneOrNoneActiveTransition.ts","../src/mutex/NullMutex.ts","../src/internal/OperationQueue.ts","../src/filter/ActiveTransitionFilter.ts","../src/error/WrongEventForStateError.ts","../src/error/LockCanNotBeAcquiredError.ts","../src/error/LockCanNotBeReleasedError.ts","../src/error/LockOwnershipUncertainError.ts","../src/error/AutomaticTransitionCycleError.ts","../src/error/ReentrancyError.ts","../src/error/QueueLimitExceededError.ts","../src/util/index.ts","../src/Statemachine.ts","../src/condition/Tautology.ts","../src/condition/Contradiction.ts","../src/condition/CallbackCondition.ts","../src/error/InvalidSubjectError.ts","../src/condition/Timeout.ts","../src/condition/CompositeCondition.ts","../src/condition/AndComposite.ts","../src/condition/OrComposite.ts","../src/condition/Not.ts","../src/observer/CallbackObserver.ts","../src/observer/StatefulStatusChanger.ts","../src/observer/OnEnterObserver.ts","../src/observer/TransitionLogger.ts","../src/filter/FilterStateByEvent.ts","../src/filter/FilterStateByTransition.ts","../src/filter/FilterStateByFinalState.ts","../src/filter/FilterTransitionByEvent.ts","../src/selector/ScoreTransition.ts","../src/selector/WeightTransition.ts","../src/mutex/LockAdapterMutex.ts","../src/mutex/MutexFactory.ts","../src/factory/Factory.ts","../src/factory/SingleProcessDetector.ts","../src/error/ProcessNotFoundError.ts","../src/factory/AbstractNamedProcessDetector.ts","../src/factory/StatefulStateNameDetector.ts","../src/graph/GraphBuilder.ts"],"sourcesContent":["import type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { Observer } from \"./interfaces/Observer.js\";\n\nexport class Event implements EventInterface {\n private readonly name: string;\n private readonly observers: Set<Observer> = new Set();\n private readonly metadata: Map<string, unknown> = new Map();\n constructor(name: string) {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n /**\n * @deprecated Always returns []. Invoke args are now passed directly to\n * Observer.update — reading them from the event was racy when one\n * Process served multiple Statemachines.\n */\n getInvokeArgs(): unknown[] {\n return [];\n }\n\n async invoke(...args: unknown[]): Promise<void> {\n await this.notify(args);\n }\n\n attach(observer: Observer): void {\n this.observers.add(observer);\n }\n\n detach(observer: Observer): void {\n this.observers.delete(observer);\n }\n\n async notify(args?: readonly unknown[]): Promise<void> {\n // Forward args as-is. invoke() always supplies a concrete array (empty when\n // called with no args), whereas a bare notify() passes undefined — letting\n // observers distinguish \"invoked with zero args\" ([]) from \"no args\n // supplied\" (undefined), e.g. CallbackObserver's legacy update(subject).\n for (const observer of [...this.observers]) {\n await observer.update(this, args);\n }\n }\n\n /** Snapshot — detaching later does not change an already-returned list,\n * and mutating it does not change the event's registrations. */\n getObservers(): Iterable<Observer> {\n return [...this.observers];\n }\n\n getMetadata(): Record<string, unknown> {\n return Object.fromEntries(this.metadata);\n }\n\n getMetadataValue(key: string): unknown {\n return this.metadata.get(key);\n }\n\n setMetadataValue(key: string, value: unknown): void {\n this.metadata.set(key, value);\n }\n\n hasMetadataValue(key: string): boolean {\n return this.metadata.has(key);\n }\n\n deleteMetadataValue(key: string): void {\n this.metadata.delete(key);\n }\n}\n","/**\n * Symbol-based construction guard for State / Transition / Process.\n *\n * These classes' constructors require this symbol as the first argument.\n * Only ProcessBuilder imports it, ensuring only the builder can instantiate\n * the graph. User code receives an opaque type error if it tries to call\n * `new State(...)` directly.\n */\nexport const INTERNAL_CONSTRUCTION_KEY: unique symbol = Symbol(\n \"@camcima/finita/InternalConstruction\",\n);\nexport type InternalConstructionKey = typeof INTERNAL_CONSTRUCTION_KEY;\n","export abstract class FinitaError extends Error {\n abstract readonly code: string;\n\n constructor(message?: string, options?: ErrorOptions) {\n super(message, options);\n if (new.target === FinitaError) {\n throw new TypeError(\n \"FinitaError is abstract and cannot be instantiated directly\",\n );\n }\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class StateNotFoundError extends FinitaError {\n readonly code = \"stateNotFound\";\n readonly stateName: string;\n readonly availableStates: readonly string[];\n\n constructor(stateName: string, availableStates: Iterable<string>) {\n const list = Array.from(availableStates);\n const display =\n list.length > 0 ? list.map((n) => `\"${n}\"`).join(\", \") : \"(none)\";\n super(`State \"${stateName}\" not found. Available: ${display}`);\n this.name = \"StateNotFoundError\";\n this.stateName = stateName;\n this.availableStates = Object.freeze([...list]);\n }\n}\n","import type { StateCollectionInterface } from \"./interfaces/StateCollectionInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport { StateNotFoundError } from \"./error/StateNotFoundError.js\";\n\nexport class StateCollection implements StateCollectionInterface {\n private readonly states: ReadonlyMap<string, StateInterface>;\n\n constructor(states: Iterable<StateInterface>) {\n const map = new Map<string, StateInterface>();\n for (const s of states) {\n map.set(s.getName(), s);\n }\n this.states = map;\n }\n\n getStates(): Iterable<StateInterface> {\n return this.states.values();\n }\n\n getState(name: string): StateInterface {\n const s = this.states.get(name);\n if (!s) {\n throw new StateNotFoundError(name, this.states.keys());\n }\n return s;\n }\n\n hasState(name: string): boolean {\n return this.states.has(name);\n }\n}\n","import type { ProcessInterface } from \"./interfaces/ProcessInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { StateCollection } from \"./StateCollection.js\";\n\nexport class Process implements ProcessInterface {\n private readonly name: string;\n private readonly initialState: StateInterface;\n private readonly states: StateCollection;\n\n constructor(\n key: InternalConstructionKey,\n name: string,\n initialState: StateInterface,\n states: Iterable<StateInterface>,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"Process is not user-constructible; use ProcessBuilder.\");\n }\n this.name = name;\n this.initialState = initialState;\n this.states = new StateCollection(states);\n Object.freeze(this);\n }\n\n getName(): string {\n return this.name;\n }\n\n getInitialState(): StateInterface {\n return this.initialState;\n }\n\n getStates(): Iterable<StateInterface> {\n return this.states.getStates();\n }\n\n getState(name: string): StateInterface {\n return this.states.getState(name);\n }\n\n hasState(name: string): boolean {\n return this.states.hasState(name);\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class StateEventNotFoundError extends FinitaError {\n readonly code = \"stateEventNotFound\";\n readonly stateName: string;\n readonly eventName: string;\n\n constructor(stateName: string, eventName: string) {\n super(`State \"${stateName}\" has no event \"${eventName}\"`);\n this.name = \"StateEventNotFoundError\";\n this.stateName = stateName;\n this.eventName = eventName;\n }\n}\n","import type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { Event } from \"./Event.js\";\nimport { StateEventNotFoundError } from \"./error/StateEventNotFoundError.js\";\n\nexport class State implements StateInterface {\n private readonly name: string;\n private _transitions: ReadonlySet<TransitionInterface> | null = null;\n private readonly events: ReadonlyMap<string, EventInterface>;\n private readonly metadata: ReadonlyMap<string, unknown>;\n\n constructor(\n key: InternalConstructionKey,\n name: string,\n eventNames: Iterable<string>,\n metadata: ReadonlyMap<string, unknown>,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"State is not user-constructible; use ProcessBuilder.\");\n }\n this.name = name;\n const events = new Map<string, EventInterface>();\n for (const en of eventNames) {\n events.set(en, new Event(en));\n }\n this.events = events;\n this.metadata = new Map(metadata);\n }\n\n /**\n * Internal: populate transitions after State construction.\n * May only be called once and only with the construction key.\n * Used by ProcessBuilder to break the cycle: State must exist before\n * Transitions can target it, but State needs its transitions to be useful.\n */\n _initTransitions(\n key: InternalConstructionKey,\n transitions: Iterable<TransitionInterface>,\n ): void {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\"_initTransitions is internal\");\n }\n if (this._transitions !== null) {\n throw new Error(`State \"${this.name}\" transitions already set`);\n }\n this._transitions = new Set(transitions);\n Object.freeze(this);\n }\n\n getName(): string {\n return this.name;\n }\n\n /** Snapshot — the graph is shared by every machine built from the\n * process, so callers must never receive the collection itself. */\n getTransitions(): Iterable<TransitionInterface> {\n if (this._transitions === null) {\n return [];\n }\n return Array.from(this._transitions);\n }\n\n getEventNames(): string[] {\n return Array.from(this.events.keys());\n }\n\n hasEvent(name: string): boolean {\n return this.events.has(name);\n }\n\n getEvent(name: string): EventInterface {\n const event = this.events.get(name);\n if (!event) {\n throw new StateEventNotFoundError(this.name, name);\n }\n return event;\n }\n\n getMetadata(): Record<string, unknown> {\n return Object.fromEntries(this.metadata);\n }\n\n getMetadataValue(key: string): unknown {\n return this.metadata.get(key);\n }\n\n hasMetadataValue(key: string): boolean {\n return this.metadata.has(key);\n }\n}\n","import type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { ConditionInterface } from \"./interfaces/ConditionInterface.js\";\nimport type { InternalConstructionKey } from \"./internal/InternalConstruction.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\n\nexport class Transition<\n TSubject = unknown,\n> implements TransitionInterface<TSubject> {\n private readonly targetState: StateInterface;\n private readonly eventName: string | null;\n private readonly condition: ConditionInterface<TSubject> | null;\n private readonly weight: number;\n\n constructor(\n key: InternalConstructionKey,\n targetState: StateInterface,\n eventName: string | null,\n condition: ConditionInterface<TSubject> | null,\n weight: number,\n ) {\n if (key !== INTERNAL_CONSTRUCTION_KEY) {\n throw new Error(\n \"Transition is not user-constructible; use ProcessBuilder.\",\n );\n }\n this.targetState = targetState;\n this.eventName = eventName;\n this.condition = condition;\n this.weight = weight;\n Object.freeze(this);\n }\n\n getTargetState(): StateInterface {\n return this.targetState;\n }\n\n getEventName(): string | null {\n return this.eventName;\n }\n\n getConditionName(): string | null {\n return this.condition ? this.condition.getName() : null;\n }\n\n getCondition(): ConditionInterface<TSubject> | null {\n return this.condition;\n }\n\n async isActive(\n subject: TSubject,\n context: Map<string, unknown>,\n event?: EventInterface,\n ): Promise<boolean> {\n let active: boolean;\n if (event) {\n active = event.getName() === this.eventName;\n } else {\n active = this.eventName === null;\n }\n if (this.condition && active) {\n active = await this.condition.checkCondition(subject, context);\n }\n return active;\n }\n\n getWeight(): number {\n return this.weight;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class DuplicateStateError extends FinitaError {\n readonly code = \"duplicateState\";\n readonly stateName: string;\n\n constructor(stateName: string) {\n super(\n `There is already a different state with name \"${stateName}\" in this collection`,\n );\n this.name = \"DuplicateStateError\";\n this.stateName = stateName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ProcessFinalizedError extends FinitaError {\n readonly code = \"processFinalized\";\n readonly processName: string;\n\n constructor(processName: string) {\n super(\n `Process \"${processName}\" has already been built; ProcessBuilder.build() may only be called once`,\n );\n this.name = \"ProcessFinalizedError\";\n this.processName = processName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport type GraphValidationCode =\n | \"unknownTarget\"\n | \"unknownSource\"\n | \"missingInitialState\"\n | \"multipleInitialStates\"\n | \"invalidStateName\"\n | \"invalidEventName\"\n | \"invalidConditionName\"\n | \"invalidTransitionWeight\"\n | \"orphanState\";\n\nexport class GraphValidationError extends FinitaError {\n readonly code: GraphValidationCode;\n readonly details: Readonly<Record<string, unknown>>;\n\n constructor(\n code: GraphValidationCode,\n message: string,\n details: Record<string, unknown> = {},\n ) {\n super(`[${code}] ${message}`);\n this.name = \"GraphValidationError\";\n this.code = code;\n this.details = Object.freeze({ ...details });\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport interface DuplicateTransitionConflict {\n fromState: string;\n toState: string;\n eventName: string | null;\n existingConditionName: string | null;\n newConditionName: string | null;\n existingWeight?: number;\n newWeight?: number;\n}\n\nexport class DuplicateTransitionError extends FinitaError {\n readonly code = \"duplicateTransition\";\n readonly conflict: Readonly<DuplicateTransitionConflict>;\n\n constructor(conflict: DuplicateTransitionConflict) {\n const eventLabel = conflict.eventName ?? \"<automatic>\";\n const existing = conflict.existingConditionName ?? \"<no condition>\";\n const incoming = conflict.newConditionName ?? \"<no condition>\";\n const weightInfo =\n conflict.existingWeight !== undefined &&\n conflict.newWeight !== undefined &&\n conflict.existingWeight !== conflict.newWeight\n ? `, existing weight ${conflict.existingWeight} vs new weight ${conflict.newWeight}`\n : \"\";\n super(\n `Conflicting transition declarations from \"${conflict.fromState}\" to \"${conflict.toState}\" on event \"${eventLabel}\": existing condition \"${existing}\" vs new condition \"${incoming}\"${weightInfo}`,\n );\n this.name = \"DuplicateTransitionError\";\n this.conflict = Object.freeze({ ...conflict });\n }\n}\n","import type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"./interfaces/TransitionInterface.js\";\nimport type { ConditionInterface } from \"./interfaces/ConditionInterface.js\";\nimport { INTERNAL_CONSTRUCTION_KEY } from \"./internal/InternalConstruction.js\";\nimport { Process } from \"./Process.js\";\nimport { State } from \"./State.js\";\nimport { Transition } from \"./Transition.js\";\nimport { DuplicateStateError } from \"./error/DuplicateStateError.js\";\nimport { ProcessFinalizedError } from \"./error/ProcessFinalizedError.js\";\nimport { GraphValidationError } from \"./error/GraphValidationError.js\";\nimport { DuplicateTransitionError } from \"./error/DuplicateTransitionError.js\";\n\ninterface StateSpec {\n name: string;\n initial: boolean;\n metadata: Map<string, unknown>;\n}\n\ninterface TransitionSpec<TSubject = unknown> {\n fromState: string;\n toState: string;\n eventName: string | null;\n condition: ConditionInterface<TSubject> | null;\n weight: number;\n}\n\nexport interface AddStateOptions {\n initial?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AddTransitionOptions<TSubject = unknown> {\n event?: string;\n condition?: ConditionInterface<TSubject>;\n weight?: number;\n}\n\nexport interface BuildOptions {\n /**\n * When true, orphan/unreachable states cause GraphValidationError.\n * When false (default), orphan states are silently allowed.\n */\n strictOrphans?: boolean;\n}\n\nexport class ProcessBuilder<TSubject = unknown> {\n private readonly processName: string;\n private readonly stateSpecs: Map<string, StateSpec> = new Map();\n private readonly transitionSpecs: TransitionSpec<TSubject>[] = [];\n private built = false;\n\n constructor(processName: string) {\n this.processName = processName;\n }\n\n addState(name: string, options: AddStateOptions = {}): this {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n if (this.stateSpecs.has(name)) {\n throw new DuplicateStateError(name);\n }\n this.validateName(\"invalidStateName\", name, `addState(\"${name}\")`, {\n stateName: name,\n });\n this.stateSpecs.set(name, {\n name,\n initial: options.initial === true,\n metadata: new Map(Object.entries(options.metadata ?? {})),\n });\n return this;\n }\n\n addTransition(\n fromState: string,\n toState: string,\n options: AddTransitionOptions<TSubject> = {},\n ): this {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n let eventName: string | null = null;\n if (options.event !== undefined) {\n this.validateName(\n \"invalidEventName\",\n options.event,\n `addTransition called with an invalid event name from \"${fromState}\" to \"${toState}\"`,\n { fromState, toState, eventName: options.event },\n );\n eventName = options.event;\n }\n if (options.condition) {\n const conditionName = options.condition.getName();\n this.validateName(\n \"invalidConditionName\",\n conditionName,\n `addTransition called with an invalid condition name from \"${fromState}\" to \"${toState}\"`,\n { fromState, toState, conditionName },\n );\n }\n const weight = options.weight ?? 1;\n if (!Number.isFinite(weight)) {\n throw new GraphValidationError(\n \"invalidTransitionWeight\",\n `addTransition from \"${fromState}\" to \"${toState}\": weight must be a finite number; got ${String(weight)}`,\n { fromState, toState, eventName, weight },\n );\n }\n this.transitionSpecs.push({\n fromState,\n toState,\n eventName,\n condition: options.condition ?? null,\n weight,\n });\n return this;\n }\n\n build(options: BuildOptions = {}): Process {\n if (this.built) {\n throw new ProcessFinalizedError(this.processName);\n }\n\n this.validateInitialState();\n this.validateTransitionEndpoints();\n this.validateNoConflictingDuplicates();\n\n const initialName = this.findInitialStateName();\n const eventNamesByState = this.collectEventNamesByState();\n\n // Two-phase construction: create all State instances first (with no\n // transitions), then build Transitions targeting those instances and attach\n // them. Identity holds by construction for any graph topology.\n const finalStates = this.buildAllStates(eventNamesByState);\n\n if (options.strictOrphans) {\n this.validateOrphans(finalStates, initialName);\n }\n\n const initialState = finalStates.get(initialName)!;\n this.built = true;\n return new Process(\n INTERNAL_CONSTRUCTION_KEY,\n this.processName,\n initialState,\n finalStates.values(),\n );\n }\n\n // --- private helpers ---\n\n /** One name rule for every named entity: non-empty, no leading/trailing whitespace. */\n private validateName(\n code: \"invalidStateName\" | \"invalidEventName\" | \"invalidConditionName\",\n raw: string,\n description: string,\n details: Record<string, unknown>,\n ): void {\n if (raw.trim() === \"\" || raw !== raw.trim()) {\n throw new GraphValidationError(\n code,\n `${description}: name ${JSON.stringify(raw)} is empty or whitespace-padded`,\n details,\n );\n }\n }\n\n private validateInitialState(): void {\n const initials = Array.from(this.stateSpecs.values()).filter(\n (s) => s.initial,\n );\n if (initials.length === 0) {\n throw new GraphValidationError(\n \"missingInitialState\",\n `Process \"${this.processName}\" has no state declared with { initial: true }`,\n { processName: this.processName },\n );\n }\n if (initials.length > 1) {\n throw new GraphValidationError(\n \"multipleInitialStates\",\n `Process \"${this.processName}\" declares multiple initial states: ${initials.map((s) => `\"${s.name}\"`).join(\", \")}`,\n {\n processName: this.processName,\n initialStates: initials.map((s) => s.name),\n },\n );\n }\n }\n\n private findInitialStateName(): string {\n return Array.from(this.stateSpecs.values()).find((s) => s.initial)!.name;\n }\n\n private validateTransitionEndpoints(): void {\n for (const t of this.transitionSpecs) {\n if (!this.stateSpecs.has(t.fromState)) {\n throw new GraphValidationError(\n \"unknownSource\",\n `Transition source state \"${t.fromState}\" was not declared with addState`,\n {\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n },\n );\n }\n if (!this.stateSpecs.has(t.toState)) {\n throw new GraphValidationError(\n \"unknownTarget\",\n `Transition target state \"${t.toState}\" was not declared with addState`,\n {\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n },\n );\n }\n }\n }\n\n /** Transition identity: (fromState, eventName, toState). Used by both the\n * conflict check and the build-time dedup — keep them in lockstep.\n * Encoded as a JSON tuple, not a delimiter join: names may contain any\n * character, so no delimiter can keep distinct tuples distinct. */\n private static transitionKey(t: {\n fromState: string;\n eventName: string | null;\n toState: string;\n }): string {\n return JSON.stringify([t.fromState, t.eventName, t.toState]);\n }\n\n private validateNoConflictingDuplicates(): void {\n // Identity key: (fromState, eventName, toState).\n // Same condition reference AND same weight → dedup (idempotent\n // re-declaration). Anything else → conflict. We cannot introspect\n // callable bodies to compare logic, so different object identity is\n // treated as different logic.\n const seen = new Map<string, TransitionSpec<TSubject>>();\n for (const t of this.transitionSpecs) {\n const key = ProcessBuilder.transitionKey(t);\n const existing = seen.get(key);\n if (!existing) {\n seen.set(key, t);\n continue;\n }\n if (existing.condition !== t.condition || existing.weight !== t.weight) {\n throw new DuplicateTransitionError({\n fromState: t.fromState,\n toState: t.toState,\n eventName: t.eventName,\n existingConditionName: existing.condition\n ? existing.condition.getName()\n : null,\n newConditionName: t.condition ? t.condition.getName() : null,\n existingWeight: existing.weight,\n newWeight: t.weight,\n });\n }\n // Same identity, same condition instance, same weight → dedup silently.\n }\n }\n\n private collectEventNamesByState(): Map<string, string[]> {\n const out = new Map<string, Set<string>>();\n for (const t of this.transitionSpecs) {\n if (t.eventName === null) continue;\n let bucket = out.get(t.fromState);\n if (!bucket) {\n bucket = new Set();\n out.set(t.fromState, bucket);\n }\n bucket.add(t.eventName);\n }\n return new Map(\n Array.from(out.entries()).map(([k, v]) => [k, Array.from(v)]),\n );\n }\n\n /**\n * Two-phase construction:\n * Phase 1 — create all final State instances with no transitions.\n * Phase 2 — build Transitions targeting the Phase-1 States, then attach\n * them via State._initTransitions.\n *\n * Because every Transition is created after every State exists, target\n * identity holds by construction for any graph topology (acyclic, cyclic,\n * self-loop).\n */\n private buildAllStates(\n eventNamesByState: Map<string, string[]>,\n ): Map<string, StateInterface> {\n const built = new Map<string, StateInterface>();\n\n // Phase 1: create all States with no transitions.\n for (const spec of this.stateSpecs.values()) {\n built.set(\n spec.name,\n new State(\n INTERNAL_CONSTRUCTION_KEY,\n spec.name,\n eventNamesByState.get(spec.name) ?? [],\n spec.metadata,\n ),\n );\n }\n\n // Phase 2: build Transitions targeting Phase-1 States, then attach.\n // validateNoConflictingDuplicates already guaranteed that specs sharing\n // the identity key are exact duplicates, so a plain key dedup suffices.\n const dedupSeen = new Set<string>();\n const transitionsByState = new Map<\n string,\n TransitionInterface<TSubject>[]\n >();\n for (const spec of this.stateSpecs.values()) {\n transitionsByState.set(spec.name, []);\n }\n for (const tSpec of this.transitionSpecs) {\n const dedupKey = ProcessBuilder.transitionKey(tSpec);\n if (dedupSeen.has(dedupKey)) continue;\n dedupSeen.add(dedupKey);\n const targetState = built.get(tSpec.toState)!;\n const transition = new Transition<TSubject>(\n INTERNAL_CONSTRUCTION_KEY,\n targetState,\n tSpec.eventName,\n tSpec.condition,\n tSpec.weight,\n );\n transitionsByState.get(tSpec.fromState)!.push(transition);\n }\n\n for (const [name, transitions] of transitionsByState) {\n (built.get(name) as State)._initTransitions(\n INTERNAL_CONSTRUCTION_KEY,\n transitions,\n );\n }\n\n return built;\n }\n\n private validateOrphans(\n states: Map<string, StateInterface>,\n initialName: string,\n ): void {\n const reachable = new Set<string>();\n const queue: string[] = [initialName];\n while (queue.length > 0) {\n const name = queue.shift()!;\n if (reachable.has(name)) continue;\n reachable.add(name);\n const s = states.get(name)!;\n for (const t of s.getTransitions()) {\n queue.push(t.getTargetState().getName());\n }\n }\n const orphans: string[] = [];\n for (const name of states.keys()) {\n if (!reachable.has(name)) orphans.push(name);\n }\n if (orphans.length > 0) {\n throw new GraphValidationError(\n \"orphanState\",\n `Process \"${this.processName}\" has unreachable states: ${orphans.map((n) => `\"${n}\"`).join(\", \")}`,\n { processName: this.processName, orphanStates: orphans },\n );\n }\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\n/** One of the simultaneously-active transitions that caused the ambiguity. */\nexport interface AmbiguousTransitionCandidate {\n targetStateName: string;\n eventName: string | null;\n conditionName: string | null;\n weight: number;\n}\n\nexport class AmbiguousTransitionError extends FinitaError {\n readonly code = \"ambiguousTransition\";\n readonly activeCount: number;\n /** The competing transitions — what you need to resolve the ambiguity. */\n readonly candidates: readonly Readonly<AmbiguousTransitionCandidate>[];\n\n constructor(\n activeCount: number,\n candidates: Iterable<AmbiguousTransitionCandidate> = [],\n ) {\n const list = Array.from(candidates, (c) => Object.freeze({ ...c }));\n const detail =\n list.length > 0\n ? ` Candidates: ${list.map(describeCandidate).join(\"; \")}.`\n : \"\";\n super(\n `More than one transition is active! (active count: ${activeCount})${detail}`,\n );\n this.name = \"AmbiguousTransitionError\";\n this.activeCount = activeCount;\n this.candidates = Object.freeze(list);\n }\n}\n\nfunction describeCandidate(candidate: AmbiguousTransitionCandidate): string {\n const parts = [`-> \"${candidate.targetStateName}\"`];\n parts.push(\n candidate.eventName === null\n ? \"on <automatic>\"\n : `on event \"${candidate.eventName}\"`,\n );\n if (candidate.conditionName !== null) {\n parts.push(`if ${candidate.conditionName}`);\n }\n parts.push(`weight ${candidate.weight}`);\n return parts.join(\" \");\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { AmbiguousTransitionError } from \"../error/AmbiguousTransitionError.js\";\n\nexport class OneOrNoneActiveTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n const arr = Array.from(transitions);\n switch (arr.length) {\n case 0:\n return null;\n case 1:\n return arr[0];\n default:\n throw new AmbiguousTransitionError(\n arr.length,\n arr.map((transition) => ({\n targetStateName: transition.getTargetState().getName(),\n eventName: transition.getEventName(),\n conditionName: transition.getConditionName(),\n weight: transition.getWeight(),\n })),\n );\n }\n }\n}\n","import type { MutexInterface } from \"../interfaces/MutexInterface.js\";\n\nexport class NullMutex implements MutexInterface {\n private acquired = false;\n\n acquireLock(): boolean {\n this.acquired = true;\n return true;\n }\n\n releaseLock(): boolean {\n this.acquired = false;\n return true;\n }\n\n isAcquired(): boolean {\n return this.acquired;\n }\n\n isLocked(): boolean {\n return false;\n }\n}\n","export interface QueuedOperation {\n /** Event name for triggerEvent operations; null for checkTransitions. */\n eventName: string | null;\n context: Map<string, unknown>;\n /** When set, the op is silently skipped unless the machine is still in this state when the op is dispatched (top of runOperation). */\n ifStateName?: string;\n resolve: () => void;\n reject: (err: unknown) => void;\n}\n\n/**\n * FIFO queue of pending top-level Statemachine operations.\n *\n * Holds the deferred resolvers so that callers' promises can be settled\n * by the engine when their operation runs. Has no side effects beyond\n * storage; the Statemachine drives execution.\n *\n * Dequeue advances a head index instead of calling Array.shift(), which is\n * O(n) and made draining a large backlog quadratic. Consumed slots are\n * cleared so operations are not retained, storage resets whenever the queue\n * empties, and a queue that never empties is compacted once the consumed\n * prefix dominates.\n */\nexport class OperationQueue {\n private static readonly COMPACT_THRESHOLD = 1024;\n\n private items: Array<QueuedOperation | undefined> = [];\n private head = 0;\n\n enqueue(op: QueuedOperation): void {\n this.items.push(op);\n }\n\n dequeue(): QueuedOperation | undefined {\n if (this.head >= this.items.length) {\n return undefined;\n }\n const op = this.items[this.head];\n this.items[this.head] = undefined;\n this.head++;\n if (this.head === this.items.length) {\n this.items = [];\n this.head = 0;\n } else if (\n this.head >= OperationQueue.COMPACT_THRESHOLD &&\n this.head * 2 >= this.items.length\n ) {\n this.items = this.items.slice(this.head);\n this.head = 0;\n }\n return op;\n }\n\n isEmpty(): boolean {\n return this.head === this.items.length;\n }\n\n size(): number {\n return this.items.length - this.head;\n }\n}\n","import type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport type { EventInterface } from \"../interfaces/EventInterface.js\";\n\nexport class ActiveTransitionFilter {\n static async filter<TSubject = unknown>(\n transitions: Iterable<TransitionInterface<TSubject>>,\n subject: TSubject,\n context: Map<string, unknown>,\n event?: EventInterface,\n /**\n * Optional wrapper run around each individual isActive() evaluation. The\n * Statemachine passes its re-entrancy guard here so that every condition —\n * not just the first — is evaluated with the guard active; without per-item\n * wrapping a re-entrant condition on a later transition would deadlock.\n */\n wrap?: <T>(fn: () => T) => T,\n ): Promise<TransitionInterface<TSubject>[]> {\n const run = wrap ?? (<T>(fn: () => T): T => fn());\n const active: TransitionInterface<TSubject>[] = [];\n for (const transition of transitions) {\n if (await run(() => transition.isActive(subject, context, event))) {\n active.push(transition);\n }\n }\n return active;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class WrongEventForStateError extends FinitaError {\n readonly code = \"wrongEventForState\";\n readonly stateName: string;\n readonly eventName: string;\n\n constructor(stateName: string, eventName: string) {\n super(`Current state \"${stateName}\" doesn't have event \"${eventName}\"`);\n this.name = \"WrongEventForStateError\";\n this.stateName = stateName;\n this.eventName = eventName;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class LockCanNotBeAcquiredError extends FinitaError {\n readonly code = \"lockCanNotBeAcquired\";\n\n constructor(message = \"Lock can not be acquired!\") {\n super(message);\n this.name = \"LockCanNotBeAcquiredError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\n/**\n * The mutex reported a failed release by returning false, as\n * LockAdapterInterface specifies (e.g. a PostgreSQL advisory unlock that\n * returns false, or a Redis DEL that removed nothing).\n *\n * The lock must be assumed to still be held: the engine surfaces this so a\n * failed release can never be mistaken for a successful one, which would let\n * every later operation piggyback on — and never release — a stuck lock.\n */\nexport class LockCanNotBeReleasedError extends FinitaError {\n readonly code = \"lockCanNotBeReleased\";\n\n constructor(\n message = \"Lock can not be released! releaseLock() returned false; the lock may still be held.\",\n ) {\n super(message);\n this.name = \"LockCanNotBeReleasedError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\n/**\n * A lock release failed earlier, so the machine can no longer tell whether it\n * still holds the lock: the unlock may have taken effect remotely with its\n * reply lost, or may never have happened. Running further operations on the\n * old ownership flag could violate mutual exclusion, so every operation is\n * rejected with this error until a manual Statemachine.releaseLock()\n * succeeds.\n *\n * `cause` carries the release failure. When the release cannot be confirmed\n * — typically because the lock was in fact already freed — discard the\n * machine and build a new one from persisted state.\n */\nexport class LockOwnershipUncertainError extends FinitaError {\n readonly code = \"lockOwnershipUncertain\";\n\n constructor(cause: unknown) {\n super(\n \"Operation rejected: a previous lock release failed, so this machine \" +\n \"cannot tell whether it still holds the lock. Call releaseLock() and \" +\n \"confirm it succeeds, or discard the machine and rebuild it from \" +\n \"persisted state.\",\n { cause },\n );\n this.name = \"LockOwnershipUncertainError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class AutomaticTransitionCycleError extends FinitaError {\n readonly code = \"automaticTransitionCycle\";\n readonly stateName: string;\n readonly hopLimit: number;\n\n constructor(stateName: string, hopLimit: number) {\n super(\n `Automatic transitions exceeded ${hopLimit} hops without reaching a quiescent state ` +\n `(last target: \"${stateName}\") — the graph is likely looping forever. ` +\n `Raise maxAutomaticHops if the loop is legitimate and bounded. ` +\n `Transitions committed before this error are NOT rolled back.`,\n );\n this.name = \"AutomaticTransitionCycleError\";\n this.stateName = stateName;\n this.hopLimit = hopLimit;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ReentrancyError extends FinitaError {\n readonly code = \"reentrancy\";\n\n constructor(operation: string) {\n super(\n `${operation} was called from inside an observer or condition of the same Statemachine. ` +\n `Awaiting it would deadlock: the machine runs one operation at a time and the runner ` +\n `is blocked on your callback. Where applicable, use the EnqueueContext passed to ` +\n `after-observers to chain events instead; from other callbacks, defer the call out of ` +\n `the synchronous path, e.g. queueMicrotask(() => sm.triggerEvent(...)).`,\n );\n this.name = \"ReentrancyError\";\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class QueueLimitExceededError extends FinitaError {\n readonly code = \"queueLimitExceeded\";\n\n constructor(limit: number, eventName: string | null) {\n super(\n `${eventName === null ? \"checkTransitions()\" : `triggerEvent(\"${eventName}\")`} rejected: ` +\n `the operation queue already holds ${limit} pending operation(s) (maxQueueLength = ${limit}).`,\n );\n this.name = \"QueueLimitExceededError\";\n }\n}\n","import type { Named } from \"../interfaces/Named.js\";\n\nexport function isNamed(obj: unknown): obj is Named {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getName\" in obj &&\n typeof (obj as Named).getName === \"function\"\n );\n}\n\n/** Render any value by its getName() when present, String(value) otherwise. */\nexport function nameOrString(obj: unknown): string {\n if (isNamed(obj)) return obj.getName();\n return String(obj);\n}\n\n/**\n * True for any thenable. Callers use it to await a MaybePromise only when it\n * actually is one: awaiting a plain value still yields to the microtask\n * queue, which ends the synchronous window the re-entrancy guard relies on.\n */\nexport function isPromiseLike<T>(value: unknown): value is PromiseLike<T> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof (value as PromiseLike<T>).then === \"function\"\n );\n}\n","import type { StatemachineInterface } from \"./interfaces/StatemachineInterface.js\";\nimport type { StateInterface } from \"./interfaces/StateInterface.js\";\nimport type { ProcessInterface } from \"./interfaces/ProcessInterface.js\";\nimport type { EventInterface } from \"./interfaces/EventInterface.js\";\nimport type { MutexInterface } from \"./interfaces/MutexInterface.js\";\nimport type { TransitionSelectorInterface } from \"./interfaces/TransitionSelectorInterface.js\";\nimport type { BeforeTransitionObserver } from \"./interfaces/BeforeTransitionObserverInterface.js\";\nimport type {\n AfterTransitionObserver,\n EnqueueContext,\n} from \"./interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"./interfaces/TransitionFrameInterface.js\";\nimport type { StatemachineOptions } from \"./interfaces/StatemachineOptions.js\";\nimport { OneOrNoneActiveTransition } from \"./selector/OneOrNoneActiveTransition.js\";\nimport { NullMutex } from \"./mutex/NullMutex.js\";\nimport { OperationQueue } from \"./internal/OperationQueue.js\";\nimport type { QueuedOperation } from \"./internal/OperationQueue.js\";\nimport { ActiveTransitionFilter } from \"./filter/ActiveTransitionFilter.js\";\nimport { WrongEventForStateError } from \"./error/WrongEventForStateError.js\";\nimport { LockCanNotBeAcquiredError } from \"./error/LockCanNotBeAcquiredError.js\";\nimport { LockCanNotBeReleasedError } from \"./error/LockCanNotBeReleasedError.js\";\nimport { LockOwnershipUncertainError } from \"./error/LockOwnershipUncertainError.js\";\nimport { AutomaticTransitionCycleError } from \"./error/AutomaticTransitionCycleError.js\";\nimport { ReentrancyError } from \"./error/ReentrancyError.js\";\nimport { QueueLimitExceededError } from \"./error/QueueLimitExceededError.js\";\nimport { isPromiseLike } from \"./util/index.js\";\n\nexport class Statemachine<\n TSubject = unknown,\n> implements StatemachineInterface<TSubject> {\n private readonly subject: TSubject;\n private readonly process: ProcessInterface;\n private readonly transitionSelector: TransitionSelectorInterface<TSubject>;\n private readonly mutex: MutexInterface;\n\n private currentState: StateInterface;\n private lastState: StateInterface | null = null;\n\n private autoreleaseLock: boolean;\n private readonly maxAutomaticHops: number;\n private readonly maxQueueLength: number;\n\n private readonly queue = new OperationQueue();\n private running = false;\n private idleWaiters: Array<() => void> = [];\n private inSyncCallback = false;\n /** Set when releasing a held lock fails; see LockOwnershipUncertainError. */\n private ownershipUncertainty: { err: unknown } | null = null;\n\n private readonly beforeObservers: BeforeTransitionObserver<TSubject>[] = [];\n private readonly afterObservers: AfterTransitionObserver<TSubject>[] = [];\n\n private readonly onChainedOperationError?: StatemachineOptions<TSubject>[\"onChainedOperationError\"];\n private readonly onReleaseError?: StatemachineOptions<TSubject>[\"onReleaseError\"];\n\n constructor(\n subject: TSubject,\n process: ProcessInterface,\n options: StatemachineOptions<TSubject> = {},\n ) {\n this.subject = subject;\n this.process = process;\n this.currentState =\n options.initialStateName !== undefined\n ? process.getState(options.initialStateName)\n : process.getInitialState();\n this.transitionSelector =\n options.transitionSelector ?? new OneOrNoneActiveTransition<TSubject>();\n this.mutex = options.mutex ?? new NullMutex();\n this.autoreleaseLock = options.autoreleaseLock ?? true;\n const hops = options.maxAutomaticHops ?? 100;\n if (!Number.isInteger(hops) || hops < 1) {\n throw new RangeError(\n `maxAutomaticHops must be a positive integer; got ${String(options.maxAutomaticHops)}`,\n );\n }\n this.maxAutomaticHops = hops;\n const maxQueue = options.maxQueueLength ?? Infinity;\n if (\n maxQueue !== Infinity &&\n (!Number.isInteger(maxQueue) || maxQueue < 1)\n ) {\n throw new RangeError(\n `maxQueueLength must be a positive integer; got ${String(options.maxQueueLength)}`,\n );\n }\n this.maxQueueLength = maxQueue;\n this.onChainedOperationError = options.onChainedOperationError;\n this.onReleaseError = options.onReleaseError;\n }\n\n // --- public getters ---\n\n getCurrentState(): StateInterface {\n return this.currentState;\n }\n\n getLastState(): StateInterface | null {\n return this.lastState;\n }\n\n getSubject(): TSubject {\n return this.subject;\n }\n\n getProcess(): ProcessInterface {\n return this.process;\n }\n\n // --- public observer attach/detach ---\n\n attachBefore(observer: BeforeTransitionObserver<TSubject>): void {\n if (this.beforeObservers.includes(observer)) return;\n this.beforeObservers.push(observer);\n }\n\n detachBefore(observer: BeforeTransitionObserver<TSubject>): void {\n const idx = this.beforeObservers.indexOf(observer);\n if (idx >= 0) this.beforeObservers.splice(idx, 1);\n }\n\n /** Snapshot — detaching later does not change an already-returned list,\n * and mutating it does not change the machine's registrations. */\n getBeforeObservers(): Iterable<BeforeTransitionObserver<TSubject>> {\n return [...this.beforeObservers];\n }\n\n attachAfter(observer: AfterTransitionObserver<TSubject>): void {\n if (this.afterObservers.includes(observer)) return;\n this.afterObservers.push(observer);\n }\n\n detachAfter(observer: AfterTransitionObserver<TSubject>): void {\n const idx = this.afterObservers.indexOf(observer);\n if (idx >= 0) this.afterObservers.splice(idx, 1);\n }\n\n /** Snapshot — see getBeforeObservers. */\n getAfterObservers(): Iterable<AfterTransitionObserver<TSubject>> {\n return [...this.afterObservers];\n }\n\n // --- public locking ---\n\n async acquireLock(): Promise<boolean> {\n return this.mutex.acquireLock();\n }\n\n /**\n * Releases the mutex. A failed release — whether the mutex throws or\n * returns false — is reported to the onReleaseError hook; it is not thrown,\n * so manual lock management keeps its existing control flow. Inspect\n * isLockAcquired() (or the hook) to learn whether the lock was actually\n * freed.\n *\n * A failed release of a held lock makes every later operation reject with\n * LockOwnershipUncertainError; a successful call here is how to recover.\n */\n async releaseLock(): Promise<void> {\n await this.releaseMutex();\n }\n\n isLockAcquired(): boolean {\n return this.mutex.isAcquired();\n }\n\n isAutoreleaseLock(): boolean {\n return this.autoreleaseLock;\n }\n\n setAutoreleaseLock(autorelease: boolean): void {\n this.autoreleaseLock = autorelease;\n }\n\n // --- public top-level operations ---\n\n triggerEvent(name: string, context?: Map<string, unknown>): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.assertNotReentrant(`triggerEvent(\"${name}\")`);\n this.enqueueOperation(name, context, resolve, reject);\n });\n }\n\n checkTransitions(context?: Map<string, unknown>): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.assertNotReentrant(\"checkTransitions()\");\n this.enqueueOperation(null, context, resolve, reject);\n });\n }\n\n /**\n * Resolves once the operation queue is empty and the runner is idle —\n * i.e. every operation enqueued so far, including operations chained via\n * EnqueueContext.enqueue(), has completed. Resolves immediately if the\n * machine is already idle. Note this is a quiescence point, not a\n * receipt: work scheduled later (e.g. from a timer) starts a new drain.\n *\n * Like triggerEvent/checkTransitions, this may not be called from inside an\n * observer or condition of the same machine: the machine cannot reach idle\n * while the runner is blocked on that very callback, so awaiting it there\n * always deadlocks.\n */\n whenIdle(): Promise<void> {\n this.assertNotReentrant(\"whenIdle()\");\n if (!this.running && this.queue.isEmpty()) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.idleWaiters.push(resolve);\n });\n }\n\n /** Runs fn with the re-entrancy flag set for its SYNCHRONOUS portion only:\n * the flag is cleared as soon as fn returns (before any promise it returned\n * is awaited), so concurrent external callers are never affected. This\n * catches triggerEvent/checkTransitions calls made before a callback's first\n * await; calls made after a prior await are not detectable without\n * AsyncLocalStorage (Node-only) and will still deadlock — a documented gap. */\n private guardSync<T>(fn: () => T): T {\n this.inSyncCallback = true;\n try {\n return fn();\n } finally {\n this.inSyncCallback = false;\n }\n }\n\n private assertNotReentrant(operation: string): void {\n if (this.inSyncCallback) {\n throw new ReentrancyError(operation);\n }\n }\n\n /** Single entry point to the operation queue — every enqueue kicks the runner. */\n private enqueueOperation(\n eventName: string | null,\n context: Map<string, unknown> | undefined,\n resolve: () => void,\n reject: (err: unknown) => void,\n ifStateName?: string,\n ): void {\n if (this.queue.size() >= this.maxQueueLength) {\n throw new QueueLimitExceededError(this.maxQueueLength, eventName);\n }\n this.queue.enqueue({\n eventName,\n context: context ?? new Map(),\n ifStateName,\n resolve,\n reject,\n });\n void this.runIfIdle();\n }\n\n // --- internal runner ---\n\n private async runIfIdle(): Promise<void> {\n if (this.running) return;\n this.running = true;\n try {\n while (!this.queue.isEmpty()) {\n const op = this.queue.dequeue()!;\n await this.runOperation(op);\n }\n } finally {\n this.running = false;\n // The drain loop only exits when the queue is empty, but guard anyway:\n // waiters must never be released while work is pending.\n if (this.queue.isEmpty() && this.idleWaiters.length > 0) {\n const waiters = this.idleWaiters;\n this.idleWaiters = [];\n for (const waiter of waiters) waiter();\n }\n }\n }\n\n private async runOperation(op: QueuedOperation): Promise<void> {\n // After a failed release the ownership flag is unreliable: the unlock\n // may have happened remotely with its reply lost. Running on it would\n // skip acquisition and execute under a lock another machine may now\n // hold, so reject before touching the mutex or any callback.\n if (this.ownershipUncertainty) {\n op.reject(new LockOwnershipUncertainError(this.ownershipUncertainty.err));\n return;\n }\n\n if (\n op.ifStateName !== undefined &&\n this.currentState.getName() !== op.ifStateName\n ) {\n // Stale chained op — the machine moved on before it was dequeued.\n op.resolve();\n return;\n }\n\n // If the caller has already acquired the mutex (e.g. manual lock\n // management with autoreleaseLock: false), don't reacquire — many\n // mutex implementations (database advisory locks, redis SET NX, etc.)\n // are not idempotent and will fail on the second acquire. We only\n // release in this method if we acquired in this method.\n //\n // The caller's promise settles only AFTER the release completes, so\n // `await sm.triggerEvent(...)` guarantees the lock is free again.\n let acquiredHere = false;\n let failure: { err: unknown } | null = null;\n try {\n if (!this.mutex.isAcquired()) {\n if (!(await this.mutex.acquireLock())) {\n throw new LockCanNotBeAcquiredError(\"Lock can not be acquired!\");\n }\n acquiredHere = true;\n }\n\n const event =\n op.eventName !== null ? this.resolveEvent(op.eventName) : null;\n\n await this.processOperation(event, op.context);\n } catch (err) {\n failure = { err };\n } finally {\n if (acquiredHere && this.autoreleaseLock) {\n const releaseFailure = await this.releaseMutex();\n // A release failure must not mask an operation error, but when the\n // operation succeeded the caller must learn the lock may still be\n // held — otherwise every later operation silently piggybacks on\n // (and never releases) the stuck lock.\n if (releaseFailure && !failure) failure = releaseFailure;\n }\n }\n if (failure) {\n op.reject(failure.err);\n } else {\n op.resolve();\n }\n }\n\n /**\n * Releases the mutex, normalizing its two failure modes into one result: a\n * thrown error, and a false return — the failure signal MutexInterface /\n * LockAdapterInterface define (a PostgreSQL advisory unlock that returns\n * false, a Redis DEL that removed nothing). A false return means the lock\n * may still be held, so it must never be mistaken for a successful release.\n *\n * Every failure is surfaced through the diagnostic hook — when the\n * operation also failed, the rejection carries the operation error and this\n * hook is the only place the release error appears.\n *\n * A failure while the mutex claimed to hold the lock leaves ownership\n * uncertain and blocks later operations; a success clears that state. A\n * failed release of a lock the mutex did not claim (a defensive manual\n * release) is still reported but changes nothing.\n *\n * @returns null on success, or the failure wrapped for the caller to raise.\n */\n private async releaseMutex(): Promise<{ err: unknown } | null> {\n const held = this.mutex.isAcquired();\n let failure: { err: unknown } | null = null;\n try {\n if (!(await this.mutex.releaseLock())) {\n failure = { err: new LockCanNotBeReleasedError() };\n }\n } catch (err) {\n failure = { err };\n }\n if (failure) {\n if (held) this.ownershipUncertainty = failure;\n const err = failure.err;\n this.callDiagnosticHook(() => this.onReleaseError?.(err));\n } else {\n this.ownershipUncertainty = null;\n }\n return failure;\n }\n\n /**\n * Runs a user diagnostic hook in isolation. Neither a synchronous throw nor\n * a rejection of a returned promise may reach the drain loop or the host:\n * an unavailable telemetry backend must not fail an operation or, via an\n * unhandled rejection, terminate the process. A returned promise is\n * deliberately not awaited — a slow reporter must not stall the runner.\n */\n private callDiagnosticHook(hook: () => unknown): void {\n try {\n const result = hook();\n if (isPromiseLike(result)) {\n result.then(undefined, () => {\n /* swallow hook failures */\n });\n }\n } catch {\n /* swallow hook failures */\n }\n }\n\n private resolveEvent(name: string): EventInterface {\n if (!this.currentState.hasEvent(name)) {\n throw new WrongEventForStateError(this.currentState.getName(), name);\n }\n return this.currentState.getEvent(name);\n }\n\n /**\n * Drive transitions starting from the current state, following automatic\n * transitions until quiescent. The first iteration may use the supplied\n * event; subsequent iterations are automatic.\n */\n private async processOperation(\n initialEvent: EventInterface | null,\n context: Map<string, unknown>,\n ): Promise<void> {\n let event = initialEvent;\n let automaticHops = 0;\n\n // Fire event-attached observers (imperative commands attached via\n // event.attach()) when the user-supplied event is resolved, regardless\n // of whether a transition fires. Runs once per triggerEvent call —\n // automatic transitions in the iteration loop have event=null and don't\n // re-trigger this dispatch.\n if (event) {\n const userEvent = event; // const capture for the closure (event is a mutable let)\n // Dispatch event-attached observers individually so each observer's\n // synchronous portion runs under the re-entrancy guard. Calling\n // invoke()/notify() wholesale would guard only the FIRST observer: the\n // notify loop awaits between observers, and guardSync clears the flag the\n // moment the first observer's update() yields. Iterate a snapshot so an\n // observer that detaches during dispatch can't shift the live set.\n const invokeArgs: readonly unknown[] = [this.subject, context];\n for (const observer of [...userEvent.getObservers()]) {\n await this.guardSync(() => observer.update(userEvent, invokeArgs));\n }\n }\n\n while (true) {\n const transitions = this.currentState.getTransitions();\n // Pass the guard per-transition: filter() awaits each isActive() call in\n // sequence, so a single guardSync around the whole call would protect\n // only the first condition. Wrapping each evaluation keeps a re-entrant\n // condition on a LATER transition detectable instead of deadlocking.\n const active = await ActiveTransitionFilter.filter(\n transitions,\n this.subject,\n context,\n event ?? undefined,\n (fn) => this.guardSync(fn),\n );\n const selected = this.guardSync(() =>\n this.transitionSelector.selectTransition(active),\n );\n\n if (!selected) {\n return;\n }\n\n const target = selected.getTargetState();\n\n if (selected.getEventName() === null) {\n automaticHops += 1;\n if (automaticHops > this.maxAutomaticHops) {\n throw new AutomaticTransitionCycleError(\n target.getName(),\n this.maxAutomaticHops,\n );\n }\n }\n\n if (this.currentState !== target) {\n const frame: TransitionFrame<TSubject> = Object.freeze({\n subject: this.subject,\n fromState: this.currentState,\n toState: target,\n transition: selected,\n event,\n condition: selected.getCondition(),\n context: this.readonlyContext(context),\n timestamp: Date.now(),\n machineName: this.process.getName(),\n });\n\n // Before phase — first observer to throw aborts. Iterate a snapshot\n // so observers that detach (themselves or others) during notify\n // can't shift the live array under the iterator.\n for (const observer of [...this.beforeObservers]) {\n await this.guardSync(() => observer.notify(frame));\n }\n\n // Commit.\n this.lastState = this.currentState;\n this.currentState = target;\n\n // After phase — collect errors, notify all, then rethrow.\n const enqueueCtx: EnqueueContext = {\n enqueue: (chainedEventName, chainedCtx, ifStateName) => {\n this.enqueueOperation(\n chainedEventName,\n chainedCtx,\n () => {\n /* chained ops are not awaited by the original caller */\n },\n (err) => {\n // Chained errors do not propagate to the original caller;\n // surface them through the optional sink instead.\n this.callDiagnosticHook(() =>\n this.onChainedOperationError?.(err, {\n eventName: chainedEventName,\n }),\n );\n },\n ifStateName,\n );\n },\n };\n\n const errors: unknown[] = [];\n for (const observer of [...this.afterObservers]) {\n try {\n await this.guardSync(() => observer.notify(frame, enqueueCtx));\n } catch (err) {\n errors.push(err);\n }\n }\n if (errors.length === 1) {\n throw errors[0];\n }\n if (errors.length > 1) {\n throw new AggregateError(\n errors,\n `${errors.length} after-transition observer(s) threw`,\n );\n }\n }\n\n // Auto-follow-on: continue with no event.\n event = null;\n }\n }\n\n private readonlyContext(\n ctx: Map<string, unknown>,\n ): ReadonlyMap<string, unknown> {\n // Wrap to discourage mutation. We don't deep-freeze the values themselves —\n // keys removed from the wrapper map don't affect the underlying ctx, so\n // a thin wrapper suffices.\n return new Map(ctx);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport class Tautology implements ConditionInterface {\n private readonly name: string;\n\n constructor(name = \"Tautology\") {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(_subject: unknown, _context: Map<string, unknown>): boolean {\n return true;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\n\nexport class Contradiction implements ConditionInterface {\n private readonly name: string;\n\n constructor(name = \"Contradiction\") {\n this.name = name;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(_subject: unknown, _context: Map<string, unknown>): boolean {\n return false;\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\n\nexport type ConditionCallbackFn<TSubject = unknown> = (\n subject: TSubject,\n context: Map<string, unknown>,\n) => MaybePromise<boolean>;\n\nexport class CallbackCondition<\n TSubject = unknown,\n> implements ConditionInterface<TSubject> {\n private readonly name: string;\n private readonly callable: ConditionCallbackFn<TSubject>;\n\n constructor(name: string, callable: ConditionCallbackFn<TSubject>) {\n this.name = name;\n this.callable = callable;\n }\n\n getName(): string {\n return this.name;\n }\n\n checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean> {\n return this.callable(subject, context);\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class InvalidSubjectError extends FinitaError {\n readonly code = \"invalidSubject\";\n readonly expectedInterface: string;\n readonly missingMembers: readonly string[];\n\n constructor(expectedInterface: string, missingMembers: Iterable<string>) {\n const members = Array.from(missingMembers);\n const memberList = members.map((m) => `\"${m}\"`).join(\", \");\n super(\n `Subject does not satisfy ${expectedInterface}; missing member(s): ${memberList || \"(unknown)\"}`,\n );\n this.name = \"InvalidSubjectError\";\n this.expectedInterface = expectedInterface;\n this.missingMembers = Object.freeze([...members]);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { LastStateHasChangedDateInterface } from \"../interfaces/LastStateHasChangedDateInterface.js\";\nimport { InvalidSubjectError } from \"../error/InvalidSubjectError.js\";\n\nfunction isLastStateHasChangedDate(\n obj: unknown,\n): obj is LastStateHasChangedDateInterface {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getLastStateHasChangedDate\" in obj &&\n typeof (obj as LastStateHasChangedDateInterface)\n .getLastStateHasChangedDate === \"function\"\n );\n}\n\nexport class Timeout implements ConditionInterface {\n private readonly timeoutMs: number;\n private readonly label: string;\n\n constructor(timeoutMs: number, label?: string) {\n this.timeoutMs = timeoutMs;\n this.label = label ?? `${timeoutMs}ms`;\n }\n\n getName(): string {\n return `Timeout: ${this.label}`;\n }\n\n protected getLastStateHasChangedDate(\n subject: unknown,\n _context: Map<string, unknown>,\n ): Date {\n if (isLastStateHasChangedDate(subject)) {\n return subject.getLastStateHasChangedDate();\n }\n throw new InvalidSubjectError(\"LastStateHasChangedDateInterface\", [\n \"getLastStateHasChangedDate\",\n ]);\n }\n\n checkCondition(subject: unknown, context: Map<string, unknown>): boolean {\n return (\n this.getLastStateHasChangedDate(subject, context).getTime() +\n this.timeoutMs <=\n Date.now()\n );\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\nimport { isPromiseLike } from \"../util/index.js\";\n\nexport abstract class CompositeCondition<\n TSubject = unknown,\n> implements ConditionInterface<TSubject> {\n protected readonly conditions: ConditionInterface<TSubject>[] = [];\n private readonly joinWord: string;\n\n constructor(joinWord: string, condition: ConditionInterface<TSubject>) {\n this.joinWord = joinWord;\n this.conditions.push(condition);\n }\n\n protected addCondition(condition: ConditionInterface<TSubject>): this {\n this.conditions.push(condition);\n return this;\n }\n\n getName(): string {\n const names = this.conditions.map((c) => c.getName());\n return `(${names.join(` ${this.joinWord} `)})`;\n }\n\n abstract checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean>;\n\n /**\n * Evaluates children in order, stopping at the first whose result equals\n * `shortCircuitOn`. A child that returns a plain boolean is consumed\n * synchronously; only a returned promise is awaited. Awaiting plain values\n * would yield between children and end the machine's synchronous\n * re-entrancy guard, so a re-entrant later child would deadlock instead of\n * throwing ReentrancyError. For the same reason the composite itself\n * returns a plain boolean when every child it evaluated did.\n */\n protected evaluate(\n subject: TSubject,\n context: Map<string, unknown>,\n shortCircuitOn: boolean,\n ): MaybePromise<boolean> {\n const from = (start: number): MaybePromise<boolean> => {\n for (let i = start; i < this.conditions.length; i++) {\n const result = this.conditions[i]!.checkCondition(subject, context);\n if (isPromiseLike<boolean>(result)) {\n return Promise.resolve(result).then((value) =>\n Boolean(value) === shortCircuitOn ? shortCircuitOn : from(i + 1),\n );\n }\n if (Boolean(result) === shortCircuitOn) return shortCircuitOn;\n }\n return !shortCircuitOn;\n };\n return from(0);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\nimport { CompositeCondition } from \"./CompositeCondition.js\";\n\nexport class AndComposite<\n TSubject = unknown,\n> extends CompositeCondition<TSubject> {\n constructor(condition: ConditionInterface<TSubject>) {\n super(\"and\", condition);\n }\n\n addAnd(condition: ConditionInterface<TSubject>): this {\n return this.addCondition(condition);\n }\n\n checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean> {\n return this.evaluate(subject, context, false);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\nimport { CompositeCondition } from \"./CompositeCondition.js\";\n\nexport class OrComposite<\n TSubject = unknown,\n> extends CompositeCondition<TSubject> {\n constructor(condition: ConditionInterface<TSubject>) {\n super(\"or\", condition);\n }\n\n addOr(condition: ConditionInterface<TSubject>): this {\n return this.addCondition(condition);\n }\n\n checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean> {\n return this.evaluate(subject, context, true);\n }\n}\n","import type { ConditionInterface } from \"../interfaces/ConditionInterface.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\nimport { isPromiseLike } from \"../util/index.js\";\n\nexport class Not<TSubject = unknown> implements ConditionInterface<TSubject> {\n private readonly condition: ConditionInterface<TSubject>;\n\n constructor(condition: ConditionInterface<TSubject>) {\n this.condition = condition;\n }\n\n getName(): string {\n return `not ( ${this.condition.getName()} )`;\n }\n\n /** Stays synchronous for a synchronous child — see CompositeCondition. */\n checkCondition(\n subject: TSubject,\n context: Map<string, unknown>,\n ): MaybePromise<boolean> {\n const result = this.condition.checkCondition(subject, context);\n if (isPromiseLike<boolean>(result)) {\n return Promise.resolve(result).then((value) => !value);\n }\n return !result;\n }\n}\n","import type { Observer, ObservableSubject } from \"../interfaces/Observer.js\";\nimport type { MaybePromise } from \"../MaybePromise.js\";\n\n/**\n * Observer for Event observers (commands attached to specific events).\n *\n * This is not a Statemachine observer. To run a callback after every\n * transition, implement AfterTransitionObserver directly or compose a small\n * wrapper.\n */\nexport class CallbackObserver implements Observer {\n private readonly callback: (...args: unknown[]) => MaybePromise<void>;\n\n constructor(callback: (...args: unknown[]) => MaybePromise<void>) {\n this.callback = callback;\n }\n\n update(\n subject: ObservableSubject,\n args?: readonly unknown[],\n ): MaybePromise<void> {\n // Event-invoked path: args is the invoke argument list — spread it into\n // the callback. An empty list means the event was invoked with zero args,\n // so the callback receives zero args (matching pre-v3.1 behavior).\n if (args !== undefined) {\n return this.callback(...args);\n }\n // Direct/legacy path: update(subject) with no args — pass the subject.\n return this.callback(subject);\n }\n}\n","import type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\nimport type { StatefulInterface } from \"../interfaces/StatefulInterface.js\";\n\nexport class StatefulStatusChanger<\n TSubject extends StatefulInterface,\n> implements AfterTransitionObserver<TSubject> {\n private readonly subject: TSubject | null;\n\n /**\n * @param subject Optional explicit subject to write to. When omitted\n * (recommended), the observer writes to frame.subject — the subject of\n * whichever machine fired the transition — so a single instance can be\n * shared safely across every machine a Factory creates.\n */\n constructor(subject?: TSubject) {\n // null sentinel lets `?? frame.subject` in notify() distinguish\n // \"no subject pinned\" from any valid subject value.\n this.subject = subject ?? null;\n }\n\n notify(frame: TransitionFrame<TSubject>): void {\n (this.subject ?? frame.subject).setCurrentStateName(\n frame.toState.getName(),\n );\n }\n}\n","import type {\n AfterTransitionObserver,\n EnqueueContext,\n} from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\n\n/**\n * After-transition observer that fires an event named DEFAULT_EVENT_NAME\n * (or a custom name) when entering any state that has that event declared.\n *\n * The chained event is *enqueued*, not invoked inline: it runs as its own\n * top-level operation after the current operation completes. Other\n * after-observers registered after OnEnterObserver still see the original\n * frame, not the chained one.\n *\n * The chained event only fires if the machine is still in the entered state\n * when the queue drains — states passed through transiently by automatic\n * transitions do not fire onEnter.\n */\nexport class OnEnterObserver<\n TSubject = unknown,\n> implements AfterTransitionObserver<TSubject> {\n static readonly DEFAULT_EVENT_NAME = \"onEnter\";\n\n private readonly eventName: string;\n\n constructor(eventName: string = OnEnterObserver.DEFAULT_EVENT_NAME) {\n this.eventName = eventName;\n }\n\n notify(frame: TransitionFrame<TSubject>, ctx: EnqueueContext): void {\n if (frame.toState.hasEvent(this.eventName)) {\n ctx.enqueue(\n this.eventName,\n new Map(frame.context),\n frame.toState.getName(),\n );\n }\n }\n}\n","import type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { TransitionFrame } from \"../interfaces/TransitionFrameInterface.js\";\nimport type { LoggerInterface } from \"../interfaces/LoggerInterface.js\";\nimport { nameOrString } from \"../util/index.js\";\n\nexport class TransitionLogger<\n TSubject = unknown,\n> implements AfterTransitionObserver<TSubject> {\n private readonly logger: LoggerInterface;\n private readonly loggerLevel: string;\n\n constructor(logger: LoggerInterface, loggerLevel = \"info\") {\n this.logger = logger;\n this.loggerLevel = loggerLevel;\n }\n\n notify(frame: TransitionFrame<TSubject>): void {\n let message = \"Transition\";\n\n message += ` from \"${nameOrString(frame.fromState)}\" to \"${nameOrString(frame.toState)}\"`;\n\n const eventName = frame.event ? frame.event.getName() : null;\n const conditionName = frame.condition ? frame.condition.getName() : null;\n if (eventName || conditionName) {\n message += \" with\";\n if (eventName) message += ` event \"${eventName}\"`;\n if (conditionName) message += ` condition \"${conditionName}\"`;\n }\n\n // frame.subject is intentionally omitted from the log context — callers\n // who need subject identity attach a custom observer that closes over it.\n this.logger.log(this.loggerLevel, message, {\n fromState: frame.fromState,\n toState: frame.toState,\n event: frame.event,\n transition: frame.transition,\n machineName: frame.machineName,\n });\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\nexport class FilterStateByEvent {\n static *filter(\n states: Iterable<StateInterface>,\n eventName: string,\n ): Iterable<StateInterface> {\n for (const state of states) {\n if (state.hasEvent(eventName)) {\n yield state;\n }\n }\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\n/**\n * Filters states that have at least one automatic transition (no event name).\n */\nexport class FilterStateByTransition {\n static *filter(states: Iterable<StateInterface>): Iterable<StateInterface> {\n for (const state of states) {\n for (const transition of state.getTransitions()) {\n if (!transition.getEventName()) {\n yield state;\n break;\n }\n }\n }\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\n\nexport class FilterStateByFinalState {\n static *filter(states: Iterable<StateInterface>): Iterable<StateInterface> {\n for (const state of states) {\n let count = 0;\n for (const _transition of state.getTransitions()) {\n count++;\n break;\n }\n if (count === 0) {\n yield state;\n }\n }\n }\n}\n","import type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\n\nexport class FilterTransitionByEvent {\n static *filter(\n transitions: Iterable<TransitionInterface>,\n eventName: string,\n ): Iterable<TransitionInterface> {\n for (const transition of transitions) {\n if (transition.getEventName() === eventName) {\n yield transition;\n }\n }\n }\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { OneOrNoneActiveTransition } from \"./OneOrNoneActiveTransition.js\";\n\nexport class ScoreTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n private readonly innerSelector: TransitionSelectorInterface<TSubject>;\n\n constructor(innerSelector?: TransitionSelectorInterface<TSubject>) {\n this.innerSelector =\n innerSelector ?? new OneOrNoneActiveTransition<TSubject>();\n }\n\n protected calculateScore(transition: TransitionInterface<TSubject>): number {\n let score = 0;\n if (transition.getEventName()) {\n score += 2;\n }\n if (transition.getConditionName()) {\n score += 1;\n }\n return score;\n }\n\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n let bestTransitions: TransitionInterface<TSubject>[] = [];\n let bestScore = -1;\n for (const transition of transitions) {\n const score = this.calculateScore(transition);\n if (score > bestScore) {\n bestScore = score;\n bestTransitions = [transition];\n } else if (score === bestScore) {\n bestTransitions.push(transition);\n }\n }\n return this.innerSelector.selectTransition(bestTransitions);\n }\n}\n","import type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport { OneOrNoneActiveTransition } from \"./OneOrNoneActiveTransition.js\";\n\nexport class WeightTransition<\n TSubject = unknown,\n> implements TransitionSelectorInterface<TSubject> {\n private readonly innerSelector: TransitionSelectorInterface<TSubject>;\n private readonly epsilon: number;\n\n constructor(\n innerSelector?: TransitionSelectorInterface<TSubject>,\n epsilon = 0.001,\n ) {\n if (!Number.isFinite(epsilon) || epsilon <= 0) {\n throw new RangeError(\n `WeightTransition epsilon must be a finite number greater than 0; got ${String(epsilon)}`,\n );\n }\n this.innerSelector =\n innerSelector ?? new OneOrNoneActiveTransition<TSubject>();\n this.epsilon = epsilon;\n }\n\n selectTransition(\n transitions: Iterable<TransitionInterface<TSubject>>,\n ): TransitionInterface<TSubject> | null {\n const all = Array.from(transitions);\n let maxWeight = Number.NEGATIVE_INFINITY;\n for (const transition of all) {\n const weight = transition.getWeight();\n if (!Number.isFinite(weight)) {\n throw new RangeError(\n `WeightTransition: transition weights must be finite numbers; got ${String(weight)}`,\n );\n }\n if (weight > maxWeight) maxWeight = weight;\n }\n const best = all.filter(\n (transition) => maxWeight - transition.getWeight() < this.epsilon,\n );\n return this.innerSelector.selectTransition(best);\n }\n}\n","import type { MutexInterface } from \"../interfaces/MutexInterface.js\";\nimport type { LockAdapterInterface } from \"../interfaces/LockAdapterInterface.js\";\n\nexport class LockAdapterMutex implements MutexInterface {\n private readonly lockAdapter: LockAdapterInterface;\n private readonly resourceName: string;\n private acquired = false;\n private pendingAcquire: Promise<boolean> | null = null;\n\n constructor(lockAdapter: LockAdapterInterface, resourceName: string) {\n this.lockAdapter = lockAdapter;\n this.resourceName = resourceName;\n }\n\n /**\n * Overlapping calls share one underlying acquire: the `acquired` flag is\n * only set after the adapter resolves, so without this both callers would\n * pass the check and acquire twice on a non-idempotent adapter (database\n * advisory locks, redis SET NX). The pending promise is cleared once it\n * settles, so a failed acquire can still be retried.\n *\n * The clearing is attached to the attempt only after it is stored: an\n * adapter that throws synchronously settles the attempt before the\n * assignment would otherwise run, and clearing inside the attempt itself\n * would then leave the rejected promise cached forever.\n */\n async acquireLock(): Promise<boolean> {\n if (this.acquired) {\n return true;\n }\n if (!this.pendingAcquire) {\n const attempt = (async () => {\n this.acquired = await this.lockAdapter.acquireLock(this.resourceName);\n return this.acquired;\n })();\n this.pendingAcquire = attempt;\n const clear = (): void => {\n if (this.pendingAcquire === attempt) this.pendingAcquire = null;\n };\n attempt.then(clear, clear);\n }\n return this.pendingAcquire;\n }\n\n async releaseLock(): Promise<boolean> {\n if (this.acquired) {\n const result = await this.lockAdapter.releaseLock(this.resourceName);\n if (result) {\n this.acquired = false;\n }\n return result;\n }\n return false;\n }\n\n isAcquired(): boolean {\n return this.acquired;\n }\n\n async isLocked(): Promise<boolean> {\n return this.lockAdapter.isLocked(this.resourceName);\n }\n}\n","import type { MutexFactoryInterface } from \"../interfaces/MutexFactoryInterface.js\";\nimport type { MutexInterface } from \"../interfaces/MutexInterface.js\";\nimport type { LockAdapterInterface } from \"../interfaces/LockAdapterInterface.js\";\nimport { LockAdapterMutex } from \"./LockAdapterMutex.js\";\n\nexport type StringConverter<TSubject = unknown> = (subject: TSubject) => string;\n\nexport class MutexFactory<\n TSubject = unknown,\n> implements MutexFactoryInterface<TSubject> {\n private readonly lockAdapter: LockAdapterInterface;\n private readonly stringConverter: StringConverter<TSubject>;\n\n constructor(\n lockAdapter: LockAdapterInterface,\n stringConverter: StringConverter<TSubject>,\n ) {\n this.lockAdapter = lockAdapter;\n this.stringConverter = stringConverter;\n }\n\n createMutex(subject: TSubject): MutexInterface {\n return new LockAdapterMutex(\n this.lockAdapter,\n this.stringConverter(subject),\n );\n }\n}\n","import type { FactoryInterface } from \"../interfaces/FactoryInterface.js\";\nimport type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { StateNameDetectorInterface } from \"../interfaces/StateNameDetectorInterface.js\";\nimport type { TransitionSelectorInterface } from \"../interfaces/TransitionSelectorInterface.js\";\nimport type { MutexFactoryInterface } from \"../interfaces/MutexFactoryInterface.js\";\nimport type { StatemachineInterface } from \"../interfaces/StatemachineInterface.js\";\nimport type { BeforeTransitionObserver } from \"../interfaces/BeforeTransitionObserverInterface.js\";\nimport type { AfterTransitionObserver } from \"../interfaces/AfterTransitionObserverInterface.js\";\nimport type { StatemachineOptions } from \"../interfaces/StatemachineOptions.js\";\nimport { Statemachine } from \"../Statemachine.js\";\n\n/**\n * Engine options applied to every machine the factory creates.\n *\n * `initialStateName`, `mutex` and `transitionSelector` are excluded: the\n * factory derives them per subject from the state-name detector, the mutex\n * factory and setTransitionSelector, so a template value could only\n * contradict them.\n */\nexport type FactoryStatemachineOptions<TSubject = unknown> = Omit<\n StatemachineOptions<TSubject>,\n \"initialStateName\" | \"mutex\" | \"transitionSelector\"\n>;\n\nexport class Factory<TSubject = unknown> implements FactoryInterface<TSubject> {\n private readonly processDetector: ProcessDetectorInterface<TSubject>;\n private readonly stateNameDetector: StateNameDetectorInterface<TSubject> | null;\n private readonly beforeObservers: Set<BeforeTransitionObserver<TSubject>> =\n new Set();\n private readonly afterObservers: Set<AfterTransitionObserver<TSubject>> =\n new Set();\n private transitionSelector: TransitionSelectorInterface<TSubject> | null =\n null;\n private mutexFactory: MutexFactoryInterface<TSubject> | null = null;\n private readonly options: FactoryStatemachineOptions<TSubject>;\n\n /**\n * @param options Engine options applied to every machine this factory\n * creates — back-pressure (maxQueueLength), the automatic-hop bound, lock\n * autorelease, and the onChainedOperationError / onReleaseError diagnostic\n * sinks. Without them, factory-created machines would silently run on\n * defaults, which is precisely where those sinks matter most.\n */\n constructor(\n processDetector: ProcessDetectorInterface<TSubject>,\n stateNameDetector?: StateNameDetectorInterface<TSubject> | null,\n options: FactoryStatemachineOptions<TSubject> = {},\n ) {\n this.processDetector = processDetector;\n this.stateNameDetector = stateNameDetector ?? null;\n this.options = { ...options };\n }\n\n setMutexFactory(factory: MutexFactoryInterface<TSubject> | null): void {\n this.mutexFactory = factory;\n }\n\n setTransitionSelector(selector: TransitionSelectorInterface<TSubject>): void {\n this.transitionSelector = selector;\n }\n\n attachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void {\n this.beforeObservers.add(observer);\n }\n\n detachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void {\n this.beforeObservers.delete(observer);\n }\n\n attachAfterObserver(observer: AfterTransitionObserver<TSubject>): void {\n this.afterObservers.add(observer);\n }\n\n detachAfterObserver(observer: AfterTransitionObserver<TSubject>): void {\n this.afterObservers.delete(observer);\n }\n\n async createStatemachine(\n subject: TSubject,\n ): Promise<StatemachineInterface<TSubject>> {\n const process = this.processDetector.detectProcess(subject);\n const stateName = this.stateNameDetector\n ? this.stateNameDetector.detectCurrentStateName(subject)\n : undefined;\n const mutex = this.mutexFactory\n ? await this.mutexFactory.createMutex(subject)\n : undefined;\n\n const sm = new Statemachine<TSubject>(subject, process, {\n ...this.options,\n initialStateName: stateName ?? undefined,\n transitionSelector: this.transitionSelector ?? undefined,\n mutex: mutex ?? undefined,\n });\n\n for (const o of this.beforeObservers) sm.attachBefore(o);\n for (const o of this.afterObservers) sm.attachAfter(o);\n\n return sm;\n }\n}\n","import type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { ProcessInterface } from \"../interfaces/ProcessInterface.js\";\n\nexport class SingleProcessDetector<\n TSubject = unknown,\n> implements ProcessDetectorInterface<TSubject> {\n private readonly process: ProcessInterface;\n\n constructor(process: ProcessInterface) {\n this.process = process;\n }\n\n detectProcess(_subject: TSubject): ProcessInterface {\n return this.process;\n }\n}\n","import { FinitaError } from \"./FinitaError.js\";\n\nexport class ProcessNotFoundError extends FinitaError {\n readonly code = \"processNotFound\";\n readonly processName: string;\n readonly availableProcesses: readonly string[];\n\n constructor(processName: string, availableProcesses: Iterable<string>) {\n const list = Array.from(availableProcesses);\n const display =\n list.length > 0 ? list.map((n) => `\"${n}\"`).join(\", \") : \"(none)\";\n super(`Process \"${processName}\" not found. Available: ${display}`);\n this.name = \"ProcessNotFoundError\";\n this.processName = processName;\n this.availableProcesses = Object.freeze([...list]);\n }\n}\n","import type { ProcessDetectorInterface } from \"../interfaces/ProcessDetectorInterface.js\";\nimport type { ProcessInterface } from \"../interfaces/ProcessInterface.js\";\nimport { ProcessNotFoundError } from \"../error/ProcessNotFoundError.js\";\n\nexport abstract class AbstractNamedProcessDetector<\n TSubject = unknown,\n> implements ProcessDetectorInterface<TSubject> {\n private readonly processes: Map<string, ProcessInterface> = new Map();\n\n protected abstract detectProcessName(subject: TSubject): string;\n\n addProcess(process: ProcessInterface): void {\n this.processes.set(process.getName(), process);\n }\n\n hasProcess(name: string): boolean {\n return this.processes.has(name);\n }\n\n detectProcess(subject: TSubject): ProcessInterface {\n const name = this.detectProcessName(subject);\n const process = this.processes.get(name);\n if (!process) {\n throw new ProcessNotFoundError(name, this.processes.keys());\n }\n return process;\n }\n}\n","import type { StateNameDetectorInterface } from \"../interfaces/StateNameDetectorInterface.js\";\nimport type { StatefulInterface } from \"../interfaces/StatefulInterface.js\";\nimport { InvalidSubjectError } from \"../error/InvalidSubjectError.js\";\n\nfunction isStateful(obj: unknown): obj is StatefulInterface {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"getCurrentStateName\" in obj &&\n typeof (obj as StatefulInterface).getCurrentStateName === \"function\"\n );\n}\n\nexport class StatefulStateNameDetector implements StateNameDetectorInterface<StatefulInterface> {\n detectCurrentStateName(subject: StatefulInterface): string | null {\n if (isStateful(subject)) {\n return subject.getCurrentStateName();\n }\n throw new InvalidSubjectError(\"StatefulInterface\", [\"getCurrentStateName\"]);\n }\n}\n","import type { StateInterface } from \"../interfaces/StateInterface.js\";\nimport type { TransitionInterface } from \"../interfaces/TransitionInterface.js\";\nimport type { StateCollectionInterface } from \"../interfaces/StateCollectionInterface.js\";\nimport { nameOrString } from \"../util/index.js\";\n\nexport interface GraphNode {\n id: string;\n label: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface GraphEdge {\n source: string;\n target: string;\n label: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface Graph {\n nodes: GraphNode[];\n edges: GraphEdge[];\n}\n\nfunction escapeDotString(str: string): string {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction toMermaidId(name: string): string {\n return (\n \"s_\" +\n name.replace(\n /[^a-zA-Z0-9]/g,\n (ch) => `_${ch.charCodeAt(0).toString(16).padStart(4, \"0\")}`,\n )\n );\n}\n\nfunction escapeMermaidLabel(str: string): string {\n return str.replace(/\\\\/g, \"#92;\").replace(/\"/g, \"#quot;\");\n}\n\nexport type GraphDirection = \"TB\" | \"BT\" | \"LR\" | \"RL\";\n\nconst VALID_DIRECTIONS: ReadonlySet<string> = new Set([\"TB\", \"BT\", \"LR\", \"RL\"]);\n\nfunction assertDirection(value: string, optionName: string): void {\n if (!VALID_DIRECTIONS.has(value)) {\n throw new RangeError(\n `${optionName} must be one of \"TB\", \"BT\", \"LR\", \"RL\"; got ${JSON.stringify(value)}`,\n );\n }\n}\n\nexport interface DotOptions {\n rankdir?: GraphDirection;\n}\n\nexport interface MermaidOptions {\n direction?: GraphDirection;\n}\n\nexport class GraphBuilder {\n private readonly nodes: Map<string, GraphNode> = new Map();\n private readonly edges: GraphEdge[] = [];\n private readonly statesWithEdges: Set<string> = new Set();\n\n private getOrCreateNode(state: StateInterface): GraphNode {\n const name = state.getName();\n let node = this.nodes.get(name);\n if (!node) {\n node = { id: name, label: name, metadata: state.getMetadata() };\n this.nodes.set(name, node);\n }\n return node;\n }\n\n protected getTransitionLabel(\n state: StateInterface,\n transition: TransitionInterface,\n ): string {\n const parts: string[] = [];\n const eventName = transition.getEventName();\n if (eventName) {\n parts.push(`E: ${eventName}`);\n if (state.hasEvent(eventName)) {\n const event = state.getEvent(eventName);\n const observerNames: string[] = [];\n for (const observer of event.getObservers()) {\n observerNames.push(nameOrString(observer));\n }\n if (observerNames.length > 0) {\n parts.push(`C: ${observerNames.join(\", \")}`);\n }\n }\n }\n const conditionName = transition.getConditionName();\n if (conditionName) {\n parts.push(`IF: ${conditionName}`);\n }\n parts.push(`W: ${transition.getWeight()}`);\n return parts.join(\"\\n\");\n }\n\n addState(state: StateInterface): void {\n this.getOrCreateNode(state);\n const name = state.getName();\n if (this.statesWithEdges.has(name)) return;\n this.statesWithEdges.add(name);\n for (const transition of state.getTransitions()) {\n const sourceNode = this.getOrCreateNode(state);\n const targetNode = this.getOrCreateNode(transition.getTargetState());\n const label = this.getTransitionLabel(state, transition);\n const metadata: Record<string, unknown> = {};\n const eventName = transition.getEventName();\n if (eventName && state.hasEvent(eventName)) {\n Object.assign(metadata, state.getEvent(eventName).getMetadata());\n }\n this.edges.push({\n source: sourceNode.id,\n target: targetNode.id,\n label,\n metadata,\n });\n }\n }\n\n addStates(states: Iterable<StateInterface>): void {\n for (const state of states) {\n this.addState(state);\n }\n }\n\n addStateCollection(stateCollection: StateCollectionInterface): void {\n this.addStates(stateCollection.getStates());\n }\n\n getGraph(): Graph {\n return {\n nodes: Array.from(this.nodes.values()),\n edges: [...this.edges],\n };\n }\n\n toDot(options?: DotOptions): string {\n const graph = this.getGraph();\n const rankdir = options?.rankdir ?? \"LR\";\n assertDirection(rankdir, \"rankdir\");\n const lines: string[] = [];\n lines.push(\"digraph {\");\n lines.push(` rankdir=${rankdir};`);\n for (const node of graph.nodes) {\n const label = escapeDotString(node.label);\n lines.push(` \"${label}\" [label=\"${label}\"];`);\n }\n for (const edge of graph.edges) {\n const source = escapeDotString(edge.source);\n const target = escapeDotString(edge.target);\n const label = escapeDotString(edge.label);\n lines.push(` \"${source}\" -> \"${target}\" [label=\"${label}\"];`);\n }\n lines.push(\"}\");\n return lines.join(\"\\n\");\n }\n\n toMermaid(options?: MermaidOptions): string {\n const graph = this.getGraph();\n const direction = options?.direction ?? \"LR\";\n assertDirection(direction, \"direction\");\n const lines: string[] = [];\n lines.push(`stateDiagram-v2`);\n lines.push(` direction ${direction}`);\n const declared = new Set<string>();\n for (const node of graph.nodes) {\n const id = toMermaidId(node.id);\n if (!declared.has(id)) {\n declared.add(id);\n const label = escapeMermaidLabel(node.label);\n lines.push(` ${id} : \"${label}\"`);\n }\n }\n for (const edge of graph.edges) {\n const source = toMermaidId(edge.source);\n const target = toMermaidId(edge.target);\n const label = escapeMermaidLabel(edge.label.replace(/\\n/g, \" / \"));\n lines.push(` ${source} --> ${target} : ${label}`);\n }\n return lines.join(\"\\n\");\n }\n}\n"],"mappings":"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","names":[]}
|