awaitly 1.34.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 +35 -5
  14. package/dist/result.d.ts +35 -5
  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-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
  24. package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
  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 +13 -178
  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-COl5oFnR.d.cts +0 -15
  75. package/dist/di-CyDj_JyZ.d.ts +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-BodHXLzX.d.cts +0 -72
  123. package/dist/guards-CeWoQ8fn.d.ts +0 -72
  124. package/dist/hitl-BPE_1UiM.d.cts +0 -468
  125. package/dist/hitl-byp570uC.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-BYT3amEz.d.ts +0 -417
  133. package/dist/index-C_ak66jy.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-DOMx3woy.d.ts +0 -822
  149. package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
  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-DQmzO9f4.d.ts +0 -323
  235. package/dist/types-qBUOYi-4.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,72 +0,0 @@
1
- import { ag as WorkflowEvent } from './run-entry-D2MmJFj9.cjs';
2
- import { A as ApprovalRejected, P as PendingApproval, c as PendingHook, R as ResumeState, W as WorkflowCancelledError } from './persistence-entry-ymCA4iDu.cjs';
3
-
4
- /**
5
- * Type guards for workflow events and errors.
6
- */
7
-
8
- /**
9
- * Type guard to check if an event is a step_complete event.
10
- * Use this to filter events for state persistence.
11
- *
12
- * @param event - The workflow event to check
13
- * @returns `true` if the event is a step_complete event, `false` otherwise
14
- *
15
- * @example
16
- * ```typescript
17
- * const savedSteps = new Map<string, Result<unknown, unknown>>();
18
- *
19
- * const workflow = createWorkflow({ fetchUser }, {
20
- * onEvent: (event) => {
21
- * if (isStepComplete(event)) {
22
- * savedSteps.set(event.stepKey, event.result);
23
- * }
24
- * }
25
- * });
26
- * ```
27
- */
28
- /**
29
- * Type guard for runtime ResumeState (steps is a Map). Use to discriminate from WorkflowSnapshot when loading.
30
- */
31
- declare function isResumeState(x: unknown): x is ResumeState;
32
- declare function isStepComplete(event: WorkflowEvent<unknown>): event is Extract<WorkflowEvent<unknown>, {
33
- type: "step_complete";
34
- }>;
35
- /**
36
- * Type guard to check if an error is a WorkflowCancelledError.
37
- *
38
- * @param error - The error to check
39
- * @returns `true` if the error is a WorkflowCancelledError, `false` otherwise
40
- */
41
- declare function isWorkflowCancelled(error: unknown): error is WorkflowCancelledError;
42
- /**
43
- * Type guard to check if an error is a PendingApproval.
44
- *
45
- * @param error - The error to check
46
- * @returns `true` if the error is a PendingApproval, `false` otherwise
47
- *
48
- * @example
49
- * ```typescript
50
- * const result = await workflow(...);
51
- * if (!result.ok && isPendingApproval(result.error)) {
52
- * console.log(`Waiting for approval: ${result.error.stepKey}`);
53
- * }
54
- * ```
55
- */
56
- declare function isPendingApproval(error: unknown): error is PendingApproval;
57
- /**
58
- * Type guard to check if an error is an ApprovalRejected.
59
- *
60
- * @param error - The error to check
61
- * @returns `true` if the error is an ApprovalRejected, `false` otherwise
62
- */
63
- declare function isApprovalRejected(error: unknown): error is ApprovalRejected;
64
- /**
65
- * Type guard to check if an error is a PendingHook.
66
- *
67
- * @param error - The error to check
68
- * @returns `true` if the error is a PendingHook, `false` otherwise
69
- */
70
- declare function isPendingHook(error: unknown): error is PendingHook;
71
-
72
- export { isApprovalRejected as a, isPendingApproval as b, isPendingHook as c, isResumeState as d, isStepComplete as e, isWorkflowCancelled as i };
@@ -1,72 +0,0 @@
1
- import { ag as WorkflowEvent } from './run-entry-Dduz-is2.js';
2
- import { A as ApprovalRejected, P as PendingApproval, c as PendingHook, R as ResumeState, W as WorkflowCancelledError } from './persistence-entry-DOMx3woy.js';
3
-
4
- /**
5
- * Type guards for workflow events and errors.
6
- */
7
-
8
- /**
9
- * Type guard to check if an event is a step_complete event.
10
- * Use this to filter events for state persistence.
11
- *
12
- * @param event - The workflow event to check
13
- * @returns `true` if the event is a step_complete event, `false` otherwise
14
- *
15
- * @example
16
- * ```typescript
17
- * const savedSteps = new Map<string, Result<unknown, unknown>>();
18
- *
19
- * const workflow = createWorkflow({ fetchUser }, {
20
- * onEvent: (event) => {
21
- * if (isStepComplete(event)) {
22
- * savedSteps.set(event.stepKey, event.result);
23
- * }
24
- * }
25
- * });
26
- * ```
27
- */
28
- /**
29
- * Type guard for runtime ResumeState (steps is a Map). Use to discriminate from WorkflowSnapshot when loading.
30
- */
31
- declare function isResumeState(x: unknown): x is ResumeState;
32
- declare function isStepComplete(event: WorkflowEvent<unknown>): event is Extract<WorkflowEvent<unknown>, {
33
- type: "step_complete";
34
- }>;
35
- /**
36
- * Type guard to check if an error is a WorkflowCancelledError.
37
- *
38
- * @param error - The error to check
39
- * @returns `true` if the error is a WorkflowCancelledError, `false` otherwise
40
- */
41
- declare function isWorkflowCancelled(error: unknown): error is WorkflowCancelledError;
42
- /**
43
- * Type guard to check if an error is a PendingApproval.
44
- *
45
- * @param error - The error to check
46
- * @returns `true` if the error is a PendingApproval, `false` otherwise
47
- *
48
- * @example
49
- * ```typescript
50
- * const result = await workflow(...);
51
- * if (!result.ok && isPendingApproval(result.error)) {
52
- * console.log(`Waiting for approval: ${result.error.stepKey}`);
53
- * }
54
- * ```
55
- */
56
- declare function isPendingApproval(error: unknown): error is PendingApproval;
57
- /**
58
- * Type guard to check if an error is an ApprovalRejected.
59
- *
60
- * @param error - The error to check
61
- * @returns `true` if the error is an ApprovalRejected, `false` otherwise
62
- */
63
- declare function isApprovalRejected(error: unknown): error is ApprovalRejected;
64
- /**
65
- * Type guard to check if an error is a PendingHook.
66
- *
67
- * @param error - The error to check
68
- * @returns `true` if the error is a PendingHook, `false` otherwise
69
- */
70
- declare function isPendingHook(error: unknown): error is PendingHook;
71
-
72
- export { isApprovalRejected as a, isPendingApproval as b, isPendingHook as c, isResumeState as d, isStepComplete as e, isWorkflowCancelled as i };
@@ -1,468 +0,0 @@
1
- import { ag as WorkflowEvent, c as AsyncResult, d as Err } from './run-entry-D2MmJFj9.cjs';
2
- import { R as ResumeState, P as PendingApproval, b as ApprovalStepOptions, A as ApprovalRejected, G as GatedStepOptions } from './persistence-entry-ymCA4iDu.cjs';
3
-
4
- /**
5
- * Resume state helpers: collectors and state manipulation for workflow replay.
6
- */
7
-
8
- /**
9
- * Create a collector for step results to build resume state.
10
- *
11
- * ## When to Use
12
- *
13
- * Use `createResumeStateCollector` when you need to:
14
- * - **Save workflow state** for later replay/resume
15
- * - **Persist step results** to a database or file system
16
- * - **Build resume state** from workflow execution
17
- * - **Enable workflow replay** after application restarts
18
- *
19
- * ## Why Use This Instead of Manual Collection
20
- *
21
- * - **Automatic filtering**: Only collects `step_complete` events (ignores other events)
22
- * - **Metadata preservation**: Captures both result and meta for proper error replay
23
- * - **Type-safe**: Returns properly typed `ResumeState`
24
- * - **Convenient API**: Simple `handleEvent` → `getResumeState` pattern
25
- *
26
- * ## How It Works
27
- *
28
- * 1. Create collector and pass `handleEvent` to workflow's `onEvent` option
29
- * 2. Workflow emits `step_complete` events for keyed steps
30
- * 3. Collector automatically captures these events
31
- * 4. Call `getResumeState()` to get the collected `ResumeState`
32
- * 5. Persist state (e.g., to database) for later resume
33
- *
34
- * ## When step_complete Events Are Emitted
35
- *
36
- * Events are emitted for ANY step that has a `key` option, regardless of calling pattern:
37
- *
38
- * ```typescript
39
- * // Function-wrapped pattern - emits step_complete
40
- * await step(() => fetchUser("1"), { key: "user:1" });
41
- *
42
- * // Direct AsyncResult pattern - also emits step_complete
43
- * await step(fetchUser("1"), { key: "user:1" });
44
- * ```
45
- *
46
- * Both patterns above will emit `step_complete` events and be captured by the collector.
47
- *
48
- * ## Important Notes
49
- *
50
- * - Only steps with a `key` option are collected (unkeyed steps are not saved)
51
- * - The collector preserves error metadata for proper replay behavior
52
- * - State can be serialized to JSON (but complex cause types may need custom handling)
53
- *
54
- * @returns An object with:
55
- * - `handleEvent`: Function to pass to workflow's `onEvent` option
56
- * - `getResumeState`: Get collected resume state (call after workflow execution)
57
- * - `clear`: Clears the collector's internal recorded entries (does not mutate workflow state)
58
- *
59
- * @example
60
- * ```typescript
61
- * // Collect state during workflow execution
62
- * const collector = createResumeStateCollector();
63
- *
64
- * const workflow = createWorkflow({ fetchUser, fetchPosts }, {
65
- * onEvent: collector.handleEvent, // Pass collector's handler
66
- * });
67
- *
68
- * await workflow(async ({ step }) => {
69
- * // Only keyed steps are collected
70
- * const user = await step(() => fetchUser("1"), { key: "user:1" });
71
- * const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` });
72
- * return { user, posts };
73
- * });
74
- *
75
- * // Get collected state for persistence
76
- * const state = collector.getResumeState();
77
- * // state.steps contains: 'user:1' and 'posts:1' entries
78
- *
79
- * // Save to database
80
- * await db.saveWorkflowState(workflowId, state);
81
- * ```
82
- *
83
- * @example
84
- * ```typescript
85
- * // Resume workflow from saved state
86
- * const savedState = await db.loadWorkflowState(workflowId);
87
- * const workflow = createWorkflow({ fetchUser, fetchPosts }, {
88
- * resumeState: savedState // Pre-populate cache from saved state
89
- * });
90
- *
91
- * // Cached steps skip execution, new steps run normally
92
- * await workflow(async ({ step }) => {
93
- * const user = await step(() => fetchUser("1"), { key: "user:1" }); // Cache hit
94
- * const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` }); // Cache hit
95
- * return { user, posts };
96
- * });
97
- * ```
98
- */
99
- declare function createResumeStateCollector(): {
100
- /** Handle workflow events. Pass this to workflow's `onEvent` option. */
101
- handleEvent: (event: WorkflowEvent<unknown>) => void;
102
- /** Get the collected resume state. Call after workflow execution. */
103
- getResumeState: () => ResumeState;
104
- /** Clears the collector's internal recorded entries (does not mutate workflow state). */
105
- clear: () => void;
106
- };
107
- /**
108
- * Inject an approved value into resume state.
109
- * Use this when an external approval is granted and you want to resume the workflow.
110
- *
111
- * @param state - The resume state to update
112
- * @param options - Object with stepKey and the approved value
113
- * @returns A new ResumeState with the approval injected
114
- *
115
- * @example
116
- * ```typescript
117
- * // When approval is granted externally:
118
- * const updatedState = injectApproval(savedState, {
119
- * stepKey: 'deploy:prod',
120
- * value: { approvedBy: 'admin', approvedAt: Date.now() }
121
- * });
122
- *
123
- * // Resume workflow with the approval injected
124
- * const workflow = createWorkflow({ ... }, { resumeState: updatedState });
125
- * ```
126
- */
127
- declare function injectApproval<T>(state: ResumeState, options: {
128
- stepKey: string;
129
- value: T;
130
- }): ResumeState;
131
- /**
132
- * Remove a step from resume state (e.g., to force re-execution).
133
- * This is an immutable operation - returns a new ResumeState without modifying the original.
134
- *
135
- * @param state - The resume state to update
136
- * @param stepKey - The key of the step to remove
137
- * @returns A new ResumeState with the step removed (original is unchanged)
138
- *
139
- * @example
140
- * ```typescript
141
- * // Force a step to re-execute on resume
142
- * const updatedState = clearStep(savedState, 'approval:123');
143
- * ```
144
- */
145
- declare function clearStep(state: ResumeState, stepKey: string): ResumeState;
146
- /**
147
- * Check if a step in resume state has a pending approval error.
148
- *
149
- * @param state - The resume state to check
150
- * @param stepKey - The key of the step to check
151
- * @returns `true` if the step has a pending approval, `false` otherwise
152
- *
153
- * @example
154
- * ```typescript
155
- * if (hasPendingApproval(savedState, 'deploy:prod')) {
156
- * // Show approval UI
157
- * }
158
- * ```
159
- */
160
- declare function hasPendingApproval(state: ResumeState, stepKey: string): boolean;
161
- /**
162
- * Get all pending approval step keys from resume state.
163
- *
164
- * @param state - The resume state to check
165
- * @returns Array of step keys that have pending approvals
166
- *
167
- * @example
168
- * ```typescript
169
- * const pendingKeys = getPendingApprovals(savedState);
170
- * // ['deploy:prod', 'deploy:staging']
171
- * ```
172
- */
173
- declare function getPendingApprovals(state: ResumeState): string[];
174
- /**
175
- * Inject a hook callback value into resume state.
176
- * Call this when the app receives the HTTP callback (e.g. POST /hook/:hookId) and pass the request body as value.
177
- *
178
- * @param state - The resume state to update
179
- * @param options - hookId (from the callback URL) and value (e.g. request body)
180
- * @returns A new ResumeState with the hook step set to ok(value)
181
- */
182
- declare function injectHook<T>(state: ResumeState, options: {
183
- hookId: string;
184
- value: T;
185
- }): ResumeState;
186
- /**
187
- * Check if a step in resume state has a pending hook error.
188
- *
189
- * @param state - The resume state to check
190
- * @param hookId - The hook id (from createHook() or the callback URL)
191
- * @returns `true` if that hook step is pending, `false` otherwise
192
- */
193
- declare function hasPendingHook(state: ResumeState, hookId: string): boolean;
194
- /**
195
- * Get all pending hook hookIds from resume state.
196
- *
197
- * @param state - The resume state to check
198
- * @returns Array of hookIds that have pending callbacks
199
- */
200
- declare function getPendingHooks(state: ResumeState): string[];
201
- /**
202
- * Extended resume state collector that tracks pending approvals.
203
- * Use this for human-in-the-loop workflows that need to track approval state.
204
- *
205
- * @returns An object with methods to handle events, get state, and manage approvals
206
- *
207
- * @example
208
- * ```typescript
209
- * const collector = createApprovalStateCollector();
210
- *
211
- * const workflow = createWorkflow({ fetchUser, requireApproval }, {
212
- * onEvent: collector.handleEvent,
213
- * });
214
- *
215
- * const result = await workflow(async ({ step }) => {
216
- * const user = await step(() => fetchUser("1"), { key: "user:1" });
217
- * const approval = await step(requireApproval, { key: "approval:1" });
218
- * return { user, approval };
219
- * });
220
- *
221
- * // Check for pending approvals
222
- * if (collector.hasPendingApprovals()) {
223
- * const pending = collector.getPendingApprovals();
224
- * // pending: [{ stepKey: 'approval:1', error: PendingApproval }]
225
- * await saveToDatabase(collector.getResumeState());
226
- * }
227
- *
228
- * // Later, when approved:
229
- * const resumeState = collector.injectApproval('approval:1', { approvedBy: 'admin' });
230
- * ```
231
- */
232
- declare function createApprovalStateCollector(): {
233
- /** Handle workflow events. Pass this to workflow's `onEvent` option. */
234
- handleEvent: (event: WorkflowEvent<unknown>) => void;
235
- /** Get the collected resume state. Call after workflow execution. */
236
- getResumeState: () => ResumeState;
237
- /** Clears the collector's internal recorded entries (does not mutate workflow state). */
238
- clear: () => void;
239
- /** Check if any steps have pending approvals */
240
- hasPendingApprovals: () => boolean;
241
- /** Get all pending approval entries with their errors */
242
- getPendingApprovals: () => Array<{
243
- stepKey: string;
244
- error: PendingApproval;
245
- }>;
246
- /** Inject an approval result, updating the collector's internal state. Returns a copy for use as resumeState. */
247
- injectApproval: <T>(stepKey: string, value: T) => ResumeState;
248
- };
249
-
250
- /**
251
- * Human-in-the-Loop (HITL) helpers: pendingApproval, createApprovalStep, gatedStep.
252
- */
253
-
254
- /**
255
- * Create a PendingApproval error result.
256
- * Convenience helper for approval-gated steps.
257
- *
258
- * @param stepKey - Stable key for this approval step (used for resume)
259
- * @param options - Optional reason and metadata for the pending approval
260
- * @returns A Result with a PendingApproval error
261
- *
262
- * @example
263
- * ```typescript
264
- * const requireApproval = async (userId: string) => {
265
- * const status = await db.getApproval(userId);
266
- * if (!status) return pendingApproval(`approval:${userId}`);
267
- * return ok(status);
268
- * };
269
- * ```
270
- */
271
- declare function pendingApproval(stepKey: string, options?: {
272
- reason?: string;
273
- metadata?: Record<string, unknown>;
274
- }): Err<PendingApproval>;
275
- /**
276
- * Create a Result-returning function that checks external approval status.
277
- *
278
- * ## When to Use
279
- *
280
- * Use `createApprovalStep` when you need:
281
- * - **Human-in-the-loop workflows**: Steps that require human approval
282
- * - **External approval systems**: Integrate with approval databases/APIs
283
- * - **Workflow pausing**: Workflows that pause and resume after approval
284
- * - **Approval tracking**: Track who approved what and when
285
- *
286
- * ## Why Use This Instead of Manual Approval Checks
287
- *
288
- * - **Standardized pattern**: Consistent approval step interface
289
- * - **Type-safe**: Returns typed `PendingApproval` or `ApprovalRejected` errors
290
- * - **Resume-friendly**: Works seamlessly with `injectApproval()` and resume state
291
- * - **Metadata support**: Can include approval reason and metadata
292
- *
293
- * ## How It Works
294
- *
295
- * 1. Create approval step with `checkApproval` function
296
- * 2. `checkApproval` returns one of:
297
- * - `{ status: 'pending' }` - Approval not yet granted (workflow pauses)
298
- * - `{ status: 'approved', value: T }` - Approval granted (workflow continues)
299
- * - `{ status: 'rejected', reason: string }` - Approval rejected (workflow fails)
300
- * 3. Use in workflow with `step()` - workflow pauses if pending
301
- * 4. When approval granted externally, use `injectApproval()` to resume
302
- *
303
- * ## Typical Approval Flow
304
- *
305
- * 1. Workflow executes → reaches approval step
306
- * 2. `checkApproval()` called → returns `{ status: 'pending' }`
307
- * 3. Workflow returns `PendingApproval` error
308
- * 4. Save workflow state → persist for later resume
309
- * 5. Show approval UI → user sees pending approval
310
- * 6. User grants/rejects → update approval system
311
- * 7. Inject approval → call `injectApproval()` with approved value
312
- * 8. Resume workflow → continue from approval step
313
- *
314
- * @param options - Configuration for the approval step:
315
- * - `key`: Stable key for this approval (must match step key in workflow)
316
- * - `checkApproval`: Async function that checks current approval status
317
- * - `pendingReason`: Optional reason shown when approval is pending
318
- * - `metadata`: Optional metadata attached to the approval request
319
- *
320
- * @returns A function that returns an AsyncResult checking approval status.
321
- * The function can be used directly with `step()` in workflows.
322
- *
323
- * @example
324
- * ```typescript
325
- * // Create approval step that checks database
326
- * const requireManagerApproval = createApprovalStep<{ approvedBy: string }>({
327
- * key: 'manager-approval',
328
- * checkApproval: async () => {
329
- * const approval = await db.getApproval('manager-approval');
330
- * if (!approval) {
331
- * return { status: 'pending' }; // Workflow pauses here
332
- * }
333
- * if (approval.rejected) {
334
- * return { status: 'rejected', reason: approval.reason };
335
- * }
336
- * return {
337
- * status: 'approved',
338
- * value: { approvedBy: approval.approvedBy }
339
- * };
340
- * },
341
- * pendingReason: 'Waiting for manager approval',
342
- * });
343
- *
344
- * // Use in workflow
345
- * const workflow = createWorkflow({ requireManagerApproval });
346
- * const result = await workflow(async ({ step }) => {
347
- * const approval = await step(requireManagerApproval, { key: 'manager-approval' });
348
- * // If pending, workflow exits with PendingApproval error
349
- * // If approved, continues with approval value
350
- * return approval;
351
- * });
352
- *
353
- * // Handle pending state
354
- * if (!result.ok && isPendingApproval(result.error)) {
355
- * // Workflow paused - show approval UI
356
- * showApprovalUI(result.error.stepKey);
357
- * }
358
- * ```
359
- *
360
- * @example
361
- * ```typescript
362
- * // With approval injection for resume
363
- * const collector = createApprovalStateCollector();
364
- * const workflow = createWorkflow({ requireApproval }, {
365
- * onEvent: collector.handleEvent,
366
- * });
367
- *
368
- * const result = await workflow(async ({ step }) => {
369
- * const approval = await step(requireApproval, { key: 'approval:1' });
370
- * return approval;
371
- * });
372
- *
373
- * // When approval granted externally
374
- * if (collector.hasPendingApprovals()) {
375
- * const resumeState = collector.injectApproval('approval:1', {
376
- * approvedBy: 'admin@example.com'
377
- * });
378
- *
379
- * // Resume workflow
380
- * const workflow2 = createWorkflow({ requireApproval }, { resumeState });
381
- * const result2 = await workflow2(async ({ step }) => {
382
- * const approval = await step(requireApproval, { key: 'approval:1' });
383
- * return approval; // Now succeeds with injected value
384
- * });
385
- * }
386
- * ```
387
- */
388
- declare function createApprovalStep<T>(options: ApprovalStepOptions<T>): () => AsyncResult<T, PendingApproval | ApprovalRejected>;
389
- /**
390
- * Create a gated step that requires approval before execution.
391
- *
392
- * This is the AI SDK / LangChain-style pattern where you intercept
393
- * tool calls *before* they execute, allowing humans to see the args
394
- * and approve, edit, or reject before the operation runs.
395
- *
396
- * ## When to Use
397
- *
398
- * Use `gatedStep` when you want to:
399
- * - **Show args before execution**: Let humans see what the operation will do
400
- * - **Allow editing args**: Humans can modify args before operation runs
401
- * - **Conditional gating**: Only require approval for certain conditions
402
- * - **AI safety**: Gate dangerous AI tool calls (send email, delete file, etc.)
403
- *
404
- * ## Difference from createApprovalStep
405
- *
406
- * - `createApprovalStep`: Checks external approval status, operation already defined
407
- * - `gatedStep`: Gates before operation, shows args, allows editing, then executes
408
- *
409
- * ## Flow
410
- *
411
- * 1. Call gatedStep with args
412
- * 2. Check if approval is required (based on requiresApproval condition)
413
- * 3. If required and not approved:
414
- * - Return PendingApproval with args visible in metadata
415
- * - Human sees: "Send email to external@example.com with subject X"
416
- * - Human can approve (run as-is), edit (modify args), or reject
417
- * 4. If approved or not required:
418
- * - Execute the operation with (potentially edited) args
419
- *
420
- * @param operation - The operation to gate (a function returning AsyncResult)
421
- * @param options - Gating configuration
422
- * @returns A gated function that checks approval before execution
423
- *
424
- * @example
425
- * ```typescript
426
- * // Gate external email sends
427
- * const sendEmail = async (to: string, subject: string, body: string) => { ... };
428
- *
429
- * const gatedSendEmail = gatedStep(
430
- * sendEmail,
431
- * {
432
- * key: 'email',
433
- * requiresApproval: (args) => !args.to.endsWith('@mycompany.com'),
434
- * description: (args) => `Send email to ${args.to}: "${args.subject}"`,
435
- * }
436
- * );
437
- *
438
- * // In workflow:
439
- * const result = await step(
440
- * () => gatedSendEmail({ to: 'external@other.com', subject: 'Hello', body: '...' }),
441
- * { key: 'send-welcome-email' }
442
- * );
443
- *
444
- * // If gated, returns PendingApproval with:
445
- * // {
446
- * // stepKey: 'email',
447
- * // reason: 'Send email to external@other.com: "Hello"',
448
- * // metadata: { pendingArgs: { to: '...', subject: '...', body: '...' } }
449
- * // }
450
- * ```
451
- *
452
- * @example
453
- * ```typescript
454
- * // Gate file deletion with explicit approval check
455
- * const gatedDelete = gatedStep(
456
- * (path: string) => deleteFile(path),
457
- * {
458
- * key: 'delete-file',
459
- * requiresApproval: true, // Always require approval
460
- * description: (args) => `Delete file: ${args.path}`,
461
- * checkApproval: () => approvalStore.getApproval('delete-file'),
462
- * }
463
- * );
464
- * ```
465
- */
466
- declare function gatedStep<TArgs extends Record<string, unknown>, T, E>(operation: (args: TArgs) => AsyncResult<T, E>, options: GatedStepOptions<TArgs, T>): (args: TArgs) => AsyncResult<T, E | PendingApproval | ApprovalRejected>;
467
-
468
- export { createApprovalStateCollector as a, createApprovalStep as b, clearStep as c, getPendingApprovals as d, createResumeStateCollector as e, getPendingHooks as f, gatedStep as g, hasPendingApproval as h, injectApproval as i, hasPendingHook as j, injectHook as k, pendingApproval as p };