awaitly 1.35.0 → 2.0.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.
Files changed (241) hide show
  1. package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
  2. package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
  3. package/dist/errors-DtXvrCiO.d.cts +708 -0
  4. package/dist/errors-DtXvrCiO.d.ts +708 -0
  5. package/dist/index.cjs +4594 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +1970 -141
  8. package/dist/index.d.ts +1970 -141
  9. package/dist/index.js +4398 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/result.cjs +641 -1
  12. package/dist/result.cjs.map +1 -1
  13. package/dist/result.d.cts +29 -4
  14. package/dist/result.d.ts +29 -4
  15. package/dist/result.js +561 -1
  16. package/dist/result.js.map +1 -1
  17. package/dist/testing.cjs +4202 -8
  18. package/dist/testing.cjs.map +1 -1
  19. package/dist/testing.d.cts +2 -6
  20. package/dist/testing.d.ts +2 -6
  21. package/dist/testing.js +4154 -8
  22. package/dist/testing.js.map +1 -1
  23. package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
  24. package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
  25. package/dist/workflow.cjs +7096 -6
  26. package/dist/workflow.cjs.map +1 -1
  27. package/dist/workflow.d.cts +3346 -22
  28. package/dist/workflow.d.ts +3346 -22
  29. package/dist/workflow.js +6929 -6
  30. package/dist/workflow.js.map +1 -1
  31. package/package.json +3 -168
  32. package/dist/adapters.cjs +0 -7
  33. package/dist/adapters.cjs.map +0 -1
  34. package/dist/adapters.d.cts +0 -179
  35. package/dist/adapters.d.ts +0 -179
  36. package/dist/adapters.js +0 -7
  37. package/dist/adapters.js.map +0 -1
  38. package/dist/batch.cjs +0 -7
  39. package/dist/batch.cjs.map +0 -1
  40. package/dist/batch.d.cts +0 -200
  41. package/dist/batch.d.ts +0 -200
  42. package/dist/batch.js +0 -7
  43. package/dist/batch.js.map +0 -1
  44. package/dist/bind-deps.cjs +0 -2
  45. package/dist/bind-deps.cjs.map +0 -1
  46. package/dist/bind-deps.d.cts +0 -28
  47. package/dist/bind-deps.d.ts +0 -28
  48. package/dist/bind-deps.js +0 -2
  49. package/dist/bind-deps.js.map +0 -1
  50. package/dist/cache.cjs +0 -2
  51. package/dist/cache.cjs.map +0 -1
  52. package/dist/cache.d.cts +0 -269
  53. package/dist/cache.d.ts +0 -269
  54. package/dist/cache.js +0 -2
  55. package/dist/cache.js.map +0 -1
  56. package/dist/circuit-breaker.cjs +0 -7
  57. package/dist/circuit-breaker.cjs.map +0 -1
  58. package/dist/circuit-breaker.d.cts +0 -211
  59. package/dist/circuit-breaker.d.ts +0 -211
  60. package/dist/circuit-breaker.js +0 -7
  61. package/dist/circuit-breaker.js.map +0 -1
  62. package/dist/conditional.cjs +0 -2
  63. package/dist/conditional.cjs.map +0 -1
  64. package/dist/conditional.d.cts +0 -252
  65. package/dist/conditional.d.ts +0 -252
  66. package/dist/conditional.js +0 -2
  67. package/dist/conditional.js.map +0 -1
  68. package/dist/core.cjs +0 -7
  69. package/dist/core.cjs.map +0 -1
  70. package/dist/core.d.cts +0 -5
  71. package/dist/core.d.ts +0 -5
  72. package/dist/core.js +0 -7
  73. package/dist/core.js.map +0 -1
  74. package/dist/di-By77n4Fa.d.ts +0 -15
  75. package/dist/di-OJfsohf-.d.cts +0 -15
  76. package/dist/diagnostics.cjs +0 -8
  77. package/dist/diagnostics.cjs.map +0 -1
  78. package/dist/diagnostics.d.cts +0 -68
  79. package/dist/diagnostics.d.ts +0 -68
  80. package/dist/diagnostics.js +0 -8
  81. package/dist/diagnostics.js.map +0 -1
  82. package/dist/durable.cjs +0 -11
  83. package/dist/durable.cjs.map +0 -1
  84. package/dist/durable.d.cts +0 -9
  85. package/dist/durable.d.ts +0 -9
  86. package/dist/durable.js +0 -11
  87. package/dist/durable.js.map +0 -1
  88. package/dist/duration.cjs +0 -2
  89. package/dist/duration.cjs.map +0 -1
  90. package/dist/duration.js +0 -2
  91. package/dist/duration.js.map +0 -1
  92. package/dist/engine.cjs +0 -11
  93. package/dist/engine.cjs.map +0 -1
  94. package/dist/engine.d.cts +0 -115
  95. package/dist/engine.d.ts +0 -115
  96. package/dist/engine.js +0 -11
  97. package/dist/engine.js.map +0 -1
  98. package/dist/errors.cjs +0 -2
  99. package/dist/errors.cjs.map +0 -1
  100. package/dist/errors.d.cts +0 -361
  101. package/dist/errors.d.ts +0 -361
  102. package/dist/errors.js +0 -2
  103. package/dist/errors.js.map +0 -1
  104. package/dist/fetch.cjs +0 -7
  105. package/dist/fetch.cjs.map +0 -1
  106. package/dist/fetch.d.cts +0 -86
  107. package/dist/fetch.d.ts +0 -86
  108. package/dist/fetch.js +0 -7
  109. package/dist/fetch.js.map +0 -1
  110. package/dist/flow.cjs +0 -7
  111. package/dist/flow.cjs.map +0 -1
  112. package/dist/flow.d.cts +0 -163
  113. package/dist/flow.d.ts +0 -163
  114. package/dist/flow.js +0 -7
  115. package/dist/flow.js.map +0 -1
  116. package/dist/functional.cjs +0 -2
  117. package/dist/functional.cjs.map +0 -1
  118. package/dist/functional.d.cts +0 -444
  119. package/dist/functional.d.ts +0 -444
  120. package/dist/functional.js +0 -2
  121. package/dist/functional.js.map +0 -1
  122. package/dist/guards-4sV7mTqj.d.cts +0 -72
  123. package/dist/guards-BIX05ALH.d.ts +0 -72
  124. package/dist/hitl-DFn4Xa_l.d.cts +0 -468
  125. package/dist/hitl-DU5VpKq7.d.ts +0 -468
  126. package/dist/hitl.cjs +0 -7
  127. package/dist/hitl.cjs.map +0 -1
  128. package/dist/hitl.d.cts +0 -442
  129. package/dist/hitl.d.ts +0 -442
  130. package/dist/hitl.js +0 -7
  131. package/dist/hitl.js.map +0 -1
  132. package/dist/index-CnvBryQB.d.ts +0 -417
  133. package/dist/index-DEZEf8Fs.d.cts +0 -417
  134. package/dist/match-entry-DjI2bLpD.d.cts +0 -209
  135. package/dist/match-entry-DjI2bLpD.d.ts +0 -209
  136. package/dist/match.cjs +0 -2
  137. package/dist/match.cjs.map +0 -1
  138. package/dist/match.d.cts +0 -1
  139. package/dist/match.d.ts +0 -1
  140. package/dist/match.js +0 -2
  141. package/dist/match.js.map +0 -1
  142. package/dist/otel.cjs +0 -2
  143. package/dist/otel.cjs.map +0 -1
  144. package/dist/otel.d.cts +0 -188
  145. package/dist/otel.d.ts +0 -188
  146. package/dist/otel.js +0 -2
  147. package/dist/otel.js.map +0 -1
  148. package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
  149. package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
  150. package/dist/persistence.cjs +0 -2
  151. package/dist/persistence.cjs.map +0 -1
  152. package/dist/persistence.d.cts +0 -7
  153. package/dist/persistence.d.ts +0 -7
  154. package/dist/persistence.js +0 -2
  155. package/dist/persistence.js.map +0 -1
  156. package/dist/policies.cjs +0 -2
  157. package/dist/policies.cjs.map +0 -1
  158. package/dist/policies.d.cts +0 -379
  159. package/dist/policies.d.ts +0 -379
  160. package/dist/policies.js +0 -2
  161. package/dist/policies.js.map +0 -1
  162. package/dist/ratelimit.cjs +0 -7
  163. package/dist/ratelimit.cjs.map +0 -1
  164. package/dist/ratelimit.d.cts +0 -458
  165. package/dist/ratelimit.d.ts +0 -458
  166. package/dist/ratelimit.js +0 -7
  167. package/dist/ratelimit.js.map +0 -1
  168. package/dist/reliability.cjs +0 -11
  169. package/dist/reliability.cjs.map +0 -1
  170. package/dist/reliability.d.cts +0 -11
  171. package/dist/reliability.d.ts +0 -11
  172. package/dist/reliability.js +0 -11
  173. package/dist/reliability.js.map +0 -1
  174. package/dist/resolver.cjs +0 -7
  175. package/dist/resolver.cjs.map +0 -1
  176. package/dist/resolver.d.cts +0 -68
  177. package/dist/resolver.d.ts +0 -68
  178. package/dist/resolver.js +0 -7
  179. package/dist/resolver.js.map +0 -1
  180. package/dist/resource.cjs +0 -7
  181. package/dist/resource.cjs.map +0 -1
  182. package/dist/resource.d.cts +0 -174
  183. package/dist/resource.d.ts +0 -174
  184. package/dist/resource.js +0 -7
  185. package/dist/resource.js.map +0 -1
  186. package/dist/result/retry.cjs +0 -2
  187. package/dist/result/retry.cjs.map +0 -1
  188. package/dist/result/retry.d.cts +0 -70
  189. package/dist/result/retry.d.ts +0 -70
  190. package/dist/result/retry.js +0 -2
  191. package/dist/result/retry.js.map +0 -1
  192. package/dist/retry.cjs +0 -2
  193. package/dist/retry.cjs.map +0 -1
  194. package/dist/retry.d.cts +0 -388
  195. package/dist/retry.d.ts +0 -388
  196. package/dist/retry.js +0 -2
  197. package/dist/retry.js.map +0 -1
  198. package/dist/run.cjs +0 -7
  199. package/dist/run.cjs.map +0 -1
  200. package/dist/run.d.cts +0 -4
  201. package/dist/run.d.ts +0 -4
  202. package/dist/run.js +0 -7
  203. package/dist/run.js.map +0 -1
  204. package/dist/saga.cjs +0 -11
  205. package/dist/saga.cjs.map +0 -1
  206. package/dist/saga.d.cts +0 -164
  207. package/dist/saga.d.ts +0 -164
  208. package/dist/saga.js +0 -11
  209. package/dist/saga.js.map +0 -1
  210. package/dist/singleflight.cjs +0 -2
  211. package/dist/singleflight.cjs.map +0 -1
  212. package/dist/singleflight.d.cts +0 -145
  213. package/dist/singleflight.d.ts +0 -145
  214. package/dist/singleflight.js +0 -2
  215. package/dist/singleflight.js.map +0 -1
  216. package/dist/slugs.cjs +0 -2
  217. package/dist/slugs.cjs.map +0 -1
  218. package/dist/slugs.d.cts +0 -67
  219. package/dist/slugs.d.ts +0 -67
  220. package/dist/slugs.js +0 -2
  221. package/dist/slugs.js.map +0 -1
  222. package/dist/streaming.cjs +0 -9
  223. package/dist/streaming.cjs.map +0 -1
  224. package/dist/streaming.d.cts +0 -596
  225. package/dist/streaming.d.ts +0 -596
  226. package/dist/streaming.js +0 -9
  227. package/dist/streaming.js.map +0 -1
  228. package/dist/tagged-error.cjs +0 -2
  229. package/dist/tagged-error.cjs.map +0 -1
  230. package/dist/tagged-error.d.cts +0 -275
  231. package/dist/tagged-error.d.ts +0 -275
  232. package/dist/tagged-error.js +0 -2
  233. package/dist/tagged-error.js.map +0 -1
  234. package/dist/types-BziYHFkD.d.ts +0 -323
  235. package/dist/types-C5jLEUqY.d.cts +0 -323
  236. package/dist/webhook.cjs +0 -7
  237. package/dist/webhook.cjs.map +0 -1
  238. package/dist/webhook.d.cts +0 -499
  239. package/dist/webhook.d.ts +0 -499
  240. package/dist/webhook.js +0 -7
  241. package/dist/webhook.js.map +0 -1
@@ -1,831 +0,0 @@
1
- import { R as Result, f as ErrorOf, ae as WorkflowEvent, av as StepFailureMeta, af as RunStep, ai as BoundSteps, c as AsyncResult, C as CauseOf } from './run-entry-DGs0tySr.cjs';
2
- import { S as StreamStore } from './types-C5jLEUqY.cjs';
3
- import { StandardSchemaV1 } from '@standard-schema/spec';
4
- import { UnexpectedError } from './errors.cjs';
5
-
6
- /**
7
- * awaitly/persistence
8
- *
9
- * Simplified Persistence API for workflow snapshots.
10
- * Provides JSON-serializable snapshot format and store adapters.
11
- */
12
-
13
- /**
14
- * Enforce JSON-safety at type level.
15
- * Only allows values that can be safely serialized with JSON.stringify.
16
- */
17
- type JSONValue = null | boolean | number | string | JSONValue[] | {
18
- [k: string]: JSONValue;
19
- };
20
- /**
21
- * Canonical error wire format - handles both Error instances and thrown non-Errors.
22
- * This is the single source of truth for serialized errors in snapshots.
23
- */
24
- type SerializedCause = {
25
- type: "error";
26
- name: string;
27
- message: string;
28
- stack?: string;
29
- cause?: SerializedCause;
30
- } | {
31
- type: "thrown";
32
- originalType?: string;
33
- value?: JSONValue;
34
- stringRepresentation: string;
35
- truncated?: true;
36
- };
37
- /**
38
- * Single source of truth for step outcome (no error/cause confusion).
39
- * Uses discriminated union with `ok` field.
40
- */
41
- type StepResult = {
42
- ok: true;
43
- value: JSONValue;
44
- } | {
45
- ok: false;
46
- error: JSONValue;
47
- cause: SerializedCause;
48
- meta?: {
49
- origin: "result" | "throw";
50
- };
51
- };
52
- /**
53
- * JSON-serializable workflow snapshot.
54
- * Designed to be passed directly to JSON.stringify without special handling.
55
- *
56
- * @example
57
- * ```typescript
58
- * // Persist
59
- * localStorage.setItem('wf-123', JSON.stringify(wf.getSnapshot()));
60
- *
61
- * // Restore (safe pattern - storage can be empty/corrupt)
62
- * const raw = localStorage.getItem('wf-123');
63
- * const snapshot = raw ? JSON.parse(raw) : null;
64
- * createWorkflow(deps, { snapshot }); // null = fresh start
65
- * ```
66
- */
67
- interface WorkflowSnapshot {
68
- /** Snapshot format version (literal type - bump when shape changes) */
69
- formatVersion: 1;
70
- /** Workflow name (from createWorkflow first argument). */
71
- workflowName?: string;
72
- /** Step results keyed by step ID. Uses Object.create(null) internally. */
73
- steps: Record<string, StepResult>;
74
- /** Execution state metadata */
75
- execution: {
76
- status: "running" | "completed" | "failed";
77
- /** ISO timestamp (UTC toISOString()) */
78
- lastUpdated: string;
79
- /** ISO timestamp if finished */
80
- completedAt?: string;
81
- /**
82
- * For paused/running workflows: the step key of the current step.
83
- * Aligns with Workflow Diagram DSL step state ids (see awaitly/workflow diagram-dsl)
84
- * so visualizers can highlight the current node.
85
- */
86
- currentStepId?: string;
87
- };
88
- /** Optional metadata for workflow identification and replay */
89
- metadata?: {
90
- /** Detect wrong snapshot for wrong workflow */
91
- workflowId?: string;
92
- /** Optional: detect definition changes (user-supplied, advisory only) */
93
- definitionHash?: string;
94
- /** Original input for replay */
95
- input?: JSONValue;
96
- [key: string]: JSONValue | undefined;
97
- };
98
- /** Warnings for lossy serialization (keeps step results pure) */
99
- warnings?: Array<{
100
- type: "lossy_value";
101
- stepId: string;
102
- path: string;
103
- reason: "non-json" | "circular" | "encode-failed";
104
- }>;
105
- }
106
- /**
107
- * Warning entry for lossy value serialization.
108
- */
109
- type SnapshotWarning = NonNullable<WorkflowSnapshot["warnings"]>[number];
110
- /**
111
- * Error thrown when snapshot structure is invalid.
112
- */
113
- declare class SnapshotFormatError extends Error {
114
- readonly errors: string[];
115
- constructor(message: string, errors?: string[]);
116
- }
117
- /**
118
- * Error thrown when snapshot doesn't match workflow (unknown steps, workflowId mismatch).
119
- */
120
- declare class SnapshotMismatchError extends Error {
121
- readonly mismatchType: "unknown_steps" | "workflow_id" | "definition_hash";
122
- readonly details?: {
123
- unknownSteps?: string[];
124
- snapshotWorkflowId?: string;
125
- expectedWorkflowId?: string;
126
- snapshotHash?: string;
127
- expectedHash?: string;
128
- } | undefined;
129
- constructor(message: string, mismatchType: "unknown_steps" | "workflow_id" | "definition_hash", details?: {
130
- unknownSteps?: string[];
131
- snapshotWorkflowId?: string;
132
- expectedWorkflowId?: string;
133
- snapshotHash?: string;
134
- expectedHash?: string;
135
- } | undefined);
136
- }
137
- /**
138
- * Error thrown when decode fails during restore.
139
- */
140
- declare class SnapshotDecodeError extends Error {
141
- readonly stepId: string;
142
- readonly originalError?: unknown | undefined;
143
- constructor(message: string, stepId: string, originalError?: unknown | undefined);
144
- }
145
- /**
146
- * Light check to see if an object looks like a WorkflowSnapshot.
147
- * Cheap check for basic structure - use validateSnapshot() for full validation.
148
- *
149
- * @example
150
- * ```typescript
151
- * const raw = JSON.parse(localStorage.getItem('wf-123') || 'null');
152
- * if (looksLikeWorkflowSnapshot(raw)) {
153
- * createWorkflow(deps, { snapshot: raw });
154
- * }
155
- * ```
156
- */
157
- declare function looksLikeWorkflowSnapshot(obj: unknown): obj is WorkflowSnapshot;
158
- /**
159
- * Type guard for WorkflowSnapshot. Same as looksLikeWorkflowSnapshot; use for consistent naming with isResumeState / isSerializedResumeState.
160
- */
161
- declare const isWorkflowSnapshot: typeof looksLikeWorkflowSnapshot;
162
- /**
163
- * Full validation with detailed errors.
164
- * Returns either a validated snapshot or an array of validation errors.
165
- */
166
- declare function validateSnapshot(obj: unknown): {
167
- valid: true;
168
- snapshot: WorkflowSnapshot;
169
- } | {
170
- valid: false;
171
- errors: string[];
172
- };
173
- /**
174
- * Throwing helper for cleaner code.
175
- * Validates a snapshot and throws SnapshotFormatError if invalid.
176
- *
177
- * @throws {SnapshotFormatError} If snapshot is invalid
178
- */
179
- declare function assertValidSnapshot(obj: unknown): WorkflowSnapshot;
180
- /**
181
- * Merge two snapshots (for incremental updates).
182
- * Delta steps overwrite base steps; execution from delta; metadata shallow merge.
183
- */
184
- declare function mergeSnapshots(base: WorkflowSnapshot, delta: WorkflowSnapshot): WorkflowSnapshot;
185
- /**
186
- * Serialize an Error object to SerializedCause format.
187
- * Preserves Error.cause recursively.
188
- */
189
- declare function serializeError(error: Error): SerializedCause;
190
- /**
191
- * Serialize a non-Error thrown value to SerializedCause format.
192
- */
193
- declare function serializeThrown(value: unknown): SerializedCause;
194
- /**
195
- * Deserialize a SerializedCause back to its original form.
196
- */
197
- declare function deserializeCauseNew(serialized: SerializedCause): unknown;
198
- /**
199
- * Simplified store interface for workflow snapshot persistence.
200
- * Works directly with WorkflowSnapshot objects.
201
- *
202
- * Adapters may implement an extended contract (see awaitly/workflow): save can accept
203
- * WorkflowSnapshot | ResumeState; load can return WorkflowSnapshot | ResumeState | null.
204
- * Use isWorkflowSnapshot / isSerializedResumeState and serializeResumeState / deserializeResumeState
205
- * when branching. For type-safe restore, use store.loadResumeState(id) or toResumeState(await store.load(id)).
206
- *
207
- * @example
208
- * ```typescript
209
- * import { postgres } from 'awaitly-postgres';
210
- * import { createWorkflow } from 'awaitly/workflow';
211
- *
212
- * const store = postgres('postgresql://localhost/mydb');
213
- * const workflow = createWorkflow(deps);
214
- *
215
- * // Run and persist resume state
216
- * const { result, resumeState } = await workflow.runWithState(fn);
217
- * await store.save('wf-123', resumeState);
218
- *
219
- * // Restore
220
- * const loaded = await store.load('wf-123');
221
- * const resumeState = toResumeState(loaded);
222
- * if (resumeState) await workflow.run(fn, { resumeState });
223
- * ```
224
- */
225
- interface SnapshotStore {
226
- /** Save a workflow snapshot (upsert - insert or update). Adapters may also accept ResumeState. */
227
- save(id: string, snapshot: WorkflowSnapshot): Promise<void>;
228
- /** Load a workflow snapshot. Returns null if not found. Adapters may return ResumeState when stored as such. */
229
- load(id: string): Promise<WorkflowSnapshot | null>;
230
- /** Delete a workflow snapshot. */
231
- delete(id: string): Promise<void>;
232
- /** List workflow IDs with their last update time. */
233
- list(options?: {
234
- prefix?: string;
235
- limit?: number;
236
- }): Promise<Array<{
237
- id: string;
238
- updatedAt: string;
239
- }>>;
240
- /** Clean shutdown for tests/graceful exit. */
241
- close(): Promise<void>;
242
- }
243
- /**
244
- * Options for the in-memory cache adapter.
245
- */
246
- interface MemoryCacheOptions {
247
- /**
248
- * Maximum number of entries to store.
249
- * Oldest entries are evicted when limit is reached.
250
- */
251
- maxSize?: number;
252
- /**
253
- * Time-to-live in milliseconds.
254
- * Entries are automatically removed after this duration.
255
- */
256
- ttl?: number;
257
- }
258
- /**
259
- * Create an in-memory StepCache with optional LRU eviction and TTL.
260
- *
261
- * @param options - Cache options
262
- * @returns StepCache implementation
263
- *
264
- * @example
265
- * ```typescript
266
- * const cache = createMemoryCache({ maxSize: 1000, ttl: 60000 });
267
- * const workflow = createWorkflow(deps, { cache });
268
- * ```
269
- */
270
- declare function createMemoryCache(options?: MemoryCacheOptions): StepCache;
271
-
272
- /**
273
- * Workflow type definitions.
274
- * Pure types and interfaces; no runtime code.
275
- */
276
-
277
- /**
278
- * Interface for step result caching.
279
- * Implement this interface to provide custom caching strategies.
280
- * A simple Map<string, Result> works for in-memory caching.
281
- *
282
- * ## When Cache is Populated
283
- *
284
- * The cache `set()` method is called after each step completes (success or error)
285
- * when the step has a `key` option. Both calling patterns work identically:
286
- *
287
- * ```typescript
288
- * // Function-wrapped pattern - cache is populated
289
- * await step(() => fetchUser("1"), { key: "user:1" });
290
- *
291
- * // Direct AsyncResult pattern - cache is also populated
292
- * await step(fetchUser("1"), { key: "user:1" });
293
- * ```
294
- *
295
- * Note: Cache stores Result<unknown, unknown, unknown> because different steps
296
- * have different value/error/cause types. The actual runtime values are preserved;
297
- * only the static types are widened. For error results, the cause value is encoded
298
- * in CachedErrorCause to preserve metadata for proper replay.
299
- *
300
- * @example
301
- * // Simple in-memory cache
302
- * const cache = new Map<string, Result<unknown, unknown, unknown>>();
303
- *
304
- * // Or implement custom cache with TTL, LRU, etc.
305
- * const cache: StepCache = {
306
- * get: (key) => myCache.get(key),
307
- * set: (key, result) => myCache.set(key, result, { ttl: 60000 }),
308
- * has: (key) => myCache.has(key),
309
- * delete: (key) => myCache.delete(key),
310
- * clear: () => myCache.clear(),
311
- * };
312
- */
313
- interface StepCache {
314
- get(key: string): Result<unknown, unknown, unknown> | undefined;
315
- set(key: string, result: Result<unknown, unknown, unknown>, options?: {
316
- ttl?: number;
317
- }): void;
318
- has(key: string): boolean;
319
- delete(key: string): boolean;
320
- clear(): void;
321
- }
322
- /**
323
- * Entry for a saved step result with optional metadata.
324
- * The meta field preserves origin information for proper replay.
325
- */
326
- interface ResumeStateEntry {
327
- result: Result<unknown, unknown, unknown>;
328
- /** Optional metadata for error origin (from step_complete event) */
329
- meta?: StepFailureMeta;
330
- }
331
- /**
332
- * Resume state for workflow replay.
333
- * Pre-populate step results to skip execution on resume.
334
- *
335
- * Note: When saving to persistent storage, you may need custom serialization
336
- * for complex cause types. JSON.stringify works for simple values, but Error
337
- * objects and other non-plain types require special handling.
338
- *
339
- * @example
340
- * // Collect from step_complete events using the helper
341
- * const collector = createResumeStateCollector();
342
- * const workflow = createWorkflow({ fetchUser }, {
343
- * onEvent: collector.handleEvent,
344
- * });
345
- * // Later: collector.getResumeState() returns ResumeState
346
- *
347
- * @example
348
- * // Resume with saved state
349
- * const workflow = createWorkflow({ fetchUser }, {
350
- * resumeState: { steps: savedSteps }
351
- * });
352
- */
353
- interface ResumeState {
354
- /** Map of step keys to their cached results with optional metadata */
355
- steps: Map<string, ResumeStateEntry>;
356
- }
357
- /**
358
- * Constraint for Result-returning functions
359
- * Used by createWorkflow to ensure only valid functions are passed
360
- */
361
- type AnyResultFn = (...args: any[]) => Result<any, any, any> | Promise<Result<any, any, any>>;
362
- /**
363
- * Extract union of error types from a deps object
364
- * Example: ErrorsOfDeps<{ fetchUser: typeof fetchUser, fetchPosts: typeof fetchPosts }>
365
- * yields: 'NOT_FOUND' | 'FETCH_ERROR'
366
- */
367
- type ErrorsOfDeps<Deps extends Record<string, AnyResultFn>> = {
368
- [K in keyof Deps]: ErrorOf<Deps[K]>;
369
- }[keyof Deps];
370
- /**
371
- * Extract union of cause types from a deps object.
372
- * Example: CausesOfDeps<{ fetchUser: typeof fetchUser }> where fetchUser returns Result<User, "NOT_FOUND", Error>
373
- * yields: Error
374
- *
375
- * Note: This represents the domain cause types from declared functions.
376
- * However, workflow results may also have unknown causes from step.try failures
377
- * or uncaught exceptions, so the actual Result cause type is `unknown`.
378
- */
379
- type CausesOfDeps<Deps extends Record<string, AnyResultFn>> = CauseOf<Deps[keyof Deps]>;
380
- /**
381
- * Execution-time options that can override creation-time options.
382
- * Pass these to `workflow.run(fn, execOptions)` for per-run configuration.
383
- *
384
- * Rule: Use `workflow(...)` for normal runs. Use `workflow.run(...)` when you need per-run hooks/options.
385
- *
386
- * @example
387
- * ```typescript
388
- * const workflow = createWorkflow(deps, { cache, onEvent: defaultHandler });
389
- *
390
- * // Normal run uses creation-time options
391
- * await workflow(async ({ step }) => { ... });
392
- *
393
- * // Per-run options override creation-time options
394
- * await workflow.run(async ({ step }) => { ... }, { onEvent: viz.handleEvent });
395
- *
396
- * // Pre-bind defaults with .with() (overridable by .run())
397
- * const visualized = workflow.with({ onEvent: viz.handleEvent });
398
- * await visualized(async ({ step }) => { ... });
399
- * ```
400
- */
401
- type ExecutionOptions<E, U = UnexpectedError, C = void> = {
402
- /**
403
- * Event handler for workflow and step lifecycle events.
404
- * Overrides `onEvent` from creation-time options.
405
- */
406
- onEvent?: (event: WorkflowEvent<E | U, C>, ctx: C) => void;
407
- /**
408
- * Error handler called when a step fails.
409
- * Overrides `onError` from creation-time options.
410
- */
411
- onError?: (error: E | U, stepName?: string, ctx?: C) => void;
412
- /**
413
- * AbortSignal for workflow-level cancellation.
414
- * Overrides `signal` from creation-time options.
415
- */
416
- signal?: AbortSignal;
417
- /**
418
- * Factory to create per-run context. Can be async.
419
- * Overrides `createContext` from creation-time options.
420
- */
421
- createContext?: () => C | Promise<C>;
422
- /**
423
- * Resume state for workflow replay. Can be a factory function (sync or async).
424
- * Overrides `resumeState` from creation-time options.
425
- */
426
- resumeState?: ResumeState | (() => ResumeState | Promise<ResumeState>);
427
- /**
428
- * Hook to check if workflow should run (concurrency control).
429
- * Overrides `shouldRun` from creation-time options.
430
- */
431
- shouldRun?: (workflowId: string, context: C) => boolean | Promise<boolean>;
432
- /**
433
- * Hook called before workflow execution starts.
434
- * Overrides `onBeforeStart` from creation-time options.
435
- */
436
- onBeforeStart?: (workflowId: string, context: C) => boolean | Promise<boolean>;
437
- /**
438
- * Hook called after each step completes (only for steps with a `key`).
439
- * Overrides `onAfterStep` from creation-time options.
440
- */
441
- onAfterStep?: (stepKey: string, result: Result<unknown, unknown, unknown>, workflowId: string, context: C) => void | Promise<void>;
442
- /**
443
- * Enable strict mode for this specific run (analyzer validation only).
444
- */
445
- strict?: boolean;
446
- /**
447
- * Enable development warnings for this run.
448
- * Only active when NODE_ENV !== 'production'.
449
- */
450
- devWarnings?: boolean;
451
- };
452
- /**
453
- * Per-run configuration. Extends ExecutionOptions with dep overrides.
454
- * Pass to `workflow.run(fn, config)` or `workflow.run(name, fn, config)`.
455
- */
456
- type RunConfig<E, U = UnexpectedError, C = void, Deps = unknown> = ExecutionOptions<E, U, C> & {
457
- /** Override creation-time deps (partial merge). */
458
- deps?: Partial<Deps>;
459
- /** Step result cache for this run. */
460
- cache?: StepCache;
461
- /** Restore workflow from a previously saved snapshot. */
462
- snapshot?: WorkflowSnapshot | null;
463
- /** Stream store for this run. */
464
- streamStore?: StreamStore;
465
- };
466
- /**
467
- * Workflow options. Error union is always closed: E | U.
468
- * When catchUnexpected is omitted, U defaults to UnexpectedError.
469
- */
470
- type WorkflowOptions<E, U = UnexpectedError, C = void, Errs extends readonly string[] = readonly string[]> = {
471
- /** Standard Schema for input validation. Works with Zod, Valibot, ArkType, etc. */
472
- inputSchema?: StandardSchemaV1;
473
- /** Input data to validate against inputSchema and pass to workflow context. */
474
- input?: unknown;
475
- /** Short description for labels/tooltips (static analysis) */
476
- description?: string;
477
- /** Full markdown documentation (static analysis) */
478
- markdown?: string;
479
- /**
480
- * Map uncaught exceptions (and cancellation) to your error type U.
481
- * When omitted, U = UnexpectedError and the default mapper returns an UnexpectedError instance.
482
- */
483
- catchUnexpected?: (cause: unknown) => U;
484
- /**
485
- * Declared errors for the workflow (strict validation).
486
- * When provided, the analyzer validates that computed errors match declared errors.
487
- */
488
- errors?: Errs;
489
- onError?: (error: E | U, stepName?: string, ctx?: C) => void;
490
- /**
491
- * Unified event stream for workflow and step lifecycle.
492
- *
493
- * Context is automatically included in `event.context` when provided via `createContext`.
494
- * The separate `ctx` parameter is provided for convenience.
495
- */
496
- onEvent?: (event: WorkflowEvent<E | U, C>, ctx: C) => void;
497
- /** Create per-run context for event correlation */
498
- createContext?: () => C;
499
- /** Step result cache - only steps with a `key` option are cached */
500
- cache?: StepCache;
501
- /** Pre-populate cache from saved state for workflow resume. Prefer `snapshot` option. */
502
- resumeState?: ResumeState | (() => ResumeState | Promise<ResumeState>);
503
- /**
504
- * Restore workflow from a previously saved snapshot.
505
- * Pass `null` for fresh start (e.g., when store.load() returns nothing).
506
- */
507
- snapshot?: WorkflowSnapshot | null;
508
- /**
509
- * Custom serialization for encoding/decoding values during snapshot operations.
510
- */
511
- serialization?: {
512
- encode?: (value: unknown) => JSONValue;
513
- decode?: (value: JSONValue) => unknown;
514
- };
515
- snapshotSerialization?: {
516
- strict?: boolean;
517
- };
518
- onUnknownSteps?: "warn" | "error" | "ignore";
519
- onDefinitionChange?: "warn" | "error" | "ignore";
520
- /**
521
- * External AbortSignal for workflow-level cancellation.
522
- * Cancellation is mapped through catchUnexpected (default: UnexpectedError with cause.thrown = WorkflowCancelledError).
523
- */
524
- signal?: AbortSignal;
525
- onBeforeStart?: (workflowId: string, context: C) => boolean | Promise<boolean>;
526
- onAfterStep?: (stepKey: string, result: Result<unknown, unknown, unknown>, workflowId: string, context: C) => void | Promise<void>;
527
- shouldRun?: (workflowId: string, context: C) => boolean | Promise<boolean>;
528
- streamStore?: StreamStore;
529
- /**
530
- * Enable development warnings.
531
- * Only active when NODE_ENV !== 'production'.
532
- */
533
- devWarnings?: boolean;
534
- };
535
- /**
536
- * Workflow context provided to callbacks, containing workflow metadata
537
- * and data store for step outputs.
538
- * This allows conditional helpers and other utilities to access workflowId, onEvent, and context.
539
- */
540
- type WorkflowContext<C = void, Input = Record<string, unknown>, Data = Record<string, unknown>> = {
541
- /**
542
- * Unique ID for this workflow run.
543
- */
544
- workflowId: string;
545
- /**
546
- * Event emitter function for workflow events.
547
- * Can be used with conditional helpers to emit step_skipped events.
548
- */
549
- onEvent?: (event: WorkflowEvent<unknown, C>) => void;
550
- /**
551
- * Per-run context created by createContext (or undefined if not provided).
552
- * Automatically included in all workflow events.
553
- */
554
- context?: C;
555
- /**
556
- * Workflow-level AbortSignal (if provided in workflow options).
557
- * Use this to check cancellation or pass to operations that support AbortSignal.
558
- *
559
- * @example
560
- * ```typescript
561
- * const result = await workflow(async ({ step, deps, ctx }) => {
562
- * // Pass signal to fetch
563
- * const response = await fetch(url, { signal: ctx.signal });
564
- * // Or check manually
565
- * if (ctx.signal?.aborted) return early();
566
- * });
567
- * ```
568
- */
569
- signal?: AbortSignal;
570
- /**
571
- * Input data passed to the workflow.
572
- * Access via `ctx.input.key` for static analysis tracking.
573
- *
574
- * @example
575
- * ```typescript
576
- * await step('getCart', () => getCart(ctx.input.cartId), {
577
- * errors: ['CART_NOT_FOUND'],
578
- * });
579
- * ```
580
- */
581
- input: Input;
582
- /**
583
- * Get a value from the workflow data store by key.
584
- * Preferred over `ctx.get()` for static analysis as it's easier to trace.
585
- *
586
- * @param key - The key to retrieve
587
- * @returns The value at that key
588
- *
589
- * @example
590
- * ```typescript
591
- * // Use ctx.ref() inside step callbacks for tracked dependencies
592
- * await step('charge', () => chargeCard(ctx.ref('cart').total), {
593
- * errors: ['CARD_DECLINED'],
594
- * });
595
- * ```
596
- */
597
- ref: <K extends keyof Data>(key: K) => Data[K];
598
- /**
599
- * Set a value in the workflow data store.
600
- * Prefer using `out` option on steps instead for better static analysis.
601
- *
602
- * @param key - The key to set
603
- * @param value - The value to store
604
- *
605
- * @example
606
- * ```typescript
607
- * // Prefer out option:
608
- * await step('getCart', () => getCart(id), { out: 'cart' });
609
- *
610
- * // Escape hatch (less analyzable):
611
- * const cart = await step('getCart', () => getCart(id));
612
- * ctx.set('cart', cart);
613
- * ```
614
- */
615
- set: <K extends string>(key: K, value: unknown) => void;
616
- /**
617
- * Get a value from the workflow data store.
618
- * Prefer `ctx.ref()` for better static analysis.
619
- *
620
- * @param key - The key to retrieve
621
- * @returns The value at that key (or undefined)
622
- */
623
- get: <K extends keyof Data>(key: K) => Data[K] | undefined;
624
- };
625
- /**
626
- * Bound steps for a workflow's deps: each dep key becomes a step function
627
- * with the dep's arguments that unwraps ok / early-exits on err — same as
628
- * the deps-first run(deps, fn) form. `never` deps (no deps) yield no steps.
629
- */
630
- type WorkflowSteps<Deps> = [Deps] extends [
631
- Record<string, (...args: never[]) => unknown>
632
- ] ? BoundSteps<Deps> : Record<string, never>;
633
- /** Workflow function type (no args). E is the full step error union (deps errors + any ExtraE from step.workflow/withFallback). */
634
- type WorkflowFn<T, E, Deps, C = void> = (context: {
635
- step: RunStep<E>;
636
- steps: WorkflowSteps<Deps>;
637
- deps: Deps;
638
- ctx: WorkflowContext<C>;
639
- }) => T | Promise<T>;
640
- /**
641
- * Return type of runWithState: result plus resume state for persistence.
642
- * resumeState is always present, even when the run fails or returns an error Result.
643
- */
644
- type RunWithStateResult<T, E, U> = {
645
- result: Result<T, E | U, unknown>;
646
- resumeState: ResumeState;
647
- };
648
- /**
649
- * Workflow return type. Error union is always closed: E | ExtraE | U (default U = UnexpectedError).
650
- * ExtraE is inferred from the callback when using step.workflow or step.withFallback with errors not in deps.
651
- * Methods: .run() (4 overloads) and .runWithState() (4 overloads) for run-and-persist flows.
652
- *
653
- * Cause type is `unknown` because step.try/catchUnexpected receive thrown values.
654
- */
655
- interface Workflow<E, U = UnexpectedError, Deps = unknown, C = void> {
656
- /**
657
- * Pre-bind dependency overrides and return another `Workflow`.
658
- * Chain `.withDeps()` and call `.run()` / `.runWithState()` as normal.
659
- * Precedence: createWorkflow deps < withDeps deps < run config deps.
660
- */
661
- withDeps(overrides: Partial<Deps>): Workflow<E, U, Deps, C>;
662
- /**
663
- * Execute workflow (anonymous run).
664
- * ExtraE is inferred from the callback (e.g. from step.workflow / step.withFallback); result is Result<T, E | ExtraE | U>.
665
- * T is inferred from the callback return type. For nested workflows (calling another workflow.run() inside the callback),
666
- * inference can sometimes fall back to `any`; adding an explicit return type to the callback (e.g.
667
- * `async (ctx): Promise<{ user: User; enriched: Enriched }> => { ... }`) gives the compiler a target and preserves types.
668
- */
669
- run<T, ExtraE = never>(fn: WorkflowFn<T, E | ExtraE, Deps, C>): AsyncResult<T, E | ExtraE | U, unknown>;
670
- /**
671
- * Execute workflow with config overrides.
672
- */
673
- run<T, ExtraE = never>(fn: WorkflowFn<T, E | ExtraE, Deps, C>, config: RunConfig<E, U, C, Deps>): AsyncResult<T, E | ExtraE | U, unknown>;
674
- /**
675
- * Execute named workflow run (for logging, tracing, resume).
676
- */
677
- run<T, ExtraE = never>(name: string, fn: WorkflowFn<T, E | ExtraE, Deps, C>): AsyncResult<T, E | ExtraE | U, unknown>;
678
- /**
679
- * Execute named workflow run with config overrides.
680
- */
681
- run<T, ExtraE = never>(name: string, fn: WorkflowFn<T, E | ExtraE, Deps, C>, config: RunConfig<E, U, C, Deps>): AsyncResult<T, E | ExtraE | U, unknown>;
682
- /**
683
- * Execute workflow and return result plus resume state for persistence.
684
- * resumeState is always present (even on failure) so callers can persist partial state.
685
- * Same overloads as run(); does not throw — follows the same "never throw, always Result" contract as run().
686
- *
687
- * @example
688
- * const { result, resumeState } = await workflow.runWithState(fn);
689
- * await store.save(id, resumeState);
690
- */
691
- runWithState<T, ExtraE = never>(fn: WorkflowFn<T, E | ExtraE, Deps, C>): Promise<RunWithStateResult<T, E | ExtraE, U>>;
692
- /**
693
- * Execute workflow with config overrides and return result plus resume state.
694
- */
695
- runWithState<T, ExtraE = never>(fn: WorkflowFn<T, E | ExtraE, Deps, C>, config: RunConfig<E, U, C, Deps>): Promise<RunWithStateResult<T, E | ExtraE, U>>;
696
- /**
697
- * Execute named workflow run and return result plus resume state.
698
- */
699
- runWithState<T, ExtraE = never>(name: string, fn: WorkflowFn<T, E | ExtraE, Deps, C>): Promise<RunWithStateResult<T, E | ExtraE, U>>;
700
- /**
701
- * Execute named workflow run with config overrides and return result plus resume state.
702
- */
703
- runWithState<T, ExtraE = never>(name: string, fn: WorkflowFn<T, E | ExtraE, Deps, C>, config: RunConfig<E, U, C, Deps>): Promise<RunWithStateResult<T, E | ExtraE, U>>;
704
- }
705
- /**
706
- * Error returned when a workflow is cancelled via AbortSignal.
707
- *
708
- * @example
709
- * ```typescript
710
- * const controller = new AbortController();
711
- * const workflow = createWorkflow(deps, { signal: controller.signal });
712
- *
713
- * // Later:
714
- * controller.abort('User navigated away');
715
- *
716
- * const result = await workflowPromise;
717
- * if (!result.ok && isWorkflowCancelled(result.error)) {
718
- * console.log('Cancelled:', result.error.reason);
719
- * }
720
- * ```
721
- */
722
- type WorkflowCancelledError = {
723
- type: "WORKFLOW_CANCELLED";
724
- /** Reason from AbortSignal.reason (if provided) */
725
- reason?: string;
726
- /** Last successfully completed keyed step (for resume purposes) */
727
- lastStepKey?: string;
728
- };
729
- /**
730
- * Standard error type for steps awaiting human approval.
731
- * Use this as the error type for approval-gated steps.
732
- *
733
- * @example
734
- * const requireApproval = async (userId: string): AsyncResult<Approval, PendingApproval> => {
735
- * const status = await checkApprovalStatus(userId);
736
- * if (status === 'pending') {
737
- * return err({ type: 'PENDING_APPROVAL', stepKey: `approval:${userId}` });
738
- * }
739
- * return ok(status.approval);
740
- * };
741
- */
742
- type PendingApproval = {
743
- type: "PENDING_APPROVAL";
744
- /** Step key for correlation when resuming */
745
- stepKey: string;
746
- /** Optional reason for the pending state */
747
- reason?: string;
748
- /** Optional metadata for the approval request */
749
- metadata?: Record<string, unknown>;
750
- };
751
- /**
752
- * Standard error type for steps awaiting an HTTP callback (webhook).
753
- * Use with injectHook() to resume when the app receives the callback.
754
- * stepKey is always "hook:" + hookId for resume state.
755
- */
756
- type PendingHook = {
757
- type: "PENDING_HOOK";
758
- hookId: string;
759
- /** Step key used in resume state; always "hook:" + hookId */
760
- stepKey: string;
761
- metadata?: Record<string, unknown>;
762
- };
763
- /**
764
- * Error returned when approval is rejected.
765
- */
766
- type ApprovalRejected = {
767
- type: "APPROVAL_REJECTED";
768
- /** Step key for correlation */
769
- stepKey: string;
770
- /** Reason the approval was rejected */
771
- reason: string;
772
- };
773
- /**
774
- * Options for creating an approval-gated step.
775
- */
776
- interface ApprovalStepOptions<T> {
777
- /** Stable key for this approval step (used for resume) */
778
- key: string;
779
- /** Function to check current approval status from external source */
780
- checkApproval: () => Promise<{
781
- status: "pending";
782
- } | {
783
- status: "approved";
784
- value: T;
785
- } | {
786
- status: "rejected";
787
- reason: string;
788
- }>;
789
- /** Optional reason shown when pending */
790
- pendingReason?: string;
791
- /** Optional metadata for the approval request */
792
- metadata?: Record<string, unknown>;
793
- }
794
- /**
795
- * Options for creating a gated (pre-approval) step.
796
- */
797
- interface GatedStepOptions<TArgs, T> {
798
- /** Stable key for this gated step (used for approval tracking) */
799
- key: string;
800
- /**
801
- * Condition to check if approval is required.
802
- * If returns true, execution pauses for approval.
803
- * If returns false, operation executes immediately.
804
- */
805
- requiresApproval: boolean | ((args: TArgs) => boolean | Promise<boolean>);
806
- /**
807
- * Human-readable description of what this operation does.
808
- * Shown in the approval UI so humans understand what they're approving.
809
- */
810
- description: string | ((args: TArgs) => string);
811
- /**
812
- * Check if approval has been granted externally.
813
- * If not provided, the step always returns PendingApproval when gated.
814
- */
815
- checkApproval?: () => Promise<{
816
- status: "pending";
817
- } | {
818
- status: "approved";
819
- value?: T;
820
- } | {
821
- status: "rejected";
822
- reason: string;
823
- }>;
824
- /**
825
- * Optional metadata to include in the approval request.
826
- * The args are automatically included as `pendingArgs`.
827
- */
828
- metadata?: Record<string, unknown>;
829
- }
830
-
831
- export { type AnyResultFn as A, deserializeCauseNew as B, type CausesOfDeps as C, serializeError as D, type ErrorsOfDeps as E, serializeThrown as F, type GatedStepOptions as G, type JSONValue as J, type MemoryCacheOptions as M, type PendingApproval as P, type ResumeState as R, type SnapshotStore as S, type WorkflowCancelledError as W, type WorkflowSnapshot as a, type WorkflowContext as b, type Workflow as c, type ApprovalRejected as d, type ApprovalStepOptions as e, type PendingHook as f, type StepResult as g, type WorkflowOptions as h, type ExecutionOptions as i, type ResumeStateEntry as j, type RunConfig as k, type RunWithStateResult as l, type SerializedCause as m, SnapshotDecodeError as n, SnapshotFormatError as o, SnapshotMismatchError as p, type SnapshotWarning as q, type StepCache as r, type WorkflowFn as s, type WorkflowSteps as t, assertValidSnapshot as u, isWorkflowSnapshot as v, looksLikeWorkflowSnapshot as w, mergeSnapshots as x, validateSnapshot as y, createMemoryCache as z };