@rytejs/core 0.6.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/chunk-YTJGSTKG.js +19 -0
- package/dist/chunk-YTJGSTKG.js.map +1 -0
- package/dist/chunk-ZFRIE42B.js +17 -0
- package/dist/chunk-ZFRIE42B.js.map +1 -0
- package/dist/executor/index.cjs +185 -0
- package/dist/executor/index.cjs.map +1 -0
- package/dist/executor/index.d.cts +69 -0
- package/dist/executor/index.d.ts +69 -0
- package/dist/executor/index.js +137 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/index.cjs +39 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -451
- package/dist/index.d.ts +7 -451
- package/dist/index.js +42 -21
- package/dist/index.js.map +1 -1
- package/dist/plugin-DHN3Pk52.d.ts +339 -0
- package/dist/plugin-DHS8yUmS.d.cts +339 -0
- package/dist/reactor/index.cjs +69 -0
- package/dist/reactor/index.cjs.map +1 -0
- package/dist/reactor/index.d.cts +31 -0
- package/dist/reactor/index.d.ts +31 -0
- package/dist/reactor/index.js +41 -0
- package/dist/reactor/index.js.map +1 -0
- package/dist/snapshot-D5iZubCz.d.cts +165 -0
- package/dist/snapshot-D5iZubCz.d.ts +165 -0
- package/dist/store/index.cjs +68 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.cts +16 -0
- package/dist/store/index.d.ts +16 -0
- package/dist/store/index.js +31 -0
- package/dist/store/index.js.map +1 -0
- package/dist/types-BtMTMoOZ.d.cts +21 -0
- package/dist/types-C0nlrs5c.d.ts +21 -0
- package/package.json +23 -6
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { W as WorkflowConfig, S as StateNames, h as StateData, j as WorkflowOf, i as Workflow, a as WorkflowSnapshot, V as ValidationError, k as WorkflowConfigInput, C as CommandNames, b as CommandPayload, g as EventNames, f as EventData, E as ErrorCodes, e as ErrorData, D as DispatchResult, P as PipelineError } from './snapshot-D5iZubCz.js';
|
|
2
|
+
import { ZodType, z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
|
|
6
|
+
*/
|
|
7
|
+
interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
8
|
+
/** The raw Zod schema configuration. */
|
|
9
|
+
readonly config: TConfig;
|
|
10
|
+
/** The workflow definition name. */
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new workflow instance in a given initial state.
|
|
14
|
+
*
|
|
15
|
+
* @param id - Unique identifier for this workflow instance
|
|
16
|
+
* @param config - Object containing `initialState` and the corresponding `data`
|
|
17
|
+
* @returns A {@link WorkflowOf} narrowed to the initial state
|
|
18
|
+
*/
|
|
19
|
+
createWorkflow<S extends StateNames<TConfig>>(id: string, config: {
|
|
20
|
+
initialState: S;
|
|
21
|
+
data: StateData<TConfig, S>;
|
|
22
|
+
}): WorkflowOf<TConfig, S>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the Zod schema for a given state name.
|
|
25
|
+
*
|
|
26
|
+
* @param stateName - The state name to look up
|
|
27
|
+
* @throws If the state name is not found in the config
|
|
28
|
+
*/
|
|
29
|
+
getStateSchema(stateName: string): ZodType;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the Zod schema for a given command name.
|
|
32
|
+
*
|
|
33
|
+
* @param commandName - The command name to look up
|
|
34
|
+
* @throws If the command name is not found in the config
|
|
35
|
+
*/
|
|
36
|
+
getCommandSchema(commandName: string): ZodType;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the Zod schema for a given event name.
|
|
39
|
+
*
|
|
40
|
+
* @param eventName - The event name to look up
|
|
41
|
+
* @throws If the event name is not found in the config
|
|
42
|
+
*/
|
|
43
|
+
getEventSchema(eventName: string): ZodType;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the Zod schema for a given error code.
|
|
46
|
+
*
|
|
47
|
+
* @param errorCode - The error code to look up
|
|
48
|
+
* @throws If the error code is not found in the config
|
|
49
|
+
*/
|
|
50
|
+
getErrorSchema(errorCode: string): ZodType;
|
|
51
|
+
/**
|
|
52
|
+
* Returns `true` if the given state name exists in the config.
|
|
53
|
+
*
|
|
54
|
+
* @param stateName - The state name to check
|
|
55
|
+
*/
|
|
56
|
+
hasState(stateName: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns `true` if the given command name exists in the config.
|
|
59
|
+
*/
|
|
60
|
+
hasCommand(commandName: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Returns `true` if the given event name exists in the config.
|
|
63
|
+
*/
|
|
64
|
+
hasEvent(eventName: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Serializes a workflow instance into a plain, JSON-safe snapshot.
|
|
67
|
+
*
|
|
68
|
+
* @param workflow - The workflow instance to serialize
|
|
69
|
+
* @returns A {@link WorkflowSnapshot} representing the current state
|
|
70
|
+
*/
|
|
71
|
+
serialize(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
|
|
72
|
+
/**
|
|
73
|
+
* Deserializes a workflow instance from a plain snapshot, validating the state data.
|
|
74
|
+
*
|
|
75
|
+
* @param snapshot - The snapshot to deserialize from
|
|
76
|
+
* @returns A result object: `{ ok: true, workflow }` or `{ ok: false, error }`
|
|
77
|
+
*/
|
|
78
|
+
deserialize(snapshot: WorkflowSnapshot<TConfig>): {
|
|
79
|
+
ok: true;
|
|
80
|
+
workflow: Workflow<TConfig>;
|
|
81
|
+
} | {
|
|
82
|
+
ok: false;
|
|
83
|
+
error: ValidationError;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a workflow definition from a name and Zod schema configuration.
|
|
88
|
+
*
|
|
89
|
+
* @param name - Unique name for this workflow type
|
|
90
|
+
* @param config - Object with `states`, `commands`, `events`, `errors` — each a record of Zod schemas
|
|
91
|
+
* @returns A {@link WorkflowDefinition} with methods for creating instances and accessing schemas
|
|
92
|
+
*/
|
|
93
|
+
declare function defineWorkflow<const TConfig extends WorkflowConfigInput>(name: string, config: TConfig): WorkflowDefinition<TConfig & {
|
|
94
|
+
_resolved: {
|
|
95
|
+
states: {
|
|
96
|
+
[K in keyof TConfig["states"]]: z.infer<TConfig["states"][K]>;
|
|
97
|
+
};
|
|
98
|
+
commands: {
|
|
99
|
+
[K in keyof TConfig["commands"]]: z.infer<TConfig["commands"][K]>;
|
|
100
|
+
};
|
|
101
|
+
events: {
|
|
102
|
+
[K in keyof TConfig["events"]]: z.infer<TConfig["events"][K]>;
|
|
103
|
+
};
|
|
104
|
+
errors: {
|
|
105
|
+
[K in keyof TConfig["errors"]]: z.infer<TConfig["errors"][K]>;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
|
|
111
|
+
interface ContextKey<T> {
|
|
112
|
+
/** @internal Phantom type brand — not used at runtime. */
|
|
113
|
+
readonly _phantom: T;
|
|
114
|
+
/** Internal symbol providing uniqueness. */
|
|
115
|
+
readonly id: symbol;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Creates a unique typed key for storing and retrieving values in context.
|
|
119
|
+
*
|
|
120
|
+
* @param name - Debug label (uniqueness comes from an internal `Symbol`)
|
|
121
|
+
* @returns A {@link ContextKey} for use with `ctx.set()`, `ctx.get()`, and `ctx.getOrNull()`
|
|
122
|
+
*/
|
|
123
|
+
declare function createKey<T>(name: string): ContextKey<T>;
|
|
124
|
+
|
|
125
|
+
/** Mutable context flowing through the middleware pipeline during dispatch. */
|
|
126
|
+
interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig> = StateNames<TConfig>, TCommand extends CommandNames<TConfig> = CommandNames<TConfig>> {
|
|
127
|
+
/** The command being dispatched, with type and validated payload. */
|
|
128
|
+
readonly command: {
|
|
129
|
+
readonly type: TCommand;
|
|
130
|
+
readonly payload: CommandPayload<TConfig, TCommand>;
|
|
131
|
+
};
|
|
132
|
+
/** The original workflow before any mutations. */
|
|
133
|
+
readonly workflow: WorkflowOf<TConfig, TState>;
|
|
134
|
+
/** Dependencies injected via the router constructor. */
|
|
135
|
+
readonly deps: TDeps;
|
|
136
|
+
/** Current state data (reflects mutations from {@link update}). */
|
|
137
|
+
readonly data: StateData<TConfig, TState>;
|
|
138
|
+
/**
|
|
139
|
+
* Merges partial data into the current state. Validates against the state's Zod schema.
|
|
140
|
+
* @param data - Partial state data to merge
|
|
141
|
+
*/
|
|
142
|
+
update(data: Partial<StateData<TConfig, TState>>): void;
|
|
143
|
+
/**
|
|
144
|
+
* Transitions the workflow to a new state with new data. Validates against the target state's Zod schema.
|
|
145
|
+
* @param target - Target state name
|
|
146
|
+
* @param data - Data for the target state
|
|
147
|
+
*/
|
|
148
|
+
transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
|
|
149
|
+
/**
|
|
150
|
+
* Emits a domain event. Validates event data against the event's Zod schema.
|
|
151
|
+
* @param event - Event with type and data
|
|
152
|
+
*/
|
|
153
|
+
emit<E extends EventNames<TConfig>>(event: {
|
|
154
|
+
type: E;
|
|
155
|
+
data: EventData<TConfig, E>;
|
|
156
|
+
}): void;
|
|
157
|
+
/** Accumulated events emitted during this dispatch. */
|
|
158
|
+
readonly events: ReadonlyArray<{
|
|
159
|
+
type: EventNames<TConfig>;
|
|
160
|
+
data: unknown;
|
|
161
|
+
}>;
|
|
162
|
+
/**
|
|
163
|
+
* Signals a domain error. Validates error data and throws internally (caught by the router).
|
|
164
|
+
* @param err - Error with code and data
|
|
165
|
+
*/
|
|
166
|
+
error<C extends ErrorCodes<TConfig>>(err: {
|
|
167
|
+
code: C;
|
|
168
|
+
data: ErrorData<TConfig, C>;
|
|
169
|
+
}): never;
|
|
170
|
+
/**
|
|
171
|
+
* Stores a value in context-scoped middleware state.
|
|
172
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
173
|
+
* @param value - The value to store
|
|
174
|
+
*/
|
|
175
|
+
set<T>(key: ContextKey<T>, value: T): void;
|
|
176
|
+
/**
|
|
177
|
+
* Retrieves a value from context-scoped middleware state. Throws if not set.
|
|
178
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
179
|
+
*/
|
|
180
|
+
get<T>(key: ContextKey<T>): T;
|
|
181
|
+
/**
|
|
182
|
+
* Retrieves a value from context-scoped middleware state, or `undefined` if not set.
|
|
183
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
184
|
+
*/
|
|
185
|
+
getOrNull<T>(key: ContextKey<T>): T | undefined;
|
|
186
|
+
/** @internal — not part of the handler API */
|
|
187
|
+
getWorkflowSnapshot(): Workflow<TConfig>;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Read-only subset of Context for hook callbacks.
|
|
192
|
+
* Includes context-key access (set/get) but excludes dispatch mutation methods.
|
|
193
|
+
*/
|
|
194
|
+
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">;
|
|
195
|
+
|
|
196
|
+
type AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;
|
|
197
|
+
type HandlerEntry = {
|
|
198
|
+
inlineMiddleware: AnyMiddleware[];
|
|
199
|
+
handler: AnyMiddleware;
|
|
200
|
+
};
|
|
201
|
+
/** Options for the {@link WorkflowRouter} constructor. */
|
|
202
|
+
interface RouterOptions {
|
|
203
|
+
/** Callback invoked when a lifecycle hook throws. Defaults to `console.error`. */
|
|
204
|
+
onHookError?: (error: unknown) => void;
|
|
205
|
+
/** Wrap deps in a Proxy to catch dependency errors. Defaults to `true`. */
|
|
206
|
+
wrapDeps?: boolean;
|
|
207
|
+
}
|
|
208
|
+
declare class StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {
|
|
209
|
+
/** @internal */ readonly middleware: AnyMiddleware[];
|
|
210
|
+
/** @internal */ readonly handlers: Map<string, HandlerEntry>;
|
|
211
|
+
constructor();
|
|
212
|
+
on<C extends CommandNames<TConfig>>(command: C, handler: (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>): this;
|
|
213
|
+
on<C extends CommandNames<TConfig>>(command: C, ...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]): this;
|
|
214
|
+
use(middleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>): this;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Routes commands to handlers based on workflow state.
|
|
218
|
+
*
|
|
219
|
+
* Supports global middleware, state-scoped middleware, inline middleware,
|
|
220
|
+
* wildcard handlers, and multi-state handlers.
|
|
221
|
+
*/
|
|
222
|
+
declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
|
|
223
|
+
readonly definition: WorkflowDefinition<TConfig>;
|
|
224
|
+
private readonly deps;
|
|
225
|
+
private globalMiddleware;
|
|
226
|
+
private singleStateBuilders;
|
|
227
|
+
private multiStateBuilders;
|
|
228
|
+
private wildcardHandlers;
|
|
229
|
+
private hookRegistry;
|
|
230
|
+
private readonly onHookError;
|
|
231
|
+
private readonly wrapDeps;
|
|
232
|
+
/**
|
|
233
|
+
* @param definition - The workflow definition describing states, commands, events, and errors
|
|
234
|
+
* @param deps - Dependencies injected into every handler context
|
|
235
|
+
* @param options - Router configuration options
|
|
236
|
+
*/
|
|
237
|
+
constructor(definition: WorkflowDefinition<TConfig>, deps?: TDeps, options?: RouterOptions);
|
|
238
|
+
/**
|
|
239
|
+
* Adds global middleware, merges another router, or applies a plugin.
|
|
240
|
+
* @param arg - A middleware function, another {@link WorkflowRouter} to merge, or a {@link Plugin}
|
|
241
|
+
*/
|
|
242
|
+
use(arg: ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>) | WorkflowRouter<TConfig, TDeps> | Plugin<TConfig, TDeps> | GenericPlugin): this;
|
|
243
|
+
private merge;
|
|
244
|
+
private mergeStateBuilders;
|
|
245
|
+
/**
|
|
246
|
+
* Registers handlers for one or more states.
|
|
247
|
+
* @param name - A state name or array of state names to register handlers for
|
|
248
|
+
* @param setup - Callback that receives a state builder to register commands and middleware
|
|
249
|
+
*/
|
|
250
|
+
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;
|
|
251
|
+
/**
|
|
252
|
+
* Registers a lifecycle hook callback.
|
|
253
|
+
* @param event - The lifecycle event name
|
|
254
|
+
* @param callback - The callback to invoke when the event fires
|
|
255
|
+
*/
|
|
256
|
+
on(event: "dispatch:start", callback: (workflow: Workflow<TConfig>, command: {
|
|
257
|
+
type: CommandNames<TConfig>;
|
|
258
|
+
payload: unknown;
|
|
259
|
+
}) => void | Promise<void>): this;
|
|
260
|
+
on(event: "dispatch:end", callback: (workflow: Workflow<TConfig>, command: {
|
|
261
|
+
type: CommandNames<TConfig>;
|
|
262
|
+
payload: unknown;
|
|
263
|
+
}, result: DispatchResult<TConfig>) => void | Promise<void>): this;
|
|
264
|
+
on(event: "pipeline:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
|
|
265
|
+
on(event: "pipeline:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
|
|
266
|
+
on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
267
|
+
on(event: "error", callback: (error: PipelineError<TConfig>, ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
|
|
268
|
+
on(event: "event", callback: (event: {
|
|
269
|
+
type: EventNames<TConfig>;
|
|
270
|
+
data: unknown;
|
|
271
|
+
}, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
272
|
+
/**
|
|
273
|
+
* Registers a wildcard handler that matches any state.
|
|
274
|
+
* @param state - Must be `"*"` to match all states
|
|
275
|
+
* @param command - The command name to handle
|
|
276
|
+
* @param handler - The terminal handler
|
|
277
|
+
*/
|
|
278
|
+
on<C extends CommandNames<TConfig>>(state: "*", command: C, handler: (ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>): this;
|
|
279
|
+
/**
|
|
280
|
+
* Registers a wildcard handler that matches any state, with inline middleware.
|
|
281
|
+
* @param state - Must be `"*"` to match all states
|
|
282
|
+
* @param command - The command name to handle
|
|
283
|
+
* @param fns - Inline middleware followed by the terminal handler
|
|
284
|
+
*/
|
|
285
|
+
on<C extends CommandNames<TConfig>>(state: "*", command: C, ...fns: [
|
|
286
|
+
...AnyMiddleware[],
|
|
287
|
+
(ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>
|
|
288
|
+
]): this;
|
|
289
|
+
/**
|
|
290
|
+
* Dispatches a command to the appropriate handler and returns the result.
|
|
291
|
+
* @param workflow - The current workflow instance to dispatch against
|
|
292
|
+
* @param command - The command with its type and payload
|
|
293
|
+
* @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
|
|
294
|
+
*/
|
|
295
|
+
dispatch(workflow: Workflow<TConfig>, command: {
|
|
296
|
+
type: CommandNames<TConfig>;
|
|
297
|
+
payload: unknown;
|
|
298
|
+
}): Promise<DispatchResult<TConfig>>;
|
|
299
|
+
private executePipeline;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
declare const PLUGIN_SYMBOL: unique symbol;
|
|
303
|
+
/** A branded plugin function that can be passed to {@link WorkflowRouter.use}. */
|
|
304
|
+
type Plugin<TConfig extends WorkflowConfig, TDeps> = ((router: WorkflowRouter<TConfig, TDeps>) => void) & {
|
|
305
|
+
readonly [PLUGIN_SYMBOL]: true;
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* Brands a function as a Ryte plugin for use with {@link WorkflowRouter.use}.
|
|
309
|
+
*
|
|
310
|
+
* @param fn - A function that configures a router (adds handlers, middleware, hooks)
|
|
311
|
+
* @returns A branded {@link Plugin} function
|
|
312
|
+
*/
|
|
313
|
+
declare function definePlugin<TConfig extends WorkflowConfig, TDeps>(fn: (router: WorkflowRouter<TConfig, TDeps>) => void): Plugin<TConfig, TDeps>;
|
|
314
|
+
/**
|
|
315
|
+
* Checks whether a value is a branded Ryte plugin.
|
|
316
|
+
*
|
|
317
|
+
* @param value - The value to check
|
|
318
|
+
* @returns `true` if the value is a {@link Plugin}
|
|
319
|
+
*/
|
|
320
|
+
/** A plugin that works with any router, regardless of config or deps. */
|
|
321
|
+
type GenericPlugin = Plugin<any, any>;
|
|
322
|
+
/**
|
|
323
|
+
* Creates a plugin that works with any router without requiring explicit type parameters.
|
|
324
|
+
* Use this for cross-cutting concerns (logging, tracing, delay) that don't reference
|
|
325
|
+
* specific states, commands, or events.
|
|
326
|
+
*
|
|
327
|
+
* @param fn - A function that configures a router (adds hooks, middleware)
|
|
328
|
+
* @returns A branded {@link GenericPlugin} function
|
|
329
|
+
*/
|
|
330
|
+
declare function defineGenericPlugin(fn: (router: WorkflowRouter<any, any>) => void): GenericPlugin;
|
|
331
|
+
/**
|
|
332
|
+
* Checks whether a value is a branded Ryte plugin.
|
|
333
|
+
*
|
|
334
|
+
* @param value - The value to check
|
|
335
|
+
* @returns `true` if the value is a {@link Plugin}
|
|
336
|
+
*/
|
|
337
|
+
declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
|
|
338
|
+
|
|
339
|
+
export { type Context as C, type GenericPlugin as G, type Plugin as P, type ReadonlyContext as R, type WorkflowDefinition as W, type ContextKey as a, type RouterOptions as b, WorkflowRouter as c, createKey as d, defineGenericPlugin as e, definePlugin as f, defineWorkflow as g, isPlugin as i };
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { W as WorkflowConfig, S as StateNames, h as StateData, j as WorkflowOf, i as Workflow, a as WorkflowSnapshot, V as ValidationError, k as WorkflowConfigInput, C as CommandNames, b as CommandPayload, g as EventNames, f as EventData, E as ErrorCodes, e as ErrorData, D as DispatchResult, P as PipelineError } from './snapshot-D5iZubCz.cjs';
|
|
2
|
+
import { ZodType, z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
|
|
6
|
+
*/
|
|
7
|
+
interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
|
|
8
|
+
/** The raw Zod schema configuration. */
|
|
9
|
+
readonly config: TConfig;
|
|
10
|
+
/** The workflow definition name. */
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new workflow instance in a given initial state.
|
|
14
|
+
*
|
|
15
|
+
* @param id - Unique identifier for this workflow instance
|
|
16
|
+
* @param config - Object containing `initialState` and the corresponding `data`
|
|
17
|
+
* @returns A {@link WorkflowOf} narrowed to the initial state
|
|
18
|
+
*/
|
|
19
|
+
createWorkflow<S extends StateNames<TConfig>>(id: string, config: {
|
|
20
|
+
initialState: S;
|
|
21
|
+
data: StateData<TConfig, S>;
|
|
22
|
+
}): WorkflowOf<TConfig, S>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the Zod schema for a given state name.
|
|
25
|
+
*
|
|
26
|
+
* @param stateName - The state name to look up
|
|
27
|
+
* @throws If the state name is not found in the config
|
|
28
|
+
*/
|
|
29
|
+
getStateSchema(stateName: string): ZodType;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the Zod schema for a given command name.
|
|
32
|
+
*
|
|
33
|
+
* @param commandName - The command name to look up
|
|
34
|
+
* @throws If the command name is not found in the config
|
|
35
|
+
*/
|
|
36
|
+
getCommandSchema(commandName: string): ZodType;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the Zod schema for a given event name.
|
|
39
|
+
*
|
|
40
|
+
* @param eventName - The event name to look up
|
|
41
|
+
* @throws If the event name is not found in the config
|
|
42
|
+
*/
|
|
43
|
+
getEventSchema(eventName: string): ZodType;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the Zod schema for a given error code.
|
|
46
|
+
*
|
|
47
|
+
* @param errorCode - The error code to look up
|
|
48
|
+
* @throws If the error code is not found in the config
|
|
49
|
+
*/
|
|
50
|
+
getErrorSchema(errorCode: string): ZodType;
|
|
51
|
+
/**
|
|
52
|
+
* Returns `true` if the given state name exists in the config.
|
|
53
|
+
*
|
|
54
|
+
* @param stateName - The state name to check
|
|
55
|
+
*/
|
|
56
|
+
hasState(stateName: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns `true` if the given command name exists in the config.
|
|
59
|
+
*/
|
|
60
|
+
hasCommand(commandName: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Returns `true` if the given event name exists in the config.
|
|
63
|
+
*/
|
|
64
|
+
hasEvent(eventName: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Serializes a workflow instance into a plain, JSON-safe snapshot.
|
|
67
|
+
*
|
|
68
|
+
* @param workflow - The workflow instance to serialize
|
|
69
|
+
* @returns A {@link WorkflowSnapshot} representing the current state
|
|
70
|
+
*/
|
|
71
|
+
serialize(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
|
|
72
|
+
/**
|
|
73
|
+
* Deserializes a workflow instance from a plain snapshot, validating the state data.
|
|
74
|
+
*
|
|
75
|
+
* @param snapshot - The snapshot to deserialize from
|
|
76
|
+
* @returns A result object: `{ ok: true, workflow }` or `{ ok: false, error }`
|
|
77
|
+
*/
|
|
78
|
+
deserialize(snapshot: WorkflowSnapshot<TConfig>): {
|
|
79
|
+
ok: true;
|
|
80
|
+
workflow: Workflow<TConfig>;
|
|
81
|
+
} | {
|
|
82
|
+
ok: false;
|
|
83
|
+
error: ValidationError;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a workflow definition from a name and Zod schema configuration.
|
|
88
|
+
*
|
|
89
|
+
* @param name - Unique name for this workflow type
|
|
90
|
+
* @param config - Object with `states`, `commands`, `events`, `errors` — each a record of Zod schemas
|
|
91
|
+
* @returns A {@link WorkflowDefinition} with methods for creating instances and accessing schemas
|
|
92
|
+
*/
|
|
93
|
+
declare function defineWorkflow<const TConfig extends WorkflowConfigInput>(name: string, config: TConfig): WorkflowDefinition<TConfig & {
|
|
94
|
+
_resolved: {
|
|
95
|
+
states: {
|
|
96
|
+
[K in keyof TConfig["states"]]: z.infer<TConfig["states"][K]>;
|
|
97
|
+
};
|
|
98
|
+
commands: {
|
|
99
|
+
[K in keyof TConfig["commands"]]: z.infer<TConfig["commands"][K]>;
|
|
100
|
+
};
|
|
101
|
+
events: {
|
|
102
|
+
[K in keyof TConfig["events"]]: z.infer<TConfig["events"][K]>;
|
|
103
|
+
};
|
|
104
|
+
errors: {
|
|
105
|
+
[K in keyof TConfig["errors"]]: z.infer<TConfig["errors"][K]>;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
|
|
111
|
+
interface ContextKey<T> {
|
|
112
|
+
/** @internal Phantom type brand — not used at runtime. */
|
|
113
|
+
readonly _phantom: T;
|
|
114
|
+
/** Internal symbol providing uniqueness. */
|
|
115
|
+
readonly id: symbol;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Creates a unique typed key for storing and retrieving values in context.
|
|
119
|
+
*
|
|
120
|
+
* @param name - Debug label (uniqueness comes from an internal `Symbol`)
|
|
121
|
+
* @returns A {@link ContextKey} for use with `ctx.set()`, `ctx.get()`, and `ctx.getOrNull()`
|
|
122
|
+
*/
|
|
123
|
+
declare function createKey<T>(name: string): ContextKey<T>;
|
|
124
|
+
|
|
125
|
+
/** Mutable context flowing through the middleware pipeline during dispatch. */
|
|
126
|
+
interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig> = StateNames<TConfig>, TCommand extends CommandNames<TConfig> = CommandNames<TConfig>> {
|
|
127
|
+
/** The command being dispatched, with type and validated payload. */
|
|
128
|
+
readonly command: {
|
|
129
|
+
readonly type: TCommand;
|
|
130
|
+
readonly payload: CommandPayload<TConfig, TCommand>;
|
|
131
|
+
};
|
|
132
|
+
/** The original workflow before any mutations. */
|
|
133
|
+
readonly workflow: WorkflowOf<TConfig, TState>;
|
|
134
|
+
/** Dependencies injected via the router constructor. */
|
|
135
|
+
readonly deps: TDeps;
|
|
136
|
+
/** Current state data (reflects mutations from {@link update}). */
|
|
137
|
+
readonly data: StateData<TConfig, TState>;
|
|
138
|
+
/**
|
|
139
|
+
* Merges partial data into the current state. Validates against the state's Zod schema.
|
|
140
|
+
* @param data - Partial state data to merge
|
|
141
|
+
*/
|
|
142
|
+
update(data: Partial<StateData<TConfig, TState>>): void;
|
|
143
|
+
/**
|
|
144
|
+
* Transitions the workflow to a new state with new data. Validates against the target state's Zod schema.
|
|
145
|
+
* @param target - Target state name
|
|
146
|
+
* @param data - Data for the target state
|
|
147
|
+
*/
|
|
148
|
+
transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
|
|
149
|
+
/**
|
|
150
|
+
* Emits a domain event. Validates event data against the event's Zod schema.
|
|
151
|
+
* @param event - Event with type and data
|
|
152
|
+
*/
|
|
153
|
+
emit<E extends EventNames<TConfig>>(event: {
|
|
154
|
+
type: E;
|
|
155
|
+
data: EventData<TConfig, E>;
|
|
156
|
+
}): void;
|
|
157
|
+
/** Accumulated events emitted during this dispatch. */
|
|
158
|
+
readonly events: ReadonlyArray<{
|
|
159
|
+
type: EventNames<TConfig>;
|
|
160
|
+
data: unknown;
|
|
161
|
+
}>;
|
|
162
|
+
/**
|
|
163
|
+
* Signals a domain error. Validates error data and throws internally (caught by the router).
|
|
164
|
+
* @param err - Error with code and data
|
|
165
|
+
*/
|
|
166
|
+
error<C extends ErrorCodes<TConfig>>(err: {
|
|
167
|
+
code: C;
|
|
168
|
+
data: ErrorData<TConfig, C>;
|
|
169
|
+
}): never;
|
|
170
|
+
/**
|
|
171
|
+
* Stores a value in context-scoped middleware state.
|
|
172
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
173
|
+
* @param value - The value to store
|
|
174
|
+
*/
|
|
175
|
+
set<T>(key: ContextKey<T>, value: T): void;
|
|
176
|
+
/**
|
|
177
|
+
* Retrieves a value from context-scoped middleware state. Throws if not set.
|
|
178
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
179
|
+
*/
|
|
180
|
+
get<T>(key: ContextKey<T>): T;
|
|
181
|
+
/**
|
|
182
|
+
* Retrieves a value from context-scoped middleware state, or `undefined` if not set.
|
|
183
|
+
* @param key - A {@link ContextKey} created via {@link createKey}
|
|
184
|
+
*/
|
|
185
|
+
getOrNull<T>(key: ContextKey<T>): T | undefined;
|
|
186
|
+
/** @internal — not part of the handler API */
|
|
187
|
+
getWorkflowSnapshot(): Workflow<TConfig>;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Read-only subset of Context for hook callbacks.
|
|
192
|
+
* Includes context-key access (set/get) but excludes dispatch mutation methods.
|
|
193
|
+
*/
|
|
194
|
+
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">;
|
|
195
|
+
|
|
196
|
+
type AnyMiddleware = (ctx: any, next: () => Promise<void>) => Promise<void>;
|
|
197
|
+
type HandlerEntry = {
|
|
198
|
+
inlineMiddleware: AnyMiddleware[];
|
|
199
|
+
handler: AnyMiddleware;
|
|
200
|
+
};
|
|
201
|
+
/** Options for the {@link WorkflowRouter} constructor. */
|
|
202
|
+
interface RouterOptions {
|
|
203
|
+
/** Callback invoked when a lifecycle hook throws. Defaults to `console.error`. */
|
|
204
|
+
onHookError?: (error: unknown) => void;
|
|
205
|
+
/** Wrap deps in a Proxy to catch dependency errors. Defaults to `true`. */
|
|
206
|
+
wrapDeps?: boolean;
|
|
207
|
+
}
|
|
208
|
+
declare class StateBuilder<TConfig extends WorkflowConfig, TDeps, TState extends StateNames<TConfig>> {
|
|
209
|
+
/** @internal */ readonly middleware: AnyMiddleware[];
|
|
210
|
+
/** @internal */ readonly handlers: Map<string, HandlerEntry>;
|
|
211
|
+
constructor();
|
|
212
|
+
on<C extends CommandNames<TConfig>>(command: C, handler: (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>): this;
|
|
213
|
+
on<C extends CommandNames<TConfig>>(command: C, ...fns: [...AnyMiddleware[], (ctx: Context<TConfig, TDeps, TState, C>) => void | Promise<void>]): this;
|
|
214
|
+
use(middleware: (ctx: Context<TConfig, TDeps, TState>, next: () => Promise<void>) => Promise<void>): this;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Routes commands to handlers based on workflow state.
|
|
218
|
+
*
|
|
219
|
+
* Supports global middleware, state-scoped middleware, inline middleware,
|
|
220
|
+
* wildcard handlers, and multi-state handlers.
|
|
221
|
+
*/
|
|
222
|
+
declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
|
|
223
|
+
readonly definition: WorkflowDefinition<TConfig>;
|
|
224
|
+
private readonly deps;
|
|
225
|
+
private globalMiddleware;
|
|
226
|
+
private singleStateBuilders;
|
|
227
|
+
private multiStateBuilders;
|
|
228
|
+
private wildcardHandlers;
|
|
229
|
+
private hookRegistry;
|
|
230
|
+
private readonly onHookError;
|
|
231
|
+
private readonly wrapDeps;
|
|
232
|
+
/**
|
|
233
|
+
* @param definition - The workflow definition describing states, commands, events, and errors
|
|
234
|
+
* @param deps - Dependencies injected into every handler context
|
|
235
|
+
* @param options - Router configuration options
|
|
236
|
+
*/
|
|
237
|
+
constructor(definition: WorkflowDefinition<TConfig>, deps?: TDeps, options?: RouterOptions);
|
|
238
|
+
/**
|
|
239
|
+
* Adds global middleware, merges another router, or applies a plugin.
|
|
240
|
+
* @param arg - A middleware function, another {@link WorkflowRouter} to merge, or a {@link Plugin}
|
|
241
|
+
*/
|
|
242
|
+
use(arg: ((ctx: Context<TConfig, TDeps>, next: () => Promise<void>) => Promise<void>) | WorkflowRouter<TConfig, TDeps> | Plugin<TConfig, TDeps> | GenericPlugin): this;
|
|
243
|
+
private merge;
|
|
244
|
+
private mergeStateBuilders;
|
|
245
|
+
/**
|
|
246
|
+
* Registers handlers for one or more states.
|
|
247
|
+
* @param name - A state name or array of state names to register handlers for
|
|
248
|
+
* @param setup - Callback that receives a state builder to register commands and middleware
|
|
249
|
+
*/
|
|
250
|
+
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;
|
|
251
|
+
/**
|
|
252
|
+
* Registers a lifecycle hook callback.
|
|
253
|
+
* @param event - The lifecycle event name
|
|
254
|
+
* @param callback - The callback to invoke when the event fires
|
|
255
|
+
*/
|
|
256
|
+
on(event: "dispatch:start", callback: (workflow: Workflow<TConfig>, command: {
|
|
257
|
+
type: CommandNames<TConfig>;
|
|
258
|
+
payload: unknown;
|
|
259
|
+
}) => void | Promise<void>): this;
|
|
260
|
+
on(event: "dispatch:end", callback: (workflow: Workflow<TConfig>, command: {
|
|
261
|
+
type: CommandNames<TConfig>;
|
|
262
|
+
payload: unknown;
|
|
263
|
+
}, result: DispatchResult<TConfig>) => void | Promise<void>): this;
|
|
264
|
+
on(event: "pipeline:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
|
|
265
|
+
on(event: "pipeline:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
|
|
266
|
+
on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
267
|
+
on(event: "error", callback: (error: PipelineError<TConfig>, ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
|
|
268
|
+
on(event: "event", callback: (event: {
|
|
269
|
+
type: EventNames<TConfig>;
|
|
270
|
+
data: unknown;
|
|
271
|
+
}, workflow: Workflow<TConfig>) => void | Promise<void>): this;
|
|
272
|
+
/**
|
|
273
|
+
* Registers a wildcard handler that matches any state.
|
|
274
|
+
* @param state - Must be `"*"` to match all states
|
|
275
|
+
* @param command - The command name to handle
|
|
276
|
+
* @param handler - The terminal handler
|
|
277
|
+
*/
|
|
278
|
+
on<C extends CommandNames<TConfig>>(state: "*", command: C, handler: (ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>): this;
|
|
279
|
+
/**
|
|
280
|
+
* Registers a wildcard handler that matches any state, with inline middleware.
|
|
281
|
+
* @param state - Must be `"*"` to match all states
|
|
282
|
+
* @param command - The command name to handle
|
|
283
|
+
* @param fns - Inline middleware followed by the terminal handler
|
|
284
|
+
*/
|
|
285
|
+
on<C extends CommandNames<TConfig>>(state: "*", command: C, ...fns: [
|
|
286
|
+
...AnyMiddleware[],
|
|
287
|
+
(ctx: Context<TConfig, TDeps, StateNames<TConfig>, C>) => void | Promise<void>
|
|
288
|
+
]): this;
|
|
289
|
+
/**
|
|
290
|
+
* Dispatches a command to the appropriate handler and returns the result.
|
|
291
|
+
* @param workflow - The current workflow instance to dispatch against
|
|
292
|
+
* @param command - The command with its type and payload
|
|
293
|
+
* @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
|
|
294
|
+
*/
|
|
295
|
+
dispatch(workflow: Workflow<TConfig>, command: {
|
|
296
|
+
type: CommandNames<TConfig>;
|
|
297
|
+
payload: unknown;
|
|
298
|
+
}): Promise<DispatchResult<TConfig>>;
|
|
299
|
+
private executePipeline;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
declare const PLUGIN_SYMBOL: unique symbol;
|
|
303
|
+
/** A branded plugin function that can be passed to {@link WorkflowRouter.use}. */
|
|
304
|
+
type Plugin<TConfig extends WorkflowConfig, TDeps> = ((router: WorkflowRouter<TConfig, TDeps>) => void) & {
|
|
305
|
+
readonly [PLUGIN_SYMBOL]: true;
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* Brands a function as a Ryte plugin for use with {@link WorkflowRouter.use}.
|
|
309
|
+
*
|
|
310
|
+
* @param fn - A function that configures a router (adds handlers, middleware, hooks)
|
|
311
|
+
* @returns A branded {@link Plugin} function
|
|
312
|
+
*/
|
|
313
|
+
declare function definePlugin<TConfig extends WorkflowConfig, TDeps>(fn: (router: WorkflowRouter<TConfig, TDeps>) => void): Plugin<TConfig, TDeps>;
|
|
314
|
+
/**
|
|
315
|
+
* Checks whether a value is a branded Ryte plugin.
|
|
316
|
+
*
|
|
317
|
+
* @param value - The value to check
|
|
318
|
+
* @returns `true` if the value is a {@link Plugin}
|
|
319
|
+
*/
|
|
320
|
+
/** A plugin that works with any router, regardless of config or deps. */
|
|
321
|
+
type GenericPlugin = Plugin<any, any>;
|
|
322
|
+
/**
|
|
323
|
+
* Creates a plugin that works with any router without requiring explicit type parameters.
|
|
324
|
+
* Use this for cross-cutting concerns (logging, tracing, delay) that don't reference
|
|
325
|
+
* specific states, commands, or events.
|
|
326
|
+
*
|
|
327
|
+
* @param fn - A function that configures a router (adds hooks, middleware)
|
|
328
|
+
* @returns A branded {@link GenericPlugin} function
|
|
329
|
+
*/
|
|
330
|
+
declare function defineGenericPlugin(fn: (router: WorkflowRouter<any, any>) => void): GenericPlugin;
|
|
331
|
+
/**
|
|
332
|
+
* Checks whether a value is a branded Ryte plugin.
|
|
333
|
+
*
|
|
334
|
+
* @param value - The value to check
|
|
335
|
+
* @returns `true` if the value is a {@link Plugin}
|
|
336
|
+
*/
|
|
337
|
+
declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
|
|
338
|
+
|
|
339
|
+
export { type Context as C, type GenericPlugin as G, type Plugin as P, type ReadonlyContext as R, type WorkflowDefinition as W, type ContextKey as a, type RouterOptions as b, WorkflowRouter as c, createKey as d, defineGenericPlugin as e, definePlugin as f, defineWorkflow as g, isPlugin as i };
|