@rytejs/core 0.2.0 → 0.4.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/dist/index.cjs CHANGED
@@ -21,13 +21,36 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  DomainErrorSignal: () => DomainErrorSignal,
24
+ MigrationError: () => MigrationError,
24
25
  ValidationError: () => ValidationError,
25
26
  WorkflowRouter: () => WorkflowRouter,
26
27
  createKey: () => createKey,
27
- defineWorkflow: () => defineWorkflow
28
+ defineMigrations: () => defineMigrations,
29
+ definePlugin: () => definePlugin,
30
+ defineWorkflow: () => defineWorkflow,
31
+ isPlugin: () => isPlugin,
32
+ migrate: () => migrate
28
33
  });
29
34
  module.exports = __toCommonJS(index_exports);
30
35
 
36
+ // src/types.ts
37
+ var ValidationError = class extends Error {
38
+ constructor(source, issues) {
39
+ super(`Validation failed (${source}): ${issues.map((i) => i.message).join(", ")}`);
40
+ this.source = source;
41
+ this.issues = issues;
42
+ this.name = "ValidationError";
43
+ }
44
+ };
45
+ var DomainErrorSignal = class extends Error {
46
+ constructor(code, data) {
47
+ super(`Domain error: ${code}`);
48
+ this.code = code;
49
+ this.data = data;
50
+ this.name = "DomainErrorSignal";
51
+ }
52
+ };
53
+
31
54
  // src/definition.ts
32
55
  function defineWorkflow(name, config) {
33
56
  return {
@@ -74,6 +97,51 @@ function defineWorkflow(name, config) {
74
97
  },
75
98
  hasState(stateName) {
76
99
  return stateName in config.states;
100
+ },
101
+ snapshot(workflow) {
102
+ return {
103
+ id: workflow.id,
104
+ definitionName: name,
105
+ state: workflow.state,
106
+ data: workflow.data,
107
+ createdAt: workflow.createdAt.toISOString(),
108
+ updatedAt: workflow.updatedAt.toISOString(),
109
+ modelVersion: config.modelVersion ?? 1
110
+ };
111
+ },
112
+ restore(snap) {
113
+ const stateSchema = config.states[snap.state];
114
+ if (!stateSchema) {
115
+ return {
116
+ ok: false,
117
+ error: new ValidationError("restore", [
118
+ {
119
+ code: "custom",
120
+ message: `Unknown state: ${snap.state}`,
121
+ input: snap.state,
122
+ path: ["state"]
123
+ }
124
+ ])
125
+ };
126
+ }
127
+ const result = stateSchema.safeParse(snap.data);
128
+ if (!result.success) {
129
+ return {
130
+ ok: false,
131
+ error: new ValidationError("restore", result.error.issues)
132
+ };
133
+ }
134
+ return {
135
+ ok: true,
136
+ workflow: {
137
+ id: snap.id,
138
+ definitionName: snap.definitionName,
139
+ state: snap.state,
140
+ data: result.data,
141
+ createdAt: new Date(snap.createdAt),
142
+ updatedAt: new Date(snap.updatedAt)
143
+ }
144
+ };
77
145
  }
78
146
  };
79
147
  }
@@ -83,6 +151,123 @@ function createKey(name) {
83
151
  return { id: Symbol(name) };
84
152
  }
85
153
 
154
+ // src/migration.ts
155
+ var MigrationError = class extends Error {
156
+ constructor(fromVersion, toVersion, cause) {
157
+ super(
158
+ `Migration ${fromVersion} \u2192 ${toVersion} failed: ${cause instanceof Error ? cause.message : String(cause)}`
159
+ );
160
+ this.fromVersion = fromVersion;
161
+ this.toVersion = toVersion;
162
+ this.cause = cause;
163
+ this.name = "MigrationError";
164
+ }
165
+ };
166
+ function defineMigrations(definition, migrationMap) {
167
+ const targetVersion = definition.config.modelVersion ?? 1;
168
+ const entries = Object.entries(migrationMap).map(([k, v]) => [Number(k), v]);
169
+ for (const [version] of entries) {
170
+ if (version <= 1) {
171
+ throw new Error(`Migration keys must be > 1 (version 1 is the baseline). Got: ${version}`);
172
+ }
173
+ }
174
+ entries.sort((a, b) => a[0] - b[0]);
175
+ if (entries.length > 0) {
176
+ const highest = entries[entries.length - 1];
177
+ if (!highest || highest[0] !== targetVersion) {
178
+ throw new Error(
179
+ `Highest migration key (${highest?.[0]}) does not match definition modelVersion (${targetVersion})`
180
+ );
181
+ }
182
+ for (let i = 0; i < entries.length; i++) {
183
+ const entry = entries[i];
184
+ const expected = targetVersion - entries.length + 1 + i;
185
+ if (!entry || entry[0] !== expected) {
186
+ throw new Error(
187
+ `Migration version gap: expected ${expected} but found ${entry?.[0]}. Migrations must be sequential from 2 to ${targetVersion}.`
188
+ );
189
+ }
190
+ }
191
+ }
192
+ return {
193
+ definition,
194
+ targetVersion,
195
+ migrations: new Map(entries)
196
+ };
197
+ }
198
+ function migrate(pipeline, snapshot, options) {
199
+ if (!Number.isInteger(snapshot.modelVersion) || snapshot.modelVersion < 1) {
200
+ const error = new MigrationError(
201
+ snapshot.modelVersion,
202
+ pipeline.targetVersion,
203
+ new Error(
204
+ `Invalid snapshot modelVersion: ${snapshot.modelVersion}. Must be a positive integer.`
205
+ )
206
+ );
207
+ options?.onError?.(error);
208
+ return { ok: false, error };
209
+ }
210
+ if (snapshot.definitionName !== pipeline.definition.name) {
211
+ const error = new MigrationError(
212
+ snapshot.modelVersion,
213
+ pipeline.targetVersion,
214
+ new Error(
215
+ `Snapshot definition '${snapshot.definitionName}' does not match pipeline definition '${pipeline.definition.name}'`
216
+ )
217
+ );
218
+ options?.onError?.(error);
219
+ return { ok: false, error };
220
+ }
221
+ if (snapshot.modelVersion > pipeline.targetVersion) {
222
+ const error = new MigrationError(
223
+ snapshot.modelVersion,
224
+ pipeline.targetVersion,
225
+ new Error(
226
+ `Snapshot modelVersion (${snapshot.modelVersion}) is higher than target (${pipeline.targetVersion}). Cannot downgrade.`
227
+ )
228
+ );
229
+ options?.onError?.(error);
230
+ return { ok: false, error };
231
+ }
232
+ if (snapshot.modelVersion === pipeline.targetVersion) {
233
+ return { ok: true, snapshot };
234
+ }
235
+ let current = { ...snapshot };
236
+ for (let version = current.modelVersion + 1; version <= pipeline.targetVersion; version++) {
237
+ const fn = pipeline.migrations.get(version);
238
+ if (!fn) {
239
+ const error = new MigrationError(
240
+ version - 1,
241
+ version,
242
+ new Error(`No migration function found for version ${version}`)
243
+ );
244
+ options?.onError?.(error);
245
+ return { ok: false, error };
246
+ }
247
+ const fromVersion = version - 1;
248
+ try {
249
+ current = { ...fn(current), modelVersion: version };
250
+ } catch (cause) {
251
+ const error = new MigrationError(fromVersion, version, cause);
252
+ options?.onError?.(error);
253
+ return { ok: false, error };
254
+ }
255
+ options?.onStep?.(fromVersion, version, current);
256
+ }
257
+ return { ok: true, snapshot: current };
258
+ }
259
+
260
+ // src/plugin.ts
261
+ var PLUGIN_SYMBOL = /* @__PURE__ */ Symbol.for("ryte:plugin");
262
+ function definePlugin(fn) {
263
+ const plugin = fn;
264
+ Object.defineProperty(plugin, PLUGIN_SYMBOL, { value: true, writable: false });
265
+ return plugin;
266
+ }
267
+ function isPlugin(value) {
268
+ return typeof value === "function" && PLUGIN_SYMBOL in value;
269
+ }
270
+
86
271
  // src/compose.ts
87
272
  function compose(middleware) {
88
273
  return async (ctx) => {
@@ -98,24 +283,6 @@ function compose(middleware) {
98
283
  };
99
284
  }
100
285
 
101
- // src/types.ts
102
- var ValidationError = class extends Error {
103
- constructor(source, issues) {
104
- super(`Validation failed (${source}): ${issues.map((i) => i.message).join(", ")}`);
105
- this.source = source;
106
- this.issues = issues;
107
- this.name = "ValidationError";
108
- }
109
- };
110
- var DomainErrorSignal = class extends Error {
111
- constructor(code, data) {
112
- super(`Domain error: ${code}`);
113
- this.code = code;
114
- this.data = data;
115
- this.name = "DomainErrorSignal";
116
- }
117
- };
118
-
119
286
  // src/context.ts
120
287
  function createContext(definition, originalWorkflow, command, deps) {
121
288
  let mutableState = originalWorkflow.state;
@@ -199,6 +366,46 @@ function createContext(definition, originalWorkflow, command, deps) {
199
366
  return ctx;
200
367
  }
201
368
 
369
+ // src/hooks.ts
370
+ var HOOK_EVENTS = /* @__PURE__ */ new Set([
371
+ "dispatch:start",
372
+ "dispatch:end",
373
+ "transition",
374
+ "error",
375
+ "event"
376
+ ]);
377
+ var HookRegistry = class {
378
+ // biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event
379
+ hooks = /* @__PURE__ */ new Map();
380
+ /** Register a callback for a hook event. */
381
+ // biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event
382
+ add(event, callback) {
383
+ const existing = this.hooks.get(event) ?? [];
384
+ existing.push(callback);
385
+ this.hooks.set(event, existing);
386
+ }
387
+ /** Emit a hook event, calling all registered callbacks. Errors are caught and forwarded. */
388
+ async emit(event, onError, ...args) {
389
+ const callbacks = this.hooks.get(event);
390
+ if (!callbacks) return;
391
+ for (const cb of callbacks) {
392
+ try {
393
+ await cb(...args);
394
+ } catch (err) {
395
+ onError(err);
396
+ }
397
+ }
398
+ }
399
+ /** Merge another registry's hooks into this one (used by composable routers). */
400
+ merge(other) {
401
+ for (const [event, callbacks] of other.hooks) {
402
+ const existing = this.hooks.get(event) ?? [];
403
+ existing.push(...callbacks);
404
+ this.hooks.set(event, existing);
405
+ }
406
+ }
407
+ };
408
+
202
409
  // src/router.ts
203
410
  var StateBuilder = class {
204
411
  /** @internal */
@@ -221,9 +428,10 @@ var StateBuilder = class {
221
428
  }
222
429
  };
223
430
  var WorkflowRouter = class _WorkflowRouter {
224
- constructor(definition, deps = {}) {
431
+ constructor(definition, deps = {}, options = {}) {
225
432
  this.definition = definition;
226
433
  this.deps = deps;
434
+ this.onHookError = options.onHookError ?? console.error;
227
435
  }
228
436
  globalMiddleware = [];
229
437
  // biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types
@@ -231,12 +439,16 @@ var WorkflowRouter = class _WorkflowRouter {
231
439
  // biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types
232
440
  multiStateBuilders = /* @__PURE__ */ new Map();
233
441
  wildcardHandlers = /* @__PURE__ */ new Map();
234
- /** Adds global middleware or merges another router's handlers. */
235
- use(middlewareOrRouter) {
236
- if (middlewareOrRouter instanceof _WorkflowRouter) {
237
- this.merge(middlewareOrRouter);
442
+ hookRegistry = new HookRegistry();
443
+ onHookError;
444
+ /** Adds global middleware, merges another router, or applies a plugin. */
445
+ use(arg) {
446
+ if (arg instanceof _WorkflowRouter) {
447
+ this.merge(arg);
448
+ } else if (isPlugin(arg)) {
449
+ arg(this);
238
450
  } else {
239
- this.globalMiddleware.push(middlewareOrRouter);
451
+ this.globalMiddleware.push(arg);
240
452
  }
241
453
  return this;
242
454
  }
@@ -257,6 +469,7 @@ var WorkflowRouter = class _WorkflowRouter {
257
469
  });
258
470
  }
259
471
  }
472
+ this.hookRegistry.merge(child.hookRegistry);
260
473
  }
261
474
  mergeStateBuilders(target, source) {
262
475
  for (const [stateName, childBuilder] of source) {
@@ -291,19 +504,29 @@ var WorkflowRouter = class _WorkflowRouter {
291
504
  }
292
505
  return this;
293
506
  }
294
- /** Registers a wildcard handler that matches any state. */
295
- on(_state, command, ...fns) {
296
- if (fns.length === 0) throw new Error("on() requires at least a handler");
297
- const handler = fns.pop();
298
- const inlineMiddleware = fns;
299
- const wrappedHandler = async (ctx, _next) => {
300
- await handler(ctx);
301
- };
302
- this.wildcardHandlers.set(command, {
303
- inlineMiddleware,
304
- handler: wrappedHandler
305
- });
306
- return this;
507
+ // biome-ignore lint/suspicious/noExplicitAny: implementation signature must be loose to handle all overloads
508
+ on(...args) {
509
+ const first = args[0];
510
+ if (HOOK_EVENTS.has(first)) {
511
+ this.hookRegistry.add(first, args[1]);
512
+ return this;
513
+ }
514
+ if (first === "*") {
515
+ const command = args[1];
516
+ const fns = args.slice(2);
517
+ if (fns.length === 0) throw new Error("on() requires at least a handler");
518
+ const handler = fns.pop();
519
+ const inlineMiddleware = fns;
520
+ const wrappedHandler = async (ctx, _next) => {
521
+ await handler(ctx);
522
+ };
523
+ this.wildcardHandlers.set(command, {
524
+ inlineMiddleware,
525
+ handler: wrappedHandler
526
+ });
527
+ return this;
528
+ }
529
+ throw new Error(`Unknown event or state: ${first}`);
307
530
  }
308
531
  /** Dispatches a command to the appropriate handler and returns the result. */
309
532
  async dispatch(workflow, command) {
@@ -377,17 +600,35 @@ var WorkflowRouter = class _WorkflowRouter {
377
600
  validatedCommand,
378
601
  this.deps
379
602
  );
603
+ await this.hookRegistry.emit("dispatch:start", this.onHookError, ctx);
380
604
  try {
381
605
  const composed = compose(chain);
382
606
  await composed(ctx);
383
- return {
607
+ const result = {
384
608
  ok: true,
385
609
  workflow: ctx.getWorkflowSnapshot(),
386
610
  events: [...ctx.events]
387
611
  };
612
+ if (result.ok && result.workflow.state !== workflow.state) {
613
+ await this.hookRegistry.emit(
614
+ "transition",
615
+ this.onHookError,
616
+ workflow.state,
617
+ result.workflow.state,
618
+ result.workflow
619
+ );
620
+ }
621
+ if (result.ok) {
622
+ for (const event of result.events) {
623
+ await this.hookRegistry.emit("event", this.onHookError, event, result.workflow);
624
+ }
625
+ }
626
+ await this.hookRegistry.emit("dispatch:end", this.onHookError, ctx, result);
627
+ return result;
388
628
  } catch (err) {
629
+ let result;
389
630
  if (err instanceof DomainErrorSignal) {
390
- return {
631
+ result = {
391
632
  ok: false,
392
633
  error: {
393
634
  category: "domain",
@@ -395,9 +636,8 @@ var WorkflowRouter = class _WorkflowRouter {
395
636
  data: err.data
396
637
  }
397
638
  };
398
- }
399
- if (err instanceof ValidationError) {
400
- return {
639
+ } else if (err instanceof ValidationError) {
640
+ result = {
401
641
  ok: false,
402
642
  error: {
403
643
  category: "validation",
@@ -406,17 +646,26 @@ var WorkflowRouter = class _WorkflowRouter {
406
646
  message: err.message
407
647
  }
408
648
  };
649
+ } else {
650
+ throw err;
409
651
  }
410
- throw err;
652
+ await this.hookRegistry.emit("error", this.onHookError, result.error, ctx);
653
+ await this.hookRegistry.emit("dispatch:end", this.onHookError, ctx, result);
654
+ return result;
411
655
  }
412
656
  }
413
657
  };
414
658
  // Annotate the CommonJS export names for ESM import in node:
415
659
  0 && (module.exports = {
416
660
  DomainErrorSignal,
661
+ MigrationError,
417
662
  ValidationError,
418
663
  WorkflowRouter,
419
664
  createKey,
420
- defineWorkflow
665
+ defineMigrations,
666
+ definePlugin,
667
+ defineWorkflow,
668
+ isPlugin,
669
+ migrate
421
670
  });
422
671
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/definition.ts","../src/key.ts","../src/compose.ts","../src/types.ts","../src/context.ts","../src/router.ts"],"sourcesContent":["export type { Context } from \"./context.js\";\nexport type { WorkflowDefinition } from \"./definition.js\";\nexport { defineWorkflow } from \"./definition.js\";\nexport type { Handler } from \"./handler.js\";\nexport type { ContextKey } from \"./key.js\";\nexport { createKey } from \"./key.js\";\nexport type { Middleware } from \"./middleware.js\";\nexport { WorkflowRouter } from \"./router.js\";\nexport type {\n\tCommandNames,\n\tCommandPayload,\n\tDispatchResult,\n\tErrorCodes,\n\tErrorData,\n\tEventData,\n\tEventNames,\n\tPipelineError,\n\tStateData,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n\tWorkflowOf,\n} from \"./types.js\";\nexport { DomainErrorSignal, ValidationError } from \"./types.js\";\n","import type { ZodType, z } from \"zod\";\nimport type { StateNames, WorkflowConfig, WorkflowOf } from \"./types.js\";\n\n/** The result of defineWorkflow() — holds schemas and creates workflow instances. */\nexport interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {\n\treadonly config: TConfig;\n\treadonly name: string;\n\tcreateWorkflow<S extends StateNames<TConfig>>(\n\t\tid: string,\n\t\tconfig: { initialState: S; data: z.infer<TConfig[\"states\"][S]> },\n\t): WorkflowOf<TConfig, S>;\n\tgetStateSchema(stateName: string): ZodType;\n\tgetCommandSchema(commandName: string): ZodType;\n\tgetEventSchema(eventName: string): ZodType;\n\tgetErrorSchema(errorCode: string): ZodType;\n\thasState(stateName: string): boolean;\n}\n\n/**\n * Creates a workflow definition from a name and Zod schema configuration.\n */\nexport function defineWorkflow<const TConfig extends WorkflowConfig>(\n\tname: string,\n\tconfig: TConfig,\n): WorkflowDefinition<TConfig> {\n\treturn {\n\t\tconfig,\n\t\tname,\n\n\t\tcreateWorkflow(id, wfConfig) {\n\t\t\tconst schema = config.states[wfConfig.initialState as string];\n\t\t\tif (!schema) throw new Error(`Unknown state: ${wfConfig.initialState as string}`);\n\t\t\tconst result = schema.safeParse(wfConfig.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid initial data for state '${wfConfig.initialState as string}': ${result.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst now = new Date();\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tdefinitionName: name,\n\t\t\t\tstate: wfConfig.initialState,\n\t\t\t\tdata: result.data,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t} as WorkflowOf<TConfig, typeof wfConfig.initialState>;\n\t\t},\n\n\t\tgetStateSchema(stateName: string): ZodType {\n\t\t\tconst schema = config.states[stateName];\n\t\t\tif (!schema) throw new Error(`Unknown state: ${stateName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetCommandSchema(commandName: string): ZodType {\n\t\t\tconst schema = config.commands[commandName];\n\t\t\tif (!schema) throw new Error(`Unknown command: ${commandName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetEventSchema(eventName: string): ZodType {\n\t\t\tconst schema = config.events[eventName];\n\t\t\tif (!schema) throw new Error(`Unknown event: ${eventName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetErrorSchema(errorCode: string): ZodType {\n\t\t\tconst schema = config.errors[errorCode];\n\t\t\tif (!schema) throw new Error(`Unknown error: ${errorCode}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\thasState(stateName: string): boolean {\n\t\t\treturn stateName in config.states;\n\t\t},\n\t};\n}\n","/** A phantom-typed key for type-safe middleware state storage. */\nexport interface ContextKey<T> {\n\treadonly _phantom: T;\n\treadonly id: symbol;\n}\n\n/** Creates a unique typed key for storing/retrieving values in context. */\nexport function createKey<T>(name: string): ContextKey<T> {\n\treturn { id: Symbol(name) } as ContextKey<T>;\n}\n","type Middleware<TCtx> = (ctx: TCtx, next: () => Promise<void>) => Promise<void>;\n\n/** Composes an array of middleware into a single function (Koa-style onion model). */\nexport function compose<TCtx>(middleware: Middleware<TCtx>[]): (ctx: TCtx) => Promise<void> {\n\treturn async (ctx: TCtx) => {\n\t\tlet index = -1;\n\t\tasync function dispatch(i: number): Promise<void> {\n\t\t\tif (i <= index) throw new Error(\"next() called multiple times\");\n\t\t\tindex = i;\n\t\t\tconst fn = middleware[i];\n\t\t\tif (!fn) return;\n\t\t\tawait fn(ctx, () => dispatch(i + 1));\n\t\t}\n\t\tawait dispatch(0);\n\t};\n}\n","import type { ZodType, z } from \"zod\";\n\nexport interface WorkflowConfig {\n\tstates: Record<string, ZodType>;\n\tcommands: Record<string, ZodType>;\n\tevents: Record<string, ZodType>;\n\terrors: Record<string, ZodType>;\n}\n\nexport type StateNames<T extends WorkflowConfig> = keyof T[\"states\"] & string;\nexport type CommandNames<T extends WorkflowConfig> = keyof T[\"commands\"] & string;\nexport type EventNames<T extends WorkflowConfig> = keyof T[\"events\"] & string;\nexport type ErrorCodes<T extends WorkflowConfig> = keyof T[\"errors\"] & string;\n\nexport type StateData<\n\tT extends WorkflowConfig,\n\tS extends StateNames<T>,\n> = T[\"states\"][S] extends ZodType ? z.infer<T[\"states\"][S]> : never;\n\nexport type CommandPayload<\n\tT extends WorkflowConfig,\n\tC extends CommandNames<T>,\n> = T[\"commands\"][C] extends ZodType ? z.infer<T[\"commands\"][C]> : never;\n\nexport type EventData<\n\tT extends WorkflowConfig,\n\tE extends EventNames<T>,\n> = T[\"events\"][E] extends ZodType ? z.infer<T[\"events\"][E]> : never;\n\nexport type ErrorData<\n\tT extends WorkflowConfig,\n\tC extends ErrorCodes<T>,\n> = T[\"errors\"][C] extends ZodType ? z.infer<T[\"errors\"][C]> : never;\n\n/** Workflow narrowed to a specific known state. */\nexport interface WorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {\n\treadonly id: string;\n\treadonly definitionName: string;\n\treadonly state: S;\n\treadonly data: StateData<TConfig, S>;\n\treadonly createdAt: Date;\n\treadonly updatedAt: Date;\n}\n\n/** Discriminated union of all possible workflow states — checking .state narrows .data. */\nexport type Workflow<TConfig extends WorkflowConfig = WorkflowConfig> = {\n\t[S in StateNames<TConfig>]: WorkflowOf<TConfig, S>;\n}[StateNames<TConfig>];\n\nexport type PipelineError<TConfig extends WorkflowConfig = WorkflowConfig> =\n\t| {\n\t\t\tcategory: \"validation\";\n\t\t\tsource: \"command\" | \"state\" | \"event\" | \"transition\";\n\t\t\tissues: z.core.$ZodIssue[];\n\t\t\tmessage: string;\n\t }\n\t| {\n\t\t\tcategory: \"domain\";\n\t\t\tcode: ErrorCodes<TConfig>;\n\t\t\tdata: ErrorData<TConfig, ErrorCodes<TConfig>>;\n\t }\n\t| {\n\t\t\tcategory: \"router\";\n\t\t\tcode: \"NO_HANDLER\" | \"UNKNOWN_STATE\";\n\t\t\tmessage: string;\n\t };\n\nexport type DispatchResult<TConfig extends WorkflowConfig = WorkflowConfig> =\n\t| {\n\t\t\tok: true;\n\t\t\tworkflow: Workflow<TConfig>;\n\t\t\tevents: Array<{ type: EventNames<TConfig>; data: unknown }>;\n\t }\n\t| {\n\t\t\tok: false;\n\t\t\terror: PipelineError<TConfig>;\n\t };\n\n/** Thrown internally when Zod validation fails during dispatch. */\nexport class ValidationError extends Error {\n\tconstructor(\n\t\tpublic readonly source: \"command\" | \"state\" | \"event\" | \"transition\",\n\t\tpublic readonly issues: z.core.$ZodIssue[],\n\t) {\n\t\tsuper(`Validation failed (${source}): ${issues.map((i) => i.message).join(\", \")}`);\n\t\tthis.name = \"ValidationError\";\n\t}\n}\n\n/** Thrown internally when a handler calls ctx.error(). Caught by the router. */\nexport class DomainErrorSignal extends Error {\n\tconstructor(\n\t\tpublic readonly code: string,\n\t\tpublic readonly data: unknown,\n\t) {\n\t\tsuper(`Domain error: ${code}`);\n\t\tthis.name = \"DomainErrorSignal\";\n\t}\n}\n","import type { WorkflowDefinition } from \"./definition.js\";\nimport type { ContextKey } from \"./key.js\";\nimport type {\n\tCommandNames,\n\tCommandPayload,\n\tErrorCodes,\n\tErrorData,\n\tEventData,\n\tEventNames,\n\tStateData,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n\tWorkflowOf,\n} from \"./types.js\";\nimport { DomainErrorSignal, ValidationError } from \"./types.js\";\n\n/** Mutable context flowing through the middleware pipeline during dispatch. */\nexport interface Context<\n\tTConfig extends WorkflowConfig,\n\tTDeps,\n\tTState extends StateNames<TConfig> = StateNames<TConfig>,\n\tTCommand extends CommandNames<TConfig> = CommandNames<TConfig>,\n> {\n\treadonly command: {\n\t\treadonly type: TCommand;\n\t\treadonly payload: CommandPayload<TConfig, TCommand>;\n\t};\n\treadonly workflow: WorkflowOf<TConfig, TState>;\n\treadonly deps: TDeps;\n\n\treadonly data: StateData<TConfig, TState>;\n\tupdate(data: Partial<StateData<TConfig, TState>>): void;\n\n\ttransition<Target extends StateNames<TConfig>>(\n\t\ttarget: Target,\n\t\tdata: StateData<TConfig, Target>,\n\t): void;\n\n\temit<E extends EventNames<TConfig>>(event: { type: E; data: EventData<TConfig, E> }): void;\n\treadonly events: ReadonlyArray<{ type: EventNames<TConfig>; data: unknown }>;\n\n\terror<C extends ErrorCodes<TConfig>>(err: { code: C; data: ErrorData<TConfig, C> }): never;\n\n\tset<T>(key: ContextKey<T>, value: T): void;\n\tget<T>(key: ContextKey<T>): T;\n\tgetOrNull<T>(key: ContextKey<T>): T | undefined;\n\n\t/** @internal — not part of the handler API */\n\tgetWorkflowSnapshot(): Workflow<TConfig>;\n}\n\ninterface DomainEvent {\n\ttype: string;\n\tdata: unknown;\n}\n\n/** @internal Creates a context for dispatch. Not part of public API. */\nexport function createContext<TConfig extends WorkflowConfig, TDeps>(\n\tdefinition: WorkflowDefinition<TConfig>,\n\toriginalWorkflow: Workflow<TConfig>,\n\tcommand: { type: string; payload: unknown },\n\tdeps: TDeps,\n): Context<TConfig, TDeps> {\n\tlet mutableState = originalWorkflow.state;\n\tlet mutableData: Record<string, unknown> = {\n\t\t...(originalWorkflow.data as Record<string, unknown>),\n\t};\n\n\tconst accumulatedEvents: DomainEvent[] = [];\n\tconst middlewareState = new Map<symbol, unknown>();\n\n\tconst ctx = {\n\t\tcommand,\n\t\tworkflow: originalWorkflow,\n\t\tdeps,\n\n\t\tget data() {\n\t\t\treturn { ...mutableData } as StateData<TConfig, StateNames<TConfig>>;\n\t\t},\n\n\t\tupdate(data: Record<string, unknown>) {\n\t\t\tconst merged = { ...mutableData, ...data };\n\t\t\tconst schema = definition.getStateSchema(mutableState);\n\t\t\tconst result = schema.safeParse(merged);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"state\", result.error.issues);\n\t\t\t}\n\t\t\tmutableData = result.data as Record<string, unknown>;\n\t\t},\n\n\t\ttransition(target: string, data: unknown) {\n\t\t\tif (!definition.hasState(target)) {\n\t\t\t\tthrow new Error(`Unknown state: ${target}`);\n\t\t\t}\n\t\t\tconst schema = definition.getStateSchema(target);\n\t\t\tconst result = schema.safeParse(data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"transition\", result.error.issues);\n\t\t\t}\n\t\t\tmutableState = target;\n\t\t\tmutableData = result.data as Record<string, unknown>;\n\t\t},\n\n\t\temit(event: { type: string; data: unknown }) {\n\t\t\tconst schema = definition.getEventSchema(event.type);\n\t\t\tconst result = schema.safeParse(event.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"event\", result.error.issues);\n\t\t\t}\n\t\t\taccumulatedEvents.push({ type: event.type, data: result.data });\n\t\t},\n\n\t\tget events() {\n\t\t\treturn [...accumulatedEvents];\n\t\t},\n\n\t\terror(err: { code: string; data: unknown }) {\n\t\t\tconst schema = definition.getErrorSchema(err.code);\n\t\t\tconst result = schema.safeParse(err.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid error data for '${err.code}': ${result.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new DomainErrorSignal(err.code, result.data);\n\t\t},\n\n\t\tset<T>(key: ContextKey<T>, value: T) {\n\t\t\tmiddlewareState.set(key.id, value);\n\t\t},\n\n\t\tget<T>(key: ContextKey<T>): T {\n\t\t\tif (!middlewareState.has(key.id)) {\n\t\t\t\tthrow new Error(`Context key not set: ${key.id.toString()}`);\n\t\t\t}\n\t\t\treturn middlewareState.get(key.id) as T;\n\t\t},\n\n\t\tgetOrNull<T>(key: ContextKey<T>): T | undefined {\n\t\t\treturn middlewareState.get(key.id) as T | undefined;\n\t\t},\n\n\t\tgetWorkflowSnapshot(): Workflow<TConfig> {\n\t\t\treturn {\n\t\t\t\tid: originalWorkflow.id,\n\t\t\t\tdefinitionName: originalWorkflow.definitionName,\n\t\t\t\tstate: mutableState,\n\t\t\t\tdata: { ...mutableData },\n\t\t\t\tcreatedAt: originalWorkflow.createdAt,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t} as Workflow<TConfig>;\n\t\t},\n\t};\n\n\treturn ctx as unknown as Context<TConfig, TDeps>;\n}\n","import { compose } from \"./compose.js\";\nimport { type Context, createContext } from \"./context.js\";\nimport type { WorkflowDefinition } from \"./definition.js\";\nimport type {\n\tCommandNames,\n\tDispatchResult,\n\tErrorCodes,\n\tErrorData,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n} from \"./types.js\";\nimport { DomainErrorSignal, ValidationError } from \"./types.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: internal type erasure for heterogeneous middleware storage\ntype AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;\n// biome-ignore lint/suspicious/noExplicitAny: internal type erasure for heterogeneous handler storage\ntype AnyHandler = (ctx: any) => void | Promise<void>;\n\ntype HandlerEntry = { inlineMiddleware: AnyMiddleware[]; handler: AnyMiddleware };\n\nclass StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {\n\t/** @internal */ readonly middleware: AnyMiddleware[] = [];\n\t/** @internal */ readonly handlers = new Map<string, HandlerEntry>();\n\n\ton<C extends CommandNames<TConfig>>(\n\t\tcommand: C,\n\t\t...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]\n\t): this {\n\t\tif (fns.length === 0) throw new Error(\"on() requires at least a handler\");\n\t\tconst handler = fns.pop() as AnyHandler;\n\t\tconst inlineMiddleware = fns as AnyMiddleware[];\n\t\tconst wrappedHandler: AnyMiddleware = async (ctx, _next) => {\n\t\t\tawait handler(ctx);\n\t\t};\n\t\tthis.handlers.set(command as string, { inlineMiddleware, handler: wrappedHandler });\n\t\treturn this;\n\t}\n\n\tuse(\n\t\tmiddleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>,\n\t): this {\n\t\tthis.middleware.push(middleware as AnyMiddleware);\n\t\treturn this;\n\t}\n}\n\n/**\n * Routes commands to handlers based on workflow state.\n *\n * Supports global middleware, state-scoped middleware, inline middleware,\n * wildcard handlers, and multi-state handlers.\n */\n// biome-ignore lint/complexity/noBannedTypes: {} is correct here — TDeps defaults to \"no deps\", inferred away when deps are provided\nexport class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {\n\tprivate globalMiddleware: AnyMiddleware[] = [];\n\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\tprivate singleStateBuilders = new Map<string, StateBuilder<TConfig, TDeps, any>>();\n\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\tprivate multiStateBuilders = new Map<string, StateBuilder<TConfig, TDeps, any>>();\n\tprivate wildcardHandlers = new Map<string, HandlerEntry>();\n\n\tconstructor(\n\t\tprivate readonly definition: WorkflowDefinition<TConfig>,\n\t\tprivate readonly deps: TDeps = {} as TDeps,\n\t) {}\n\n\t/** Adds global middleware or merges another router's handlers. */\n\tuse(\n\t\tmiddlewareOrRouter:\n\t\t\t| ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>)\n\t\t\t| WorkflowRouter<TConfig, TDeps>,\n\t): this {\n\t\tif (middlewareOrRouter instanceof WorkflowRouter) {\n\t\t\tthis.merge(middlewareOrRouter);\n\t\t} else {\n\t\t\tthis.globalMiddleware.push(middlewareOrRouter as AnyMiddleware);\n\t\t}\n\t\treturn this;\n\t}\n\n\tprivate merge(child: WorkflowRouter<TConfig, TDeps>): void {\n\t\tif (child.definition !== this.definition) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot merge router for '${child.definition.name}' into router for '${this.definition.name}': definition mismatch`,\n\t\t\t);\n\t\t}\n\n\t\tthis.globalMiddleware.push(...child.globalMiddleware);\n\t\tthis.mergeStateBuilders(this.singleStateBuilders, child.singleStateBuilders);\n\t\tthis.mergeStateBuilders(this.multiStateBuilders, child.multiStateBuilders);\n\n\t\tfor (const [command, entry] of child.wildcardHandlers) {\n\t\t\tif (!this.wildcardHandlers.has(command)) {\n\t\t\t\tthis.wildcardHandlers.set(command, {\n\t\t\t\t\tinlineMiddleware: [...entry.inlineMiddleware],\n\t\t\t\t\thandler: entry.handler,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate mergeStateBuilders(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\t\ttarget: Map<string, StateBuilder<TConfig, TDeps, any>>,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\t\tsource: Map<string, StateBuilder<TConfig, TDeps, any>>,\n\t): void {\n\t\tfor (const [stateName, childBuilder] of source) {\n\t\t\tlet parentBuilder = target.get(stateName);\n\t\t\tif (!parentBuilder) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — state name is dynamic at runtime\n\t\t\t\tparentBuilder = new StateBuilder<TConfig, TDeps, any>();\n\t\t\t\ttarget.set(stateName, parentBuilder);\n\t\t\t}\n\t\t\tfor (const [command, entry] of childBuilder.handlers) {\n\t\t\t\tif (!parentBuilder.handlers.has(command)) {\n\t\t\t\t\tparentBuilder.handlers.set(command, {\n\t\t\t\t\t\tinlineMiddleware: [...entry.inlineMiddleware],\n\t\t\t\t\t\thandler: entry.handler,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tparentBuilder.middleware.push(...childBuilder.middleware);\n\t\t}\n\t}\n\n\t/** Registers handlers for one or more states. */\n\tstate<P extends StateNames<TConfig> | readonly StateNames<TConfig>[]>(\n\t\tname: P,\n\t\tsetup: (\n\t\t\tstate: StateBuilder<\n\t\t\t\tTConfig,\n\t\t\t\tTDeps,\n\t\t\t\tP extends readonly (infer S)[] ? S & StateNames<TConfig> : P & StateNames<TConfig>\n\t\t\t>,\n\t\t) => void,\n\t): this {\n\t\tconst names = Array.isArray(name) ? name : [name];\n\t\tconst isMulti = Array.isArray(name);\n\t\tconst routerMap = isMulti ? this.multiStateBuilders : this.singleStateBuilders;\n\n\t\tfor (const n of names as string[]) {\n\t\t\tlet router = routerMap.get(n);\n\t\t\tif (!router) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — state name is dynamic at runtime\n\t\t\t\trouter = new StateBuilder<TConfig, TDeps, any>();\n\t\t\t\trouterMap.set(n, router);\n\t\t\t}\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — setup callback expects a specific state type\n\t\t\tsetup(router as any);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Registers a wildcard handler that matches any state. */\n\ton<C extends CommandNames<TConfig>>(\n\t\t_state: \"*\",\n\t\tcommand: C,\n\t\t...fns: [\n\t\t\t...AnyMiddleware[],\n\t\t\t(ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>,\n\t\t]\n\t): this {\n\t\tif (fns.length === 0) throw new Error(\"on() requires at least a handler\");\n\t\tconst handler = fns.pop() as AnyHandler;\n\t\tconst inlineMiddleware = fns as AnyMiddleware[];\n\t\tconst wrappedHandler: AnyMiddleware = async (ctx, _next) => {\n\t\t\tawait handler(ctx);\n\t\t};\n\t\tthis.wildcardHandlers.set(command as string, {\n\t\t\tinlineMiddleware,\n\t\t\thandler: wrappedHandler,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Dispatches a command to the appropriate handler and returns the result. */\n\tasync dispatch(\n\t\tworkflow: Workflow<TConfig>,\n\t\tcommand: { type: CommandNames<TConfig>; payload: unknown },\n\t): Promise<DispatchResult<TConfig>> {\n\t\tif (!this.definition.hasState(workflow.state)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"router\",\n\t\t\t\t\tcode: \"UNKNOWN_STATE\",\n\t\t\t\t\tmessage: `Unknown state: ${workflow.state}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst commandSchema = this.definition.getCommandSchema(command.type);\n\t\tconst payloadResult = commandSchema.safeParse(command.payload);\n\t\tif (!payloadResult.success) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"validation\",\n\t\t\t\t\tsource: \"command\",\n\t\t\t\t\tissues: payloadResult.error.issues,\n\t\t\t\t\tmessage: `Invalid command payload: ${payloadResult.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconst validatedCommand = { type: command.type, payload: payloadResult.data };\n\n\t\tconst stateName = workflow.state;\n\t\tconst singleRouter = this.singleStateBuilders.get(stateName);\n\t\tconst multiRouter = this.multiStateBuilders.get(stateName);\n\t\tconst singleHandler = singleRouter?.handlers.get(command.type);\n\t\tconst multiHandler = multiRouter?.handlers.get(command.type);\n\t\tconst wildcardHandler = this.wildcardHandlers.get(command.type);\n\n\t\tlet routeEntry: HandlerEntry | undefined;\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — matched router's state type is dynamic\n\t\tlet matchedRouter: StateBuilder<TConfig, TDeps, any> | undefined;\n\n\t\tif (singleHandler) {\n\t\t\trouteEntry = singleHandler;\n\t\t\tmatchedRouter = singleRouter;\n\t\t} else if (multiHandler) {\n\t\t\trouteEntry = multiHandler;\n\t\t\tmatchedRouter = multiRouter;\n\t\t} else if (wildcardHandler) {\n\t\t\trouteEntry = wildcardHandler;\n\t\t\tmatchedRouter = undefined;\n\t\t}\n\n\t\tif (!routeEntry) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"router\",\n\t\t\t\t\tcode: \"NO_HANDLER\",\n\t\t\t\t\tmessage: `No handler for command '${command.type}' in state '${stateName}'`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst stateMiddleware: AnyMiddleware[] = [];\n\t\tif (matchedRouter) {\n\t\t\tif (singleRouter) stateMiddleware.push(...singleRouter.middleware);\n\t\t\tif (multiRouter && multiRouter !== singleRouter)\n\t\t\t\tstateMiddleware.push(...multiRouter.middleware);\n\t\t}\n\n\t\tconst chain: AnyMiddleware[] = [\n\t\t\t...this.globalMiddleware,\n\t\t\t...stateMiddleware,\n\t\t\t...routeEntry.inlineMiddleware,\n\t\t\trouteEntry.handler,\n\t\t];\n\n\t\tconst ctx = createContext<TConfig, TDeps>(\n\t\t\tthis.definition,\n\t\t\tworkflow,\n\t\t\tvalidatedCommand,\n\t\t\tthis.deps,\n\t\t);\n\n\t\ttry {\n\t\t\tconst composed = compose(chain);\n\t\t\tawait composed(ctx);\n\t\t\treturn {\n\t\t\t\tok: true as const,\n\t\t\t\tworkflow: ctx.getWorkflowSnapshot(),\n\t\t\t\tevents: [...ctx.events],\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tif (err instanceof DomainErrorSignal) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"domain\" as const,\n\t\t\t\t\t\tcode: err.code as ErrorCodes<TConfig>,\n\t\t\t\t\t\tdata: err.data as ErrorData<TConfig, ErrorCodes<TConfig>>,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (err instanceof ValidationError) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"validation\" as const,\n\t\t\t\t\t\tsource: err.source,\n\t\t\t\t\t\tissues: err.issues,\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqBO,SAAS,eACf,MACA,QAC8B;AAC9B,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IAEA,eAAe,IAAI,UAAU;AAC5B,YAAM,SAAS,OAAO,OAAO,SAAS,YAAsB;AAC5D,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,kBAAkB,SAAS,YAAsB,EAAE;AAChF,YAAM,SAAS,OAAO,UAAU,SAAS,IAAI;AAC7C,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,IAAI;AAAA,UACT,mCAAmC,SAAS,YAAsB,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QAC7H;AAAA,MACD;AACA,YAAM,MAAM,oBAAI,KAAK;AACrB,aAAO;AAAA,QACN;AAAA,QACA,gBAAgB;AAAA,QAChB,OAAO,SAAS;AAAA,QAChB,MAAM,OAAO;AAAA,QACb,WAAW;AAAA,QACX,WAAW;AAAA,MACZ;AAAA,IACD;AAAA,IAEA,eAAe,WAA4B;AAC1C,YAAM,SAAS,OAAO,OAAO,SAAS;AACtC,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,kBAAkB,SAAS,EAAE;AAC1D,aAAO;AAAA,IACR;AAAA,IAEA,iBAAiB,aAA8B;AAC9C,YAAM,SAAS,OAAO,SAAS,WAAW;AAC1C,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,oBAAoB,WAAW,EAAE;AAC9D,aAAO;AAAA,IACR;AAAA,IAEA,eAAe,WAA4B;AAC1C,YAAM,SAAS,OAAO,OAAO,SAAS;AACtC,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,kBAAkB,SAAS,EAAE;AAC1D,aAAO;AAAA,IACR;AAAA,IAEA,eAAe,WAA4B;AAC1C,YAAM,SAAS,OAAO,OAAO,SAAS;AACtC,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,kBAAkB,SAAS,EAAE;AAC1D,aAAO;AAAA,IACR;AAAA,IAEA,SAAS,WAA4B;AACpC,aAAO,aAAa,OAAO;AAAA,IAC5B;AAAA,EACD;AACD;;;ACtEO,SAAS,UAAa,MAA6B;AACzD,SAAO,EAAE,IAAI,OAAO,IAAI,EAAE;AAC3B;;;ACNO,SAAS,QAAc,YAA8D;AAC3F,SAAO,OAAO,QAAc;AAC3B,QAAI,QAAQ;AACZ,mBAAe,SAAS,GAA0B;AACjD,UAAI,KAAK,MAAO,OAAM,IAAI,MAAM,8BAA8B;AAC9D,cAAQ;AACR,YAAM,KAAK,WAAW,CAAC;AACvB,UAAI,CAAC,GAAI;AACT,YAAM,GAAG,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,SAAS,CAAC;AAAA,EACjB;AACD;;;ACgEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAC1C,YACiB,QACA,QACf;AACD,UAAM,sBAAsB,MAAM,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AAHjE;AACA;AAGhB,SAAK,OAAO;AAAA,EACb;AACD;AAGO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC5C,YACiB,MACA,MACf;AACD,UAAM,iBAAiB,IAAI,EAAE;AAHb;AACA;AAGhB,SAAK,OAAO;AAAA,EACb;AACD;;;ACxCO,SAAS,cACf,YACA,kBACA,SACA,MAC0B;AAC1B,MAAI,eAAe,iBAAiB;AACpC,MAAI,cAAuC;AAAA,IAC1C,GAAI,iBAAiB;AAAA,EACtB;AAEA,QAAM,oBAAmC,CAAC;AAC1C,QAAM,kBAAkB,oBAAI,IAAqB;AAEjD,QAAM,MAAM;AAAA,IACX;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IAEA,IAAI,OAAO;AACV,aAAO,EAAE,GAAG,YAAY;AAAA,IACzB;AAAA,IAEA,OAAO,MAA+B;AACrC,YAAM,SAAS,EAAE,GAAG,aAAa,GAAG,KAAK;AACzC,YAAM,SAAS,WAAW,eAAe,YAAY;AACrD,YAAM,SAAS,OAAO,UAAU,MAAM;AACtC,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,IAAI,gBAAgB,SAAS,OAAO,MAAM,MAAM;AAAA,MACvD;AACA,oBAAc,OAAO;AAAA,IACtB;AAAA,IAEA,WAAW,QAAgB,MAAe;AACzC,UAAI,CAAC,WAAW,SAAS,MAAM,GAAG;AACjC,cAAM,IAAI,MAAM,kBAAkB,MAAM,EAAE;AAAA,MAC3C;AACA,YAAM,SAAS,WAAW,eAAe,MAAM;AAC/C,YAAM,SAAS,OAAO,UAAU,IAAI;AACpC,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,IAAI,gBAAgB,cAAc,OAAO,MAAM,MAAM;AAAA,MAC5D;AACA,qBAAe;AACf,oBAAc,OAAO;AAAA,IACtB;AAAA,IAEA,KAAK,OAAwC;AAC5C,YAAM,SAAS,WAAW,eAAe,MAAM,IAAI;AACnD,YAAM,SAAS,OAAO,UAAU,MAAM,IAAI;AAC1C,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,IAAI,gBAAgB,SAAS,OAAO,MAAM,MAAM;AAAA,MACvD;AACA,wBAAkB,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK,CAAC;AAAA,IAC/D;AAAA,IAEA,IAAI,SAAS;AACZ,aAAO,CAAC,GAAG,iBAAiB;AAAA,IAC7B;AAAA,IAEA,MAAM,KAAsC;AAC3C,YAAM,SAAS,WAAW,eAAe,IAAI,IAAI;AACjD,YAAM,SAAS,OAAO,UAAU,IAAI,IAAI;AACxC,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,IAAI;AAAA,UACT,2BAA2B,IAAI,IAAI,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QAC9F;AAAA,MACD;AACA,YAAM,IAAI,kBAAkB,IAAI,MAAM,OAAO,IAAI;AAAA,IAClD;AAAA,IAEA,IAAO,KAAoB,OAAU;AACpC,sBAAgB,IAAI,IAAI,IAAI,KAAK;AAAA,IAClC;AAAA,IAEA,IAAO,KAAuB;AAC7B,UAAI,CAAC,gBAAgB,IAAI,IAAI,EAAE,GAAG;AACjC,cAAM,IAAI,MAAM,wBAAwB,IAAI,GAAG,SAAS,CAAC,EAAE;AAAA,MAC5D;AACA,aAAO,gBAAgB,IAAI,IAAI,EAAE;AAAA,IAClC;AAAA,IAEA,UAAa,KAAmC;AAC/C,aAAO,gBAAgB,IAAI,IAAI,EAAE;AAAA,IAClC;AAAA,IAEA,sBAAyC;AACxC,aAAO;AAAA,QACN,IAAI,iBAAiB;AAAA,QACrB,gBAAgB,iBAAiB;AAAA,QACjC,OAAO;AAAA,QACP,MAAM,EAAE,GAAG,YAAY;AAAA,QACvB,WAAW,iBAAiB;AAAA,QAC5B,WAAW,oBAAI,KAAK;AAAA,MACrB;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;;;ACvIA,IAAM,eAAN,MAA8F;AAAA;AAAA,EACnE,aAA8B,CAAC;AAAA;AAAA,EAC/B,WAAW,oBAAI,IAA0B;AAAA,EAEnE,GACC,YACG,KACI;AACP,QAAI,IAAI,WAAW,EAAG,OAAM,IAAI,MAAM,kCAAkC;AACxE,UAAM,UAAU,IAAI,IAAI;AACxB,UAAM,mBAAmB;AACzB,UAAM,iBAAgC,OAAO,KAAK,UAAU;AAC3D,YAAM,QAAQ,GAAG;AAAA,IAClB;AACA,SAAK,SAAS,IAAI,SAAmB,EAAE,kBAAkB,SAAS,eAAe,CAAC;AAClF,WAAO;AAAA,EACR;AAAA,EAEA,IACC,YACO;AACP,SAAK,WAAW,KAAK,UAA2B;AAChD,WAAO;AAAA,EACR;AACD;AASO,IAAM,iBAAN,MAAM,gBAA2D;AAAA,EAQvE,YACkB,YACA,OAAc,CAAC,GAC/B;AAFgB;AACA;AAAA,EACf;AAAA,EAVK,mBAAoC,CAAC;AAAA;AAAA,EAErC,sBAAsB,oBAAI,IAA+C;AAAA;AAAA,EAEzE,qBAAqB,oBAAI,IAA+C;AAAA,EACxE,mBAAmB,oBAAI,IAA0B;AAAA;AAAA,EAQzD,IACC,oBAGO;AACP,QAAI,8BAA8B,iBAAgB;AACjD,WAAK,MAAM,kBAAkB;AAAA,IAC9B,OAAO;AACN,WAAK,iBAAiB,KAAK,kBAAmC;AAAA,IAC/D;AACA,WAAO;AAAA,EACR;AAAA,EAEQ,MAAM,OAA6C;AAC1D,QAAI,MAAM,eAAe,KAAK,YAAY;AACzC,YAAM,IAAI;AAAA,QACT,4BAA4B,MAAM,WAAW,IAAI,sBAAsB,KAAK,WAAW,IAAI;AAAA,MAC5F;AAAA,IACD;AAEA,SAAK,iBAAiB,KAAK,GAAG,MAAM,gBAAgB;AACpD,SAAK,mBAAmB,KAAK,qBAAqB,MAAM,mBAAmB;AAC3E,SAAK,mBAAmB,KAAK,oBAAoB,MAAM,kBAAkB;AAEzE,eAAW,CAAC,SAAS,KAAK,KAAK,MAAM,kBAAkB;AACtD,UAAI,CAAC,KAAK,iBAAiB,IAAI,OAAO,GAAG;AACxC,aAAK,iBAAiB,IAAI,SAAS;AAAA,UAClC,kBAAkB,CAAC,GAAG,MAAM,gBAAgB;AAAA,UAC5C,SAAS,MAAM;AAAA,QAChB,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,mBAEP,QAEA,QACO;AACP,eAAW,CAAC,WAAW,YAAY,KAAK,QAAQ;AAC/C,UAAI,gBAAgB,OAAO,IAAI,SAAS;AACxC,UAAI,CAAC,eAAe;AAEnB,wBAAgB,IAAI,aAAkC;AACtD,eAAO,IAAI,WAAW,aAAa;AAAA,MACpC;AACA,iBAAW,CAAC,SAAS,KAAK,KAAK,aAAa,UAAU;AACrD,YAAI,CAAC,cAAc,SAAS,IAAI,OAAO,GAAG;AACzC,wBAAc,SAAS,IAAI,SAAS;AAAA,YACnC,kBAAkB,CAAC,GAAG,MAAM,gBAAgB;AAAA,YAC5C,SAAS,MAAM;AAAA,UAChB,CAAC;AAAA,QACF;AAAA,MACD;AACA,oBAAc,WAAW,KAAK,GAAG,aAAa,UAAU;AAAA,IACzD;AAAA,EACD;AAAA;AAAA,EAGA,MACC,MACA,OAOO;AACP,UAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAChD,UAAM,UAAU,MAAM,QAAQ,IAAI;AAClC,UAAM,YAAY,UAAU,KAAK,qBAAqB,KAAK;AAE3D,eAAW,KAAK,OAAmB;AAClC,UAAI,SAAS,UAAU,IAAI,CAAC;AAC5B,UAAI,CAAC,QAAQ;AAEZ,iBAAS,IAAI,aAAkC;AAC/C,kBAAU,IAAI,GAAG,MAAM;AAAA,MACxB;AAEA,YAAM,MAAa;AAAA,IACpB;AACA,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,GACC,QACA,YACG,KAII;AACP,QAAI,IAAI,WAAW,EAAG,OAAM,IAAI,MAAM,kCAAkC;AACxE,UAAM,UAAU,IAAI,IAAI;AACxB,UAAM,mBAAmB;AACzB,UAAM,iBAAgC,OAAO,KAAK,UAAU;AAC3D,YAAM,QAAQ,GAAG;AAAA,IAClB;AACA,SAAK,iBAAiB,IAAI,SAAmB;AAAA,MAC5C;AAAA,MACA,SAAS;AAAA,IACV,CAAC;AACD,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,MAAM,SACL,UACA,SACmC;AACnC,QAAI,CAAC,KAAK,WAAW,SAAS,SAAS,KAAK,GAAG;AAC9C,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,UACN,UAAU;AAAA,UACV,MAAM;AAAA,UACN,SAAS,kBAAkB,SAAS,KAAK;AAAA,QAC1C;AAAA,MACD;AAAA,IACD;AAEA,UAAM,gBAAgB,KAAK,WAAW,iBAAiB,QAAQ,IAAI;AACnE,UAAM,gBAAgB,cAAc,UAAU,QAAQ,OAAO;AAC7D,QAAI,CAAC,cAAc,SAAS;AAC3B,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,QAAQ,cAAc,MAAM;AAAA,UAC5B,SAAS,4BAA4B,cAAc,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QACjG;AAAA,MACD;AAAA,IACD;AACA,UAAM,mBAAmB,EAAE,MAAM,QAAQ,MAAM,SAAS,cAAc,KAAK;AAE3E,UAAM,YAAY,SAAS;AAC3B,UAAM,eAAe,KAAK,oBAAoB,IAAI,SAAS;AAC3D,UAAM,cAAc,KAAK,mBAAmB,IAAI,SAAS;AACzD,UAAM,gBAAgB,cAAc,SAAS,IAAI,QAAQ,IAAI;AAC7D,UAAM,eAAe,aAAa,SAAS,IAAI,QAAQ,IAAI;AAC3D,UAAM,kBAAkB,KAAK,iBAAiB,IAAI,QAAQ,IAAI;AAE9D,QAAI;AAEJ,QAAI;AAEJ,QAAI,eAAe;AAClB,mBAAa;AACb,sBAAgB;AAAA,IACjB,WAAW,cAAc;AACxB,mBAAa;AACb,sBAAgB;AAAA,IACjB,WAAW,iBAAiB;AAC3B,mBAAa;AACb,sBAAgB;AAAA,IACjB;AAEA,QAAI,CAAC,YAAY;AAChB,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,UACN,UAAU;AAAA,UACV,MAAM;AAAA,UACN,SAAS,2BAA2B,QAAQ,IAAI,eAAe,SAAS;AAAA,QACzE;AAAA,MACD;AAAA,IACD;AAEA,UAAM,kBAAmC,CAAC;AAC1C,QAAI,eAAe;AAClB,UAAI,aAAc,iBAAgB,KAAK,GAAG,aAAa,UAAU;AACjE,UAAI,eAAe,gBAAgB;AAClC,wBAAgB,KAAK,GAAG,YAAY,UAAU;AAAA,IAChD;AAEA,UAAM,QAAyB;AAAA,MAC9B,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,MACH,GAAG,WAAW;AAAA,MACd,WAAW;AAAA,IACZ;AAEA,UAAM,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACN;AAEA,QAAI;AACH,YAAM,WAAW,QAAQ,KAAK;AAC9B,YAAM,SAAS,GAAG;AAClB,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,IAAI,oBAAoB;AAAA,QAClC,QAAQ,CAAC,GAAG,IAAI,MAAM;AAAA,MACvB;AAAA,IACD,SAAS,KAAK;AACb,UAAI,eAAe,mBAAmB;AACrC,eAAO;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,YACN,UAAU;AAAA,YACV,MAAM,IAAI;AAAA,YACV,MAAM,IAAI;AAAA,UACX;AAAA,QACD;AAAA,MACD;AACA,UAAI,eAAe,iBAAiB;AACnC,eAAO;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,YACN,UAAU;AAAA,YACV,QAAQ,IAAI;AAAA,YACZ,QAAQ,IAAI;AAAA,YACZ,SAAS,IAAI;AAAA,UACd;AAAA,QACD;AAAA,MACD;AACA,YAAM;AAAA,IACP;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/definition.ts","../src/key.ts","../src/migration.ts","../src/plugin.ts","../src/compose.ts","../src/context.ts","../src/hooks.ts","../src/router.ts"],"sourcesContent":["export type { Context } from \"./context.js\";\nexport type { WorkflowDefinition } from \"./definition.js\";\nexport { defineWorkflow } from \"./definition.js\";\nexport type { Handler } from \"./handler.js\";\nexport type { HookEvent } from \"./hooks.js\";\nexport type { ContextKey } from \"./key.js\";\nexport { createKey } from \"./key.js\";\nexport type { Middleware } from \"./middleware.js\";\nexport type { MigrateOptions, MigrateResult, MigrationFn, MigrationPipeline } from \"./migration.js\";\nexport { defineMigrations, MigrationError, migrate } from \"./migration.js\";\nexport type { Plugin } from \"./plugin.js\";\nexport { definePlugin, isPlugin } from \"./plugin.js\";\nexport type { ReadonlyContext } from \"./readonly-context.js\";\nexport type { RouterOptions } from \"./router.js\";\nexport { WorkflowRouter } from \"./router.js\";\nexport type { WorkflowSnapshot } from \"./snapshot.js\";\nexport type {\n\tCommandNames,\n\tCommandPayload,\n\tDispatchResult,\n\tErrorCodes,\n\tErrorData,\n\tEventData,\n\tEventNames,\n\tPipelineError,\n\tStateData,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n\tWorkflowOf,\n} from \"./types.js\";\nexport { DomainErrorSignal, ValidationError } from \"./types.js\";\n","import type { ZodType, z } from \"zod\";\n\nexport interface WorkflowConfig {\n\tmodelVersion?: number;\n\tstates: Record<string, ZodType>;\n\tcommands: Record<string, ZodType>;\n\tevents: Record<string, ZodType>;\n\terrors: Record<string, ZodType>;\n}\n\nexport type StateNames<T extends WorkflowConfig> = keyof T[\"states\"] & string;\nexport type CommandNames<T extends WorkflowConfig> = keyof T[\"commands\"] & string;\nexport type EventNames<T extends WorkflowConfig> = keyof T[\"events\"] & string;\nexport type ErrorCodes<T extends WorkflowConfig> = keyof T[\"errors\"] & string;\n\nexport type StateData<\n\tT extends WorkflowConfig,\n\tS extends StateNames<T>,\n> = T[\"states\"][S] extends ZodType ? z.infer<T[\"states\"][S]> : never;\n\nexport type CommandPayload<\n\tT extends WorkflowConfig,\n\tC extends CommandNames<T>,\n> = T[\"commands\"][C] extends ZodType ? z.infer<T[\"commands\"][C]> : never;\n\nexport type EventData<\n\tT extends WorkflowConfig,\n\tE extends EventNames<T>,\n> = T[\"events\"][E] extends ZodType ? z.infer<T[\"events\"][E]> : never;\n\nexport type ErrorData<\n\tT extends WorkflowConfig,\n\tC extends ErrorCodes<T>,\n> = T[\"errors\"][C] extends ZodType ? z.infer<T[\"errors\"][C]> : never;\n\n/** Workflow narrowed to a specific known state. */\nexport interface WorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {\n\treadonly id: string;\n\treadonly definitionName: string;\n\treadonly state: S;\n\treadonly data: StateData<TConfig, S>;\n\treadonly createdAt: Date;\n\treadonly updatedAt: Date;\n}\n\n/** Discriminated union of all possible workflow states — checking .state narrows .data. */\nexport type Workflow<TConfig extends WorkflowConfig = WorkflowConfig> = {\n\t[S in StateNames<TConfig>]: WorkflowOf<TConfig, S>;\n}[StateNames<TConfig>];\n\nexport type PipelineError<TConfig extends WorkflowConfig = WorkflowConfig> =\n\t| {\n\t\t\tcategory: \"validation\";\n\t\t\tsource: \"command\" | \"state\" | \"event\" | \"transition\" | \"restore\";\n\t\t\tissues: z.core.$ZodIssue[];\n\t\t\tmessage: string;\n\t }\n\t| {\n\t\t\tcategory: \"domain\";\n\t\t\tcode: ErrorCodes<TConfig>;\n\t\t\tdata: ErrorData<TConfig, ErrorCodes<TConfig>>;\n\t }\n\t| {\n\t\t\tcategory: \"router\";\n\t\t\tcode: \"NO_HANDLER\" | \"UNKNOWN_STATE\";\n\t\t\tmessage: string;\n\t };\n\nexport type DispatchResult<TConfig extends WorkflowConfig = WorkflowConfig> =\n\t| {\n\t\t\tok: true;\n\t\t\tworkflow: Workflow<TConfig>;\n\t\t\tevents: Array<{ type: EventNames<TConfig>; data: unknown }>;\n\t }\n\t| {\n\t\t\tok: false;\n\t\t\terror: PipelineError<TConfig>;\n\t };\n\n/** Thrown internally when Zod validation fails during dispatch. */\nexport class ValidationError extends Error {\n\tconstructor(\n\t\tpublic readonly source: \"command\" | \"state\" | \"event\" | \"transition\" | \"restore\",\n\t\tpublic readonly issues: z.core.$ZodIssue[],\n\t) {\n\t\tsuper(`Validation failed (${source}): ${issues.map((i) => i.message).join(\", \")}`);\n\t\tthis.name = \"ValidationError\";\n\t}\n}\n\n/** Thrown internally when a handler calls ctx.error(). Caught by the router. */\nexport class DomainErrorSignal extends Error {\n\tconstructor(\n\t\tpublic readonly code: string,\n\t\tpublic readonly data: unknown,\n\t) {\n\t\tsuper(`Domain error: ${code}`);\n\t\tthis.name = \"DomainErrorSignal\";\n\t}\n}\n","import type { ZodType, z } from \"zod\";\nimport type { WorkflowSnapshot } from \"./snapshot.js\";\nimport type { StateNames, Workflow, WorkflowConfig, WorkflowOf } from \"./types.js\";\nimport { ValidationError } from \"./types.js\";\n\n/** The result of defineWorkflow() — holds schemas and creates workflow instances. */\nexport interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {\n\treadonly config: TConfig;\n\treadonly name: string;\n\tcreateWorkflow<S extends StateNames<TConfig>>(\n\t\tid: string,\n\t\tconfig: { initialState: S; data: z.infer<TConfig[\"states\"][S]> },\n\t): WorkflowOf<TConfig, S>;\n\tgetStateSchema(stateName: string): ZodType;\n\tgetCommandSchema(commandName: string): ZodType;\n\tgetEventSchema(eventName: string): ZodType;\n\tgetErrorSchema(errorCode: string): ZodType;\n\thasState(stateName: string): boolean;\n\tsnapshot(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;\n\trestore(\n\t\tsnapshot: WorkflowSnapshot<TConfig>,\n\t): { ok: true; workflow: Workflow<TConfig> } | { ok: false; error: ValidationError };\n}\n\n/**\n * Creates a workflow definition from a name and Zod schema configuration.\n */\nexport function defineWorkflow<const TConfig extends WorkflowConfig>(\n\tname: string,\n\tconfig: TConfig,\n): WorkflowDefinition<TConfig> {\n\treturn {\n\t\tconfig,\n\t\tname,\n\n\t\tcreateWorkflow(id, wfConfig) {\n\t\t\tconst schema = config.states[wfConfig.initialState as string];\n\t\t\tif (!schema) throw new Error(`Unknown state: ${wfConfig.initialState as string}`);\n\t\t\tconst result = schema.safeParse(wfConfig.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid initial data for state '${wfConfig.initialState as string}': ${result.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst now = new Date();\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tdefinitionName: name,\n\t\t\t\tstate: wfConfig.initialState,\n\t\t\t\tdata: result.data,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t} as WorkflowOf<TConfig, typeof wfConfig.initialState>;\n\t\t},\n\n\t\tgetStateSchema(stateName: string): ZodType {\n\t\t\tconst schema = config.states[stateName];\n\t\t\tif (!schema) throw new Error(`Unknown state: ${stateName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetCommandSchema(commandName: string): ZodType {\n\t\t\tconst schema = config.commands[commandName];\n\t\t\tif (!schema) throw new Error(`Unknown command: ${commandName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetEventSchema(eventName: string): ZodType {\n\t\t\tconst schema = config.events[eventName];\n\t\t\tif (!schema) throw new Error(`Unknown event: ${eventName}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\tgetErrorSchema(errorCode: string): ZodType {\n\t\t\tconst schema = config.errors[errorCode];\n\t\t\tif (!schema) throw new Error(`Unknown error: ${errorCode}`);\n\t\t\treturn schema;\n\t\t},\n\n\t\thasState(stateName: string): boolean {\n\t\t\treturn stateName in config.states;\n\t\t},\n\n\t\tsnapshot(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig> {\n\t\t\treturn {\n\t\t\t\tid: workflow.id,\n\t\t\t\tdefinitionName: name,\n\t\t\t\tstate: workflow.state,\n\t\t\t\tdata: workflow.data,\n\t\t\t\tcreatedAt: workflow.createdAt.toISOString(),\n\t\t\t\tupdatedAt: workflow.updatedAt.toISOString(),\n\t\t\t\tmodelVersion: config.modelVersion ?? 1,\n\t\t\t} as WorkflowSnapshot<TConfig>;\n\t\t},\n\n\t\trestore(\n\t\t\tsnap: WorkflowSnapshot<TConfig>,\n\t\t): { ok: true; workflow: Workflow<TConfig> } | { ok: false; error: ValidationError } {\n\t\t\tconst stateSchema = config.states[snap.state as string];\n\t\t\tif (!stateSchema) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: new ValidationError(\"restore\", [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"custom\",\n\t\t\t\t\t\t\tmessage: `Unknown state: ${snap.state}`,\n\t\t\t\t\t\t\tinput: snap.state,\n\t\t\t\t\t\t\tpath: [\"state\"],\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst result = stateSchema.safeParse(snap.data);\n\t\t\tif (!result.success) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: new ValidationError(\"restore\", result.error.issues),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tworkflow: {\n\t\t\t\t\tid: snap.id,\n\t\t\t\t\tdefinitionName: snap.definitionName,\n\t\t\t\t\tstate: snap.state,\n\t\t\t\t\tdata: result.data,\n\t\t\t\t\tcreatedAt: new Date(snap.createdAt),\n\t\t\t\t\tupdatedAt: new Date(snap.updatedAt),\n\t\t\t\t} as Workflow<TConfig>,\n\t\t\t};\n\t\t},\n\t};\n}\n","/** A phantom-typed key for type-safe middleware state storage. */\nexport interface ContextKey<T> {\n\treadonly _phantom: T;\n\treadonly id: symbol;\n}\n\n/** Creates a unique typed key for storing/retrieving values in context. */\nexport function createKey<T>(name: string): ContextKey<T> {\n\treturn { id: Symbol(name) } as ContextKey<T>;\n}\n","import type { WorkflowDefinition } from \"./definition.js\";\nimport type { WorkflowSnapshot } from \"./snapshot.js\";\nimport type { WorkflowConfig } from \"./types.js\";\n\n/** A function that transforms a snapshot's data from one version to the next. */\nexport type MigrationFn = (snapshot: WorkflowSnapshot) => WorkflowSnapshot;\n\n/** A validated migration pipeline ready to transform snapshots. */\nexport interface MigrationPipeline<TConfig extends WorkflowConfig = WorkflowConfig> {\n\treadonly definition: WorkflowDefinition<TConfig>;\n\treadonly targetVersion: number;\n\treadonly migrations: ReadonlyMap<number, MigrationFn>;\n}\n\n/** Result of migrate(). */\nexport type MigrateResult =\n\t| { ok: true; snapshot: WorkflowSnapshot }\n\t| { ok: false; error: MigrationError };\n\n/** Options for migrate(). */\nexport interface MigrateOptions {\n\tonStep?: (fromVersion: number, toVersion: number, snapshot: WorkflowSnapshot) => void;\n\tonError?: (error: MigrationError) => void;\n}\n\n/** Error thrown when a migration step fails. */\nexport class MigrationError extends Error {\n\tconstructor(\n\t\tpublic readonly fromVersion: number,\n\t\tpublic readonly toVersion: number,\n\t\tpublic readonly cause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Migration ${fromVersion} → ${toVersion} failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t);\n\t\tthis.name = \"MigrationError\";\n\t}\n}\n\n/**\n * Creates a validated migration pipeline from a definition and version-keyed transform functions.\n * Each key is the target version — the function transforms from (key - 1) to key.\n */\nexport function defineMigrations<TConfig extends WorkflowConfig>(\n\tdefinition: WorkflowDefinition<TConfig>,\n\tmigrationMap: Record<number, MigrationFn>,\n): MigrationPipeline<TConfig> {\n\tconst targetVersion = definition.config.modelVersion ?? 1;\n\tconst entries = Object.entries(migrationMap).map(([k, v]) => [Number(k), v] as const);\n\n\tfor (const [version] of entries) {\n\t\tif (version <= 1) {\n\t\t\tthrow new Error(`Migration keys must be > 1 (version 1 is the baseline). Got: ${version}`);\n\t\t}\n\t}\n\n\tentries.sort((a, b) => a[0] - b[0]);\n\n\tif (entries.length > 0) {\n\t\tconst highest = entries[entries.length - 1];\n\t\tif (!highest || highest[0] !== targetVersion) {\n\t\t\tthrow new Error(\n\t\t\t\t`Highest migration key (${highest?.[0]}) does not match definition modelVersion (${targetVersion})`,\n\t\t\t);\n\t\t}\n\t\tfor (let i = 0; i < entries.length; i++) {\n\t\t\tconst entry = entries[i];\n\t\t\tconst expected = targetVersion - entries.length + 1 + i;\n\t\t\tif (!entry || entry[0] !== expected) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Migration version gap: expected ${expected} but found ${entry?.[0]}. Migrations must be sequential from 2 to ${targetVersion}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdefinition,\n\t\ttargetVersion,\n\t\tmigrations: new Map(entries),\n\t};\n}\n\n/**\n * Runs the migration chain from the snapshot's modelVersion to the pipeline's targetVersion.\n * Returns a Result. Auto-stamps modelVersion after each step.\n */\nexport function migrate<TConfig extends WorkflowConfig>(\n\tpipeline: MigrationPipeline<TConfig>,\n\tsnapshot: WorkflowSnapshot,\n\toptions?: MigrateOptions,\n): MigrateResult {\n\tif (!Number.isInteger(snapshot.modelVersion) || snapshot.modelVersion < 1) {\n\t\tconst error = new MigrationError(\n\t\t\tsnapshot.modelVersion,\n\t\t\tpipeline.targetVersion,\n\t\t\tnew Error(\n\t\t\t\t`Invalid snapshot modelVersion: ${snapshot.modelVersion}. Must be a positive integer.`,\n\t\t\t),\n\t\t);\n\t\toptions?.onError?.(error);\n\t\treturn { ok: false, error };\n\t}\n\n\tif (snapshot.definitionName !== pipeline.definition.name) {\n\t\tconst error = new MigrationError(\n\t\t\tsnapshot.modelVersion,\n\t\t\tpipeline.targetVersion,\n\t\t\tnew Error(\n\t\t\t\t`Snapshot definition '${snapshot.definitionName}' does not match pipeline definition '${pipeline.definition.name}'`,\n\t\t\t),\n\t\t);\n\t\toptions?.onError?.(error);\n\t\treturn { ok: false, error };\n\t}\n\n\tif (snapshot.modelVersion > pipeline.targetVersion) {\n\t\tconst error = new MigrationError(\n\t\t\tsnapshot.modelVersion,\n\t\t\tpipeline.targetVersion,\n\t\t\tnew Error(\n\t\t\t\t`Snapshot modelVersion (${snapshot.modelVersion}) is higher than target (${pipeline.targetVersion}). Cannot downgrade.`,\n\t\t\t),\n\t\t);\n\t\toptions?.onError?.(error);\n\t\treturn { ok: false, error };\n\t}\n\n\tif (snapshot.modelVersion === pipeline.targetVersion) {\n\t\treturn { ok: true, snapshot };\n\t}\n\n\tlet current = { ...snapshot };\n\tfor (let version = current.modelVersion + 1; version <= pipeline.targetVersion; version++) {\n\t\tconst fn = pipeline.migrations.get(version);\n\t\tif (!fn) {\n\t\t\tconst error = new MigrationError(\n\t\t\t\tversion - 1,\n\t\t\t\tversion,\n\t\t\t\tnew Error(`No migration function found for version ${version}`),\n\t\t\t);\n\t\t\toptions?.onError?.(error);\n\t\t\treturn { ok: false, error };\n\t\t}\n\n\t\tconst fromVersion = version - 1;\n\t\ttry {\n\t\t\tcurrent = { ...fn(current), modelVersion: version };\n\t\t} catch (cause) {\n\t\t\tconst error = new MigrationError(fromVersion, version, cause);\n\t\t\toptions?.onError?.(error);\n\t\t\treturn { ok: false, error };\n\t\t}\n\n\t\toptions?.onStep?.(fromVersion, version, current);\n\t}\n\n\treturn { ok: true, snapshot: current };\n}\n","import type { WorkflowRouter } from \"./router.js\";\nimport type { WorkflowConfig } from \"./types.js\";\n\nconst PLUGIN_SYMBOL: unique symbol = Symbol.for(\"ryte:plugin\");\n\n/** A branded plugin function that can be passed to router.use(). */\nexport type Plugin<TConfig extends WorkflowConfig, TDeps> = ((\n\trouter: WorkflowRouter<TConfig, TDeps>,\n) => void) & { readonly [PLUGIN_SYMBOL]: true };\n\n/** Brands a function as a Ryte plugin for use with router.use(). */\nexport function definePlugin<TConfig extends WorkflowConfig, TDeps>(\n\tfn: (router: WorkflowRouter<TConfig, TDeps>) => void,\n): Plugin<TConfig, TDeps> {\n\tconst plugin = fn as Plugin<TConfig, TDeps>;\n\tObject.defineProperty(plugin, PLUGIN_SYMBOL, { value: true, writable: false });\n\treturn plugin;\n}\n\n/** Checks whether a value is a branded Ryte plugin. */\nexport function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown> {\n\treturn typeof value === \"function\" && PLUGIN_SYMBOL in value;\n}\n","type Middleware<TCtx> = (ctx: TCtx, next: () => Promise<void>) => Promise<void>;\n\n/** Composes an array of middleware into a single function (Koa-style onion model). */\nexport function compose<TCtx>(middleware: Middleware<TCtx>[]): (ctx: TCtx) => Promise<void> {\n\treturn async (ctx: TCtx) => {\n\t\tlet index = -1;\n\t\tasync function dispatch(i: number): Promise<void> {\n\t\t\tif (i <= index) throw new Error(\"next() called multiple times\");\n\t\t\tindex = i;\n\t\t\tconst fn = middleware[i];\n\t\t\tif (!fn) return;\n\t\t\tawait fn(ctx, () => dispatch(i + 1));\n\t\t}\n\t\tawait dispatch(0);\n\t};\n}\n","import type { WorkflowDefinition } from \"./definition.js\";\nimport type { ContextKey } from \"./key.js\";\nimport type {\n\tCommandNames,\n\tCommandPayload,\n\tErrorCodes,\n\tErrorData,\n\tEventData,\n\tEventNames,\n\tStateData,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n\tWorkflowOf,\n} from \"./types.js\";\nimport { DomainErrorSignal, ValidationError } from \"./types.js\";\n\n/** Mutable context flowing through the middleware pipeline during dispatch. */\nexport interface Context<\n\tTConfig extends WorkflowConfig,\n\tTDeps,\n\tTState extends StateNames<TConfig> = StateNames<TConfig>,\n\tTCommand extends CommandNames<TConfig> = CommandNames<TConfig>,\n> {\n\treadonly command: {\n\t\treadonly type: TCommand;\n\t\treadonly payload: CommandPayload<TConfig, TCommand>;\n\t};\n\treadonly workflow: WorkflowOf<TConfig, TState>;\n\treadonly deps: TDeps;\n\n\treadonly data: StateData<TConfig, TState>;\n\tupdate(data: Partial<StateData<TConfig, TState>>): void;\n\n\ttransition<Target extends StateNames<TConfig>>(\n\t\ttarget: Target,\n\t\tdata: StateData<TConfig, Target>,\n\t): void;\n\n\temit<E extends EventNames<TConfig>>(event: { type: E; data: EventData<TConfig, E> }): void;\n\treadonly events: ReadonlyArray<{ type: EventNames<TConfig>; data: unknown }>;\n\n\terror<C extends ErrorCodes<TConfig>>(err: { code: C; data: ErrorData<TConfig, C> }): never;\n\n\tset<T>(key: ContextKey<T>, value: T): void;\n\tget<T>(key: ContextKey<T>): T;\n\tgetOrNull<T>(key: ContextKey<T>): T | undefined;\n\n\t/** @internal — not part of the handler API */\n\tgetWorkflowSnapshot(): Workflow<TConfig>;\n}\n\ninterface DomainEvent {\n\ttype: string;\n\tdata: unknown;\n}\n\n/** @internal Creates a context for dispatch. Not part of public API. */\nexport function createContext<TConfig extends WorkflowConfig, TDeps>(\n\tdefinition: WorkflowDefinition<TConfig>,\n\toriginalWorkflow: Workflow<TConfig>,\n\tcommand: { type: string; payload: unknown },\n\tdeps: TDeps,\n): Context<TConfig, TDeps> {\n\tlet mutableState = originalWorkflow.state;\n\tlet mutableData: Record<string, unknown> = {\n\t\t...(originalWorkflow.data as Record<string, unknown>),\n\t};\n\n\tconst accumulatedEvents: DomainEvent[] = [];\n\tconst middlewareState = new Map<symbol, unknown>();\n\n\tconst ctx = {\n\t\tcommand,\n\t\tworkflow: originalWorkflow,\n\t\tdeps,\n\n\t\tget data() {\n\t\t\treturn { ...mutableData } as StateData<TConfig, StateNames<TConfig>>;\n\t\t},\n\n\t\tupdate(data: Record<string, unknown>) {\n\t\t\tconst merged = { ...mutableData, ...data };\n\t\t\tconst schema = definition.getStateSchema(mutableState);\n\t\t\tconst result = schema.safeParse(merged);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"state\", result.error.issues);\n\t\t\t}\n\t\t\tmutableData = result.data as Record<string, unknown>;\n\t\t},\n\n\t\ttransition(target: string, data: unknown) {\n\t\t\tif (!definition.hasState(target)) {\n\t\t\t\tthrow new Error(`Unknown state: ${target}`);\n\t\t\t}\n\t\t\tconst schema = definition.getStateSchema(target);\n\t\t\tconst result = schema.safeParse(data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"transition\", result.error.issues);\n\t\t\t}\n\t\t\tmutableState = target;\n\t\t\tmutableData = result.data as Record<string, unknown>;\n\t\t},\n\n\t\temit(event: { type: string; data: unknown }) {\n\t\t\tconst schema = definition.getEventSchema(event.type);\n\t\t\tconst result = schema.safeParse(event.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new ValidationError(\"event\", result.error.issues);\n\t\t\t}\n\t\t\taccumulatedEvents.push({ type: event.type, data: result.data });\n\t\t},\n\n\t\tget events() {\n\t\t\treturn [...accumulatedEvents];\n\t\t},\n\n\t\terror(err: { code: string; data: unknown }) {\n\t\t\tconst schema = definition.getErrorSchema(err.code);\n\t\t\tconst result = schema.safeParse(err.data);\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid error data for '${err.code}': ${result.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new DomainErrorSignal(err.code, result.data);\n\t\t},\n\n\t\tset<T>(key: ContextKey<T>, value: T) {\n\t\t\tmiddlewareState.set(key.id, value);\n\t\t},\n\n\t\tget<T>(key: ContextKey<T>): T {\n\t\t\tif (!middlewareState.has(key.id)) {\n\t\t\t\tthrow new Error(`Context key not set: ${key.id.toString()}`);\n\t\t\t}\n\t\t\treturn middlewareState.get(key.id) as T;\n\t\t},\n\n\t\tgetOrNull<T>(key: ContextKey<T>): T | undefined {\n\t\t\treturn middlewareState.get(key.id) as T | undefined;\n\t\t},\n\n\t\tgetWorkflowSnapshot(): Workflow<TConfig> {\n\t\t\treturn {\n\t\t\t\tid: originalWorkflow.id,\n\t\t\t\tdefinitionName: originalWorkflow.definitionName,\n\t\t\t\tstate: mutableState,\n\t\t\t\tdata: { ...mutableData },\n\t\t\t\tcreatedAt: originalWorkflow.createdAt,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t} as Workflow<TConfig>;\n\t\t},\n\t};\n\n\treturn ctx as unknown as Context<TConfig, TDeps>;\n}\n","/** The lifecycle hook event names. */\nexport type HookEvent = \"dispatch:start\" | \"dispatch:end\" | \"transition\" | \"error\" | \"event\";\n\nexport const HOOK_EVENTS: ReadonlySet<string> = new Set<HookEvent>([\n\t\"dispatch:start\",\n\t\"dispatch:end\",\n\t\"transition\",\n\t\"error\",\n\t\"event\",\n]);\n\n/**\n * Internal registry for lifecycle hook callbacks.\n * Hooks are observers — errors are caught and forwarded, never affecting dispatch.\n */\nexport class HookRegistry {\n\t// biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event\n\tprivate hooks = new Map<string, Function[]>();\n\n\t/** Register a callback for a hook event. */\n\t// biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event\n\tadd(event: string, callback: Function): void {\n\t\tconst existing = this.hooks.get(event) ?? [];\n\t\texisting.push(callback);\n\t\tthis.hooks.set(event, existing);\n\t}\n\n\t/** Emit a hook event, calling all registered callbacks. Errors are caught and forwarded. */\n\tasync emit(event: string, onError: (err: unknown) => void, ...args: unknown[]): Promise<void> {\n\t\tconst callbacks = this.hooks.get(event);\n\t\tif (!callbacks) return;\n\t\tfor (const cb of callbacks) {\n\t\t\ttry {\n\t\t\t\tawait cb(...args);\n\t\t\t} catch (err) {\n\t\t\t\tonError(err);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Merge another registry's hooks into this one (used by composable routers). */\n\tmerge(other: HookRegistry): void {\n\t\tfor (const [event, callbacks] of other.hooks) {\n\t\t\tconst existing = this.hooks.get(event) ?? [];\n\t\t\texisting.push(...callbacks);\n\t\t\tthis.hooks.set(event, existing);\n\t\t}\n\t}\n}\n","import { compose } from \"./compose.js\";\nimport { type Context, createContext } from \"./context.js\";\nimport type { WorkflowDefinition } from \"./definition.js\";\nimport { HOOK_EVENTS, HookRegistry } from \"./hooks.js\";\nimport type { Plugin } from \"./plugin.js\";\nimport { isPlugin } from \"./plugin.js\";\nimport type { ReadonlyContext } from \"./readonly-context.js\";\nimport type {\n\tCommandNames,\n\tDispatchResult,\n\tErrorCodes,\n\tErrorData,\n\tEventNames,\n\tPipelineError,\n\tStateNames,\n\tWorkflow,\n\tWorkflowConfig,\n} from \"./types.js\";\nimport { DomainErrorSignal, ValidationError } from \"./types.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: internal type erasure for heterogeneous middleware storage\ntype AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;\n// biome-ignore lint/suspicious/noExplicitAny: internal type erasure for heterogeneous handler storage\ntype AnyHandler = (ctx: any) => void | Promise<void>;\n\ntype HandlerEntry = {\n\tinlineMiddleware: AnyMiddleware[];\n\thandler: AnyMiddleware;\n};\n\nexport interface RouterOptions {\n\tonHookError?: (error: unknown) => void;\n}\n\nclass StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {\n\t/** @internal */ readonly middleware: AnyMiddleware[] = [];\n\t/** @internal */ readonly handlers = new Map<string, HandlerEntry>();\n\n\ton<C extends CommandNames<TConfig>>(\n\t\tcommand: C,\n\t\t...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]\n\t): this {\n\t\tif (fns.length === 0) throw new Error(\"on() requires at least a handler\");\n\t\tconst handler = fns.pop() as AnyHandler;\n\t\tconst inlineMiddleware = fns as AnyMiddleware[];\n\t\tconst wrappedHandler: AnyMiddleware = async (ctx, _next) => {\n\t\t\tawait handler(ctx);\n\t\t};\n\t\tthis.handlers.set(command as string, { inlineMiddleware, handler: wrappedHandler });\n\t\treturn this;\n\t}\n\n\tuse(\n\t\tmiddleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>,\n\t): this {\n\t\tthis.middleware.push(middleware as AnyMiddleware);\n\t\treturn this;\n\t}\n}\n\n/**\n * Routes commands to handlers based on workflow state.\n *\n * Supports global middleware, state-scoped middleware, inline middleware,\n * wildcard handlers, and multi-state handlers.\n */\n// biome-ignore lint/complexity/noBannedTypes: {} is correct here — TDeps defaults to \"no deps\", inferred away when deps are provided\nexport class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {\n\tprivate globalMiddleware: AnyMiddleware[] = [];\n\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\tprivate singleStateBuilders = new Map<string, StateBuilder<TConfig, TDeps, any>>();\n\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\tprivate multiStateBuilders = new Map<string, StateBuilder<TConfig, TDeps, any>>();\n\tprivate wildcardHandlers = new Map<string, HandlerEntry>();\n\tprivate hookRegistry = new HookRegistry();\n\tprivate readonly onHookError: (error: unknown) => void;\n\n\tconstructor(\n\t\tprivate readonly definition: WorkflowDefinition<TConfig>,\n\t\tprivate readonly deps: TDeps = {} as TDeps,\n\t\toptions: RouterOptions = {},\n\t) {\n\t\tthis.onHookError = options.onHookError ?? console.error;\n\t}\n\n\t/** Adds global middleware, merges another router, or applies a plugin. */\n\tuse(\n\t\targ:\n\t\t\t| ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>)\n\t\t\t| WorkflowRouter<TConfig, TDeps>\n\t\t\t| Plugin<TConfig, TDeps>,\n\t): this {\n\t\tif (arg instanceof WorkflowRouter) {\n\t\t\tthis.merge(arg);\n\t\t} else if (isPlugin(arg)) {\n\t\t\t(arg as (router: WorkflowRouter<TConfig, TDeps>) => void)(this);\n\t\t} else {\n\t\t\tthis.globalMiddleware.push(arg as AnyMiddleware);\n\t\t}\n\t\treturn this;\n\t}\n\n\tprivate merge(child: WorkflowRouter<TConfig, TDeps>): void {\n\t\tif (child.definition !== this.definition) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot merge router for '${child.definition.name}' into router for '${this.definition.name}': definition mismatch`,\n\t\t\t);\n\t\t}\n\n\t\tthis.globalMiddleware.push(...child.globalMiddleware);\n\t\tthis.mergeStateBuilders(this.singleStateBuilders, child.singleStateBuilders);\n\t\tthis.mergeStateBuilders(this.multiStateBuilders, child.multiStateBuilders);\n\n\t\tfor (const [command, entry] of child.wildcardHandlers) {\n\t\t\tif (!this.wildcardHandlers.has(command)) {\n\t\t\t\tthis.wildcardHandlers.set(command, {\n\t\t\t\t\tinlineMiddleware: [...entry.inlineMiddleware],\n\t\t\t\t\thandler: entry.handler,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.hookRegistry.merge(child.hookRegistry);\n\t}\n\n\tprivate mergeStateBuilders(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\t\ttarget: Map<string, StateBuilder<TConfig, TDeps, any>>,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types\n\t\tsource: Map<string, StateBuilder<TConfig, TDeps, any>>,\n\t): void {\n\t\tfor (const [stateName, childBuilder] of source) {\n\t\t\tlet parentBuilder = target.get(stateName);\n\t\t\tif (!parentBuilder) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — state name is dynamic at runtime\n\t\t\t\tparentBuilder = new StateBuilder<TConfig, TDeps, any>();\n\t\t\t\ttarget.set(stateName, parentBuilder);\n\t\t\t}\n\t\t\tfor (const [command, entry] of childBuilder.handlers) {\n\t\t\t\tif (!parentBuilder.handlers.has(command)) {\n\t\t\t\t\tparentBuilder.handlers.set(command, {\n\t\t\t\t\t\tinlineMiddleware: [...entry.inlineMiddleware],\n\t\t\t\t\t\thandler: entry.handler,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tparentBuilder.middleware.push(...childBuilder.middleware);\n\t\t}\n\t}\n\n\t/** Registers handlers for one or more states. */\n\tstate<P extends StateNames<TConfig> | readonly StateNames<TConfig>[]>(\n\t\tname: P,\n\t\tsetup: (\n\t\t\tstate: StateBuilder<\n\t\t\t\tTConfig,\n\t\t\t\tTDeps,\n\t\t\t\tP extends readonly (infer S)[] ? S & StateNames<TConfig> : P & StateNames<TConfig>\n\t\t\t>,\n\t\t) => void,\n\t): this {\n\t\tconst names = Array.isArray(name) ? name : [name];\n\t\tconst isMulti = Array.isArray(name);\n\t\tconst routerMap = isMulti ? this.multiStateBuilders : this.singleStateBuilders;\n\n\t\tfor (const n of names as string[]) {\n\t\t\tlet router = routerMap.get(n);\n\t\t\tif (!router) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — state name is dynamic at runtime\n\t\t\t\trouter = new StateBuilder<TConfig, TDeps, any>();\n\t\t\t\trouterMap.set(n, router);\n\t\t\t}\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — setup callback expects a specific state type\n\t\t\tsetup(router as any);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Registers a lifecycle hook callback. */\n\ton(\n\t\tevent: \"dispatch:start\",\n\t\tcallback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>,\n\t): this;\n\ton(\n\t\tevent: \"dispatch:end\",\n\t\tcallback: (\n\t\t\tctx: ReadonlyContext<TConfig, TDeps>,\n\t\t\tresult: DispatchResult<TConfig>,\n\t\t) => void | Promise<void>,\n\t): this;\n\ton(\n\t\tevent: \"transition\",\n\t\tcallback: (\n\t\t\tfrom: StateNames<TConfig>,\n\t\t\tto: StateNames<TConfig>,\n\t\t\tworkflow: Workflow<TConfig>,\n\t\t) => void | Promise<void>,\n\t): this;\n\ton(\n\t\tevent: \"error\",\n\t\tcallback: (\n\t\t\terror: PipelineError<TConfig>,\n\t\t\tctx: ReadonlyContext<TConfig, TDeps>,\n\t\t) => void | Promise<void>,\n\t): this;\n\ton(\n\t\tevent: \"event\",\n\t\tcallback: (\n\t\t\tevent: { type: EventNames<TConfig>; data: unknown },\n\t\t\tworkflow: Workflow<TConfig>,\n\t\t) => void | Promise<void>,\n\t): this;\n\t/** Registers a wildcard handler that matches any state. */\n\ton<C extends CommandNames<TConfig>>(\n\t\tstate: \"*\",\n\t\tcommand: C,\n\t\t...fns: [\n\t\t\t...AnyMiddleware[],\n\t\t\t(ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>,\n\t\t]\n\t): this;\n\t// biome-ignore lint/suspicious/noExplicitAny: implementation signature must be loose to handle all overloads\n\ton(...args: any[]): this {\n\t\tconst first = args[0] as string;\n\n\t\tif (HOOK_EVENTS.has(first)) {\n\t\t\t// biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event\n\t\t\tthis.hookRegistry.add(first, args[1] as Function);\n\t\t\treturn this;\n\t\t}\n\n\t\tif (first === \"*\") {\n\t\t\tconst command = args[1] as string;\n\t\t\tconst fns = args.slice(2) as unknown[];\n\t\t\tif (fns.length === 0) throw new Error(\"on() requires at least a handler\");\n\t\t\tconst handler = fns.pop() as AnyHandler;\n\t\t\tconst inlineMiddleware = fns as AnyMiddleware[];\n\t\t\tconst wrappedHandler: AnyMiddleware = async (ctx, _next) => {\n\t\t\t\tawait handler(ctx);\n\t\t\t};\n\t\t\tthis.wildcardHandlers.set(command, {\n\t\t\t\tinlineMiddleware,\n\t\t\t\thandler: wrappedHandler,\n\t\t\t});\n\t\t\treturn this;\n\t\t}\n\n\t\tthrow new Error(`Unknown event or state: ${first}`);\n\t}\n\n\t/** Dispatches a command to the appropriate handler and returns the result. */\n\tasync dispatch(\n\t\tworkflow: Workflow<TConfig>,\n\t\tcommand: { type: CommandNames<TConfig>; payload: unknown },\n\t): Promise<DispatchResult<TConfig>> {\n\t\tif (!this.definition.hasState(workflow.state)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"router\",\n\t\t\t\t\tcode: \"UNKNOWN_STATE\",\n\t\t\t\t\tmessage: `Unknown state: ${workflow.state}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst commandSchema = this.definition.getCommandSchema(command.type);\n\t\tconst payloadResult = commandSchema.safeParse(command.payload);\n\t\tif (!payloadResult.success) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"validation\",\n\t\t\t\t\tsource: \"command\",\n\t\t\t\t\tissues: payloadResult.error.issues,\n\t\t\t\t\tmessage: `Invalid command payload: ${payloadResult.error.issues.map((i) => i.message).join(\", \")}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconst validatedCommand = { type: command.type, payload: payloadResult.data };\n\n\t\tconst stateName = workflow.state;\n\t\tconst singleRouter = this.singleStateBuilders.get(stateName);\n\t\tconst multiRouter = this.multiStateBuilders.get(stateName);\n\t\tconst singleHandler = singleRouter?.handlers.get(command.type);\n\t\tconst multiHandler = multiRouter?.handlers.get(command.type);\n\t\tconst wildcardHandler = this.wildcardHandlers.get(command.type);\n\n\t\tlet routeEntry: HandlerEntry | undefined;\n\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — matched router's state type is dynamic\n\t\tlet matchedRouter: StateBuilder<TConfig, TDeps, any> | undefined;\n\n\t\tif (singleHandler) {\n\t\t\trouteEntry = singleHandler;\n\t\t\tmatchedRouter = singleRouter;\n\t\t} else if (multiHandler) {\n\t\t\trouteEntry = multiHandler;\n\t\t\tmatchedRouter = multiRouter;\n\t\t} else if (wildcardHandler) {\n\t\t\trouteEntry = wildcardHandler;\n\t\t\tmatchedRouter = undefined;\n\t\t}\n\n\t\tif (!routeEntry) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"router\",\n\t\t\t\t\tcode: \"NO_HANDLER\",\n\t\t\t\t\tmessage: `No handler for command '${command.type}' in state '${stateName}'`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst stateMiddleware: AnyMiddleware[] = [];\n\t\tif (matchedRouter) {\n\t\t\tif (singleRouter) stateMiddleware.push(...singleRouter.middleware);\n\t\t\tif (multiRouter && multiRouter !== singleRouter)\n\t\t\t\tstateMiddleware.push(...multiRouter.middleware);\n\t\t}\n\n\t\tconst chain: AnyMiddleware[] = [\n\t\t\t...this.globalMiddleware,\n\t\t\t...stateMiddleware,\n\t\t\t...routeEntry.inlineMiddleware,\n\t\t\trouteEntry.handler,\n\t\t];\n\n\t\tconst ctx = createContext<TConfig, TDeps>(\n\t\t\tthis.definition,\n\t\t\tworkflow,\n\t\t\tvalidatedCommand,\n\t\t\tthis.deps,\n\t\t);\n\n\t\t// Hook: dispatch:start\n\t\tawait this.hookRegistry.emit(\"dispatch:start\", this.onHookError, ctx);\n\n\t\ttry {\n\t\t\tconst composed = compose(chain);\n\t\t\tawait composed(ctx);\n\t\t\tconst result: DispatchResult<TConfig> = {\n\t\t\t\tok: true as const,\n\t\t\t\tworkflow: ctx.getWorkflowSnapshot(),\n\t\t\t\tevents: [...ctx.events],\n\t\t\t};\n\n\t\t\t// Hook: transition (if state changed)\n\t\t\tif (result.ok && result.workflow.state !== workflow.state) {\n\t\t\t\tawait this.hookRegistry.emit(\n\t\t\t\t\t\"transition\",\n\t\t\t\t\tthis.onHookError,\n\t\t\t\t\tworkflow.state,\n\t\t\t\t\tresult.workflow.state,\n\t\t\t\t\tresult.workflow,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Hook: event (for each emitted event)\n\t\t\tif (result.ok) {\n\t\t\t\tfor (const event of result.events) {\n\t\t\t\t\tawait this.hookRegistry.emit(\"event\", this.onHookError, event, result.workflow);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Hook: dispatch:end\n\t\t\tawait this.hookRegistry.emit(\"dispatch:end\", this.onHookError, ctx, result);\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tlet result: DispatchResult<TConfig>;\n\t\t\tif (err instanceof DomainErrorSignal) {\n\t\t\t\tresult = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"domain\" as const,\n\t\t\t\t\t\tcode: err.code as ErrorCodes<TConfig>,\n\t\t\t\t\t\tdata: err.data as ErrorData<TConfig, ErrorCodes<TConfig>>,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else if (err instanceof ValidationError) {\n\t\t\t\tresult = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"validation\" as const,\n\t\t\t\t\t\tsource: err.source,\n\t\t\t\t\t\tissues: err.issues,\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\n\t\t\t// Hook: error\n\t\t\tawait this.hookRegistry.emit(\"error\", this.onHookError, result.error, ctx);\n\n\t\t\t// Hook: dispatch:end\n\t\t\tawait this.hookRegistry.emit(\"dispatch:end\", this.onHookError, ctx, result);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}