@rytejs/core 0.5.0 → 0.7.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.d.ts CHANGED
@@ -1,293 +1,14 @@
1
- import { ZodType, z } from 'zod';
2
-
3
- /**
4
- * Shape of the configuration object passed to {@link defineWorkflow}.
5
- */
6
- interface WorkflowConfig {
7
- /** Optional version number for schema migrations. Defaults to 1. */
8
- modelVersion?: number;
9
- /** Record of state names to Zod schemas defining their data shape. */
10
- states: Record<string, ZodType>;
11
- /** Record of command names to Zod schemas defining their payload shape. */
12
- commands: Record<string, ZodType>;
13
- /** Record of event names to Zod schemas defining their data shape. */
14
- events: Record<string, ZodType>;
15
- /** Record of error codes to Zod schemas defining their data shape. */
16
- errors: Record<string, ZodType>;
17
- }
18
- type StateNames<T extends WorkflowConfig> = keyof T["states"] & string;
19
- type CommandNames<T extends WorkflowConfig> = keyof T["commands"] & string;
20
- type EventNames<T extends WorkflowConfig> = keyof T["events"] & string;
21
- type ErrorCodes<T extends WorkflowConfig> = keyof T["errors"] & string;
22
- /** Infers the data type for a given state. */
23
- type StateData<T extends WorkflowConfig, S extends StateNames<T>> = T["states"][S] extends ZodType ? z.infer<T["states"][S]> : never;
24
- /** Infers the payload type for a given command. */
25
- type CommandPayload<T extends WorkflowConfig, C extends CommandNames<T>> = T["commands"][C] extends ZodType ? z.infer<T["commands"][C]> : never;
26
- /** Infers the data type for a given event. */
27
- type EventData<T extends WorkflowConfig, E extends EventNames<T>> = T["events"][E] extends ZodType ? z.infer<T["events"][E]> : never;
28
- /** Infers the data type for a given error code. */
29
- type ErrorData<T extends WorkflowConfig, C extends ErrorCodes<T>> = T["errors"][C] extends ZodType ? z.infer<T["errors"][C]> : never;
30
- /** Workflow narrowed to a specific known state. */
31
- interface WorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {
32
- /** Unique workflow instance identifier. */
33
- readonly id: string;
34
- /** Name of the workflow definition this instance belongs to. */
35
- readonly definitionName: string;
36
- /** Current state name. */
37
- readonly state: S;
38
- /** State data, typed according to the state's Zod schema. */
39
- readonly data: StateData<TConfig, S>;
40
- /** Timestamp of workflow creation. */
41
- readonly createdAt: Date;
42
- /** Timestamp of last state change. */
43
- readonly updatedAt: Date;
44
- }
45
- /** Discriminated union of all possible workflow states — checking .state narrows .data. */
46
- type Workflow<TConfig extends WorkflowConfig = WorkflowConfig> = {
47
- [S in StateNames<TConfig>]: WorkflowOf<TConfig, S>;
48
- }[StateNames<TConfig>];
49
- /** Discriminated union of all pipeline error types on `category`. */
50
- type PipelineError<TConfig extends WorkflowConfig = WorkflowConfig> = {
51
- category: "validation";
52
- source: "command" | "state" | "event" | "transition" | "restore";
53
- issues: z.core.$ZodIssue[];
54
- message: string;
55
- } | {
56
- category: "domain";
57
- code: ErrorCodes<TConfig>;
58
- data: ErrorData<TConfig, ErrorCodes<TConfig>>;
59
- } | {
60
- category: "router";
61
- code: "NO_HANDLER" | "UNKNOWN_STATE";
62
- message: string;
63
- } | {
64
- category: "unexpected";
65
- error: unknown;
66
- message: string;
67
- };
68
- /** Return type of {@link WorkflowRouter.dispatch}. Discriminated union on `ok`. */
69
- type DispatchResult<TConfig extends WorkflowConfig = WorkflowConfig> = {
70
- ok: true;
71
- workflow: Workflow<TConfig>;
72
- events: Array<{
73
- type: EventNames<TConfig>;
74
- data: unknown;
75
- }>;
76
- } | {
77
- ok: false;
78
- error: PipelineError<TConfig>;
79
- };
80
- /**
81
- * Thrown internally when Zod validation fails during dispatch.
82
- * Caught by the router and returned as a validation error in {@link DispatchResult}.
83
- *
84
- * @param source - Which validation stage failed
85
- * @param issues - Array of Zod validation issues
86
- */
87
- declare class ValidationError extends Error {
88
- readonly source: "command" | "state" | "event" | "transition" | "restore";
89
- readonly issues: z.core.$ZodIssue[];
90
- constructor(source: "command" | "state" | "event" | "transition" | "restore", issues: z.core.$ZodIssue[]);
91
- }
92
- /**
93
- * Thrown internally when a handler calls `ctx.error()`.
94
- * Caught by the router and returned as a domain error in {@link DispatchResult}.
95
- *
96
- * @param code - The error code string
97
- * @param data - The error data payload
98
- */
99
- declare class DomainErrorSignal extends Error {
100
- readonly code: string;
101
- readonly data: unknown;
102
- constructor(code: string, data: unknown);
103
- }
104
-
105
- /** A plain, JSON-safe representation of a workflow's state for serialization and storage. */
106
- interface WorkflowSnapshot<TConfig extends WorkflowConfig = WorkflowConfig> {
107
- /** Unique workflow instance identifier. */
108
- readonly id: string;
109
- /** Name of the workflow definition. */
110
- readonly definitionName: string;
111
- /** Current state name. */
112
- readonly state: StateNames<TConfig>;
113
- /** State data (untyped — validated on {@link WorkflowDefinition.restore}). */
114
- readonly data: unknown;
115
- /** ISO 8601 timestamp of workflow creation. */
116
- readonly createdAt: string;
117
- /** ISO 8601 timestamp of last state change. */
118
- readonly updatedAt: string;
119
- /** Schema version number for migration support. */
120
- readonly modelVersion: number;
121
- }
122
-
123
- /**
124
- * The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
125
- */
126
- interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
127
- /** The raw Zod schema configuration. */
128
- readonly config: TConfig;
129
- /** The workflow definition name. */
130
- readonly name: string;
131
- /**
132
- * Creates a new workflow instance in a given initial state.
133
- *
134
- * @param id - Unique identifier for this workflow instance
135
- * @param config - Object containing `initialState` and the corresponding `data`
136
- * @returns A {@link WorkflowOf} narrowed to the initial state
137
- */
138
- createWorkflow<S extends StateNames<TConfig>>(id: string, config: {
139
- initialState: S;
140
- data: z.infer<TConfig["states"][S]>;
141
- }): WorkflowOf<TConfig, S>;
142
- /**
143
- * Returns the Zod schema for a given state name.
144
- *
145
- * @param stateName - The state name to look up
146
- * @throws If the state name is not found in the config
147
- */
148
- getStateSchema(stateName: string): ZodType;
149
- /**
150
- * Returns the Zod schema for a given command name.
151
- *
152
- * @param commandName - The command name to look up
153
- * @throws If the command name is not found in the config
154
- */
155
- getCommandSchema(commandName: string): ZodType;
156
- /**
157
- * Returns the Zod schema for a given event name.
158
- *
159
- * @param eventName - The event name to look up
160
- * @throws If the event name is not found in the config
161
- */
162
- getEventSchema(eventName: string): ZodType;
163
- /**
164
- * Returns the Zod schema for a given error code.
165
- *
166
- * @param errorCode - The error code to look up
167
- * @throws If the error code is not found in the config
168
- */
169
- getErrorSchema(errorCode: string): ZodType;
170
- /**
171
- * Returns `true` if the given state name exists in the config.
172
- *
173
- * @param stateName - The state name to check
174
- */
175
- hasState(stateName: string): boolean;
176
- /**
177
- * Serializes a workflow instance into a plain, JSON-safe snapshot.
178
- *
179
- * @param workflow - The workflow instance to serialize
180
- * @returns A {@link WorkflowSnapshot} representing the current state
181
- */
182
- snapshot(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
183
- /**
184
- * Restores a workflow instance from a plain snapshot, validating the state data.
185
- *
186
- * @param snapshot - The snapshot to restore from
187
- * @returns A result object: `{ ok: true, workflow }` or `{ ok: false, error }`
188
- */
189
- restore(snapshot: WorkflowSnapshot<TConfig>): {
190
- ok: true;
191
- workflow: Workflow<TConfig>;
192
- } | {
193
- ok: false;
194
- error: ValidationError;
195
- };
196
- }
197
- /**
198
- * Creates a workflow definition from a name and Zod schema configuration.
199
- *
200
- * @param name - Unique name for this workflow type
201
- * @param config - Object with `states`, `commands`, `events`, `errors` — each a record of Zod schemas
202
- * @returns A {@link WorkflowDefinition} with methods for creating instances and accessing schemas
203
- */
204
- declare function defineWorkflow<const TConfig extends WorkflowConfig>(name: string, config: TConfig): WorkflowDefinition<TConfig>;
205
-
206
- /** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
207
- interface ContextKey<T> {
208
- /** @internal Phantom type brand — not used at runtime. */
209
- readonly _phantom: T;
210
- /** Internal symbol providing uniqueness. */
211
- readonly id: symbol;
212
- }
213
- /**
214
- * Creates a unique typed key for storing and retrieving values in context.
215
- *
216
- * @param name - Debug label (uniqueness comes from an internal `Symbol`)
217
- * @returns A {@link ContextKey} for use with `ctx.set()`, `ctx.get()`, and `ctx.getOrNull()`
218
- */
219
- declare function createKey<T>(name: string): ContextKey<T>;
220
-
221
- /** Mutable context flowing through the middleware pipeline during dispatch. */
222
- interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig> = StateNames<TConfig>, TCommand extends CommandNames<TConfig> = CommandNames<TConfig>> {
223
- /** The command being dispatched, with type and validated payload. */
224
- readonly command: {
225
- readonly type: TCommand;
226
- readonly payload: CommandPayload<TConfig, TCommand>;
227
- };
228
- /** The original workflow before any mutations. */
229
- readonly workflow: WorkflowOf<TConfig, TState>;
230
- /** Dependencies injected via the router constructor. */
231
- readonly deps: TDeps;
232
- /** Current state data (reflects mutations from {@link update}). */
233
- readonly data: StateData<TConfig, TState>;
234
- /**
235
- * Merges partial data into the current state. Validates against the state's Zod schema.
236
- * @param data - Partial state data to merge
237
- */
238
- update(data: Partial<StateData<TConfig, TState>>): void;
239
- /**
240
- * Transitions the workflow to a new state with new data. Validates against the target state's Zod schema.
241
- * @param target - Target state name
242
- * @param data - Data for the target state
243
- */
244
- transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
245
- /**
246
- * Emits a domain event. Validates event data against the event's Zod schema.
247
- * @param event - Event with type and data
248
- */
249
- emit<E extends EventNames<TConfig>>(event: {
250
- type: E;
251
- data: EventData<TConfig, E>;
252
- }): void;
253
- /** Accumulated events emitted during this dispatch. */
254
- readonly events: ReadonlyArray<{
255
- type: EventNames<TConfig>;
256
- data: unknown;
257
- }>;
258
- /**
259
- * Signals a domain error. Validates error data and throws internally (caught by the router).
260
- * @param err - Error with code and data
261
- */
262
- error<C extends ErrorCodes<TConfig>>(err: {
263
- code: C;
264
- data: ErrorData<TConfig, C>;
265
- }): never;
266
- /**
267
- * Stores a value in context-scoped middleware state.
268
- * @param key - A {@link ContextKey} created via {@link createKey}
269
- * @param value - The value to store
270
- */
271
- set<T>(key: ContextKey<T>, value: T): void;
272
- /**
273
- * Retrieves a value from context-scoped middleware state. Throws if not set.
274
- * @param key - A {@link ContextKey} created via {@link createKey}
275
- */
276
- get<T>(key: ContextKey<T>): T;
277
- /**
278
- * Retrieves a value from context-scoped middleware state, or `undefined` if not set.
279
- * @param key - A {@link ContextKey} created via {@link createKey}
280
- */
281
- getOrNull<T>(key: ContextKey<T>): T | undefined;
282
- /** @internal — not part of the handler API */
283
- getWorkflowSnapshot(): Workflow<TConfig>;
284
- }
1
+ import { C as Context, W as WorkflowDefinition } from './plugin-DHN3Pk52.js';
2
+ export { a as ContextKey, G as GenericPlugin, P as Plugin, R as ReadonlyContext, b as RouterOptions, c as WorkflowRouter, d as createKey, e as defineGenericPlugin, f as definePlugin, g as defineWorkflow, i as isPlugin } from './plugin-DHN3Pk52.js';
3
+ import { W as WorkflowConfig, S as StateNames, C as CommandNames, a as WorkflowSnapshot } from './snapshot-D5iZubCz.js';
4
+ export { b as CommandPayload, c as ConfigOf, D as DispatchResult, d as DomainErrorSignal, E as ErrorCodes, e as ErrorData, f as EventData, g as EventNames, P as PipelineError, h as StateData, V as ValidationError, i as Workflow, j as WorkflowOf } from './snapshot-D5iZubCz.js';
5
+ import 'zod';
285
6
 
286
7
  /** Terminal handler function — receives fully typed context with state and command narrowing. */
287
8
  type Handler<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>, TCommand extends CommandNames<TConfig>> = (ctx: Context<TConfig, TDeps, TState, TCommand>) => void | Promise<void>;
288
9
 
289
10
  /** The lifecycle hook event names. */
290
- type HookEvent = "dispatch:start" | "dispatch:end" | "transition" | "error" | "event";
11
+ type HookEvent = "dispatch:start" | "dispatch:end" | "pipeline:start" | "pipeline:end" | "transition" | "error" | "event";
291
12
 
292
13
  /**
293
14
  * Koa-style middleware function with full context narrowing via defaults.
@@ -376,115 +97,4 @@ declare function defineMigrations<TConfig extends WorkflowConfig>(definition: Wo
376
97
  */
377
98
  declare function migrate<TConfig extends WorkflowConfig>(pipeline: MigrationPipeline<TConfig>, snapshot: WorkflowSnapshot, options?: MigrateOptions): MigrateResult;
378
99
 
379
- /**
380
- * Read-only subset of Context for hook callbacks.
381
- * Includes context-key access (set/get) but excludes dispatch mutation methods.
382
- */
383
- type ReadonlyContext<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig> = StateNames<TConfig>, TCommand extends CommandNames<TConfig> = CommandNames<TConfig>> = Omit<Context<TConfig, TDeps, TState, TCommand>, "update" | "transition" | "emit" | "error" | "getWorkflowSnapshot">;
384
-
385
- type AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;
386
- type HandlerEntry = {
387
- inlineMiddleware: AnyMiddleware[];
388
- handler: AnyMiddleware;
389
- };
390
- /** Options for the {@link WorkflowRouter} constructor. */
391
- interface RouterOptions {
392
- /** Callback invoked when a lifecycle hook throws. Defaults to `console.error`. */
393
- onHookError?: (error: unknown) => void;
394
- }
395
- declare class StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {
396
- /** @internal */ readonly middleware: AnyMiddleware[];
397
- /** @internal */ readonly handlers: Map<string, HandlerEntry>;
398
- on: <C extends CommandNames<TConfig>>(command: C, ...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]) => this;
399
- use: (middleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>) => this;
400
- }
401
- /**
402
- * Routes commands to handlers based on workflow state.
403
- *
404
- * Supports global middleware, state-scoped middleware, inline middleware,
405
- * wildcard handlers, and multi-state handlers.
406
- */
407
- declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
408
- private readonly definition;
409
- private readonly deps;
410
- private globalMiddleware;
411
- private singleStateBuilders;
412
- private multiStateBuilders;
413
- private wildcardHandlers;
414
- private hookRegistry;
415
- private readonly onHookError;
416
- /**
417
- * @param definition - The workflow definition describing states, commands, events, and errors
418
- * @param deps - Dependencies injected into every handler context
419
- * @param options - Router configuration options
420
- */
421
- constructor(definition: WorkflowDefinition<TConfig>, deps?: TDeps, options?: RouterOptions);
422
- /**
423
- * Adds global middleware, merges another router, or applies a plugin.
424
- * @param arg - A middleware function, another {@link WorkflowRouter} to merge, or a {@link Plugin}
425
- */
426
- use(arg: ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>) | WorkflowRouter<TConfig, TDeps> | Plugin<TConfig, TDeps>): this;
427
- private merge;
428
- private mergeStateBuilders;
429
- /**
430
- * Registers handlers for one or more states.
431
- * @param name - A state name or array of state names to register handlers for
432
- * @param setup - Callback that receives a state builder to register commands and middleware
433
- */
434
- state<P extends StateNames<TConfig> | readonly StateNames<TConfig>[]>(name: P, setup: (state: StateBuilder<TConfig, TDeps, P extends readonly (infer S)[] ? S & StateNames<TConfig> : P & StateNames<TConfig>>) => void): this;
435
- /**
436
- * Registers a lifecycle hook callback.
437
- * @param event - The lifecycle event name
438
- * @param callback - The callback to invoke when the event fires
439
- */
440
- on(event: "dispatch:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
441
- on(event: "dispatch:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
442
- on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
443
- on(event: "error", callback: (error: PipelineError<TConfig>, ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
444
- on(event: "event", callback: (event: {
445
- type: EventNames<TConfig>;
446
- data: unknown;
447
- }, workflow: Workflow<TConfig>) => void | Promise<void>): this;
448
- /**
449
- * Registers a wildcard handler that matches any state.
450
- * @param state - Must be `"*"` to match all states
451
- * @param command - The command name to handle
452
- * @param fns - Optional inline middleware followed by the terminal handler
453
- */
454
- on<C extends CommandNames<TConfig>>(state: "*", command: C, ...fns: [
455
- ...AnyMiddleware[],
456
- (ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>
457
- ]): this;
458
- /**
459
- * Dispatches a command to the appropriate handler and returns the result.
460
- * @param workflow - The current workflow instance to dispatch against
461
- * @param command - The command with its type and payload
462
- * @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
463
- */
464
- dispatch(workflow: Workflow<TConfig>, command: {
465
- type: CommandNames<TConfig>;
466
- payload: unknown;
467
- }): Promise<DispatchResult<TConfig>>;
468
- }
469
-
470
- declare const PLUGIN_SYMBOL: unique symbol;
471
- /** A branded plugin function that can be passed to {@link WorkflowRouter.use}. */
472
- type Plugin<TConfig extends WorkflowConfig, TDeps> = ((router: WorkflowRouter<TConfig, TDeps>) => void) & {
473
- readonly [PLUGIN_SYMBOL]: true;
474
- };
475
- /**
476
- * Brands a function as a Ryte plugin for use with {@link WorkflowRouter.use}.
477
- *
478
- * @param fn - A function that configures a router (adds handlers, middleware, hooks)
479
- * @returns A branded {@link Plugin} function
480
- */
481
- declare function definePlugin<TConfig extends WorkflowConfig, TDeps>(fn: (router: WorkflowRouter<TConfig, TDeps>) => void): Plugin<TConfig, TDeps>;
482
- /**
483
- * Checks whether a value is a branded Ryte plugin.
484
- *
485
- * @param value - The value to check
486
- * @returns `true` if the value is a {@link Plugin}
487
- */
488
- declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
489
-
490
- export { type CommandNames, type CommandPayload, type Context, type ContextKey, type DispatchResult, DomainErrorSignal, type ErrorCodes, type ErrorData, type EventData, type EventNames, type Handler, type HookEvent, type Middleware, type MigrateOptions, type MigrateResult, type MigrationEntry, MigrationError, type MigrationFn, type MigrationPipeline, type PipelineError, type Plugin, type ReadonlyContext, type RouterOptions, type StateData, type StateNames, ValidationError, type Workflow, type WorkflowConfig, type WorkflowDefinition, type WorkflowOf, WorkflowRouter, type WorkflowSnapshot, createKey, defineMigrations, definePlugin, defineWorkflow, isPlugin, migrate };
100
+ export { CommandNames, Context, type Handler, type HookEvent, type Middleware, type MigrateOptions, type MigrateResult, type MigrationEntry, MigrationError, type MigrationFn, type MigrationPipeline, StateNames, WorkflowConfig, WorkflowDefinition, WorkflowSnapshot, defineMigrations, migrate };