@rytejs/core 0.4.0 → 0.6.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 +10 -4
- package/dist/index.cjs +140 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +299 -27
- package/dist/index.d.ts +299 -27
- package/dist/index.js +140 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,33 +1,74 @@
|
|
|
1
1
|
import { ZodType, z } from 'zod';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Shape of the configuration object passed to {@link defineWorkflow}.
|
|
5
|
+
* Exported for internal package use only — not re-exported from index.ts.
|
|
6
|
+
*/
|
|
7
|
+
interface WorkflowConfigInput {
|
|
8
|
+
/** Optional version number for schema migrations. Defaults to 1. */
|
|
4
9
|
modelVersion?: number;
|
|
10
|
+
/** Record of state names to Zod schemas defining their data shape. */
|
|
5
11
|
states: Record<string, ZodType>;
|
|
12
|
+
/** Record of command names to Zod schemas defining their payload shape. */
|
|
6
13
|
commands: Record<string, ZodType>;
|
|
14
|
+
/** Record of event names to Zod schemas defining their data shape. */
|
|
7
15
|
events: Record<string, ZodType>;
|
|
16
|
+
/** Record of error codes to Zod schemas defining their data shape. */
|
|
8
17
|
errors: Record<string, ZodType>;
|
|
9
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Workflow configuration with pre-resolved types for IDE completion.
|
|
21
|
+
*
|
|
22
|
+
* Extends {@link WorkflowConfigInput} with a `_resolved` phantom type that
|
|
23
|
+
* caches `z.infer` results. This exists because Zod v4's `z.infer` uses
|
|
24
|
+
* conditional types that TypeScript defers in deep generic chains, breaking
|
|
25
|
+
* IDE autocomplete. The `_resolved` property is never set at runtime — it is
|
|
26
|
+
* populated at the type level by {@link defineWorkflow}'s return type.
|
|
27
|
+
*/
|
|
28
|
+
interface WorkflowConfig extends WorkflowConfigInput {
|
|
29
|
+
_resolved: {
|
|
30
|
+
states: Record<string, unknown>;
|
|
31
|
+
commands: Record<string, unknown>;
|
|
32
|
+
events: Record<string, unknown>;
|
|
33
|
+
errors: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
10
36
|
type StateNames<T extends WorkflowConfig> = keyof T["states"] & string;
|
|
11
37
|
type CommandNames<T extends WorkflowConfig> = keyof T["commands"] & string;
|
|
12
38
|
type EventNames<T extends WorkflowConfig> = keyof T["events"] & string;
|
|
13
39
|
type ErrorCodes<T extends WorkflowConfig> = keyof T["errors"] & string;
|
|
14
|
-
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
|
|
40
|
+
/** Forces TypeScript to flatten a type for better IDE autocomplete. */
|
|
41
|
+
type Prettify<T> = {
|
|
42
|
+
[K in keyof T]: T[K];
|
|
43
|
+
} & {};
|
|
44
|
+
/** Resolves the data type for a given state from pre-computed types. */
|
|
45
|
+
type StateData<T extends WorkflowConfig, S extends StateNames<T>> = Prettify<T["_resolved"]["states"][S]>;
|
|
46
|
+
/** Resolves the payload type for a given command from pre-computed types. */
|
|
47
|
+
type CommandPayload<T extends WorkflowConfig, C extends CommandNames<T>> = Prettify<T["_resolved"]["commands"][C]>;
|
|
48
|
+
/** Resolves the data type for a given event from pre-computed types. */
|
|
49
|
+
type EventData<T extends WorkflowConfig, E extends EventNames<T>> = Prettify<T["_resolved"]["events"][E]>;
|
|
50
|
+
/** Resolves the data type for a given error code from pre-computed types. */
|
|
51
|
+
type ErrorData<T extends WorkflowConfig, C extends ErrorCodes<T>> = Prettify<T["_resolved"]["errors"][C]>;
|
|
18
52
|
/** Workflow narrowed to a specific known state. */
|
|
19
53
|
interface WorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {
|
|
54
|
+
/** Unique workflow instance identifier. */
|
|
20
55
|
readonly id: string;
|
|
56
|
+
/** Name of the workflow definition this instance belongs to. */
|
|
21
57
|
readonly definitionName: string;
|
|
58
|
+
/** Current state name. */
|
|
22
59
|
readonly state: S;
|
|
60
|
+
/** State data, typed according to the state's Zod schema. */
|
|
23
61
|
readonly data: StateData<TConfig, S>;
|
|
62
|
+
/** Timestamp of workflow creation. */
|
|
24
63
|
readonly createdAt: Date;
|
|
64
|
+
/** Timestamp of last state change. */
|
|
25
65
|
readonly updatedAt: Date;
|
|
26
66
|
}
|
|
27
67
|
/** Discriminated union of all possible workflow states — checking .state narrows .data. */
|
|
28
68
|
type Workflow<TConfig extends WorkflowConfig = WorkflowConfig> = {
|
|
29
69
|
[S in StateNames<TConfig>]: WorkflowOf<TConfig, S>;
|
|
30
70
|
}[StateNames<TConfig>];
|
|
71
|
+
/** Discriminated union of all pipeline error types on `category`. */
|
|
31
72
|
type PipelineError<TConfig extends WorkflowConfig = WorkflowConfig> = {
|
|
32
73
|
category: "validation";
|
|
33
74
|
source: "command" | "state" | "event" | "transition" | "restore";
|
|
@@ -41,7 +82,17 @@ type PipelineError<TConfig extends WorkflowConfig = WorkflowConfig> = {
|
|
|
41
82
|
category: "router";
|
|
42
83
|
code: "NO_HANDLER" | "UNKNOWN_STATE";
|
|
43
84
|
message: string;
|
|
85
|
+
} | {
|
|
86
|
+
category: "unexpected";
|
|
87
|
+
error: unknown;
|
|
88
|
+
message: string;
|
|
89
|
+
} | {
|
|
90
|
+
category: "dependency";
|
|
91
|
+
name: string;
|
|
92
|
+
error: unknown;
|
|
93
|
+
message: string;
|
|
44
94
|
};
|
|
95
|
+
/** Return type of {@link WorkflowRouter.dispatch}. Discriminated union on `ok`. */
|
|
45
96
|
type DispatchResult<TConfig extends WorkflowConfig = WorkflowConfig> = {
|
|
46
97
|
ok: true;
|
|
47
98
|
workflow: Workflow<TConfig>;
|
|
@@ -53,44 +104,115 @@ type DispatchResult<TConfig extends WorkflowConfig = WorkflowConfig> = {
|
|
|
53
104
|
ok: false;
|
|
54
105
|
error: PipelineError<TConfig>;
|
|
55
106
|
};
|
|
56
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Thrown internally when Zod validation fails during dispatch.
|
|
109
|
+
* Caught by the router and returned as a validation error in {@link DispatchResult}.
|
|
110
|
+
*
|
|
111
|
+
* @param source - Which validation stage failed
|
|
112
|
+
* @param issues - Array of Zod validation issues
|
|
113
|
+
*/
|
|
57
114
|
declare class ValidationError extends Error {
|
|
58
115
|
readonly source: "command" | "state" | "event" | "transition" | "restore";
|
|
59
116
|
readonly issues: z.core.$ZodIssue[];
|
|
60
117
|
constructor(source: "command" | "state" | "event" | "transition" | "restore", issues: z.core.$ZodIssue[]);
|
|
61
118
|
}
|
|
62
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Thrown internally when a handler calls `ctx.error()`.
|
|
121
|
+
* Caught by the router and returned as a domain error in {@link DispatchResult}.
|
|
122
|
+
*
|
|
123
|
+
* @param code - The error code string
|
|
124
|
+
* @param data - The error data payload
|
|
125
|
+
*/
|
|
63
126
|
declare class DomainErrorSignal extends Error {
|
|
64
127
|
readonly code: string;
|
|
65
128
|
readonly data: unknown;
|
|
66
129
|
constructor(code: string, data: unknown);
|
|
67
130
|
}
|
|
68
131
|
|
|
69
|
-
/** A plain, JSON-safe representation of a workflow's state. */
|
|
132
|
+
/** A plain, JSON-safe representation of a workflow's state for serialization and storage. */
|
|
70
133
|
interface WorkflowSnapshot<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
134
|
+
/** Unique workflow instance identifier. */
|
|
71
135
|
readonly id: string;
|
|
136
|
+
/** Name of the workflow definition. */
|
|
72
137
|
readonly definitionName: string;
|
|
138
|
+
/** Current state name. */
|
|
73
139
|
readonly state: StateNames<TConfig>;
|
|
140
|
+
/** State data (untyped — validated on {@link WorkflowDefinition.restore}). */
|
|
74
141
|
readonly data: unknown;
|
|
142
|
+
/** ISO 8601 timestamp of workflow creation. */
|
|
75
143
|
readonly createdAt: string;
|
|
144
|
+
/** ISO 8601 timestamp of last state change. */
|
|
76
145
|
readonly updatedAt: string;
|
|
146
|
+
/** Schema version number for migration support. */
|
|
77
147
|
readonly modelVersion: number;
|
|
78
148
|
}
|
|
79
149
|
|
|
80
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
|
|
152
|
+
*/
|
|
81
153
|
interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
154
|
+
/** The raw Zod schema configuration. */
|
|
82
155
|
readonly config: TConfig;
|
|
156
|
+
/** The workflow definition name. */
|
|
83
157
|
readonly name: string;
|
|
158
|
+
/**
|
|
159
|
+
* Creates a new workflow instance in a given initial state.
|
|
160
|
+
*
|
|
161
|
+
* @param id - Unique identifier for this workflow instance
|
|
162
|
+
* @param config - Object containing `initialState` and the corresponding `data`
|
|
163
|
+
* @returns A {@link WorkflowOf} narrowed to the initial state
|
|
164
|
+
*/
|
|
84
165
|
createWorkflow<S extends StateNames<TConfig>>(id: string, config: {
|
|
85
166
|
initialState: S;
|
|
86
|
-
data:
|
|
167
|
+
data: StateData<TConfig, S>;
|
|
87
168
|
}): WorkflowOf<TConfig, S>;
|
|
169
|
+
/**
|
|
170
|
+
* Returns the Zod schema for a given state name.
|
|
171
|
+
*
|
|
172
|
+
* @param stateName - The state name to look up
|
|
173
|
+
* @throws If the state name is not found in the config
|
|
174
|
+
*/
|
|
88
175
|
getStateSchema(stateName: string): ZodType;
|
|
176
|
+
/**
|
|
177
|
+
* Returns the Zod schema for a given command name.
|
|
178
|
+
*
|
|
179
|
+
* @param commandName - The command name to look up
|
|
180
|
+
* @throws If the command name is not found in the config
|
|
181
|
+
*/
|
|
89
182
|
getCommandSchema(commandName: string): ZodType;
|
|
183
|
+
/**
|
|
184
|
+
* Returns the Zod schema for a given event name.
|
|
185
|
+
*
|
|
186
|
+
* @param eventName - The event name to look up
|
|
187
|
+
* @throws If the event name is not found in the config
|
|
188
|
+
*/
|
|
90
189
|
getEventSchema(eventName: string): ZodType;
|
|
190
|
+
/**
|
|
191
|
+
* Returns the Zod schema for a given error code.
|
|
192
|
+
*
|
|
193
|
+
* @param errorCode - The error code to look up
|
|
194
|
+
* @throws If the error code is not found in the config
|
|
195
|
+
*/
|
|
91
196
|
getErrorSchema(errorCode: string): ZodType;
|
|
197
|
+
/**
|
|
198
|
+
* Returns `true` if the given state name exists in the config.
|
|
199
|
+
*
|
|
200
|
+
* @param stateName - The state name to check
|
|
201
|
+
*/
|
|
92
202
|
hasState(stateName: string): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Serializes a workflow instance into a plain, JSON-safe snapshot.
|
|
205
|
+
*
|
|
206
|
+
* @param workflow - The workflow instance to serialize
|
|
207
|
+
* @returns A {@link WorkflowSnapshot} representing the current state
|
|
208
|
+
*/
|
|
93
209
|
snapshot(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
|
|
210
|
+
/**
|
|
211
|
+
* Restores a workflow instance from a plain snapshot, validating the state data.
|
|
212
|
+
*
|
|
213
|
+
* @param snapshot - The snapshot to restore from
|
|
214
|
+
* @returns A result object: `{ ok: true, workflow }` or `{ ok: false, error }`
|
|
215
|
+
*/
|
|
94
216
|
restore(snapshot: WorkflowSnapshot<TConfig>): {
|
|
95
217
|
ok: true;
|
|
96
218
|
workflow: Workflow<TConfig>;
|
|
@@ -101,42 +223,103 @@ interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
|
101
223
|
}
|
|
102
224
|
/**
|
|
103
225
|
* Creates a workflow definition from a name and Zod schema configuration.
|
|
226
|
+
*
|
|
227
|
+
* @param name - Unique name for this workflow type
|
|
228
|
+
* @param config - Object with `states`, `commands`, `events`, `errors` — each a record of Zod schemas
|
|
229
|
+
* @returns A {@link WorkflowDefinition} with methods for creating instances and accessing schemas
|
|
104
230
|
*/
|
|
105
|
-
declare function defineWorkflow<const TConfig extends
|
|
231
|
+
declare function defineWorkflow<const TConfig extends WorkflowConfigInput>(name: string, config: TConfig): WorkflowDefinition<TConfig & {
|
|
232
|
+
_resolved: {
|
|
233
|
+
states: {
|
|
234
|
+
[K in keyof TConfig["states"]]: z.infer<TConfig["states"][K]>;
|
|
235
|
+
};
|
|
236
|
+
commands: {
|
|
237
|
+
[K in keyof TConfig["commands"]]: z.infer<TConfig["commands"][K]>;
|
|
238
|
+
};
|
|
239
|
+
events: {
|
|
240
|
+
[K in keyof TConfig["events"]]: z.infer<TConfig["events"][K]>;
|
|
241
|
+
};
|
|
242
|
+
errors: {
|
|
243
|
+
[K in keyof TConfig["errors"]]: z.infer<TConfig["errors"][K]>;
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
}>;
|
|
106
247
|
|
|
107
|
-
/** A phantom-typed key for type-safe middleware state storage. */
|
|
248
|
+
/** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
|
|
108
249
|
interface ContextKey<T> {
|
|
250
|
+
/** @internal Phantom type brand — not used at runtime. */
|
|
109
251
|
readonly _phantom: T;
|
|
252
|
+
/** Internal symbol providing uniqueness. */
|
|
110
253
|
readonly id: symbol;
|
|
111
254
|
}
|
|
112
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* Creates a unique typed key for storing and retrieving values in context.
|
|
257
|
+
*
|
|
258
|
+
* @param name - Debug label (uniqueness comes from an internal `Symbol`)
|
|
259
|
+
* @returns A {@link ContextKey} for use with `ctx.set()`, `ctx.get()`, and `ctx.getOrNull()`
|
|
260
|
+
*/
|
|
113
261
|
declare function createKey<T>(name: string): ContextKey<T>;
|
|
114
262
|
|
|
115
263
|
/** Mutable context flowing through the middleware pipeline during dispatch. */
|
|
116
264
|
interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig> = StateNames<TConfig>, TCommand extends CommandNames<TConfig> = CommandNames<TConfig>> {
|
|
265
|
+
/** The command being dispatched, with type and validated payload. */
|
|
117
266
|
readonly command: {
|
|
118
267
|
readonly type: TCommand;
|
|
119
268
|
readonly payload: CommandPayload<TConfig, TCommand>;
|
|
120
269
|
};
|
|
270
|
+
/** The original workflow before any mutations. */
|
|
121
271
|
readonly workflow: WorkflowOf<TConfig, TState>;
|
|
272
|
+
/** Dependencies injected via the router constructor. */
|
|
122
273
|
readonly deps: TDeps;
|
|
274
|
+
/** Current state data (reflects mutations from {@link update}). */
|
|
123
275
|
readonly data: StateData<TConfig, TState>;
|
|
276
|
+
/**
|
|
277
|
+
* Merges partial data into the current state. Validates against the state's Zod schema.
|
|
278
|
+
* @param data - Partial state data to merge
|
|
279
|
+
*/
|
|
124
280
|
update(data: Partial<StateData<TConfig, TState>>): void;
|
|
281
|
+
/**
|
|
282
|
+
* Transitions the workflow to a new state with new data. Validates against the target state's Zod schema.
|
|
283
|
+
* @param target - Target state name
|
|
284
|
+
* @param data - Data for the target state
|
|
285
|
+
*/
|
|
125
286
|
transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
|
|
287
|
+
/**
|
|
288
|
+
* Emits a domain event. Validates event data against the event's Zod schema.
|
|
289
|
+
* @param event - Event with type and data
|
|
290
|
+
*/
|
|
126
291
|
emit<E extends EventNames<TConfig>>(event: {
|
|
127
292
|
type: E;
|
|
128
293
|
data: EventData<TConfig, E>;
|
|
129
294
|
}): void;
|
|
295
|
+
/** Accumulated events emitted during this dispatch. */
|
|
130
296
|
readonly events: ReadonlyArray<{
|
|
131
297
|
type: EventNames<TConfig>;
|
|
132
298
|
data: unknown;
|
|
133
299
|
}>;
|
|
300
|
+
/**
|
|
301
|
+
* Signals a domain error. Validates error data and throws internally (caught by the router).
|
|
302
|
+
* @param err - Error with code and data
|
|
303
|
+
*/
|
|
134
304
|
error<C extends ErrorCodes<TConfig>>(err: {
|
|
135
305
|
code: C;
|
|
136
306
|
data: ErrorData<TConfig, C>;
|
|
137
307
|
}): never;
|
|
308
|
+
/**
|
|
309
|
+
* Stores a value in context-scoped middleware state.
|
|
310
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
311
|
+
* @param value - The value to store
|
|
312
|
+
*/
|
|
138
313
|
set<T>(key: ContextKey<T>, value: T): void;
|
|
314
|
+
/**
|
|
315
|
+
* Retrieves a value from context-scoped middleware state. Throws if not set.
|
|
316
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
317
|
+
*/
|
|
139
318
|
get<T>(key: ContextKey<T>): T;
|
|
319
|
+
/**
|
|
320
|
+
* Retrieves a value from context-scoped middleware state, or `undefined` if not set.
|
|
321
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
322
|
+
*/
|
|
140
323
|
getOrNull<T>(key: ContextKey<T>): T | undefined;
|
|
141
324
|
/** @internal — not part of the handler API */
|
|
142
325
|
getWorkflowSnapshot(): Workflow<TConfig>;
|
|
@@ -159,13 +342,26 @@ type Middleware<TConfig extends WorkflowConfig, TDeps, TState extends StateNames
|
|
|
159
342
|
|
|
160
343
|
/** A function that transforms a snapshot's data from one version to the next. */
|
|
161
344
|
type MigrationFn = (snapshot: WorkflowSnapshot) => WorkflowSnapshot;
|
|
345
|
+
/** A migration entry — either a bare {@link MigrationFn} or an object with a description. */
|
|
346
|
+
type MigrationEntry = MigrationFn | {
|
|
347
|
+
description: string;
|
|
348
|
+
up: MigrationFn;
|
|
349
|
+
};
|
|
350
|
+
/** Internal normalized migration step with optional description. */
|
|
351
|
+
interface NormalizedMigration {
|
|
352
|
+
fn: MigrationFn;
|
|
353
|
+
description?: string;
|
|
354
|
+
}
|
|
162
355
|
/** A validated migration pipeline ready to transform snapshots. */
|
|
163
356
|
interface MigrationPipeline<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
357
|
+
/** The workflow definition this pipeline belongs to. */
|
|
164
358
|
readonly definition: WorkflowDefinition<TConfig>;
|
|
359
|
+
/** The target schema version to migrate snapshots to. */
|
|
165
360
|
readonly targetVersion: number;
|
|
166
|
-
|
|
361
|
+
/** Map of version number to normalized migration step. */
|
|
362
|
+
readonly migrations: ReadonlyMap<number, NormalizedMigration>;
|
|
167
363
|
}
|
|
168
|
-
/** Result of migrate
|
|
364
|
+
/** Result of {@link migrate}. */
|
|
169
365
|
type MigrateResult = {
|
|
170
366
|
ok: true;
|
|
171
367
|
snapshot: WorkflowSnapshot;
|
|
@@ -173,9 +369,20 @@ type MigrateResult = {
|
|
|
173
369
|
ok: false;
|
|
174
370
|
error: MigrationError;
|
|
175
371
|
};
|
|
176
|
-
/** Options for migrate
|
|
372
|
+
/** Options for {@link migrate}. */
|
|
177
373
|
interface MigrateOptions {
|
|
178
|
-
|
|
374
|
+
/**
|
|
375
|
+
* Called after each successful migration step.
|
|
376
|
+
* @param fromVersion - The version before this step
|
|
377
|
+
* @param toVersion - The version after this step
|
|
378
|
+
* @param snapshot - The snapshot after this step
|
|
379
|
+
* @param description - Optional description from the migration entry
|
|
380
|
+
*/
|
|
381
|
+
onStep?: (fromVersion: number, toVersion: number, snapshot: WorkflowSnapshot, description?: string) => void;
|
|
382
|
+
/**
|
|
383
|
+
* Called when a migration step fails.
|
|
384
|
+
* @param error - The {@link MigrationError} describing the failure
|
|
385
|
+
*/
|
|
179
386
|
onError?: (error: MigrationError) => void;
|
|
180
387
|
}
|
|
181
388
|
/** Error thrown when a migration step fails. */
|
|
@@ -183,16 +390,31 @@ declare class MigrationError extends Error {
|
|
|
183
390
|
readonly fromVersion: number;
|
|
184
391
|
readonly toVersion: number;
|
|
185
392
|
readonly cause: unknown;
|
|
393
|
+
/**
|
|
394
|
+
* @param fromVersion - The schema version the migration started from
|
|
395
|
+
* @param toVersion - The schema version the migration was attempting to reach
|
|
396
|
+
* @param cause - The underlying error that caused the failure
|
|
397
|
+
*/
|
|
186
398
|
constructor(fromVersion: number, toVersion: number, cause: unknown);
|
|
187
399
|
}
|
|
188
400
|
/**
|
|
189
401
|
* Creates a validated migration pipeline from a definition and version-keyed transform functions.
|
|
190
402
|
* Each key is the target version — the function transforms from (key - 1) to key.
|
|
403
|
+
*
|
|
404
|
+
* @param definition - The workflow definition the migrations belong to
|
|
405
|
+
* @param migrationMap - A record mapping target version numbers to {@link MigrationEntry} values
|
|
406
|
+
* @returns A validated {@link MigrationPipeline} ready for use with {@link migrate}
|
|
407
|
+
* @throws If migration keys are not sequential from 2 to the definition's `modelVersion`, or if the highest key does not match `modelVersion`
|
|
191
408
|
*/
|
|
192
|
-
declare function defineMigrations<TConfig extends WorkflowConfig>(definition: WorkflowDefinition<TConfig>, migrationMap: Record<number,
|
|
409
|
+
declare function defineMigrations<TConfig extends WorkflowConfig>(definition: WorkflowDefinition<TConfig>, migrationMap: Record<number, MigrationEntry>): MigrationPipeline<TConfig>;
|
|
193
410
|
/**
|
|
194
411
|
* Runs the migration chain from the snapshot's modelVersion to the pipeline's targetVersion.
|
|
195
412
|
* Returns a Result. Auto-stamps modelVersion after each step.
|
|
413
|
+
*
|
|
414
|
+
* @param pipeline - The {@link MigrationPipeline} created by {@link defineMigrations}
|
|
415
|
+
* @param snapshot - The workflow snapshot to migrate
|
|
416
|
+
* @param options - Optional callbacks for step progress and error reporting
|
|
417
|
+
* @returns A {@link MigrateResult} with the migrated snapshot on success, or a {@link MigrationError} on failure
|
|
196
418
|
*/
|
|
197
419
|
declare function migrate<TConfig extends WorkflowConfig>(pipeline: MigrationPipeline<TConfig>, snapshot: WorkflowSnapshot, options?: MigrateOptions): MigrateResult;
|
|
198
420
|
|
|
@@ -207,12 +429,18 @@ type HandlerEntry = {
|
|
|
207
429
|
inlineMiddleware: AnyMiddleware[];
|
|
208
430
|
handler: AnyMiddleware;
|
|
209
431
|
};
|
|
432
|
+
/** Options for the {@link WorkflowRouter} constructor. */
|
|
210
433
|
interface RouterOptions {
|
|
434
|
+
/** Callback invoked when a lifecycle hook throws. Defaults to `console.error`. */
|
|
211
435
|
onHookError?: (error: unknown) => void;
|
|
436
|
+
/** Wrap deps in a Proxy to catch dependency errors. Defaults to `true`. */
|
|
437
|
+
wrapDeps?: boolean;
|
|
212
438
|
}
|
|
213
439
|
declare class StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {
|
|
214
440
|
/** @internal */ readonly middleware: AnyMiddleware[];
|
|
215
441
|
/** @internal */ readonly handlers: Map<string, HandlerEntry>;
|
|
442
|
+
constructor();
|
|
443
|
+
on<C extends CommandNames<TConfig>>(command: C, handler: (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>): this;
|
|
216
444
|
on<C extends CommandNames<TConfig>>(command: C, ...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]): this;
|
|
217
445
|
use(middleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>): this;
|
|
218
446
|
}
|
|
@@ -231,14 +459,31 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
|
|
|
231
459
|
private wildcardHandlers;
|
|
232
460
|
private hookRegistry;
|
|
233
461
|
private readonly onHookError;
|
|
462
|
+
private readonly wrapDeps;
|
|
463
|
+
/**
|
|
464
|
+
* @param definition - The workflow definition describing states, commands, events, and errors
|
|
465
|
+
* @param deps - Dependencies injected into every handler context
|
|
466
|
+
* @param options - Router configuration options
|
|
467
|
+
*/
|
|
234
468
|
constructor(definition: WorkflowDefinition<TConfig>, deps?: TDeps, options?: RouterOptions);
|
|
235
|
-
/**
|
|
469
|
+
/**
|
|
470
|
+
* Adds global middleware, merges another router, or applies a plugin.
|
|
471
|
+
* @param arg - A middleware function, another {@link WorkflowRouter} to merge, or a {@link Plugin}
|
|
472
|
+
*/
|
|
236
473
|
use(arg: ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>) | WorkflowRouter<TConfig, TDeps> | Plugin<TConfig, TDeps>): this;
|
|
237
474
|
private merge;
|
|
238
475
|
private mergeStateBuilders;
|
|
239
|
-
/**
|
|
476
|
+
/**
|
|
477
|
+
* Registers handlers for one or more states.
|
|
478
|
+
* @param name - A state name or array of state names to register handlers for
|
|
479
|
+
* @param setup - Callback that receives a state builder to register commands and middleware
|
|
480
|
+
*/
|
|
240
481
|
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;
|
|
241
|
-
/**
|
|
482
|
+
/**
|
|
483
|
+
* Registers a lifecycle hook callback.
|
|
484
|
+
* @param event - The lifecycle event name
|
|
485
|
+
* @param callback - The callback to invoke when the event fires
|
|
486
|
+
*/
|
|
242
487
|
on(event: "dispatch:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
|
|
243
488
|
on(event: "dispatch:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
|
|
244
489
|
on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
@@ -247,12 +492,29 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
|
|
|
247
492
|
type: EventNames<TConfig>;
|
|
248
493
|
data: unknown;
|
|
249
494
|
}, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
250
|
-
/**
|
|
495
|
+
/**
|
|
496
|
+
* Registers a wildcard handler that matches any state.
|
|
497
|
+
* @param state - Must be `"*"` to match all states
|
|
498
|
+
* @param command - The command name to handle
|
|
499
|
+
* @param handler - The terminal handler
|
|
500
|
+
*/
|
|
501
|
+
on<C extends CommandNames<TConfig>>(state: "*", command: C, handler: (ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>): this;
|
|
502
|
+
/**
|
|
503
|
+
* Registers a wildcard handler that matches any state, with inline middleware.
|
|
504
|
+
* @param state - Must be `"*"` to match all states
|
|
505
|
+
* @param command - The command name to handle
|
|
506
|
+
* @param fns - Inline middleware followed by the terminal handler
|
|
507
|
+
*/
|
|
251
508
|
on<C extends CommandNames<TConfig>>(state: "*", command: C, ...fns: [
|
|
252
509
|
...AnyMiddleware[],
|
|
253
510
|
(ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>
|
|
254
511
|
]): this;
|
|
255
|
-
/**
|
|
512
|
+
/**
|
|
513
|
+
* Dispatches a command to the appropriate handler and returns the result.
|
|
514
|
+
* @param workflow - The current workflow instance to dispatch against
|
|
515
|
+
* @param command - The command with its type and payload
|
|
516
|
+
* @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
|
|
517
|
+
*/
|
|
256
518
|
dispatch(workflow: Workflow<TConfig>, command: {
|
|
257
519
|
type: CommandNames<TConfig>;
|
|
258
520
|
payload: unknown;
|
|
@@ -260,13 +522,23 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
|
|
|
260
522
|
}
|
|
261
523
|
|
|
262
524
|
declare const PLUGIN_SYMBOL: unique symbol;
|
|
263
|
-
/** A branded plugin function that can be passed to
|
|
525
|
+
/** A branded plugin function that can be passed to {@link WorkflowRouter.use}. */
|
|
264
526
|
type Plugin<TConfig extends WorkflowConfig, TDeps> = ((router: WorkflowRouter<TConfig, TDeps>) => void) & {
|
|
265
527
|
readonly [PLUGIN_SYMBOL]: true;
|
|
266
528
|
};
|
|
267
|
-
/**
|
|
529
|
+
/**
|
|
530
|
+
* Brands a function as a Ryte plugin for use with {@link WorkflowRouter.use}.
|
|
531
|
+
*
|
|
532
|
+
* @param fn - A function that configures a router (adds handlers, middleware, hooks)
|
|
533
|
+
* @returns A branded {@link Plugin} function
|
|
534
|
+
*/
|
|
268
535
|
declare function definePlugin<TConfig extends WorkflowConfig, TDeps>(fn: (router: WorkflowRouter<TConfig, TDeps>) => void): Plugin<TConfig, TDeps>;
|
|
269
|
-
/**
|
|
536
|
+
/**
|
|
537
|
+
* Checks whether a value is a branded Ryte plugin.
|
|
538
|
+
*
|
|
539
|
+
* @param value - The value to check
|
|
540
|
+
* @returns `true` if the value is a {@link Plugin}
|
|
541
|
+
*/
|
|
270
542
|
declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
|
|
271
543
|
|
|
272
|
-
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, 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 };
|
|
544
|
+
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 };
|