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
package/dist/hitl.d.ts DELETED
@@ -1,442 +0,0 @@
1
- import { R as ResumeState, c as Workflow } from './persistence-entry-D8zRkLiT.js';
2
- export { d as ApprovalRejected, e as ApprovalStepOptions, G as GatedStepOptions, P as PendingApproval } from './persistence-entry-D8zRkLiT.js';
3
- export { a as isApprovalRejected, b as isPendingApproval } from './guards-BIX05ALH.js';
4
- export { c as clearStep, a as createApprovalStateCollector, b as createApprovalStep, g as gatedStep, d as getPendingApprovals, h as hasPendingApproval, i as injectApproval, p as pendingApproval } from './hitl-DU5VpKq7.js';
5
- import { R as Result, ae as WorkflowEvent } from './run-entry-BOuNyVoO.js';
6
- import './types-BziYHFkD.js';
7
- import '@standard-schema/spec';
8
- import './errors.js';
9
- import './tagged-error.js';
10
- import './slugs.js';
11
-
12
- /**
13
- * awaitly/hitl
14
- *
15
- * Human-in-the-Loop Orchestration Helpers.
16
- * Provides pollers, webhook handlers, and resume injectors
17
- * for production-ready approval workflows.
18
- */
19
-
20
- /**
21
- * Options passed to the workflow factory by the HITL orchestrator.
22
- */
23
- interface HITLWorkflowFactoryOptions {
24
- /** Resume state for replaying completed steps */
25
- resumeState?: ResumeState;
26
- /** Event handler for tracking workflow events (required for HITL) */
27
- onEvent: (event: WorkflowEvent<unknown>) => void;
28
- }
29
- /**
30
- * Approval status returned from the approval store.
31
- */
32
- type ApprovalStatus<T = unknown> = {
33
- status: "pending";
34
- } | {
35
- status: "approved";
36
- value: T;
37
- approvedBy?: string;
38
- approvedAt?: number;
39
- } | {
40
- status: "rejected";
41
- reason: string;
42
- rejectedBy?: string;
43
- rejectedAt?: number;
44
- } | {
45
- status: "expired";
46
- expiredAt: number;
47
- } | {
48
- status: "edited";
49
- originalValue: T;
50
- editedValue: T;
51
- editedBy?: string;
52
- editedAt?: number;
53
- };
54
- /**
55
- * Context passed to notification channel when an approval is needed.
56
- */
57
- interface ApprovalNeededContext {
58
- /** Unique approval key for correlation */
59
- approvalKey: string;
60
- /** Workflow run ID */
61
- runId: string;
62
- /** Workflow name/type */
63
- workflowName: string;
64
- /** Human-readable reason for the approval */
65
- reason?: string;
66
- /** Custom metadata attached to the approval */
67
- metadata?: Record<string, unknown>;
68
- /** When the approval expires (timestamp) */
69
- expiresAt?: number;
70
- /** Human-readable summary for notifications */
71
- summary?: string;
72
- /** For gated steps: the operation args that need approval */
73
- pendingArgs?: Record<string, unknown>;
74
- }
75
- /**
76
- * Context passed to notification channel when an approval is resolved.
77
- */
78
- interface ApprovalResolvedContext {
79
- /** Unique approval key */
80
- approvalKey: string;
81
- /** Resolution action */
82
- action: "approved" | "rejected" | "edited" | "expired" | "cancelled";
83
- /** Who performed the action (if available) */
84
- actorId?: string;
85
- /** Timestamp of resolution */
86
- resolvedAt: number;
87
- /** Reason (for rejections) */
88
- reason?: string;
89
- /** Value (for approvals/edits) */
90
- value?: unknown;
91
- /** Original value (for edits) */
92
- originalValue?: unknown;
93
- }
94
- /**
95
- * Notification channel for external integrations (Slack, email, etc).
96
- * Implement this interface to receive push notifications when approvals
97
- * are created or resolved.
98
- */
99
- interface NotificationChannel {
100
- /**
101
- * Called when a new approval request is created.
102
- * Use this to send Slack messages, emails, or push to a UI.
103
- */
104
- onApprovalNeeded(context: ApprovalNeededContext): Promise<void>;
105
- /**
106
- * Called when an approval is granted, rejected, edited, or expires.
107
- * Use this to update Slack messages, send confirmation emails, etc.
108
- */
109
- onApprovalResolved?(context: ApprovalResolvedContext): Promise<void>;
110
- }
111
- /**
112
- * Interface for approval storage backends.
113
- */
114
- interface ApprovalStore {
115
- /**
116
- * Get the status of an approval.
117
- */
118
- getApproval(key: string): Promise<ApprovalStatus>;
119
- /**
120
- * Create or update a pending approval request.
121
- */
122
- createApproval(key: string, options?: {
123
- metadata?: Record<string, unknown>;
124
- expiresAt?: number;
125
- requestedBy?: string;
126
- }): Promise<void>;
127
- /**
128
- * Grant an approval.
129
- */
130
- grantApproval<T>(key: string, value: T, options?: {
131
- approvedBy?: string;
132
- }): Promise<void>;
133
- /**
134
- * Reject an approval.
135
- */
136
- rejectApproval(key: string, reason: string, options?: {
137
- rejectedBy?: string;
138
- }): Promise<void>;
139
- /**
140
- * Edit an approval (approve with modifications).
141
- * Records both the original proposed value and the edited value.
142
- */
143
- editApproval<T>(key: string, originalValue: T, editedValue: T, options?: {
144
- editedBy?: string;
145
- }): Promise<void>;
146
- /**
147
- * Cancel a pending approval.
148
- */
149
- cancelApproval(key: string): Promise<void>;
150
- /**
151
- * List all pending approvals.
152
- */
153
- listPending(options?: {
154
- prefix?: string;
155
- }): Promise<string[]>;
156
- }
157
- /**
158
- * Saved workflow state for resumption.
159
- */
160
- interface SavedWorkflowState {
161
- /** Unique identifier for this workflow run */
162
- runId: string;
163
- /** Workflow name/type */
164
- workflowName: string;
165
- /** Resume state with step results */
166
- resumeState: ResumeState;
167
- /** Pending approval keys */
168
- pendingApprovals: string[];
169
- /** Input that was passed to the workflow */
170
- input?: unknown;
171
- /** Custom metadata */
172
- metadata?: Record<string, unknown>;
173
- /** When the workflow was started */
174
- startedAt: number;
175
- /** When the state was last updated */
176
- updatedAt: number;
177
- }
178
- /**
179
- * Interface for workflow state storage.
180
- */
181
- interface WorkflowStateStore {
182
- /**
183
- * Save workflow state.
184
- */
185
- save(state: SavedWorkflowState): Promise<void>;
186
- /**
187
- * Load workflow state by run ID.
188
- */
189
- load(runId: string): Promise<SavedWorkflowState | undefined>;
190
- /**
191
- * Delete workflow state.
192
- */
193
- delete(runId: string): Promise<void>;
194
- /**
195
- * List all saved workflow states.
196
- */
197
- list(options?: {
198
- workflowName?: string;
199
- hasPendingApprovals?: boolean;
200
- }): Promise<string[]>;
201
- /**
202
- * Find workflows waiting for a specific approval.
203
- */
204
- findByPendingApproval(approvalKey: string): Promise<string[]>;
205
- }
206
- /**
207
- * Options for the HITL orchestrator.
208
- */
209
- interface HITLOrchestratorOptions {
210
- /** Approval store for managing approval states */
211
- approvalStore: ApprovalStore;
212
- /** Workflow state store for persisting workflow state */
213
- workflowStateStore: WorkflowStateStore;
214
- /** Default expiration time for approvals (in milliseconds) */
215
- defaultExpirationMs?: number;
216
- /** Logger function */
217
- logger?: (message: string) => void;
218
- /**
219
- * Notification channel for external integrations.
220
- * When provided, the orchestrator will call onApprovalNeeded when
221
- * an approval is created, and onApprovalResolved when resolved.
222
- */
223
- notificationChannel?: NotificationChannel;
224
- }
225
- /**
226
- * Result of executing a workflow that may pause for approval.
227
- * Uses unknown for error type since workflows add UnexpectedError to the union.
228
- */
229
- type HITLExecutionResult<T, E> = {
230
- status: "completed";
231
- result: Result<T, E | unknown>;
232
- } | {
233
- status: "paused";
234
- runId: string;
235
- pendingApprovals: string[];
236
- reason?: string;
237
- } | {
238
- status: "resumed";
239
- runId: string;
240
- result: Result<T, E | unknown>;
241
- };
242
- /**
243
- * Poller configuration.
244
- */
245
- interface PollerOptions {
246
- /** Polling interval in milliseconds */
247
- intervalMs: number;
248
- /** Maximum number of polls (undefined = unlimited) */
249
- maxPolls?: number;
250
- /** Timeout for the entire polling operation */
251
- timeoutMs?: number;
252
- /** Callback when polling starts */
253
- onPollStart?: () => void;
254
- /** Callback when a poll completes */
255
- onPollComplete?: (result: ApprovalStatus) => void;
256
- }
257
- /**
258
- * Create an in-memory approval store for development/testing.
259
- */
260
- declare function createMemoryApprovalStore(): ApprovalStore;
261
- /**
262
- * Create an in-memory workflow state store for development/testing.
263
- */
264
- declare function createMemoryWorkflowStateStore(): WorkflowStateStore;
265
- /**
266
- * HITL orchestrator interface.
267
- */
268
- interface HITLOrchestrator {
269
- /**
270
- * Execute a workflow that may pause for approvals.
271
- * If the workflow pauses, state is automatically saved.
272
- *
273
- * The workflowFactory receives options including onEvent handler which MUST be
274
- * passed to createWorkflow for HITL tracking to work.
275
- */
276
- execute<T, E, TInput>(workflowName: string, workflowFactory: (options: HITLWorkflowFactoryOptions) => Workflow<E, unknown>, workflowFn: (context: {
277
- step: unknown;
278
- deps: unknown;
279
- args: TInput;
280
- }) => Promise<T>, input: TInput, options?: {
281
- runId?: string;
282
- metadata?: Record<string, unknown>;
283
- }): Promise<HITLExecutionResult<T, E>>;
284
- /**
285
- * Resume a paused workflow after approvals have been granted.
286
- */
287
- resume<T, E, TInput>(runId: string, workflowFactory: (options: HITLWorkflowFactoryOptions) => Workflow<E, unknown>, workflowFn: (context: {
288
- step: unknown;
289
- deps: unknown;
290
- args: TInput;
291
- }) => Promise<T>): Promise<HITLExecutionResult<T, E>>;
292
- /**
293
- * Grant an approval and automatically resume any waiting workflows.
294
- */
295
- grantApproval<T>(approvalKey: string, value: T, options?: {
296
- approvedBy?: string;
297
- autoResume?: boolean;
298
- }): Promise<{
299
- grantedAt: number;
300
- resumedWorkflows: string[];
301
- }>;
302
- /**
303
- * Reject an approval.
304
- */
305
- rejectApproval(approvalKey: string, reason: string, options?: {
306
- rejectedBy?: string;
307
- }): Promise<void>;
308
- /**
309
- * Edit an approval (approve with modifications).
310
- * Use this when a human wants to approve but with changes to the proposed value.
311
- * Records both the original and edited values for audit trail.
312
- */
313
- editApproval<T>(approvalKey: string, originalValue: T, editedValue: T, options?: {
314
- editedBy?: string;
315
- }): Promise<{
316
- editedAt: number;
317
- }>;
318
- /**
319
- * Poll for an approval to be granted.
320
- */
321
- pollApproval<T>(approvalKey: string, options?: PollerOptions): Promise<ApprovalStatus<T>>;
322
- /**
323
- * Get the status of a workflow run.
324
- */
325
- getWorkflowStatus(runId: string): Promise<SavedWorkflowState | undefined>;
326
- /**
327
- * List all pending workflows.
328
- */
329
- listPendingWorkflows(workflowName?: string): Promise<string[]>;
330
- /**
331
- * Clean up completed workflows older than the specified age.
332
- */
333
- cleanup(maxAgeMs: number): Promise<number>;
334
- }
335
- /**
336
- * Create a HITL orchestrator for managing approval workflows.
337
- *
338
- * @example
339
- * ```typescript
340
- * const orchestrator = createHITLOrchestrator({
341
- * approvalStore: createMemoryApprovalStore(),
342
- * workflowStateStore: createMemoryWorkflowStateStore(),
343
- * });
344
- *
345
- * // Execute workflow - IMPORTANT: pass onEvent to createWorkflow!
346
- * const result = await orchestrator.execute(
347
- * 'order-approval',
348
- * ({ resumeState, onEvent }) => createWorkflow('order-approval', deps, { resumeState, onEvent }),
349
- * async ({ step, deps, args: input }) => {
350
- * const order = await step(() => deps.createOrder(input));
351
- * const approval = await step(() => deps.requireApproval(order.id), { key: `approval:${order.id}` });
352
- * await step(() => deps.processOrder(order.id));
353
- * return { orderId: order.id, approvedBy: approval.approvedBy };
354
- * },
355
- * { items: [...], total: 100 }
356
- * );
357
- *
358
- * if (result.status === 'paused') {
359
- * console.log(`Workflow paused, waiting for: ${result.pendingApprovals}`);
360
- * }
361
- *
362
- * // Later, grant approval
363
- * await orchestrator.grantApproval(
364
- * `approval:${orderId}`,
365
- * { approvedBy: 'manager@example.com' },
366
- * { autoResume: true }
367
- * );
368
- * ```
369
- */
370
- declare function createHITLOrchestrator(options: HITLOrchestratorOptions): HITLOrchestrator;
371
- /**
372
- * Approval webhook request body.
373
- */
374
- interface ApprovalWebhookRequest {
375
- /** Approval key */
376
- key: string;
377
- /** Action: approve, reject, edit, or cancel */
378
- action: "approve" | "reject" | "edit" | "cancel";
379
- /** Value to inject (for approve) */
380
- value?: unknown;
381
- /** Original value (for edit - what was proposed) */
382
- originalValue?: unknown;
383
- /** Edited value (for edit - what human changed it to) */
384
- editedValue?: unknown;
385
- /** Reason (for reject) */
386
- reason?: string;
387
- /** Who performed this action */
388
- actorId?: string;
389
- }
390
- /**
391
- * Approval webhook response.
392
- */
393
- interface ApprovalWebhookResponse {
394
- success: boolean;
395
- message: string;
396
- data?: {
397
- key: string;
398
- action: string;
399
- timestamp: number;
400
- };
401
- }
402
- /**
403
- * Create a webhook handler for approval actions.
404
- *
405
- * @example
406
- * ```typescript
407
- * const handleApproval = createApprovalWebhookHandler(approvalStore);
408
- *
409
- * // Express
410
- * app.post('/api/approvals', async (req, res) => {
411
- * const result = await handleApproval(req.body);
412
- * res.json(result);
413
- * });
414
- * ```
415
- */
416
- declare function createApprovalWebhookHandler(store: ApprovalStore): (request: ApprovalWebhookRequest) => Promise<ApprovalWebhookResponse>;
417
- /**
418
- * Create an approval checker function for use in approval steps.
419
- * This wraps the approval store with the standard checkApproval interface.
420
- *
421
- * @example
422
- * ```typescript
423
- * const checkApproval = createApprovalChecker(approvalStore);
424
- *
425
- * const requireManagerApproval = createApprovalStep<{ approvedBy: string }>({
426
- * key: 'manager-approval',
427
- * checkApproval: checkApproval('manager-approval'),
428
- * pendingReason: 'Waiting for manager approval',
429
- * });
430
- * ```
431
- */
432
- declare function createApprovalChecker<T>(store: ApprovalStore): (key: string) => () => Promise<{
433
- status: "pending";
434
- } | {
435
- status: "approved";
436
- value: T;
437
- } | {
438
- status: "rejected";
439
- reason: string;
440
- }>;
441
-
442
- export { type ApprovalNeededContext, type ApprovalResolvedContext, type ApprovalStatus, type ApprovalStore, type ApprovalWebhookRequest, type ApprovalWebhookResponse, type HITLExecutionResult, type HITLOrchestrator, type HITLOrchestratorOptions, type HITLWorkflowFactoryOptions, type NotificationChannel, type PollerOptions, type SavedWorkflowState, type WorkflowStateStore, createApprovalChecker, createApprovalWebhookHandler, createHITLOrchestrator, createMemoryApprovalStore, createMemoryWorkflowStateStore };
package/dist/hitl.js DELETED
@@ -1,7 +0,0 @@
1
- var Ge={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function Ae(t){return`https://jagreehal.github.io/awaitly/rules/#${t}`}var ft=Object.keys(Ge);var le=class extends Error{_tag};function z(t,e){return class extends le{_tag=t;constructor(r,d){let y=e?.message?e.message(r??{}):t;if(super(y),this.name=t,e?.slug!==void 0){if(!e.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${e.slug}")`);Object.defineProperty(this,"code",{value:e.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:e.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:Ae(e.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),r&&typeof r=="object"){let l;if(e?.slug!==void 0){let{_tag:W,name:_,message:B,stack:i,code:$,hint:Y,docsUrl:S,...N}=r;l=N}else{let{_tag:W,name:_,message:B,stack:i,...$}=r;l=$}let k=Object.prototype.hasOwnProperty.call(l,"cause"),h=k?l.cause:void 0;k&&delete l.cause;let M=d?.cause!==void 0;if(k&&M)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,l),k&&(this.cause=h),M&&(this.cause=d?.cause)}else d?.cause!==void 0&&(this.cause=d.cause)}}}Object.defineProperty(z,Symbol.hasInstance,{value:t=>t instanceof le});(y=>{function t(l){return l instanceof Error}y.isError=t;function e(l){return l instanceof le}y.isTaggedError=e;function r(l,k){let h=l._tag,M=k[h];return M(l)}y.match=r;function d(l,k,h){let M=l._tag,W=k[M];return W?W(l):h(l)}y.matchPartial=d})(z||={});var ve=class extends z("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:e=>e.operation?`TimeoutError: ${e.operation} timed out after ${e.ms}ms`:`TimeoutError: Operation timed out after ${e.ms}ms`}){},he=class extends z("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:e=>e.operation?`RetryExhaustedError: ${e.operation} failed after ${e.attempts} attempts`:`RetryExhaustedError: Operation failed after ${e.attempts} attempts`}){},Se=class extends z("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:e=>e.limiterName?`RateLimitError: Rate limit exceeded for ${e.limiterName}${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`}){},be=class extends z("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:e=>`CircuitBreakerOpenError: Circuit ${e.circuitName} is ${e.state??"OPEN"}${e.retryAfterMs?`, retry after ${Math.ceil(e.retryAfterMs/1e3)}s`:""}`}){},Pe=class extends z("ValidationError",{message:e=>`ValidationError: Invalid ${e.field} - ${e.reason}`}){},Oe=class extends z("NotFoundError",{message:e=>e.id?`NotFoundError: ${e.resource} with id ${e.id} not found`:`NotFoundError: ${e.resource} not found`}){},_e=class extends z("UnauthorizedError",{message:e=>e.reason?`UnauthorizedError: ${e.reason}`:e.action&&e.resource?`UnauthorizedError: Not authorized to ${e.action} ${e.resource}`:"UnauthorizedError: Access denied"}){},Ie=class extends z("NetworkError",{message:e=>e.url?`NetworkError: ${e.reason} (${e.url})`:`NetworkError: ${e.reason}`}){},Me=class extends z("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:e=>`CompensationError: Failed to compensate step ${e.step}`}){},Ee=class extends z("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:e=>`UnexpectedError: ${e.cause instanceof Error?e.cause.message:String(e.cause??"unknown")}`}){};function De(t){return{ok:!0,value:t}}var Xe=t=>typeof t=="object"&&t!==null&&"ok"in t&&typeof t.ok=="boolean"&&(t.ok?"value"in t:"error"in t),Ue=(t,e)=>{let r={},d=new Map;for(let y of Object.keys(t)){let l=t[y];typeof l=="function"&&(r[y]=(...k)=>{let h=(d.get(y)??0)+1;d.set(y,h);let M=h===1?y:`${y}#${h}`;return e(M,async()=>{let W=await l(...k);return Xe(W)?W:De(W)})})}return r};function Ze(t){let e=t.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!e)return;let r=parseFloat(e[1]),d=e[2].toLowerCase();return{_tag:"Duration",millis:r*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[d]??1)}}function Qe(t){return new Ee({cause:t})}function q(t){return{ok:!0,value:t}}function F(t,e){let r=e?.cause;return{ok:!1,error:t,...r!==void 0?{cause:r}:{}}}function et(t){if(t==null)return"unknown";if(typeof t=="string")return t.trim()||"unknown";if(typeof t=="object"){let e=t;if(typeof e._tag=="string"){let r=e._tag.trim();if(r)return r}if(typeof e.tag=="string"){let r=e.tag.trim();if(r)return r}if(typeof e.code=="string"){let r=e.code.trim();if(r)return r}else if(typeof e.code=="number")return String(e.code);if(t instanceof Error&&t.name){let r=t.name.trim();if(r)return r}}return"unknown"}function tt(t,e){if(!(!e||!t))return e[t]}function rt(t){let{intent:e,domain:r,owner:d,tags:y,stateChanges:l,emits:k,calls:h}=t;if(!e&&!r&&!d&&!y?.length&&!l?.length&&!k?.length&&!h?.length)return;let M={};return e&&(M.intent=e),r&&(M.domain=r),d&&(M.owner=d),y?.length&&(M.tags=y),l?.length&&(M.stateChanges=l),k?.length&&(M.emits=k),h?.length&&(M.calls=h),M}function X(t,e,r,d,y){let l=et(t),k=tt(l,e),h={tag:l,origin:r};return k!==void 0&&(h.classification=k),d!==void 0&&(h.attempt=d),y!==void 0&&(h.cumulativeDurationMs=y),h}var ue=Symbol.for("step_timeout_marker");function je(t){return typeof t!="object"||t===null?!1:t.type==="STEP_TIMEOUT"?!0:ue in t}function nt(t){if(!(typeof t!="object"||t===null)){if(t.type==="STEP_TIMEOUT"){let e=t;return{timeoutMs:e.timeoutMs,stepName:e.stepName,stepKey:e.stepKey,attempt:e.attempt}}if(ue in t)return t[ue]}}var Fe=Symbol("early-exit");function ot(t,e){return{[Fe]:!0,error:t,meta:e}}function st(t){return typeof t=="object"&&t!==null&&t[Fe]===!0}var We=Symbol("mapper-exception");function ae(t){return{[We]:!0,thrown:t}}function at(t){return typeof t=="object"&&t!==null&&t[We]===!0}function ge(t,e){let{backoff:r,initialDelay:d,maxDelay:y,jitter:l}=e,k;switch(r){case"fixed":k=d;break;case"linear":k=d*t;break;case"exponential":k=d*Math.pow(2,t-1);break}if(k=Math.min(k,y),l){let h=k*.25*Math.random();k=k+h}return Math.floor(k)}function Re(t){return new Promise(e=>setTimeout(e,t))}var Ke=Symbol("timeout"),me=Symbol("timeout-option");function it(t){return typeof t=="object"&&t!==null&&t[me]===!0}async function ut(t,e,r,d){let y=new AbortController,l=e.onTimeout??"error",k=()=>typeof l=="function"?l({name:r.name,key:r.key,ms:e.ms}):e.error??{type:"STEP_TIMEOUT",stepName:r.name,stepKey:r.key,timeoutMs:e.ms,attempt:r.attempt},h;d?.aborted&&y.abort(d.reason);let M;d&&!d.aborted&&(M=()=>y.abort(d.reason),d.addEventListener("abort",M,{once:!0}));let W=new Promise((B,i)=>{h=setTimeout(()=>{if(l!=="disconnect"&&y.abort(),l==="option"){i({[me]:!0,ms:e.ms});return}i({[Ke]:!0,error:k()})},e.ms)}),_;e.signal?_=Promise.resolve(t(y.signal)):_=Promise.resolve(t());try{return await Promise.race([_,W])}catch(B){if(typeof B=="object"&&B!==null&&B[me]===!0)throw{[me]:!0,ms:e.ms};if(typeof B=="object"&&B!==null&&B[Ke]===!0){l==="disconnect"&&_.catch(()=>{});let i=B.error;if(typeof i=="object"&&i!==null&&i.type!=="STEP_TIMEOUT"){let $={timeoutMs:e.ms,stepName:r.name,stepKey:r.key,attempt:r.attempt};ue in i?i[ue]=$:Object.defineProperty(i,ue,{value:$,enumerable:!1,writable:!0,configurable:!1})}throw i}throw B}finally{clearTimeout(h),M&&d&&d.removeEventListener("abort",M)}}var ie={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function xe(t,e,r){if(typeof t!="function"){let p=t,I=e;if(typeof I!="function")throw new TypeError("[awaitly] run(deps, fn) requires a callback as the second argument. Example: run({ getUser }, async (s) => s.getUser(id))");return xe(({step:G})=>I(Ue(p,G),{step:G}),r)}let d=t,y=e,{onError:l,onEvent:k,catchUnexpected:h,workflowId:M,workflowName:W,context:_,_workflowSignal:B}=y&&typeof y=="object"?y:{},i=M??crypto.randomUUID(),$=h??Qe,Y=[],S=0,N=p=>p??`step_${++S}`,a=p=>{let I=p.context!==void 0||_===void 0?p:{...p,context:_},H=W!==void 0&&I.workflowName===void 0?{...I,workflowName:W}:I;if(H.type==="step_success"){let G=H.stepId;for(let ne=Y.length-1;ne>=0;ne--){let L=Y[ne];if(L.type==="race"&&!L.winnerId){L.winnerId=G;break}}}k?.(H,_)},A=ot,D=p=>st(p),U=(p,I)=>p,J=p=>typeof p=="function"?!1:!!(p&&typeof p=="object"&&"ok"in p||p&&typeof p=="object"&&"then"in p&&typeof p.then=="function");try{let I=function(u){let m={};for(let[o,s]of Object.entries(u))if(typeof s=="function")m[o]=s;else if(s&&typeof s=="object"&&"fn"in s)m[o]=s.fn;else throw new TypeError(`step.all: operation "${o}" must be a function or { fn, errors? } object`);return m},H=function(u,m){let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1;Y.push({scopeId:o,type:"parallel"});let c=()=>{if(n)return;n=!0;let E=Y.findIndex(f=>f.scopeId===o);E!==-1&&Y.splice(E,1),a({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};a({type:"scope_start",workflowId:i,scopeId:o,scopeType:"parallel",name:u,ts:Date.now()});try{let E=await m();if(c(),!E.ok)throw l?.(E.error,u,_),A(E.error,{origin:"result",resultCause:E.cause});return E.value}catch(E){throw c(),E}})()},G=function(u,m){let o=Object.keys(u),s=m.name??`Parallel(${o.join(", ")})`,n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let c=performance.now(),E=!1;Y.push({scopeId:n,type:"parallel"});let f=()=>{if(E)return;E=!0;let w=Y.findIndex(T=>T.scopeId===n);w!==-1&&Y.splice(w,1),a({type:"scope_end",workflowId:i,scopeId:n,ts:Date.now(),durationMs:performance.now()-c})};a({type:"scope_start",workflowId:i,scopeId:n,scopeType:"parallel",name:s,ts:Date.now()});try{let w=await new Promise(R=>{if(o.length===0){R([]);return}let P=!1,K=o.length,x=new Array(o.length);for(let j=0;j<o.length;j++){let C=o[j],b=j;Promise.resolve(u[C]()).catch(v=>F({type:"PROMISE_REJECTED",cause:v},{cause:{type:"PROMISE_REJECTION",reason:v}})).then(v=>{if(!P){if(!v.ok){P=!0,R([{key:C,result:v}]);return}x[b]={key:C,result:v},K--,K===0&&R(x)}})}});f();let T={};for(let{key:R,result:P}of w){if(!P.ok)throw l?.(P.error,R,_),A(P.error,{origin:"result",resultCause:P.cause});T[R]=P.value}return T}catch(w){throw f(),w}})()};var se=I,Z=H,V=G;let p=(u,m,o)=>(async()=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let s=o??{},n=rt(s),c=u,E=s.key??u,f=s.key??u,{description:w,retry:T,timeout:R}=s,P=N(E),K=k,x=K?performance.now():0,C=J(m)?()=>m:m,v={attempts:Math.max(1,T?.attempts??1),backoff:T?.backoff??ie.backoff,initialDelay:T?.initialDelay??ie.initialDelay,maxDelay:T?.maxDelay??ie.maxDelay,jitter:T?.jitter??ie.jitter,shouldRetry:T?.shouldRetry??ie.shouldRetry,onRetry:T?.onRetry??ie.onRetry};k&&a({type:"step_start",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),...n&&{metadata:n}});let oe;for(let O=1;O<=v.attempts;O++){let ze=K?performance.now():0;try{let g;if(R?g=await ut(C,R,{name:c,key:E,attempt:O},B):g=await C(),g.ok){let re=performance.now()-x;return a({type:"step_success",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:re,...n&&{metadata:n}}),f&&a({type:"step_complete",workflowId:i,stepKey:f,name:c,description:w,ts:Date.now(),durationMs:re,result:g,...n&&{metadata:n}}),g.value}if(oe=g,O<v.attempts&&v.shouldRetry(g.error,O)){let re=ge(O,v);a({type:"step_retry",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),attempt:O+1,maxAttempts:v.attempts,delayMs:re,error:g.error,...n&&{metadata:n},diagnostics:X(g.error,s.errorMeta,"result",O,performance.now()-x)}),v.onRetry(g.error,O,re),await Re(re);continue}v.attempts>1&&a({type:"step_retries_exhausted",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:g.error,...n&&{metadata:n},diagnostics:X(g.error,s.errorMeta,"result",O,performance.now()-x)});break}catch(g){let re=performance.now()-ze;if(it(g)){let ee=g.ms;a({type:"step_timeout",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),timeoutMs:ee,attempt:O,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"timeout",O)}),a({type:"step_success",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:performance.now()-x,...n&&{metadata:n}}),f&&a({type:"step_complete",workflowId:i,stepKey:f,name:c,description:w,ts:Date.now(),durationMs:performance.now()-x,result:q(void 0),...n&&{metadata:n}});return}if(D(g))throw a({type:"step_aborted",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:re,...n&&{metadata:n}}),g;if(je(g)){let ee=nt(g),Je=R?.ms??ee?.timeoutMs??0;if(a({type:"step_timeout",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),timeoutMs:Je,attempt:O,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"timeout",O)}),O<v.attempts&&v.shouldRetry(g,O)){let Te=ge(O,v);a({type:"step_retry",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),attempt:O+1,maxAttempts:v.attempts,delayMs:Te,error:g,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"timeout",O,performance.now()-x)}),v.onRetry(g,O,Te),await Re(Te);continue}v.attempts>1&&a({type:"step_retries_exhausted",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:g,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"timeout",O,performance.now()-x)});let ke=performance.now()-x;throw a({type:"step_error",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:ke,error:g,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"timeout",O,ke)}),f&&a({type:"step_complete",workflowId:i,stepKey:f,name:c,description:w,ts:Date.now(),durationMs:ke,result:F(g,{cause:g}),meta:{origin:"throw",thrown:g},...n&&{metadata:n}}),l?.(g,c,_),A(g,{origin:"throw",thrown:g})}if(O<v.attempts&&v.shouldRetry(g,O)){let ee=ge(O,v);a({type:"step_retry",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),attempt:O+1,maxAttempts:v.attempts,delayMs:ee,error:g,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"throw",O,performance.now()-x)}),v.onRetry(g,O,ee),await Re(ee);continue}v.attempts>1&&!je(g)&&a({type:"step_retries_exhausted",workflowId:i,stepId:P,stepKey:E,name:c,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:g,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"throw",O,performance.now()-x)});let ye=performance.now()-x,pe;try{pe=$(g)}catch(ee){throw ae(ee)}throw a({type:"step_error",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:ye,error:pe,...n&&{metadata:n},diagnostics:X(g,s.errorMeta,"throw",O,ye)}),f&&a({type:"step_complete",workflowId:i,stepKey:f,name:c,description:w,ts:Date.now(),durationMs:ye,result:F(pe,{cause:g}),meta:{origin:"throw",thrown:g},...n&&{metadata:n}}),l?.(pe,c,_),A(pe,{origin:"throw",thrown:g})}}let te=oe,fe=performance.now()-x,we=U(te.error,{origin:"result",resultCause:te.cause});throw a({type:"step_error",workflowId:i,stepId:P,stepKey:E,name:c,description:w,ts:Date.now(),durationMs:fe,error:we,...n&&{metadata:n},diagnostics:X(te.error,s.errorMeta,"result",v.attempts,fe)}),f&&a({type:"step_complete",workflowId:i,stepKey:f,name:c,description:w,ts:Date.now(),durationMs:fe,result:te,meta:{origin:"result",resultCause:te.cause},...n&&{metadata:n}}),l?.(we,c,_),A(we,{origin:"result",resultCause:te.cause})})();p.try=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.try() requires an explicit string ID as the first argument. Example: step.try("parse", () => JSON.parse(str), { error: "PARSE_ERROR" })');let s="error"in o?()=>o.error:o.onError;if(o.retry||o.timeout)return p.retry(u,async()=>{try{return q(await m())}catch(w){return F(s(w),{cause:w})}},{attempts:o.retry?.attempts??1,...o.retry??{},key:o.key,timeout:o.timeout});let n=o.key??u,c=u,E=u,f=k;return(async()=>{let w=f?performance.now():0;k&&a({type:"step_start",workflowId:i,stepId:E,stepKey:n,name:c,ts:Date.now()});try{let T=await m(),R=performance.now()-w;return a({type:"step_success",workflowId:i,stepId:E,stepKey:n,name:c,ts:Date.now(),durationMs:R}),n&&a({type:"step_complete",workflowId:i,stepKey:n,name:c,ts:Date.now(),durationMs:R,result:q(T)}),T}catch(T){let R=s(T),P=performance.now()-w,K=U(R,{origin:"throw",thrown:T});throw a({type:"step_error",workflowId:i,stepId:E,stepKey:n,name:c,ts:Date.now(),durationMs:P,error:K}),n&&a({type:"step_complete",workflowId:i,stepKey:n,name:c,ts:Date.now(),durationMs:P,result:F(R,{cause:T}),meta:{origin:"throw",thrown:T}}),l?.(K,c,_),A(K,{origin:"throw",thrown:T})}})()},p.fromResult=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.fromResult() requires an explicit string ID as the first argument. Example: step.fromResult("callProvider", () => callProvider(input), { onError: (e) => ({ type: "FAILED" }) })');let s=o.key??u,n=u,c=u,E="error"in o?()=>o.error:o.onError,f=k;return(async()=>{let w=f?performance.now():0;k&&a({type:"step_start",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now()});let T=await m();if(T.ok){let R=performance.now()-w;return a({type:"step_success",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:R}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:R,result:q(T.value)}),T.value}else{let R=E(T.error),P=performance.now()-w,K=U(R,{origin:"result",resultCause:T.error});throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:P,error:K}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:P,result:F(R,{cause:T.error}),meta:{origin:"result",resultCause:T.error}}),l?.(K,n,_),A(K,{origin:"result",resultCause:T.error})}})()},p.fromNullable=(u,m,o,s)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.fromNullable() requires an explicit string ID as the first argument. Example: step.fromNullable("getUser", () => db.find(id), () => ({ type: "NOT_FOUND" }))');return p(u,async()=>{let n=await m();return n!=null?q(n):F(o())},s)},p.retry=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.retry() requires an explicit string ID as the first argument. Example: step.retry("fetchData", () => fetchData(), { attempts: 3 })');return p(u,m,{key:o.key??u,retry:{attempts:o.attempts,backoff:o.backoff,initialDelay:o.initialDelay,maxDelay:o.maxDelay,jitter:o.jitter,shouldRetry:o.shouldRetry,onRetry:o.onRetry},timeout:o.timeout})},p.withTimeout=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.withTimeout() requires an explicit string ID as the first argument. Example: step.withTimeout("slowOp", () => slowOp(), { ms: 5000 })');return p(u,m,{key:o.key??u,timeout:o})},p.sleep=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let s=typeof m=="string"?Ze(m):m;if(!s)throw new Error(`step.sleep: invalid duration '${m}'`);let n=s.millis,c=o?.signal;return p(u,async()=>{if(B?.aborted||c?.aborted){let E=new Error("Sleep aborted");throw E.name="AbortError",E}return new Promise((E,f)=>{let w={timeoutId:void 0},T=()=>{w.timeoutId&&clearTimeout(w.timeoutId);let R=new Error("Sleep aborted");R.name="AbortError",f(R)};B?.addEventListener("abort",T,{once:!0}),c?.addEventListener("abort",T,{once:!0}),w.timeoutId=setTimeout(()=>{B?.removeEventListener("abort",T),c?.removeEventListener("abort",T),E(q(void 0))},n)})},{key:o?.key??u,description:o?.description})},p.all=((...u)=>{if(typeof u[0]!="string")throw new TypeError("step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let m=u[0],o=u[1];if(typeof o=="function")return H(m,o);if(o&&typeof o=="object"&&!Array.isArray(o)){let n=I(o);return G(n,{name:m})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(u,m)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1,c={scopeId:o,type:"race",winnerId:void 0};Y.push(c);let E=()=>{if(n)return;n=!0;let f=Y.findIndex(w=>w.scopeId===o);f!==-1&&Y.splice(f,1),a({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s,winnerId:c.winnerId})};a({type:"scope_start",workflowId:i,scopeId:o,scopeType:"race",name:u,ts:Date.now()});try{let f=await m();if(E(),!f.ok)throw l?.(f.error,u,_),A(f.error,{origin:"result",resultCause:f.cause});return f.value}catch(f){throw E(),f}})()},p.if=(u,m,o)=>o(),p.label=p.if,p.branch=async(u,m)=>{let{condition:o,then:s,else:n}=m;if(o())return await s();if(n)return await n()},p.arm=(u,m)=>({fn:u,errors:m}),p.forEach=async(u,m,o)=>{let s=[],n=o.maxIterations,c=0,E="run"in o,f=Symbol.asyncIterator in m?m:(async function*(){yield*m})();for await(let w of f){if(n!==void 0&&c>=n)break;let T;E?T=await o.run(w,c):T=await o.item.handler(w,c,p),s.push(T),c++}return s},p.item=u=>({__forEachItemHandler:!0,handler:u}),p.dep=(u,m)=>m,p.workflow=(u,m,o)=>p(u,m,o),p.map=async(u,m,o,s)=>{let n=s?.concurrency??m.length;return p(u,()=>n>=m.length?Ne(m.map((c,E)=>o(c,E))):(async()=>{let c=[];for(let E=0;E<m.length;E+=n){let f=m.slice(E,E+n),w=await Ne(f.map((T,R)=>o(T,E+R)));if(!w.ok)return w;c.push(...w.value)}return q(c)})(),{key:s?.key})},p.withFallback=(u,m,o)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.withFallback() requires an explicit string ID as the first argument. Example: step.withFallback("getUser", () => fetchUser(id), { fallback: () => fetchFromCache(id) })');let s=o.key??u,n=u,c=N(s),E=k;return(async()=>{let f=E?performance.now():0;k&&a({type:"step_start",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now()});let w;try{w=await m()}catch(x){if(D(x))throw a({type:"step_aborted",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-f}),x;let j;try{j=$(x)}catch(b){throw ae(b)}if(o.on!==void 0&&o.on!==j){let b=performance.now()-f;throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:b,error:j}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:b,result:F(j,{cause:x}),meta:{origin:"throw",thrown:x}}),l?.(j,n,_),A(j,{origin:"throw",thrown:x})}let C;try{C=await o.fallback()}catch(b){if(D(b))throw a({type:"step_aborted",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-f}),b;let v;try{v=$(b)}catch(te){throw ae(te)}let oe=performance.now()-f;throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:oe,error:v}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:oe,result:F(v,{cause:b}),meta:{origin:"throw",thrown:b}}),l?.(v,n,_),A(v,{origin:"throw",thrown:b})}if(C.ok){let b=performance.now()-f;return a({type:"step_success",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:b}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:b,result:C,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(j)}}),C.value}else{let b=performance.now()-f,v=U(C.error,{origin:"result",resultCause:C.cause});throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:b,error:v}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:b,result:C,meta:{origin:"result",resultCause:C.cause}}),l?.(v,n,_),A(v,{origin:"result",resultCause:C.cause})}}if(w.ok){let x=performance.now()-f;return a({type:"step_success",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:x}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:x,result:w}),w.value}let T=w.error;if(o.on!==void 0&&o.on!==T){let x=performance.now()-f,j=U(T,{origin:"result",resultCause:w.cause});throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:x,error:j}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:x,result:w,meta:{origin:"result",resultCause:w.cause}}),l?.(j,n,_),A(j,{origin:"result",resultCause:w.cause})}let R;try{R=await o.fallback()}catch(x){if(D(x))throw a({type:"step_aborted",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-f}),x;let j;try{j=$(x)}catch(b){throw ae(b)}let C=performance.now()-f;throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:C,error:j}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:C,result:F(j,{cause:x}),meta:{origin:"throw",thrown:x}}),l?.(j,n,_),A(j,{origin:"throw",thrown:x})}if(R.ok){let x=performance.now()-f;return a({type:"step_success",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:x}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:x,result:R,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(T)}}),R.value}let P=performance.now()-f,K=U(R.error,{origin:"result",resultCause:R.cause});throw a({type:"step_error",workflowId:i,stepId:c,stepKey:s,name:n,ts:Date.now(),durationMs:P,error:K}),s&&a({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:P,result:R,meta:{origin:"result",resultCause:R.cause}}),l?.(K,n,_),A(K,{origin:"result",resultCause:R.cause})})()},p.withResource=(u,m)=>{if(typeof u!="string"||u.length===0)throw new Error('[awaitly] step.withResource() requires an explicit string ID as the first argument. Example: step.withResource("useDb", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })');let o=u,s=u,n=N(o),c=k;return(async()=>{let E=c?performance.now():0;k&&a({type:"step_start",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now()});let f;try{f=await m.acquire()}catch(C){if(D(C))throw a({type:"step_aborted",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:performance.now()-E}),C;let b;try{b=$(C)}catch(oe){throw ae(oe)}let v=performance.now()-E;throw a({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:v,error:b}),o&&a({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:v,result:F(b,{cause:C}),meta:{origin:"throw",thrown:C}}),l?.(b,s,_),A(b,{origin:"throw",thrown:C})}if(!f.ok){let C=performance.now()-E,b=U(f.error,{origin:"result",resultCause:f.cause});throw a({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:C,error:b}),o&&a({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:C,result:f,meta:{origin:"result",resultCause:f.cause}}),l?.(b,s,_),A(b,{origin:"result",resultCause:f.cause})}let w=f.value,T,R,P=!1;try{T=await m.use(w)}catch(C){if(D(C)){try{await m.release(w)}catch(b){console.warn(`[awaitly] step.withResource("${u}"): release threw after earlyExit:`,b)}throw C}R=C,P=!0}try{await m.release(w)}catch(C){console.warn(`[awaitly] step.withResource("${u}"): release threw:`,C)}if(P){let C;try{C=$(R)}catch(v){throw ae(v)}let b=performance.now()-E;throw a({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:b,error:C}),o&&a({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:b,result:F(C,{cause:R}),meta:{origin:"throw",thrown:R}}),l?.(C,s,_),A(C,{origin:"throw",thrown:R})}let K=T;if(K.ok){let C=performance.now()-E;return a({type:"step_success",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:C}),o&&a({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:C,result:K}),K.value}let x=performance.now()-E,j=U(K.error,{origin:"result",resultCause:K.cause});throw a({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:x,error:j}),o&&a({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:x,result:K,meta:{origin:"result",resultCause:K.cause}}),l?.(j,s,_),A(j,{origin:"result",resultCause:K.cause})})()};let L=await d({step:p});if(process.env.NODE_ENV!=="production"&&L!==null&&typeof L=="object"&&"ok"in L&&typeof L.ok=="boolean"){let u=L;(u.ok===!0&&"value"in u||u.ok===!1&&"error"in u)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
2
-
3
- Incorrect: return ok({ data });
4
- Correct: return { data };
5
-
6
- See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return q(L)}catch(p){if(at(p))throw p.thrown;if(D(p)){let H=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return F(p.error,{cause:H})}let I=$(p);return l?.(I,"unexpected",_),F(I,{cause:p})}}xe.strict=(t,e)=>xe(t,e);async function Ne(t){return t.length===0?q([]):new Promise(e=>{let r=!1,d=t.length,y=new Array(t.length);for(let l=0;l<t.length;l++){let k=l;Promise.resolve(t[k]).catch(h=>F({type:"PROMISE_REJECTED",cause:h},{cause:{type:"PROMISE_REJECTION",reason:h}})).then(h=>{if(!r){if(!h.ok){r=!0,e(h);return}y[k]=h.value,d--,d===0&&e(q(y))}})}})}function Ce(t){return t.type==="step_complete"}function Q(t){return typeof t=="object"&&t!==null&&t.type==="PENDING_APPROVAL"}function Be(t){return typeof t=="object"&&t!==null&&t.type==="APPROVAL_REJECTED"}function ce(t,e){let r=new Map(t.steps);return r.set(e.stepKey,{result:q(e.value)}),{steps:r}}function Le(t,e){let r=new Map(t.steps);return r.delete(e),{steps:r}}function Ve(t,e){let r=t.steps.get(e);return!r||r.result.ok?!1:Q(r.result.error)}function He(t){let e=[];for(let[r,d]of t.steps)!d.result.ok&&Q(d.result.error)&&e.push(r);return e}function de(){let t=new Map;return{handleEvent:e=>{Ce(e)&&t.set(e.stepKey,{result:e.result,meta:e.meta})},getResumeState:()=>({steps:new Map(t)}),clear:()=>t.clear(),hasPendingApprovals:()=>{for(let e of t.values())if(!e.result.ok&&Q(e.result.error))return!0;return!1},getPendingApprovals:()=>{let e=[];for(let[r,d]of t)!d.result.ok&&Q(d.result.error)&&e.push({stepKey:r,error:d.result.error});return e},injectApproval:(e,r)=>(t.set(e,{result:q(r)}),{steps:new Map(t)})}}function $e(t,e){return F({type:"PENDING_APPROVAL",stepKey:t,reason:e?.reason,metadata:e?.metadata})}function qe(t){return async()=>{let e=await t.checkApproval();switch(e.status){case"pending":return F({type:"PENDING_APPROVAL",stepKey:t.key,reason:t.pendingReason,metadata:t.metadata});case"rejected":return F({type:"APPROVAL_REJECTED",stepKey:t.key,reason:e.reason});case"approved":return q(e.value)}}}function Ye(t,e){return async r=>{if(!(typeof e.requiresApproval=="function"?await e.requiresApproval(r):e.requiresApproval))return t(r);if(e.checkApproval){let l=await e.checkApproval();switch(l.status){case"approved":return t(r);case"rejected":return F({type:"APPROVAL_REJECTED",stepKey:e.key,reason:l.reason});case"pending":break}}let y=typeof e.description=="function"?e.description(r):e.description;return F({type:"PENDING_APPROVAL",stepKey:e.key,reason:y,metadata:{...e.metadata,pendingArgs:r,gatedOperation:!0}})}}function lt(){let t=new Map;return{async getApproval(e){let r=t.get(e);return r?r.expiresAt&&Date.now()>r.expiresAt?{status:"expired",expiredAt:r.expiresAt}:r:{status:"pending"}},async createApproval(e,r){t.set(e,{status:"pending",metadata:r?.metadata,expiresAt:r?.expiresAt})},async grantApproval(e,r,d){t.set(e,{status:"approved",value:r,approvedBy:d?.approvedBy,approvedAt:Date.now()})},async rejectApproval(e,r,d){t.set(e,{status:"rejected",reason:r,rejectedBy:d?.rejectedBy,rejectedAt:Date.now()})},async editApproval(e,r,d,y){t.set(e,{status:"edited",originalValue:r,editedValue:d,editedBy:y?.editedBy,editedAt:Date.now()})},async cancelApproval(e){t.delete(e)},async listPending(e){let r=[];for(let[d,y]of t)y.status==="pending"&&(!e?.prefix||d.startsWith(e.prefix))&&r.push(d);return r}}}function ct(){let t=new Map;return{async save(e){t.set(e.runId,{...e,updatedAt:Date.now()})},async load(e){return t.get(e)},async delete(e){t.delete(e)},async list(e){let r=[];for(let[d,y]of t)if(!(e?.workflowName&&y.workflowName!==e.workflowName)){if(e?.hasPendingApprovals!==void 0){let l=y.pendingApprovals.length>0;if(e.hasPendingApprovals!==l)continue}r.push(d)}return r},async findByPendingApproval(e){let r=[];for(let[d,y]of t)y.pendingApprovals.includes(e)&&r.push(d);return r}}}function dt(t){let{approvalStore:e,workflowStateStore:r,defaultExpirationMs:d=10080*60*1e3,logger:y=()=>{},notificationChannel:l}=t;async function k(S,N,a,A,D){let U=D?.runId??crypto.randomUUID(),J=de(),se=N({onEvent:J.handleEvent}),Z=A,V=await se.run(async I=>a({...I,args:Z})),p=J.getPendingApprovals().map(I=>I.stepKey);if(p.length>0){let I={runId:U,workflowName:S,resumeState:J.getResumeState(),pendingApprovals:p,input:A,metadata:D?.metadata,startedAt:Date.now(),updatedAt:Date.now()};await r.save(I);let H,G;!V.ok&&Q(V.error)&&(H=V.error.reason,G=V.error.metadata);let ne=Date.now()+d;for(let L of p)await e.createApproval(L,{metadata:{...G,runId:U,workflowName:S},expiresAt:ne});if(l)for(let L of p)try{let u=J.getPendingApprovals().find(m=>m.stepKey===L);await l.onApprovalNeeded({approvalKey:L,runId:U,workflowName:S,reason:H,metadata:{...D?.metadata,...G},expiresAt:ne,summary:H??`Approval needed for ${L}`,pendingArgs:u?.error.metadata})}catch(u){y(`Failed to notify for approval ${L}: ${u}`)}return y(`Workflow ${U} paused, waiting for: ${p.join(", ")}`),{status:"paused",runId:U,pendingApprovals:p,reason:H}}return y(`Workflow ${U} completed`),{status:"completed",result:V}}async function h(S,N,a){let A=await r.load(S);if(!A)throw new Error(`Workflow run not found: ${S}`);for(let p of A.pendingApprovals){let I=await e.getApproval(p);if(I.status==="pending")return{status:"paused",runId:S,pendingApprovals:A.pendingApprovals};if(I.status,I.status==="expired")throw new Error(`Approval ${p} has expired`)}let D=A.resumeState;for(let p of A.pendingApprovals){let I=await e.getApproval(p);I.status==="approved"?D=ce(D,{stepKey:p,value:I.value}):I.status==="edited"&&(D=ce(D,{stepKey:p,value:I.editedValue}))}let U=de(),J=N({resumeState:D,onEvent:U.handleEvent}),se=A.input,Z=await J.run(async p=>a({...p,args:se})),V=U.getPendingApprovals().map(p=>p.stepKey);if(V.length>0){let p={...A,resumeState:U.getResumeState(),pendingApprovals:V,updatedAt:Date.now()};await r.save(p);for(let H of V)await e.createApproval(H,{metadata:{runId:S,workflowName:A.workflowName},expiresAt:Date.now()+d});y(`Workflow ${S} paused again, waiting for: ${V.join(", ")}`);let I;return!Z.ok&&Q(Z.error)&&(I=Z.error.reason),{status:"paused",runId:S,pendingApprovals:V,reason:I}}return await r.delete(S),y(`Workflow ${S} resumed and completed`),{status:"resumed",runId:S,result:Z}}async function M(S,N,a){await e.grantApproval(S,N,{approvedBy:a?.approvedBy});let A=Date.now(),D=[];if(a?.autoResume!==!1){let U=await r.findByPendingApproval(S);for(let J of U)D.push(J)}return l?.onApprovalResolved&&await l.onApprovalResolved({approvalKey:S,action:"approved",actorId:a?.approvedBy,resolvedAt:A,value:N}),y(`Approval ${S} granted by ${a?.approvedBy??"unknown"}`),{grantedAt:A,resumedWorkflows:D}}async function W(S,N,a){await e.rejectApproval(S,N,{rejectedBy:a?.rejectedBy}),l?.onApprovalResolved&&await l.onApprovalResolved({approvalKey:S,action:"rejected",actorId:a?.rejectedBy,resolvedAt:Date.now(),reason:N}),y(`Approval ${S} rejected: ${N}`)}async function _(S,N,a,A){await e.editApproval(S,N,a,{editedBy:A?.editedBy});let D=Date.now();return l?.onApprovalResolved&&await l.onApprovalResolved({approvalKey:S,action:"edited",actorId:A?.editedBy,resolvedAt:D,value:a,originalValue:N}),y(`Approval ${S} edited by ${A?.editedBy??"unknown"}`),{editedAt:D}}async function B(S,N){let{intervalMs:a=1e3,maxPolls:A,timeoutMs:D,onPollStart:U,onPollComplete:J}=N??{},se=Date.now(),Z=0;for(;;){U?.();let V=await e.getApproval(S);if(J?.(V),V.status!=="pending")return V;if(Z++,A!==void 0&&Z>=A)return{status:"pending"};if(D!==void 0&&Date.now()-se>=D)return{status:"pending"};await new Promise(p=>setTimeout(p,a))}}async function i(S){return r.load(S)}async function $(S){return r.list({workflowName:S,hasPendingApprovals:!0})}async function Y(S){let N=await r.list(),a=0,A=Date.now()-S;for(let D of N){let U=await r.load(D);U&&U.updatedAt<A&&U.pendingApprovals.length===0&&(await r.delete(D),a++)}return y(`Cleaned up ${a} old workflow states`),a}return{execute:k,resume:h,grantApproval:M,rejectApproval:W,editApproval:_,pollApproval:B,getWorkflowStatus:i,listPendingWorkflows:$,cleanup:Y}}function Et(t){return async e=>{let{key:r,action:d,value:y,originalValue:l,editedValue:k,reason:h,actorId:M}=e;try{switch(d){case"approve":return await t.grantApproval(r,y,{approvedBy:M}),{success:!0,message:`Approval ${r} granted`,data:{key:r,action:d,timestamp:Date.now()}};case"reject":return h?(await t.rejectApproval(r,h,{rejectedBy:M}),{success:!0,message:`Approval ${r} rejected`,data:{key:r,action:d,timestamp:Date.now()}}):{success:!1,message:"Reason is required for rejection"};case"edit":return l===void 0||k===void 0?{success:!1,message:"Both originalValue and editedValue are required for edit"}:(await t.editApproval(r,l,k,{editedBy:M}),{success:!0,message:`Approval ${r} edited`,data:{key:r,action:d,timestamp:Date.now()}});case"cancel":return await t.cancelApproval(r),{success:!0,message:`Approval ${r} cancelled`,data:{key:r,action:d,timestamp:Date.now()}};default:return{success:!1,message:`Unknown action: ${d}`}}}catch(W){return{success:!1,message:W instanceof Error?W.message:String(W)}}}}function mt(t){return e=>async()=>{let r=await t.getApproval(e);switch(r.status){case"pending":return{status:"pending"};case"approved":return{status:"approved",value:r.value};case"edited":return{status:"approved",value:r.editedValue};case"rejected":return{status:"rejected",reason:r.reason};case"expired":return{status:"rejected",reason:"Approval request expired"};default:return{status:"pending"}}}}export{Le as clearStep,mt as createApprovalChecker,de as createApprovalStateCollector,qe as createApprovalStep,Et as createApprovalWebhookHandler,dt as createHITLOrchestrator,lt as createMemoryApprovalStore,ct as createMemoryWorkflowStateStore,Ye as gatedStep,He as getPendingApprovals,Ve as hasPendingApproval,ce as injectApproval,Be as isApprovalRejected,Q as isPendingApproval,$e as pendingApproval};
7
- //# sourceMappingURL=hitl.js.map