awaitly 2.0.0 → 3.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 (88) hide show
  1. package/dist/di-Biw_plBn.d.cts +15 -0
  2. package/dist/di-DxyH2N3i.d.ts +15 -0
  3. package/dist/durable.cjs +4670 -0
  4. package/dist/durable.cjs.map +1 -0
  5. package/dist/durable.d.cts +9 -0
  6. package/dist/durable.d.ts +9 -0
  7. package/dist/durable.js +4610 -0
  8. package/dist/durable.js.map +1 -0
  9. package/dist/{di-BbFFfO8y.d.ts → duration-BjVn3QpB.d.cts} +1 -15
  10. package/dist/{di-BDlT7InM.d.cts → duration-BjVn3QpB.d.ts} +1 -15
  11. package/dist/engine.cjs +4501 -0
  12. package/dist/engine.cjs.map +1 -0
  13. package/dist/engine.d.cts +113 -0
  14. package/dist/engine.d.ts +113 -0
  15. package/dist/engine.js +4474 -0
  16. package/dist/engine.js.map +1 -0
  17. package/dist/{errors-DtXvrCiO.d.cts → errors-sDSeaZBO.d.cts} +1 -1
  18. package/dist/{errors-DtXvrCiO.d.ts → errors-sDSeaZBO.d.ts} +1 -1
  19. package/dist/guards-CwQZro1F.d.ts +72 -0
  20. package/dist/guards-DhhOJZda.d.cts +72 -0
  21. package/dist/hitl-BnnnLzh2.d.cts +468 -0
  22. package/dist/hitl-pYfkQMv_.d.ts +468 -0
  23. package/dist/hitl.cjs +646 -0
  24. package/dist/hitl.cjs.map +1 -0
  25. package/dist/hitl.d.cts +440 -0
  26. package/dist/hitl.d.ts +440 -0
  27. package/dist/hitl.js +605 -0
  28. package/dist/hitl.js.map +1 -0
  29. package/dist/index-Bew12SZ8.d.ts +417 -0
  30. package/dist/index-Bwt-iz50.d.cts +417 -0
  31. package/dist/{types-B8NfNRGX.d.ts → index-Cv4K_3sZ.d.ts} +2 -1162
  32. package/dist/{types-BZ2f4MRR.d.cts → index-ICmfQi08.d.cts} +2 -1162
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +11 -1527
  35. package/dist/index.d.ts +11 -1527
  36. package/dist/persistence.cjs +552 -0
  37. package/dist/persistence.cjs.map +1 -0
  38. package/dist/persistence.d.cts +254 -0
  39. package/dist/persistence.d.ts +254 -0
  40. package/dist/persistence.js +499 -0
  41. package/dist/persistence.js.map +1 -0
  42. package/dist/reliability.cjs +1651 -0
  43. package/dist/reliability.cjs.map +1 -0
  44. package/dist/reliability.d.cts +1442 -0
  45. package/dist/reliability.d.ts +1442 -0
  46. package/dist/reliability.js +1589 -0
  47. package/dist/reliability.js.map +1 -0
  48. package/dist/result.d.cts +1 -1
  49. package/dist/result.d.ts +1 -1
  50. package/dist/run.cjs +2283 -0
  51. package/dist/run.cjs.map +1 -0
  52. package/dist/run.d.cts +90 -0
  53. package/dist/run.d.ts +90 -0
  54. package/dist/run.js +2247 -0
  55. package/dist/run.js.map +1 -0
  56. package/dist/saga.cjs +3699 -0
  57. package/dist/saga.cjs.map +1 -0
  58. package/dist/saga.d.cts +162 -0
  59. package/dist/saga.d.ts +162 -0
  60. package/dist/saga.js +3670 -0
  61. package/dist/saga.js.map +1 -0
  62. package/dist/store-contract-BI98VYmX.d.ts +66 -0
  63. package/dist/store-contract-C2HyR_o6.d.cts +66 -0
  64. package/dist/streaming.cjs +895 -0
  65. package/dist/streaming.cjs.map +1 -0
  66. package/dist/streaming.d.cts +594 -0
  67. package/dist/streaming.d.ts +594 -0
  68. package/dist/streaming.js +832 -0
  69. package/dist/streaming.js.map +1 -0
  70. package/dist/testing.d.cts +4 -2
  71. package/dist/testing.d.ts +4 -2
  72. package/dist/types-BDTxgKKc.d.ts +845 -0
  73. package/dist/types-C9Y71dua.d.cts +845 -0
  74. package/dist/types-d8q8iQlk.d.cts +323 -0
  75. package/dist/types-sObbY4mX.d.ts +323 -0
  76. package/dist/webhook.cjs +461 -0
  77. package/dist/webhook.cjs.map +1 -0
  78. package/dist/webhook.d.cts +497 -0
  79. package/dist/webhook.d.ts +497 -0
  80. package/dist/webhook.js +422 -0
  81. package/dist/webhook.js.map +1 -0
  82. package/dist/workflow.cjs +2 -2614
  83. package/dist/workflow.cjs.map +1 -1
  84. package/dist/workflow.d.cts +12 -3023
  85. package/dist/workflow.d.ts +12 -3023
  86. package/dist/workflow.js +2 -2535
  87. package/dist/workflow.js.map +1 -1
  88. package/package.json +46 -1
@@ -0,0 +1,440 @@
1
+ import { R as ResumeState, W as Workflow } from './types-C9Y71dua.cjs';
2
+ export { A as ApprovalRejected, a as ApprovalStepOptions, G as GatedStepOptions, P as PendingApproval } from './types-C9Y71dua.cjs';
3
+ export { i as isApprovalRejected, a as isPendingApproval } from './guards-DhhOJZda.cjs';
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-BnnnLzh2.cjs';
5
+ import { R as Result, W as WorkflowEvent } from './index-ICmfQi08.cjs';
6
+ import './types-d8q8iQlk.cjs';
7
+ import '@standard-schema/spec';
8
+ import './errors-sDSeaZBO.cjs';
9
+
10
+ /**
11
+ * awaitly/hitl
12
+ *
13
+ * Human-in-the-Loop Orchestration Helpers.
14
+ * Provides pollers, webhook handlers, and resume injectors
15
+ * for production-ready approval workflows.
16
+ */
17
+
18
+ /**
19
+ * Options passed to the workflow factory by the HITL orchestrator.
20
+ */
21
+ interface HITLWorkflowFactoryOptions {
22
+ /** Resume state for replaying completed steps */
23
+ resumeState?: ResumeState;
24
+ /** Event handler for tracking workflow events (required for HITL) */
25
+ onEvent: (event: WorkflowEvent<unknown>) => void;
26
+ }
27
+ /**
28
+ * Approval status returned from the approval store.
29
+ */
30
+ type ApprovalStatus<T = unknown> = {
31
+ status: "pending";
32
+ } | {
33
+ status: "approved";
34
+ value: T;
35
+ approvedBy?: string;
36
+ approvedAt?: number;
37
+ } | {
38
+ status: "rejected";
39
+ reason: string;
40
+ rejectedBy?: string;
41
+ rejectedAt?: number;
42
+ } | {
43
+ status: "expired";
44
+ expiredAt: number;
45
+ } | {
46
+ status: "edited";
47
+ originalValue: T;
48
+ editedValue: T;
49
+ editedBy?: string;
50
+ editedAt?: number;
51
+ };
52
+ /**
53
+ * Context passed to notification channel when an approval is needed.
54
+ */
55
+ interface ApprovalNeededContext {
56
+ /** Unique approval key for correlation */
57
+ approvalKey: string;
58
+ /** Workflow run ID */
59
+ runId: string;
60
+ /** Workflow name/type */
61
+ workflowName: string;
62
+ /** Human-readable reason for the approval */
63
+ reason?: string;
64
+ /** Custom metadata attached to the approval */
65
+ metadata?: Record<string, unknown>;
66
+ /** When the approval expires (timestamp) */
67
+ expiresAt?: number;
68
+ /** Human-readable summary for notifications */
69
+ summary?: string;
70
+ /** For gated steps: the operation args that need approval */
71
+ pendingArgs?: Record<string, unknown>;
72
+ }
73
+ /**
74
+ * Context passed to notification channel when an approval is resolved.
75
+ */
76
+ interface ApprovalResolvedContext {
77
+ /** Unique approval key */
78
+ approvalKey: string;
79
+ /** Resolution action */
80
+ action: "approved" | "rejected" | "edited" | "expired" | "cancelled";
81
+ /** Who performed the action (if available) */
82
+ actorId?: string;
83
+ /** Timestamp of resolution */
84
+ resolvedAt: number;
85
+ /** Reason (for rejections) */
86
+ reason?: string;
87
+ /** Value (for approvals/edits) */
88
+ value?: unknown;
89
+ /** Original value (for edits) */
90
+ originalValue?: unknown;
91
+ }
92
+ /**
93
+ * Notification channel for external integrations (Slack, email, etc).
94
+ * Implement this interface to receive push notifications when approvals
95
+ * are created or resolved.
96
+ */
97
+ interface NotificationChannel {
98
+ /**
99
+ * Called when a new approval request is created.
100
+ * Use this to send Slack messages, emails, or push to a UI.
101
+ */
102
+ onApprovalNeeded(context: ApprovalNeededContext): Promise<void>;
103
+ /**
104
+ * Called when an approval is granted, rejected, edited, or expires.
105
+ * Use this to update Slack messages, send confirmation emails, etc.
106
+ */
107
+ onApprovalResolved?(context: ApprovalResolvedContext): Promise<void>;
108
+ }
109
+ /**
110
+ * Interface for approval storage backends.
111
+ */
112
+ interface ApprovalStore {
113
+ /**
114
+ * Get the status of an approval.
115
+ */
116
+ getApproval(key: string): Promise<ApprovalStatus>;
117
+ /**
118
+ * Create or update a pending approval request.
119
+ */
120
+ createApproval(key: string, options?: {
121
+ metadata?: Record<string, unknown>;
122
+ expiresAt?: number;
123
+ requestedBy?: string;
124
+ }): Promise<void>;
125
+ /**
126
+ * Grant an approval.
127
+ */
128
+ grantApproval<T>(key: string, value: T, options?: {
129
+ approvedBy?: string;
130
+ }): Promise<void>;
131
+ /**
132
+ * Reject an approval.
133
+ */
134
+ rejectApproval(key: string, reason: string, options?: {
135
+ rejectedBy?: string;
136
+ }): Promise<void>;
137
+ /**
138
+ * Edit an approval (approve with modifications).
139
+ * Records both the original proposed value and the edited value.
140
+ */
141
+ editApproval<T>(key: string, originalValue: T, editedValue: T, options?: {
142
+ editedBy?: string;
143
+ }): Promise<void>;
144
+ /**
145
+ * Cancel a pending approval.
146
+ */
147
+ cancelApproval(key: string): Promise<void>;
148
+ /**
149
+ * List all pending approvals.
150
+ */
151
+ listPending(options?: {
152
+ prefix?: string;
153
+ }): Promise<string[]>;
154
+ }
155
+ /**
156
+ * Saved workflow state for resumption.
157
+ */
158
+ interface SavedWorkflowState {
159
+ /** Unique identifier for this workflow run */
160
+ runId: string;
161
+ /** Workflow name/type */
162
+ workflowName: string;
163
+ /** Resume state with step results */
164
+ resumeState: ResumeState;
165
+ /** Pending approval keys */
166
+ pendingApprovals: string[];
167
+ /** Input that was passed to the workflow */
168
+ input?: unknown;
169
+ /** Custom metadata */
170
+ metadata?: Record<string, unknown>;
171
+ /** When the workflow was started */
172
+ startedAt: number;
173
+ /** When the state was last updated */
174
+ updatedAt: number;
175
+ }
176
+ /**
177
+ * Interface for workflow state storage.
178
+ */
179
+ interface WorkflowStateStore {
180
+ /**
181
+ * Save workflow state.
182
+ */
183
+ save(state: SavedWorkflowState): Promise<void>;
184
+ /**
185
+ * Load workflow state by run ID.
186
+ */
187
+ load(runId: string): Promise<SavedWorkflowState | undefined>;
188
+ /**
189
+ * Delete workflow state.
190
+ */
191
+ delete(runId: string): Promise<void>;
192
+ /**
193
+ * List all saved workflow states.
194
+ */
195
+ list(options?: {
196
+ workflowName?: string;
197
+ hasPendingApprovals?: boolean;
198
+ }): Promise<string[]>;
199
+ /**
200
+ * Find workflows waiting for a specific approval.
201
+ */
202
+ findByPendingApproval(approvalKey: string): Promise<string[]>;
203
+ }
204
+ /**
205
+ * Options for the HITL orchestrator.
206
+ */
207
+ interface HITLOrchestratorOptions {
208
+ /** Approval store for managing approval states */
209
+ approvalStore: ApprovalStore;
210
+ /** Workflow state store for persisting workflow state */
211
+ workflowStateStore: WorkflowStateStore;
212
+ /** Default expiration time for approvals (in milliseconds) */
213
+ defaultExpirationMs?: number;
214
+ /** Logger function */
215
+ logger?: (message: string) => void;
216
+ /**
217
+ * Notification channel for external integrations.
218
+ * When provided, the orchestrator will call onApprovalNeeded when
219
+ * an approval is created, and onApprovalResolved when resolved.
220
+ */
221
+ notificationChannel?: NotificationChannel;
222
+ }
223
+ /**
224
+ * Result of executing a workflow that may pause for approval.
225
+ * Uses unknown for error type since workflows add UnexpectedError to the union.
226
+ */
227
+ type HITLExecutionResult<T, E> = {
228
+ status: "completed";
229
+ result: Result<T, E | unknown>;
230
+ } | {
231
+ status: "paused";
232
+ runId: string;
233
+ pendingApprovals: string[];
234
+ reason?: string;
235
+ } | {
236
+ status: "resumed";
237
+ runId: string;
238
+ result: Result<T, E | unknown>;
239
+ };
240
+ /**
241
+ * Poller configuration.
242
+ */
243
+ interface PollerOptions {
244
+ /** Polling interval in milliseconds */
245
+ intervalMs: number;
246
+ /** Maximum number of polls (undefined = unlimited) */
247
+ maxPolls?: number;
248
+ /** Timeout for the entire polling operation */
249
+ timeoutMs?: number;
250
+ /** Callback when polling starts */
251
+ onPollStart?: () => void;
252
+ /** Callback when a poll completes */
253
+ onPollComplete?: (result: ApprovalStatus) => void;
254
+ }
255
+ /**
256
+ * Create an in-memory approval store for development/testing.
257
+ */
258
+ declare function createMemoryApprovalStore(): ApprovalStore;
259
+ /**
260
+ * Create an in-memory workflow state store for development/testing.
261
+ */
262
+ declare function createMemoryWorkflowStateStore(): WorkflowStateStore;
263
+ /**
264
+ * HITL orchestrator interface.
265
+ */
266
+ interface HITLOrchestrator {
267
+ /**
268
+ * Execute a workflow that may pause for approvals.
269
+ * If the workflow pauses, state is automatically saved.
270
+ *
271
+ * The workflowFactory receives options including onEvent handler which MUST be
272
+ * passed to createWorkflow for HITL tracking to work.
273
+ */
274
+ execute<T, E, TInput>(workflowName: string, workflowFactory: (options: HITLWorkflowFactoryOptions) => Workflow<E, unknown>, workflowFn: (context: {
275
+ step: unknown;
276
+ deps: unknown;
277
+ args: TInput;
278
+ }) => Promise<T>, input: TInput, options?: {
279
+ runId?: string;
280
+ metadata?: Record<string, unknown>;
281
+ }): Promise<HITLExecutionResult<T, E>>;
282
+ /**
283
+ * Resume a paused workflow after approvals have been granted.
284
+ */
285
+ resume<T, E, TInput>(runId: string, workflowFactory: (options: HITLWorkflowFactoryOptions) => Workflow<E, unknown>, workflowFn: (context: {
286
+ step: unknown;
287
+ deps: unknown;
288
+ args: TInput;
289
+ }) => Promise<T>): Promise<HITLExecutionResult<T, E>>;
290
+ /**
291
+ * Grant an approval and automatically resume any waiting workflows.
292
+ */
293
+ grantApproval<T>(approvalKey: string, value: T, options?: {
294
+ approvedBy?: string;
295
+ autoResume?: boolean;
296
+ }): Promise<{
297
+ grantedAt: number;
298
+ resumedWorkflows: string[];
299
+ }>;
300
+ /**
301
+ * Reject an approval.
302
+ */
303
+ rejectApproval(approvalKey: string, reason: string, options?: {
304
+ rejectedBy?: string;
305
+ }): Promise<void>;
306
+ /**
307
+ * Edit an approval (approve with modifications).
308
+ * Use this when a human wants to approve but with changes to the proposed value.
309
+ * Records both the original and edited values for audit trail.
310
+ */
311
+ editApproval<T>(approvalKey: string, originalValue: T, editedValue: T, options?: {
312
+ editedBy?: string;
313
+ }): Promise<{
314
+ editedAt: number;
315
+ }>;
316
+ /**
317
+ * Poll for an approval to be granted.
318
+ */
319
+ pollApproval<T>(approvalKey: string, options?: PollerOptions): Promise<ApprovalStatus<T>>;
320
+ /**
321
+ * Get the status of a workflow run.
322
+ */
323
+ getWorkflowStatus(runId: string): Promise<SavedWorkflowState | undefined>;
324
+ /**
325
+ * List all pending workflows.
326
+ */
327
+ listPendingWorkflows(workflowName?: string): Promise<string[]>;
328
+ /**
329
+ * Clean up completed workflows older than the specified age.
330
+ */
331
+ cleanup(maxAgeMs: number): Promise<number>;
332
+ }
333
+ /**
334
+ * Create a HITL orchestrator for managing approval workflows.
335
+ *
336
+ * @example
337
+ * ```typescript
338
+ * const orchestrator = createHITLOrchestrator({
339
+ * approvalStore: createMemoryApprovalStore(),
340
+ * workflowStateStore: createMemoryWorkflowStateStore(),
341
+ * });
342
+ *
343
+ * // Execute workflow - IMPORTANT: pass onEvent to createWorkflow!
344
+ * const result = await orchestrator.execute(
345
+ * 'order-approval',
346
+ * ({ resumeState, onEvent }) => createWorkflow('order-approval', deps, { resumeState, onEvent }),
347
+ * async ({ step, deps, args: input }) => {
348
+ * const order = await step(() => deps.createOrder(input));
349
+ * const approval = await step(() => deps.requireApproval(order.id), { key: `approval:${order.id}` });
350
+ * await step(() => deps.processOrder(order.id));
351
+ * return { orderId: order.id, approvedBy: approval.approvedBy };
352
+ * },
353
+ * { items: [...], total: 100 }
354
+ * );
355
+ *
356
+ * if (result.status === 'paused') {
357
+ * console.log(`Workflow paused, waiting for: ${result.pendingApprovals}`);
358
+ * }
359
+ *
360
+ * // Later, grant approval
361
+ * await orchestrator.grantApproval(
362
+ * `approval:${orderId}`,
363
+ * { approvedBy: 'manager@example.com' },
364
+ * { autoResume: true }
365
+ * );
366
+ * ```
367
+ */
368
+ declare function createHITLOrchestrator(options: HITLOrchestratorOptions): HITLOrchestrator;
369
+ /**
370
+ * Approval webhook request body.
371
+ */
372
+ interface ApprovalWebhookRequest {
373
+ /** Approval key */
374
+ key: string;
375
+ /** Action: approve, reject, edit, or cancel */
376
+ action: "approve" | "reject" | "edit" | "cancel";
377
+ /** Value to inject (for approve) */
378
+ value?: unknown;
379
+ /** Original value (for edit - what was proposed) */
380
+ originalValue?: unknown;
381
+ /** Edited value (for edit - what human changed it to) */
382
+ editedValue?: unknown;
383
+ /** Reason (for reject) */
384
+ reason?: string;
385
+ /** Who performed this action */
386
+ actorId?: string;
387
+ }
388
+ /**
389
+ * Approval webhook response.
390
+ */
391
+ interface ApprovalWebhookResponse {
392
+ success: boolean;
393
+ message: string;
394
+ data?: {
395
+ key: string;
396
+ action: string;
397
+ timestamp: number;
398
+ };
399
+ }
400
+ /**
401
+ * Create a webhook handler for approval actions.
402
+ *
403
+ * @example
404
+ * ```typescript
405
+ * const handleApproval = createApprovalWebhookHandler(approvalStore);
406
+ *
407
+ * // Express
408
+ * app.post('/api/approvals', async (req, res) => {
409
+ * const result = await handleApproval(req.body);
410
+ * res.json(result);
411
+ * });
412
+ * ```
413
+ */
414
+ declare function createApprovalWebhookHandler(store: ApprovalStore): (request: ApprovalWebhookRequest) => Promise<ApprovalWebhookResponse>;
415
+ /**
416
+ * Create an approval checker function for use in approval steps.
417
+ * This wraps the approval store with the standard checkApproval interface.
418
+ *
419
+ * @example
420
+ * ```typescript
421
+ * const checkApproval = createApprovalChecker(approvalStore);
422
+ *
423
+ * const requireManagerApproval = createApprovalStep<{ approvedBy: string }>({
424
+ * key: 'manager-approval',
425
+ * checkApproval: checkApproval('manager-approval'),
426
+ * pendingReason: 'Waiting for manager approval',
427
+ * });
428
+ * ```
429
+ */
430
+ declare function createApprovalChecker<T>(store: ApprovalStore): (key: string) => () => Promise<{
431
+ status: "pending";
432
+ } | {
433
+ status: "approved";
434
+ value: T;
435
+ } | {
436
+ status: "rejected";
437
+ reason: string;
438
+ }>;
439
+
440
+ 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 };