@rytejs/core 0.1.0 → 0.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/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @rytejs/core
2
+
3
+ Type-safe workflow engine with Zod validation and middleware pipelines.
4
+
5
+ [![CI](https://github.com/helico-tech/rytejs/actions/workflows/ci.yml/badge.svg)](https://github.com/helico-tech/rytejs/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/@rytejs/core)](https://www.npmjs.com/package/@rytejs/core)
7
+
8
+ ## Why Ryte?
9
+
10
+ - **Fully typed from definition to dispatch** -- define your states, commands, events, and errors with Zod schemas. TypeScript infers everything automatically. State names, command payloads, event data, error codes -- all with full autocompletion, no manual type annotations.
11
+ - **Checking `workflow.state` narrows `workflow.data`** -- TypeScript knows exactly which data shape each state has. Discriminated unions, not type casts.
12
+ - **`ctx.error()` is type-checked** -- you can only raise error codes that exist in your definition, with the correct data shape. Domain failures are part of the contract.
13
+ - **Koa-style middleware** -- global, state-scoped, and inline middleware with the onion model. Add auth, logging, or validation without touching handlers.
14
+ - **Fluent builder API** -- chain `.state()`, `.on()`, `.use()` calls. Every method returns `this`.
15
+ - **Composable routers** -- split handlers across files and compose them with `.use()`. Routers are routers.
16
+ - **Zero platform lock-in** -- pure logic with no runtime dependencies beyond Zod. Works on Node.js, Bun, and Deno.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pnpm add @rytejs/core zod
22
+ ```
23
+
24
+ ## Quick Example
25
+
26
+ ```ts
27
+ import { z } from "zod";
28
+ import { defineWorkflow, WorkflowRouter } from "@rytejs/core";
29
+
30
+ const taskWorkflow = defineWorkflow("task", {
31
+ states: {
32
+ Todo: z.object({ title: z.string(), assignee: z.string().optional() }),
33
+ Done: z.object({ title: z.string(), completedAt: z.coerce.date() }),
34
+ },
35
+ commands: {
36
+ Complete: z.object({}),
37
+ },
38
+ events: {
39
+ TaskCompleted: z.object({ taskId: z.string() }),
40
+ },
41
+ errors: {
42
+ NotAssigned: z.object({ title: z.string() }),
43
+ },
44
+ });
45
+
46
+ const router = new WorkflowRouter(taskWorkflow)
47
+ .state("Todo", (state) => {
48
+ state.on("Complete", (ctx) => {
49
+ if (!ctx.data.assignee) {
50
+ ctx.error({ code: "NotAssigned", data: { title: ctx.data.title } });
51
+ }
52
+ ctx.transition("Done", {
53
+ title: ctx.data.title,
54
+ completedAt: new Date(),
55
+ });
56
+ ctx.emit({ type: "TaskCompleted", data: { taskId: ctx.workflow.id } });
57
+ });
58
+ });
59
+
60
+ const task = taskWorkflow.createWorkflow("task-1", {
61
+ initialState: "Todo",
62
+ data: { title: "Read the docs", assignee: "alice" },
63
+ });
64
+
65
+ const result = await router.dispatch(task, {
66
+ type: "Complete",
67
+ payload: {},
68
+ });
69
+
70
+ if (result.ok) {
71
+ console.log(result.workflow.state); // "Done"
72
+ console.log(result.events[0]?.type); // "TaskCompleted"
73
+ } else if (result.error.category === "domain") {
74
+ console.log(result.error.code); // "NotAssigned"
75
+ }
76
+ ```
77
+
78
+ ## Type Safety Highlights
79
+
80
+ Every part of the API is fully typed with zero manual annotations:
81
+
82
+ - **State names** -- `router.state("Todo", ...)` only accepts states from your definition
83
+ - **Command names** -- `state.on("Complete", ...)` only accepts commands from your definition
84
+ - **Payload types** -- `ctx.command.payload` is typed based on the command's Zod schema
85
+ - **State data** -- `ctx.data` is typed based on the current state's Zod schema
86
+ - **Transitions** -- `ctx.transition("Done", data)` validates that `data` matches the target state's schema
87
+ - **Events** -- `ctx.emit({ type, data })` validates both type and data against event schemas
88
+ - **Errors** -- `ctx.error({ code, data })` only accepts error codes from your definition with matching data
89
+ - **Discriminated unions** -- `if (workflow.state === "Todo") { workflow.data.title }` narrows automatically
90
+
91
+ ## Documentation
92
+
93
+ - [Getting Started](https://helico-tech.github.io/rytejs/guide/getting-started)
94
+ - [Defining Workflows](https://helico-tech.github.io/rytejs/guide/defining-workflows)
95
+ - [Routing Commands](https://helico-tech.github.io/rytejs/guide/routing-commands)
96
+ - [API Reference](https://helico-tech.github.io/rytejs/api/)
97
+
98
+ ## License
99
+
100
+ MIT
package/dist/index.cjs CHANGED
@@ -24,10 +24,30 @@ __export(index_exports, {
24
24
  ValidationError: () => ValidationError,
25
25
  WorkflowRouter: () => WorkflowRouter,
26
26
  createKey: () => createKey,
27
- defineWorkflow: () => defineWorkflow
27
+ definePlugin: () => definePlugin,
28
+ defineWorkflow: () => defineWorkflow,
29
+ isPlugin: () => isPlugin
28
30
  });
29
31
  module.exports = __toCommonJS(index_exports);
30
32
 
33
+ // src/types.ts
34
+ var ValidationError = class extends Error {
35
+ constructor(source, issues) {
36
+ super(`Validation failed (${source}): ${issues.map((i) => i.message).join(", ")}`);
37
+ this.source = source;
38
+ this.issues = issues;
39
+ this.name = "ValidationError";
40
+ }
41
+ };
42
+ var DomainErrorSignal = class extends Error {
43
+ constructor(code, data) {
44
+ super(`Domain error: ${code}`);
45
+ this.code = code;
46
+ this.data = data;
47
+ this.name = "DomainErrorSignal";
48
+ }
49
+ };
50
+
31
51
  // src/definition.ts
32
52
  function defineWorkflow(name, config) {
33
53
  return {
@@ -74,6 +94,51 @@ function defineWorkflow(name, config) {
74
94
  },
75
95
  hasState(stateName) {
76
96
  return stateName in config.states;
97
+ },
98
+ snapshot(workflow) {
99
+ return {
100
+ id: workflow.id,
101
+ definitionName: name,
102
+ state: workflow.state,
103
+ data: workflow.data,
104
+ createdAt: workflow.createdAt.toISOString(),
105
+ updatedAt: workflow.updatedAt.toISOString(),
106
+ modelVersion: config.modelVersion ?? 1
107
+ };
108
+ },
109
+ restore(snap) {
110
+ const stateSchema = config.states[snap.state];
111
+ if (!stateSchema) {
112
+ return {
113
+ ok: false,
114
+ error: new ValidationError("restore", [
115
+ {
116
+ code: "custom",
117
+ message: `Unknown state: ${snap.state}`,
118
+ input: snap.state,
119
+ path: ["state"]
120
+ }
121
+ ])
122
+ };
123
+ }
124
+ const result = stateSchema.safeParse(snap.data);
125
+ if (!result.success) {
126
+ return {
127
+ ok: false,
128
+ error: new ValidationError("restore", result.error.issues)
129
+ };
130
+ }
131
+ return {
132
+ ok: true,
133
+ workflow: {
134
+ id: snap.id,
135
+ definitionName: snap.definitionName,
136
+ state: snap.state,
137
+ data: result.data,
138
+ createdAt: new Date(snap.createdAt),
139
+ updatedAt: new Date(snap.updatedAt)
140
+ }
141
+ };
77
142
  }
78
143
  };
79
144
  }
@@ -83,6 +148,17 @@ function createKey(name) {
83
148
  return { id: Symbol(name) };
84
149
  }
85
150
 
151
+ // src/plugin.ts
152
+ var PLUGIN_SYMBOL = /* @__PURE__ */ Symbol.for("ryte:plugin");
153
+ function definePlugin(fn) {
154
+ const plugin = fn;
155
+ Object.defineProperty(plugin, PLUGIN_SYMBOL, { value: true, writable: false });
156
+ return plugin;
157
+ }
158
+ function isPlugin(value) {
159
+ return typeof value === "function" && PLUGIN_SYMBOL in value;
160
+ }
161
+
86
162
  // src/compose.ts
87
163
  function compose(middleware) {
88
164
  return async (ctx) => {
@@ -98,24 +174,6 @@ function compose(middleware) {
98
174
  };
99
175
  }
100
176
 
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
177
  // src/context.ts
120
178
  function createContext(definition, originalWorkflow, command, deps) {
121
179
  let mutableState = originalWorkflow.state;
@@ -199,6 +257,46 @@ function createContext(definition, originalWorkflow, command, deps) {
199
257
  return ctx;
200
258
  }
201
259
 
260
+ // src/hooks.ts
261
+ var HOOK_EVENTS = /* @__PURE__ */ new Set([
262
+ "dispatch:start",
263
+ "dispatch:end",
264
+ "transition",
265
+ "error",
266
+ "event"
267
+ ]);
268
+ var HookRegistry = class {
269
+ // biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event
270
+ hooks = /* @__PURE__ */ new Map();
271
+ /** Register a callback for a hook event. */
272
+ // biome-ignore lint/complexity/noBannedTypes: callbacks have varying signatures per hook event
273
+ add(event, callback) {
274
+ const existing = this.hooks.get(event) ?? [];
275
+ existing.push(callback);
276
+ this.hooks.set(event, existing);
277
+ }
278
+ /** Emit a hook event, calling all registered callbacks. Errors are caught and forwarded. */
279
+ async emit(event, onError, ...args) {
280
+ const callbacks = this.hooks.get(event);
281
+ if (!callbacks) return;
282
+ for (const cb of callbacks) {
283
+ try {
284
+ await cb(...args);
285
+ } catch (err) {
286
+ onError(err);
287
+ }
288
+ }
289
+ }
290
+ /** Merge another registry's hooks into this one (used by composable routers). */
291
+ merge(other) {
292
+ for (const [event, callbacks] of other.hooks) {
293
+ const existing = this.hooks.get(event) ?? [];
294
+ existing.push(...callbacks);
295
+ this.hooks.set(event, existing);
296
+ }
297
+ }
298
+ };
299
+
202
300
  // src/router.ts
203
301
  var StateBuilder = class {
204
302
  /** @internal */
@@ -220,20 +318,68 @@ var StateBuilder = class {
220
318
  return this;
221
319
  }
222
320
  };
223
- var WorkflowRouter = class {
224
- constructor(definition, deps = {}) {
321
+ var WorkflowRouter = class _WorkflowRouter {
322
+ constructor(definition, deps = {}, options = {}) {
225
323
  this.definition = definition;
226
324
  this.deps = deps;
325
+ this.onHookError = options.onHookError ?? console.error;
227
326
  }
228
327
  globalMiddleware = [];
328
+ // biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types
229
329
  singleStateBuilders = /* @__PURE__ */ new Map();
330
+ // biome-ignore lint/suspicious/noExplicitAny: type erasure — builders store handlers for different state types
230
331
  multiStateBuilders = /* @__PURE__ */ new Map();
231
332
  wildcardHandlers = /* @__PURE__ */ new Map();
232
- /** Adds global middleware that wraps all dispatches. */
233
- use(middleware) {
234
- this.globalMiddleware.push(middleware);
333
+ hookRegistry = new HookRegistry();
334
+ onHookError;
335
+ /** Adds global middleware, merges another router, or applies a plugin. */
336
+ use(arg) {
337
+ if (arg instanceof _WorkflowRouter) {
338
+ this.merge(arg);
339
+ } else if (isPlugin(arg)) {
340
+ arg(this);
341
+ } else {
342
+ this.globalMiddleware.push(arg);
343
+ }
235
344
  return this;
236
345
  }
346
+ merge(child) {
347
+ if (child.definition !== this.definition) {
348
+ throw new Error(
349
+ `Cannot merge router for '${child.definition.name}' into router for '${this.definition.name}': definition mismatch`
350
+ );
351
+ }
352
+ this.globalMiddleware.push(...child.globalMiddleware);
353
+ this.mergeStateBuilders(this.singleStateBuilders, child.singleStateBuilders);
354
+ this.mergeStateBuilders(this.multiStateBuilders, child.multiStateBuilders);
355
+ for (const [command, entry] of child.wildcardHandlers) {
356
+ if (!this.wildcardHandlers.has(command)) {
357
+ this.wildcardHandlers.set(command, {
358
+ inlineMiddleware: [...entry.inlineMiddleware],
359
+ handler: entry.handler
360
+ });
361
+ }
362
+ }
363
+ this.hookRegistry.merge(child.hookRegistry);
364
+ }
365
+ mergeStateBuilders(target, source) {
366
+ for (const [stateName, childBuilder] of source) {
367
+ let parentBuilder = target.get(stateName);
368
+ if (!parentBuilder) {
369
+ parentBuilder = new StateBuilder();
370
+ target.set(stateName, parentBuilder);
371
+ }
372
+ for (const [command, entry] of childBuilder.handlers) {
373
+ if (!parentBuilder.handlers.has(command)) {
374
+ parentBuilder.handlers.set(command, {
375
+ inlineMiddleware: [...entry.inlineMiddleware],
376
+ handler: entry.handler
377
+ });
378
+ }
379
+ }
380
+ parentBuilder.middleware.push(...childBuilder.middleware);
381
+ }
382
+ }
237
383
  /** Registers handlers for one or more states. */
238
384
  state(name, setup) {
239
385
  const names = Array.isArray(name) ? name : [name];
@@ -249,19 +395,29 @@ var WorkflowRouter = class {
249
395
  }
250
396
  return this;
251
397
  }
252
- /** Registers a wildcard handler that matches any state. */
253
- on(_state, command, ...fns) {
254
- if (fns.length === 0) throw new Error("on() requires at least a handler");
255
- const handler = fns.pop();
256
- const inlineMiddleware = fns;
257
- const wrappedHandler = async (ctx, _next) => {
258
- await handler(ctx);
259
- };
260
- this.wildcardHandlers.set(command, {
261
- inlineMiddleware,
262
- handler: wrappedHandler
263
- });
264
- return this;
398
+ // biome-ignore lint/suspicious/noExplicitAny: implementation signature must be loose to handle all overloads
399
+ on(...args) {
400
+ const first = args[0];
401
+ if (HOOK_EVENTS.has(first)) {
402
+ this.hookRegistry.add(first, args[1]);
403
+ return this;
404
+ }
405
+ if (first === "*") {
406
+ const command = args[1];
407
+ const fns = args.slice(2);
408
+ if (fns.length === 0) throw new Error("on() requires at least a handler");
409
+ const handler = fns.pop();
410
+ const inlineMiddleware = fns;
411
+ const wrappedHandler = async (ctx, _next) => {
412
+ await handler(ctx);
413
+ };
414
+ this.wildcardHandlers.set(command, {
415
+ inlineMiddleware,
416
+ handler: wrappedHandler
417
+ });
418
+ return this;
419
+ }
420
+ throw new Error(`Unknown event or state: ${first}`);
265
421
  }
266
422
  /** Dispatches a command to the appropriate handler and returns the result. */
267
423
  async dispatch(workflow, command) {
@@ -335,17 +491,35 @@ var WorkflowRouter = class {
335
491
  validatedCommand,
336
492
  this.deps
337
493
  );
494
+ await this.hookRegistry.emit("dispatch:start", this.onHookError, ctx);
338
495
  try {
339
496
  const composed = compose(chain);
340
497
  await composed(ctx);
341
- return {
498
+ const result = {
342
499
  ok: true,
343
500
  workflow: ctx.getWorkflowSnapshot(),
344
501
  events: [...ctx.events]
345
502
  };
503
+ if (result.ok && result.workflow.state !== workflow.state) {
504
+ await this.hookRegistry.emit(
505
+ "transition",
506
+ this.onHookError,
507
+ workflow.state,
508
+ result.workflow.state,
509
+ result.workflow
510
+ );
511
+ }
512
+ if (result.ok) {
513
+ for (const event of result.events) {
514
+ await this.hookRegistry.emit("event", this.onHookError, event, result.workflow);
515
+ }
516
+ }
517
+ await this.hookRegistry.emit("dispatch:end", this.onHookError, ctx, result);
518
+ return result;
346
519
  } catch (err) {
520
+ let result;
347
521
  if (err instanceof DomainErrorSignal) {
348
- return {
522
+ result = {
349
523
  ok: false,
350
524
  error: {
351
525
  category: "domain",
@@ -353,9 +527,8 @@ var WorkflowRouter = class {
353
527
  data: err.data
354
528
  }
355
529
  };
356
- }
357
- if (err instanceof ValidationError) {
358
- return {
530
+ } else if (err instanceof ValidationError) {
531
+ result = {
359
532
  ok: false,
360
533
  error: {
361
534
  category: "validation",
@@ -364,8 +537,12 @@ var WorkflowRouter = class {
364
537
  message: err.message
365
538
  }
366
539
  };
540
+ } else {
541
+ throw err;
367
542
  }
368
- throw err;
543
+ await this.hookRegistry.emit("error", this.onHookError, result.error, ctx);
544
+ await this.hookRegistry.emit("dispatch:end", this.onHookError, ctx, result);
545
+ return result;
369
546
  }
370
547
  }
371
548
  };
@@ -375,6 +552,8 @@ var WorkflowRouter = class {
375
552
  ValidationError,
376
553
  WorkflowRouter,
377
554
  createKey,
378
- defineWorkflow
555
+ definePlugin,
556
+ defineWorkflow,
557
+ isPlugin
379
558
  });
380
559
  //# 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\ntype AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;\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 */\nexport class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {\n\tprivate globalMiddleware: AnyMiddleware[] = [];\n\tprivate singleStateBuilders = new Map<string, StateBuilder<TConfig, TDeps, any>>();\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 that wraps all dispatches. */\n\tuse(\n\t\tmiddleware: (ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>,\n\t): this {\n\t\tthis.globalMiddleware.push(middleware as AnyMiddleware);\n\t\treturn this;\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\trouter = new StateBuilder<TConfig, TDeps, any>();\n\t\t\t\trouterMap.set(n, router);\n\t\t\t}\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\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":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/definition.ts","../src/key.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 { 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 { 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgFO,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;;;ACxEO,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,IAEA,SAAS,UAAwD;AAChE,aAAO;AAAA,QACN,IAAI,SAAS;AAAA,QACb,gBAAgB;AAAA,QAChB,OAAO,SAAS;AAAA,QAChB,MAAM,SAAS;AAAA,QACf,WAAW,SAAS,UAAU,YAAY;AAAA,QAC1C,WAAW,SAAS,UAAU,YAAY;AAAA,QAC1C,cAAc,OAAO,gBAAgB;AAAA,MACtC;AAAA,IACD;AAAA,IAEA,QACC,MACoF;AACpF,YAAM,cAAc,OAAO,OAAO,KAAK,KAAe;AACtD,UAAI,CAAC,aAAa;AACjB,eAAO;AAAA,UACN,IAAI;AAAA,UACJ,OAAO,IAAI,gBAAgB,WAAW;AAAA,YACrC;AAAA,cACC,MAAM;AAAA,cACN,SAAS,kBAAkB,KAAK,KAAK;AAAA,cACrC,OAAO,KAAK;AAAA,cACZ,MAAM,CAAC,OAAO;AAAA,YACf;AAAA,UACD,CAAC;AAAA,QACF;AAAA,MACD;AAEA,YAAM,SAAS,YAAY,UAAU,KAAK,IAAI;AAC9C,UAAI,CAAC,OAAO,SAAS;AACpB,eAAO;AAAA,UACN,IAAI;AAAA,UACJ,OAAO,IAAI,gBAAgB,WAAW,OAAO,MAAM,MAAM;AAAA,QAC1D;AAAA,MACD;AAEA,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,UAAU;AAAA,UACT,IAAI,KAAK;AAAA,UACT,gBAAgB,KAAK;AAAA,UACrB,OAAO,KAAK;AAAA,UACZ,MAAM,OAAO;AAAA,UACb,WAAW,IAAI,KAAK,KAAK,SAAS;AAAA,UAClC,WAAW,IAAI,KAAK,KAAK,SAAS;AAAA,QACnC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;;;AC/HO,SAAS,UAAa,MAA6B;AACzD,SAAO,EAAE,IAAI,OAAO,IAAI,EAAE;AAC3B;;;ACNA,IAAM,gBAA+B,uBAAO,IAAI,aAAa;AAQtD,SAAS,aACf,IACyB;AACzB,QAAM,SAAS;AACf,SAAO,eAAe,QAAQ,eAAe,EAAE,OAAO,MAAM,UAAU,MAAM,CAAC;AAC7E,SAAO;AACR;AAGO,SAAS,SAAS,OAA0D;AAClF,SAAO,OAAO,UAAU,cAAc,iBAAiB;AACxD;;;ACnBO,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;;;AC2CO,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;;;ACzJO,IAAM,cAAmC,oBAAI,IAAe;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAMM,IAAM,eAAN,MAAmB;AAAA;AAAA,EAEjB,QAAQ,oBAAI,IAAwB;AAAA;AAAA;AAAA,EAI5C,IAAI,OAAe,UAA0B;AAC5C,UAAM,WAAW,KAAK,MAAM,IAAI,KAAK,KAAK,CAAC;AAC3C,aAAS,KAAK,QAAQ;AACtB,SAAK,MAAM,IAAI,OAAO,QAAQ;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,KAAK,OAAe,YAAoC,MAAgC;AAC7F,UAAM,YAAY,KAAK,MAAM,IAAI,KAAK;AACtC,QAAI,CAAC,UAAW;AAChB,eAAW,MAAM,WAAW;AAC3B,UAAI;AACH,cAAM,GAAG,GAAG,IAAI;AAAA,MACjB,SAAS,KAAK;AACb,gBAAQ,GAAG;AAAA,MACZ;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAGA,MAAM,OAA2B;AAChC,eAAW,CAAC,OAAO,SAAS,KAAK,MAAM,OAAO;AAC7C,YAAM,WAAW,KAAK,MAAM,IAAI,KAAK,KAAK,CAAC;AAC3C,eAAS,KAAK,GAAG,SAAS;AAC1B,WAAK,MAAM,IAAI,OAAO,QAAQ;AAAA,IAC/B;AAAA,EACD;AACD;;;ACdA,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,EAUvE,YACkB,YACA,OAAc,CAAC,GAChC,UAAyB,CAAC,GACzB;AAHgB;AACA;AAGjB,SAAK,cAAc,QAAQ,eAAe,QAAQ;AAAA,EACnD;AAAA,EAfQ,mBAAoC,CAAC;AAAA;AAAA,EAErC,sBAAsB,oBAAI,IAA+C;AAAA;AAAA,EAEzE,qBAAqB,oBAAI,IAA+C;AAAA,EACxE,mBAAmB,oBAAI,IAA0B;AAAA,EACjD,eAAe,IAAI,aAAa;AAAA,EACvB;AAAA;AAAA,EAWjB,IACC,KAIO;AACP,QAAI,eAAe,iBAAgB;AAClC,WAAK,MAAM,GAAG;AAAA,IACf,WAAW,SAAS,GAAG,GAAG;AACzB,MAAC,IAAyD,IAAI;AAAA,IAC/D,OAAO;AACN,WAAK,iBAAiB,KAAK,GAAoB;AAAA,IAChD;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;AAEA,SAAK,aAAa,MAAM,MAAM,YAAY;AAAA,EAC3C;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,EA8CA,MAAM,MAAmB;AACxB,UAAM,QAAQ,KAAK,CAAC;AAEpB,QAAI,YAAY,IAAI,KAAK,GAAG;AAE3B,WAAK,aAAa,IAAI,OAAO,KAAK,CAAC,CAAa;AAChD,aAAO;AAAA,IACR;AAEA,QAAI,UAAU,KAAK;AAClB,YAAM,UAAU,KAAK,CAAC;AACtB,YAAM,MAAM,KAAK,MAAM,CAAC;AACxB,UAAI,IAAI,WAAW,EAAG,OAAM,IAAI,MAAM,kCAAkC;AACxE,YAAM,UAAU,IAAI,IAAI;AACxB,YAAM,mBAAmB;AACzB,YAAM,iBAAgC,OAAO,KAAK,UAAU;AAC3D,cAAM,QAAQ,GAAG;AAAA,MAClB;AACA,WAAK,iBAAiB,IAAI,SAAS;AAAA,QAClC;AAAA,QACA,SAAS;AAAA,MACV,CAAC;AACD,aAAO;AAAA,IACR;AAEA,UAAM,IAAI,MAAM,2BAA2B,KAAK,EAAE;AAAA,EACnD;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;AAGA,UAAM,KAAK,aAAa,KAAK,kBAAkB,KAAK,aAAa,GAAG;AAEpE,QAAI;AACH,YAAM,WAAW,QAAQ,KAAK;AAC9B,YAAM,SAAS,GAAG;AAClB,YAAM,SAAkC;AAAA,QACvC,IAAI;AAAA,QACJ,UAAU,IAAI,oBAAoB;AAAA,QAClC,QAAQ,CAAC,GAAG,IAAI,MAAM;AAAA,MACvB;AAGA,UAAI,OAAO,MAAM,OAAO,SAAS,UAAU,SAAS,OAAO;AAC1D,cAAM,KAAK,aAAa;AAAA,UACvB;AAAA,UACA,KAAK;AAAA,UACL,SAAS;AAAA,UACT,OAAO,SAAS;AAAA,UAChB,OAAO;AAAA,QACR;AAAA,MACD;AAGA,UAAI,OAAO,IAAI;AACd,mBAAW,SAAS,OAAO,QAAQ;AAClC,gBAAM,KAAK,aAAa,KAAK,SAAS,KAAK,aAAa,OAAO,OAAO,QAAQ;AAAA,QAC/E;AAAA,MACD;AAGA,YAAM,KAAK,aAAa,KAAK,gBAAgB,KAAK,aAAa,KAAK,MAAM;AAE1E,aAAO;AAAA,IACR,SAAS,KAAK;AACb,UAAI;AACJ,UAAI,eAAe,mBAAmB;AACrC,iBAAS;AAAA,UACR,IAAI;AAAA,UACJ,OAAO;AAAA,YACN,UAAU;AAAA,YACV,MAAM,IAAI;AAAA,YACV,MAAM,IAAI;AAAA,UACX;AAAA,QACD;AAAA,MACD,WAAW,eAAe,iBAAiB;AAC1C,iBAAS;AAAA,UACR,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,OAAO;AACN,cAAM;AAAA,MACP;AAGA,YAAM,KAAK,aAAa,KAAK,SAAS,KAAK,aAAa,OAAO,OAAO,GAAG;AAGzE,YAAM,KAAK,aAAa,KAAK,gBAAgB,KAAK,aAAa,KAAK,MAAM;AAE1E,aAAO;AAAA,IACR;AAAA,EACD;AACD;","names":[]}