@rytejs/core 0.7.1 → 0.9.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.
@@ -1,6 +1,33 @@
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';
1
+ import { W as WorkflowConfig, a as WorkflowSnapshot, c as ClientWorkflow, V as ValidationError, S as StateNames, l as StateData, n as WorkflowOf, m as Workflow, o as WorkflowConfigInput, C as CommandNames, f as CommandPayload, k as EventNames, j as EventData, E as ErrorCodes, i as ErrorData, e as Command, D as DispatchResult, P as PipelineError } from './snapshot-6pxxtOjB.js';
2
2
  import { ZodType, z } from 'zod';
3
3
 
4
+ declare const SERVER_BRAND: unique symbol;
5
+ /** Brands a Zod schema type as server-only at the TypeScript level. */
6
+ type Server<T extends ZodType> = T & {
7
+ readonly [SERVER_BRAND]: true;
8
+ };
9
+ /**
10
+ * Marks a Zod schema as server-only. Fields wrapped in `server()` are stripped
11
+ * from client snapshots and excluded from client TypeScript types.
12
+ *
13
+ * Returns a new schema reference — the original is not mutated, so shared
14
+ * schemas can safely be used in both server and non-server positions.
15
+ */
16
+ declare function server<T extends ZodType>(schema: T): Server<T>;
17
+ /** Returns `true` if the schema was wrapped with `server()`. */
18
+ declare function isServerField(schema: ZodType): boolean;
19
+ type ServerBranded = {
20
+ readonly [SERVER_BRAND]: true;
21
+ };
22
+ /** Computes the client-safe inferred type from a Zod schema by filtering out server-branded fields. */
23
+ type ClientInfer<T extends ZodType> = T extends {
24
+ shape: infer Shape extends Record<string, ZodType>;
25
+ } ? {
26
+ [K in keyof Shape as Shape[K] extends ServerBranded ? never : K]: Shape[K] extends {
27
+ shape: Record<string, ZodType>;
28
+ } ? ClientInfer<Shape[K]> : z.infer<Shape[K]>;
29
+ } : z.infer<T>;
30
+
4
31
  /**
5
32
  * The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
6
33
  */
@@ -82,6 +109,36 @@ interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
82
109
  ok: false;
83
110
  error: ValidationError;
84
111
  };
112
+ /**
113
+ * Serializes a workflow into a client-safe snapshot with server-only fields stripped.
114
+ *
115
+ * @param workflow - The workflow instance to serialize
116
+ * @returns A {@link WorkflowSnapshot} with server-only fields removed from `data`
117
+ */
118
+ serializeForClient(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
119
+ /**
120
+ * Returns a client-safe projection of this definition.
121
+ * Memoized — returns the same instance on repeated calls.
122
+ */
123
+ forClient(): ClientWorkflowDefinition<TConfig>;
124
+ }
125
+ /**
126
+ * A client-safe projection of a workflow definition.
127
+ * State schemas have server-only fields removed. Returned by {@link WorkflowDefinition.forClient}.
128
+ */
129
+ interface ClientWorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
130
+ /** The raw Zod schema configuration. */
131
+ readonly config: TConfig;
132
+ readonly name: string;
133
+ getStateSchema(stateName: string): ZodType;
134
+ hasState(stateName: string): boolean;
135
+ deserialize(snapshot: WorkflowSnapshot<TConfig>): {
136
+ ok: true;
137
+ workflow: ClientWorkflow<TConfig>;
138
+ } | {
139
+ ok: false;
140
+ error: ValidationError;
141
+ };
85
142
  }
86
143
  /**
87
144
  * Creates a workflow definition from a name and Zod schema configuration.
@@ -105,6 +162,11 @@ declare function defineWorkflow<const TConfig extends WorkflowConfigInput>(name:
105
162
  [K in keyof TConfig["errors"]]: z.infer<TConfig["errors"][K]>;
106
163
  };
107
164
  };
165
+ _clientResolved: {
166
+ states: {
167
+ [K in keyof TConfig["states"]]: ClientInfer<TConfig["states"][K]>;
168
+ };
169
+ };
108
170
  }>;
109
171
 
110
172
  /** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
@@ -146,14 +208,14 @@ interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNam
146
208
  * @param data - Data for the target state
147
209
  */
148
210
  transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
211
+ /** Current state name (reflects mutations from {@link transition}). */
212
+ readonly state: TState;
149
213
  /**
150
214
  * Emits a domain event. Validates event data against the event's Zod schema.
151
- * @param event - Event with type and data
215
+ * @param type - Event type name
216
+ * @param data - Event data matching the event's schema
152
217
  */
153
- emit<E extends EventNames<TConfig>>(event: {
154
- type: E;
155
- data: EventData<TConfig, E>;
156
- }): void;
218
+ emit<E extends EventNames<TConfig>>(type: E, data: EventData<TConfig, E>): void;
157
219
  /** Accumulated events emitted during this dispatch. */
158
220
  readonly events: ReadonlyArray<{
159
221
  type: EventNames<TConfig>;
@@ -161,12 +223,23 @@ interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNam
161
223
  }>;
162
224
  /**
163
225
  * Signals a domain error. Validates error data and throws internally (caught by the router).
164
- * @param err - Error with code and data
226
+ * @param code - Error code
227
+ * @param data - Error data matching the error code's schema
228
+ */
229
+ error<C extends ErrorCodes<TConfig>>(code: C, data: ErrorData<TConfig, C>): never;
230
+ /**
231
+ * Pattern-matches on the current state, calling the matching callback with narrowed data.
232
+ * All states must be handled (exhaustive).
233
+ */
234
+ match<R>(matchers: {
235
+ [S in StateNames<TConfig>]: (data: StateData<TConfig, S>, workflow: WorkflowOf<TConfig, S>) => R;
236
+ }): R;
237
+ /**
238
+ * Pattern-matches on the current state with a fallback for unhandled states.
165
239
  */
166
- error<C extends ErrorCodes<TConfig>>(err: {
167
- code: C;
168
- data: ErrorData<TConfig, C>;
169
- }): never;
240
+ match<R>(matchers: Partial<{
241
+ [S in StateNames<TConfig>]: (data: StateData<TConfig, S>, workflow: WorkflowOf<TConfig, S>) => R;
242
+ }>, fallback: () => R): R;
170
243
  /**
171
244
  * Stores a value in context-scoped middleware state.
172
245
  * @param key - A {@link ContextKey} created via {@link createKey}
@@ -253,14 +326,8 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
253
326
  * @param event - The lifecycle event name
254
327
  * @param callback - The callback to invoke when the event fires
255
328
  */
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;
329
+ on(event: "dispatch:start", callback: (workflow: Workflow<TConfig>, command: Command<TConfig>) => void | Promise<void>): this;
330
+ on(event: "dispatch:end", callback: (workflow: Workflow<TConfig>, command: Command<TConfig>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
264
331
  on(event: "pipeline:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
265
332
  on(event: "pipeline:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
266
333
  on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
@@ -292,10 +359,7 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
292
359
  * @param command - The command with its type and payload
293
360
  * @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
294
361
  */
295
- dispatch(workflow: Workflow<TConfig>, command: {
296
- type: CommandNames<TConfig>;
297
- payload: unknown;
298
- }): Promise<DispatchResult<TConfig>>;
362
+ dispatch<C extends CommandNames<TConfig>>(workflow: Workflow<TConfig>, type: C, payload: CommandPayload<TConfig, C>): Promise<DispatchResult<TConfig>>;
299
363
  private executePipeline;
300
364
  }
301
365
 
@@ -336,4 +400,4 @@ declare function defineGenericPlugin(fn: (router: WorkflowRouter<any, any>) => v
336
400
  */
337
401
  declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
338
402
 
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 };
403
+ export { type Context as C, type GenericPlugin as G, type Plugin as P, type ReadonlyContext as R, type Server as S, type WorkflowDefinition as W, type ClientWorkflowDefinition as a, type ContextKey as b, type RouterOptions as c, WorkflowRouter as d, createKey as e, defineGenericPlugin as f, definePlugin as g, defineWorkflow as h, isPlugin as i, isServerField as j, server as s };
@@ -1,6 +1,33 @@
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';
1
+ import { W as WorkflowConfig, a as WorkflowSnapshot, c as ClientWorkflow, V as ValidationError, S as StateNames, l as StateData, n as WorkflowOf, m as Workflow, o as WorkflowConfigInput, C as CommandNames, f as CommandPayload, k as EventNames, j as EventData, E as ErrorCodes, i as ErrorData, e as Command, D as DispatchResult, P as PipelineError } from './snapshot-6pxxtOjB.cjs';
2
2
  import { ZodType, z } from 'zod';
3
3
 
4
+ declare const SERVER_BRAND: unique symbol;
5
+ /** Brands a Zod schema type as server-only at the TypeScript level. */
6
+ type Server<T extends ZodType> = T & {
7
+ readonly [SERVER_BRAND]: true;
8
+ };
9
+ /**
10
+ * Marks a Zod schema as server-only. Fields wrapped in `server()` are stripped
11
+ * from client snapshots and excluded from client TypeScript types.
12
+ *
13
+ * Returns a new schema reference — the original is not mutated, so shared
14
+ * schemas can safely be used in both server and non-server positions.
15
+ */
16
+ declare function server<T extends ZodType>(schema: T): Server<T>;
17
+ /** Returns `true` if the schema was wrapped with `server()`. */
18
+ declare function isServerField(schema: ZodType): boolean;
19
+ type ServerBranded = {
20
+ readonly [SERVER_BRAND]: true;
21
+ };
22
+ /** Computes the client-safe inferred type from a Zod schema by filtering out server-branded fields. */
23
+ type ClientInfer<T extends ZodType> = T extends {
24
+ shape: infer Shape extends Record<string, ZodType>;
25
+ } ? {
26
+ [K in keyof Shape as Shape[K] extends ServerBranded ? never : K]: Shape[K] extends {
27
+ shape: Record<string, ZodType>;
28
+ } ? ClientInfer<Shape[K]> : z.infer<Shape[K]>;
29
+ } : z.infer<T>;
30
+
4
31
  /**
5
32
  * The result of {@link defineWorkflow} — holds schemas and creates workflow instances.
6
33
  */
@@ -82,6 +109,36 @@ interface WorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
82
109
  ok: false;
83
110
  error: ValidationError;
84
111
  };
112
+ /**
113
+ * Serializes a workflow into a client-safe snapshot with server-only fields stripped.
114
+ *
115
+ * @param workflow - The workflow instance to serialize
116
+ * @returns A {@link WorkflowSnapshot} with server-only fields removed from `data`
117
+ */
118
+ serializeForClient(workflow: Workflow<TConfig>): WorkflowSnapshot<TConfig>;
119
+ /**
120
+ * Returns a client-safe projection of this definition.
121
+ * Memoized — returns the same instance on repeated calls.
122
+ */
123
+ forClient(): ClientWorkflowDefinition<TConfig>;
124
+ }
125
+ /**
126
+ * A client-safe projection of a workflow definition.
127
+ * State schemas have server-only fields removed. Returned by {@link WorkflowDefinition.forClient}.
128
+ */
129
+ interface ClientWorkflowDefinition<TConfig extends WorkflowConfig = WorkflowConfig> {
130
+ /** The raw Zod schema configuration. */
131
+ readonly config: TConfig;
132
+ readonly name: string;
133
+ getStateSchema(stateName: string): ZodType;
134
+ hasState(stateName: string): boolean;
135
+ deserialize(snapshot: WorkflowSnapshot<TConfig>): {
136
+ ok: true;
137
+ workflow: ClientWorkflow<TConfig>;
138
+ } | {
139
+ ok: false;
140
+ error: ValidationError;
141
+ };
85
142
  }
86
143
  /**
87
144
  * Creates a workflow definition from a name and Zod schema configuration.
@@ -105,6 +162,11 @@ declare function defineWorkflow<const TConfig extends WorkflowConfigInput>(name:
105
162
  [K in keyof TConfig["errors"]]: z.infer<TConfig["errors"][K]>;
106
163
  };
107
164
  };
165
+ _clientResolved: {
166
+ states: {
167
+ [K in keyof TConfig["states"]]: ClientInfer<TConfig["states"][K]>;
168
+ };
169
+ };
108
170
  }>;
109
171
 
110
172
  /** A phantom-typed key for type-safe middleware state storage via {@link Context.set} and {@link Context.get}. */
@@ -146,14 +208,14 @@ interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNam
146
208
  * @param data - Data for the target state
147
209
  */
148
210
  transition<Target extends StateNames<TConfig>>(target: Target, data: StateData<TConfig, Target>): void;
211
+ /** Current state name (reflects mutations from {@link transition}). */
212
+ readonly state: TState;
149
213
  /**
150
214
  * Emits a domain event. Validates event data against the event's Zod schema.
151
- * @param event - Event with type and data
215
+ * @param type - Event type name
216
+ * @param data - Event data matching the event's schema
152
217
  */
153
- emit<E extends EventNames<TConfig>>(event: {
154
- type: E;
155
- data: EventData<TConfig, E>;
156
- }): void;
218
+ emit<E extends EventNames<TConfig>>(type: E, data: EventData<TConfig, E>): void;
157
219
  /** Accumulated events emitted during this dispatch. */
158
220
  readonly events: ReadonlyArray<{
159
221
  type: EventNames<TConfig>;
@@ -161,12 +223,23 @@ interface Context<TConfig extends WorkflowConfig, TDeps, TState extends StateNam
161
223
  }>;
162
224
  /**
163
225
  * Signals a domain error. Validates error data and throws internally (caught by the router).
164
- * @param err - Error with code and data
226
+ * @param code - Error code
227
+ * @param data - Error data matching the error code's schema
228
+ */
229
+ error<C extends ErrorCodes<TConfig>>(code: C, data: ErrorData<TConfig, C>): never;
230
+ /**
231
+ * Pattern-matches on the current state, calling the matching callback with narrowed data.
232
+ * All states must be handled (exhaustive).
233
+ */
234
+ match<R>(matchers: {
235
+ [S in StateNames<TConfig>]: (data: StateData<TConfig, S>, workflow: WorkflowOf<TConfig, S>) => R;
236
+ }): R;
237
+ /**
238
+ * Pattern-matches on the current state with a fallback for unhandled states.
165
239
  */
166
- error<C extends ErrorCodes<TConfig>>(err: {
167
- code: C;
168
- data: ErrorData<TConfig, C>;
169
- }): never;
240
+ match<R>(matchers: Partial<{
241
+ [S in StateNames<TConfig>]: (data: StateData<TConfig, S>, workflow: WorkflowOf<TConfig, S>) => R;
242
+ }>, fallback: () => R): R;
170
243
  /**
171
244
  * Stores a value in context-scoped middleware state.
172
245
  * @param key - A {@link ContextKey} created via {@link createKey}
@@ -253,14 +326,8 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
253
326
  * @param event - The lifecycle event name
254
327
  * @param callback - The callback to invoke when the event fires
255
328
  */
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;
329
+ on(event: "dispatch:start", callback: (workflow: Workflow<TConfig>, command: Command<TConfig>) => void | Promise<void>): this;
330
+ on(event: "dispatch:end", callback: (workflow: Workflow<TConfig>, command: Command<TConfig>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
264
331
  on(event: "pipeline:start", callback: (ctx: ReadonlyContext<TConfig, TDeps>) => void | Promise<void>): this;
265
332
  on(event: "pipeline:end", callback: (ctx: ReadonlyContext<TConfig, TDeps>, result: DispatchResult<TConfig>) => void | Promise<void>): this;
266
333
  on(event: "transition", callback: (from: StateNames<TConfig>, to: StateNames<TConfig>, workflow: Workflow<TConfig>) => void | Promise<void>): this;
@@ -292,10 +359,7 @@ declare class WorkflowRouter<TConfig extends WorkflowConfig, TDeps = {}> {
292
359
  * @param command - The command with its type and payload
293
360
  * @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
294
361
  */
295
- dispatch(workflow: Workflow<TConfig>, command: {
296
- type: CommandNames<TConfig>;
297
- payload: unknown;
298
- }): Promise<DispatchResult<TConfig>>;
362
+ dispatch<C extends CommandNames<TConfig>>(workflow: Workflow<TConfig>, type: C, payload: CommandPayload<TConfig, C>): Promise<DispatchResult<TConfig>>;
299
363
  private executePipeline;
300
364
  }
301
365
 
@@ -336,4 +400,4 @@ declare function defineGenericPlugin(fn: (router: WorkflowRouter<any, any>) => v
336
400
  */
337
401
  declare function isPlugin(value: unknown): value is Plugin<WorkflowConfig, unknown>;
338
402
 
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 };
403
+ export { type Context as C, type GenericPlugin as G, type Plugin as P, type ReadonlyContext as R, type Server as S, type WorkflowDefinition as W, type ClientWorkflowDefinition as a, type ContextKey as b, type RouterOptions as c, WorkflowRouter as d, createKey as e, defineGenericPlugin as f, definePlugin as g, defineWorkflow as h, isPlugin as i, isServerField as j, server as s };
@@ -1,5 +1,5 @@
1
- import { c as WorkflowRouter } from '../plugin-DHS8yUmS.cjs';
2
- import { W as WorkflowConfig, g as EventNames, f as EventData } from '../snapshot-D5iZubCz.cjs';
1
+ import { d as WorkflowRouter } from '../plugin-CGikcWDu.cjs';
2
+ import { W as WorkflowConfig, k as EventNames, j as EventData } from '../snapshot-6pxxtOjB.cjs';
3
3
  import 'zod';
4
4
 
5
5
  interface ReactorCommand {
@@ -1,5 +1,5 @@
1
- import { c as WorkflowRouter } from '../plugin-DHN3Pk52.js';
2
- import { W as WorkflowConfig, g as EventNames, f as EventData } from '../snapshot-D5iZubCz.js';
1
+ import { d as WorkflowRouter } from '../plugin-ByX9Eoe-.js';
2
+ import { W as WorkflowConfig, k as EventNames, j as EventData } from '../snapshot-6pxxtOjB.js';
3
3
  import 'zod';
4
4
 
5
5
  interface ReactorCommand {
@@ -32,6 +32,9 @@ interface WorkflowConfig extends WorkflowConfigInput {
32
32
  events: Record<string, unknown>;
33
33
  errors: Record<string, unknown>;
34
34
  };
35
+ _clientResolved: {
36
+ states: Record<string, unknown>;
37
+ };
35
38
  }
36
39
  type StateNames<T extends WorkflowConfig> = keyof T["states"] & string;
37
40
  type CommandNames<T extends WorkflowConfig> = keyof T["commands"] & string;
@@ -41,8 +44,30 @@ type ErrorCodes<T extends WorkflowConfig> = keyof T["errors"] & string;
41
44
  type Prettify<T> = {
42
45
  [K in keyof T]: T[K];
43
46
  } & {};
47
+ /** Discriminated union of all commands with typed payloads — narrows payload when checking type. */
48
+ type Command<T extends WorkflowConfig> = {
49
+ [C in CommandNames<T>]: {
50
+ type: C;
51
+ payload: CommandPayload<T, C>;
52
+ };
53
+ }[CommandNames<T>];
44
54
  /** Resolves the data type for a given state from pre-computed types. */
45
55
  type StateData<T extends WorkflowConfig, S extends StateNames<T>> = Prettify<T["_resolved"]["states"][S]>;
56
+ /** Resolves the client-safe data type for a given state (server fields stripped). */
57
+ type ClientStateData<T extends WorkflowConfig, S extends StateNames<T>> = Prettify<T["_clientResolved"]["states"][S]>;
58
+ /** Client-side workflow narrowed to a specific known state. */
59
+ interface ClientWorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {
60
+ readonly id: string;
61
+ readonly definitionName: string;
62
+ readonly state: S;
63
+ readonly data: ClientStateData<TConfig, S>;
64
+ readonly createdAt: Date;
65
+ readonly updatedAt: Date;
66
+ }
67
+ /** Discriminated union of all possible client-side workflow states. */
68
+ type ClientWorkflow<TConfig extends WorkflowConfig = WorkflowConfig> = {
69
+ [S in StateNames<TConfig>]: ClientWorkflowOf<TConfig, S>;
70
+ }[StateNames<TConfig>];
46
71
  /** Resolves the payload type for a given command from pre-computed types. */
47
72
  type CommandPayload<T extends WorkflowConfig, C extends CommandNames<T>> = Prettify<T["_resolved"]["commands"][C]>;
48
73
  /** Resolves the data type for a given event from pre-computed types. */
@@ -162,4 +187,4 @@ interface WorkflowSnapshot<TConfig extends WorkflowConfig = WorkflowConfig> {
162
187
  readonly version: number;
163
188
  }
164
189
 
165
- export { type CommandNames as C, type DispatchResult as D, type ErrorCodes as E, type PipelineError as P, type StateNames as S, ValidationError as V, type WorkflowConfig as W, type WorkflowSnapshot as a, type CommandPayload as b, type ConfigOf as c, DomainErrorSignal as d, type ErrorData as e, type EventData as f, type EventNames as g, type StateData as h, type Workflow as i, type WorkflowOf as j, type WorkflowConfigInput as k };
190
+ export { type CommandNames as C, type DispatchResult as D, type ErrorCodes as E, type PipelineError as P, type StateNames as S, ValidationError as V, type WorkflowConfig as W, type WorkflowSnapshot as a, type ClientStateData as b, type ClientWorkflow as c, type ClientWorkflowOf as d, type Command as e, type CommandPayload as f, type ConfigOf as g, DomainErrorSignal as h, type ErrorData as i, type EventData as j, type EventNames as k, type StateData as l, type Workflow as m, type WorkflowOf as n, type WorkflowConfigInput as o };
@@ -32,6 +32,9 @@ interface WorkflowConfig extends WorkflowConfigInput {
32
32
  events: Record<string, unknown>;
33
33
  errors: Record<string, unknown>;
34
34
  };
35
+ _clientResolved: {
36
+ states: Record<string, unknown>;
37
+ };
35
38
  }
36
39
  type StateNames<T extends WorkflowConfig> = keyof T["states"] & string;
37
40
  type CommandNames<T extends WorkflowConfig> = keyof T["commands"] & string;
@@ -41,8 +44,30 @@ type ErrorCodes<T extends WorkflowConfig> = keyof T["errors"] & string;
41
44
  type Prettify<T> = {
42
45
  [K in keyof T]: T[K];
43
46
  } & {};
47
+ /** Discriminated union of all commands with typed payloads — narrows payload when checking type. */
48
+ type Command<T extends WorkflowConfig> = {
49
+ [C in CommandNames<T>]: {
50
+ type: C;
51
+ payload: CommandPayload<T, C>;
52
+ };
53
+ }[CommandNames<T>];
44
54
  /** Resolves the data type for a given state from pre-computed types. */
45
55
  type StateData<T extends WorkflowConfig, S extends StateNames<T>> = Prettify<T["_resolved"]["states"][S]>;
56
+ /** Resolves the client-safe data type for a given state (server fields stripped). */
57
+ type ClientStateData<T extends WorkflowConfig, S extends StateNames<T>> = Prettify<T["_clientResolved"]["states"][S]>;
58
+ /** Client-side workflow narrowed to a specific known state. */
59
+ interface ClientWorkflowOf<TConfig extends WorkflowConfig, S extends StateNames<TConfig>> {
60
+ readonly id: string;
61
+ readonly definitionName: string;
62
+ readonly state: S;
63
+ readonly data: ClientStateData<TConfig, S>;
64
+ readonly createdAt: Date;
65
+ readonly updatedAt: Date;
66
+ }
67
+ /** Discriminated union of all possible client-side workflow states. */
68
+ type ClientWorkflow<TConfig extends WorkflowConfig = WorkflowConfig> = {
69
+ [S in StateNames<TConfig>]: ClientWorkflowOf<TConfig, S>;
70
+ }[StateNames<TConfig>];
46
71
  /** Resolves the payload type for a given command from pre-computed types. */
47
72
  type CommandPayload<T extends WorkflowConfig, C extends CommandNames<T>> = Prettify<T["_resolved"]["commands"][C]>;
48
73
  /** Resolves the data type for a given event from pre-computed types. */
@@ -162,4 +187,4 @@ interface WorkflowSnapshot<TConfig extends WorkflowConfig = WorkflowConfig> {
162
187
  readonly version: number;
163
188
  }
164
189
 
165
- export { type CommandNames as C, type DispatchResult as D, type ErrorCodes as E, type PipelineError as P, type StateNames as S, ValidationError as V, type WorkflowConfig as W, type WorkflowSnapshot as a, type CommandPayload as b, type ConfigOf as c, DomainErrorSignal as d, type ErrorData as e, type EventData as f, type EventNames as g, type StateData as h, type Workflow as i, type WorkflowOf as j, type WorkflowConfigInput as k };
190
+ export { type CommandNames as C, type DispatchResult as D, type ErrorCodes as E, type PipelineError as P, type StateNames as S, ValidationError as V, type WorkflowConfig as W, type WorkflowSnapshot as a, type ClientStateData as b, type ClientWorkflow as c, type ClientWorkflowOf as d, type Command as e, type CommandPayload as f, type ConfigOf as g, DomainErrorSignal as h, type ErrorData as i, type EventData as j, type EventNames as k, type StateData as l, type Workflow as m, type WorkflowOf as n, type WorkflowConfigInput as o };
@@ -1,6 +1,6 @@
1
- import { a as StoreAdapter } from '../types-BtMTMoOZ.cjs';
2
- export { b as SaveOptions, S as StoredWorkflow } from '../types-BtMTMoOZ.cjs';
3
- import '../snapshot-D5iZubCz.cjs';
1
+ import { a as StoreAdapter } from '../types-BuFyzP66.cjs';
2
+ export { b as SaveOptions, S as StoredWorkflow } from '../types-BuFyzP66.cjs';
3
+ import '../snapshot-6pxxtOjB.cjs';
4
4
  import 'zod';
5
5
 
6
6
  declare class ConcurrencyConflictError extends Error {
@@ -1,6 +1,6 @@
1
- import { a as StoreAdapter } from '../types-C0nlrs5c.js';
2
- export { b as SaveOptions, S as StoredWorkflow } from '../types-C0nlrs5c.js';
3
- import '../snapshot-D5iZubCz.js';
1
+ import { a as StoreAdapter } from '../types-D41DR3xh.js';
2
+ export { b as SaveOptions, S as StoredWorkflow } from '../types-D41DR3xh.js';
3
+ import '../snapshot-6pxxtOjB.js';
4
4
  import 'zod';
5
5
 
6
6
  declare class ConcurrencyConflictError extends Error {
@@ -1,4 +1,4 @@
1
- import { a as WorkflowSnapshot } from './snapshot-D5iZubCz.cjs';
1
+ import { a as WorkflowSnapshot } from './snapshot-6pxxtOjB.cjs';
2
2
 
3
3
  interface StoredWorkflow {
4
4
  snapshot: WorkflowSnapshot;
@@ -1,4 +1,4 @@
1
- import { a as WorkflowSnapshot } from './snapshot-D5iZubCz.js';
1
+ import { a as WorkflowSnapshot } from './snapshot-6pxxtOjB.js';
2
2
 
3
3
  interface StoredWorkflow {
4
4
  snapshot: WorkflowSnapshot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rytejs/core",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "description": "Type-safe workflow engine with Zod validation and middleware pipelines",
5
5
  "license": "MIT",
6
6
  "type": "module",