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
package/dist/hitl.js ADDED
@@ -0,0 +1,605 @@
1
+ // src/core/index.ts
2
+ function ok(value) {
3
+ return { ok: true, value };
4
+ }
5
+ function err(error, options) {
6
+ const cause = options?.cause;
7
+ return { ok: false, error, ...cause !== void 0 ? { cause } : {} };
8
+ }
9
+
10
+ // src/workflow/guards.ts
11
+ function isStepComplete(event) {
12
+ return event.type === "step_complete";
13
+ }
14
+ function isPendingApproval(error) {
15
+ return typeof error === "object" && error !== null && error.type === "PENDING_APPROVAL";
16
+ }
17
+ function isApprovalRejected(error) {
18
+ return typeof error === "object" && error !== null && error.type === "APPROVAL_REJECTED";
19
+ }
20
+
21
+ // src/workflow/resume-state.ts
22
+ function injectApproval(state, options) {
23
+ const newSteps = new Map(state.steps);
24
+ newSteps.set(options.stepKey, {
25
+ result: ok(options.value)
26
+ });
27
+ return { steps: newSteps };
28
+ }
29
+ function clearStep(state, stepKey) {
30
+ const newSteps = new Map(state.steps);
31
+ newSteps.delete(stepKey);
32
+ return { steps: newSteps };
33
+ }
34
+ function hasPendingApproval(state, stepKey) {
35
+ const entry = state.steps.get(stepKey);
36
+ if (!entry || entry.result.ok) return false;
37
+ return isPendingApproval(entry.result.error);
38
+ }
39
+ function getPendingApprovals(state) {
40
+ const pending = [];
41
+ for (const [key, entry] of state.steps) {
42
+ if (!entry.result.ok && isPendingApproval(entry.result.error)) {
43
+ pending.push(key);
44
+ }
45
+ }
46
+ return pending;
47
+ }
48
+ function createApprovalStateCollector() {
49
+ const steps = /* @__PURE__ */ new Map();
50
+ return {
51
+ handleEvent: (event) => {
52
+ if (isStepComplete(event)) {
53
+ steps.set(event.stepKey, { result: event.result, meta: event.meta });
54
+ }
55
+ },
56
+ getResumeState: () => ({ steps: new Map(steps) }),
57
+ clear: () => steps.clear(),
58
+ hasPendingApprovals: () => {
59
+ for (const entry of steps.values()) {
60
+ if (!entry.result.ok && isPendingApproval(entry.result.error)) {
61
+ return true;
62
+ }
63
+ }
64
+ return false;
65
+ },
66
+ getPendingApprovals: () => {
67
+ const pending = [];
68
+ for (const [key, entry] of steps) {
69
+ if (!entry.result.ok && isPendingApproval(entry.result.error)) {
70
+ pending.push({ stepKey: key, error: entry.result.error });
71
+ }
72
+ }
73
+ return pending;
74
+ },
75
+ injectApproval: (stepKey, value) => {
76
+ steps.set(stepKey, { result: ok(value) });
77
+ return { steps: new Map(steps) };
78
+ }
79
+ };
80
+ }
81
+
82
+ // src/workflow/hitl.ts
83
+ function pendingApproval(stepKey, options) {
84
+ return err({
85
+ type: "PENDING_APPROVAL",
86
+ stepKey,
87
+ reason: options?.reason,
88
+ metadata: options?.metadata
89
+ });
90
+ }
91
+ function createApprovalStep(options) {
92
+ return async () => {
93
+ const result = await options.checkApproval();
94
+ switch (result.status) {
95
+ case "pending":
96
+ return err({
97
+ type: "PENDING_APPROVAL",
98
+ stepKey: options.key,
99
+ reason: options.pendingReason,
100
+ metadata: options.metadata
101
+ });
102
+ case "rejected":
103
+ return err({
104
+ type: "APPROVAL_REJECTED",
105
+ stepKey: options.key,
106
+ reason: result.reason
107
+ });
108
+ case "approved":
109
+ return ok(result.value);
110
+ }
111
+ };
112
+ }
113
+ function gatedStep(operation, options) {
114
+ return async (args) => {
115
+ const requiresApproval = typeof options.requiresApproval === "function" ? await options.requiresApproval(args) : options.requiresApproval;
116
+ if (!requiresApproval) {
117
+ return operation(args);
118
+ }
119
+ if (options.checkApproval) {
120
+ const approvalStatus = await options.checkApproval();
121
+ switch (approvalStatus.status) {
122
+ case "approved":
123
+ return operation(args);
124
+ case "rejected":
125
+ return err({
126
+ type: "APPROVAL_REJECTED",
127
+ stepKey: options.key,
128
+ reason: approvalStatus.reason
129
+ });
130
+ case "pending":
131
+ break;
132
+ }
133
+ }
134
+ const description = typeof options.description === "function" ? options.description(args) : options.description;
135
+ return err({
136
+ type: "PENDING_APPROVAL",
137
+ stepKey: options.key,
138
+ reason: description,
139
+ metadata: {
140
+ ...options.metadata,
141
+ pendingArgs: args,
142
+ gatedOperation: true
143
+ }
144
+ });
145
+ };
146
+ }
147
+
148
+ // src/hitl/index.ts
149
+ function createMemoryApprovalStore() {
150
+ const approvals = /* @__PURE__ */ new Map();
151
+ return {
152
+ async getApproval(key) {
153
+ const approval = approvals.get(key);
154
+ if (!approval) {
155
+ return { status: "pending" };
156
+ }
157
+ if (approval.expiresAt && Date.now() > approval.expiresAt) {
158
+ return { status: "expired", expiredAt: approval.expiresAt };
159
+ }
160
+ return approval;
161
+ },
162
+ async createApproval(key, options) {
163
+ approvals.set(key, {
164
+ status: "pending",
165
+ metadata: options?.metadata,
166
+ expiresAt: options?.expiresAt
167
+ });
168
+ },
169
+ async grantApproval(key, value, options) {
170
+ approvals.set(key, {
171
+ status: "approved",
172
+ value,
173
+ approvedBy: options?.approvedBy,
174
+ approvedAt: Date.now()
175
+ });
176
+ },
177
+ async rejectApproval(key, reason, options) {
178
+ approvals.set(key, {
179
+ status: "rejected",
180
+ reason,
181
+ rejectedBy: options?.rejectedBy,
182
+ rejectedAt: Date.now()
183
+ });
184
+ },
185
+ async editApproval(key, originalValue, editedValue, options) {
186
+ approvals.set(key, {
187
+ status: "edited",
188
+ originalValue,
189
+ editedValue,
190
+ editedBy: options?.editedBy,
191
+ editedAt: Date.now()
192
+ });
193
+ },
194
+ async cancelApproval(key) {
195
+ approvals.delete(key);
196
+ },
197
+ async listPending(options) {
198
+ const pending = [];
199
+ for (const [key, approval] of approvals) {
200
+ if (approval.status === "pending") {
201
+ if (!options?.prefix || key.startsWith(options.prefix)) {
202
+ pending.push(key);
203
+ }
204
+ }
205
+ }
206
+ return pending;
207
+ }
208
+ };
209
+ }
210
+ function createMemoryWorkflowStateStore() {
211
+ const states = /* @__PURE__ */ new Map();
212
+ return {
213
+ async save(state) {
214
+ states.set(state.runId, { ...state, updatedAt: Date.now() });
215
+ },
216
+ async load(runId) {
217
+ return states.get(runId);
218
+ },
219
+ async delete(runId) {
220
+ states.delete(runId);
221
+ },
222
+ async list(options) {
223
+ const results = [];
224
+ for (const [runId, state] of states) {
225
+ if (options?.workflowName && state.workflowName !== options.workflowName) {
226
+ continue;
227
+ }
228
+ if (options?.hasPendingApprovals !== void 0) {
229
+ const hasPending = state.pendingApprovals.length > 0;
230
+ if (options.hasPendingApprovals !== hasPending) {
231
+ continue;
232
+ }
233
+ }
234
+ results.push(runId);
235
+ }
236
+ return results;
237
+ },
238
+ async findByPendingApproval(approvalKey) {
239
+ const results = [];
240
+ for (const [runId, state] of states) {
241
+ if (state.pendingApprovals.includes(approvalKey)) {
242
+ results.push(runId);
243
+ }
244
+ }
245
+ return results;
246
+ }
247
+ };
248
+ }
249
+ function createHITLOrchestrator(options) {
250
+ const {
251
+ approvalStore,
252
+ workflowStateStore,
253
+ defaultExpirationMs = 7 * 24 * 60 * 60 * 1e3,
254
+ // 7 days
255
+ logger = () => {
256
+ },
257
+ notificationChannel
258
+ } = options;
259
+ async function execute(workflowName, workflowFactory, workflowFn, input, opts) {
260
+ const runId = opts?.runId ?? crypto.randomUUID();
261
+ const collector = createApprovalStateCollector();
262
+ const workflow = workflowFactory({
263
+ onEvent: collector.handleEvent
264
+ });
265
+ const args = input;
266
+ const result = await workflow.run(
267
+ async (context) => workflowFn({ ...context, args })
268
+ );
269
+ const pendingApprovals = collector.getPendingApprovals().map((p) => p.stepKey);
270
+ if (pendingApprovals.length > 0) {
271
+ const state = {
272
+ runId,
273
+ workflowName,
274
+ resumeState: collector.getResumeState(),
275
+ pendingApprovals,
276
+ input,
277
+ metadata: opts?.metadata,
278
+ startedAt: Date.now(),
279
+ updatedAt: Date.now()
280
+ };
281
+ await workflowStateStore.save(state);
282
+ let reason;
283
+ let pendingMetadata;
284
+ if (!result.ok && isPendingApproval(result.error)) {
285
+ reason = result.error.reason;
286
+ pendingMetadata = result.error.metadata;
287
+ }
288
+ const expiresAt = Date.now() + defaultExpirationMs;
289
+ for (const key of pendingApprovals) {
290
+ await approvalStore.createApproval(key, {
291
+ metadata: { ...pendingMetadata, runId, workflowName },
292
+ expiresAt
293
+ });
294
+ }
295
+ if (notificationChannel) {
296
+ for (const key of pendingApprovals) {
297
+ try {
298
+ const pendingInfo = collector.getPendingApprovals().find((p) => p.stepKey === key);
299
+ await notificationChannel.onApprovalNeeded({
300
+ approvalKey: key,
301
+ runId,
302
+ workflowName,
303
+ reason,
304
+ metadata: { ...opts?.metadata, ...pendingMetadata },
305
+ expiresAt,
306
+ summary: reason ?? `Approval needed for ${key}`,
307
+ pendingArgs: pendingInfo?.error.metadata
308
+ });
309
+ } catch (notifyError) {
310
+ logger(`Failed to notify for approval ${key}: ${notifyError}`);
311
+ }
312
+ }
313
+ }
314
+ logger(`Workflow ${runId} paused, waiting for: ${pendingApprovals.join(", ")}`);
315
+ return {
316
+ status: "paused",
317
+ runId,
318
+ pendingApprovals,
319
+ reason
320
+ };
321
+ }
322
+ logger(`Workflow ${runId} completed`);
323
+ return { status: "completed", result };
324
+ }
325
+ async function resume(runId, workflowFactory, workflowFn) {
326
+ const savedState = await workflowStateStore.load(runId);
327
+ if (!savedState) {
328
+ throw new Error(`Workflow run not found: ${runId}`);
329
+ }
330
+ for (const key of savedState.pendingApprovals) {
331
+ const status = await approvalStore.getApproval(key);
332
+ if (status.status === "pending") {
333
+ return {
334
+ status: "paused",
335
+ runId,
336
+ pendingApprovals: savedState.pendingApprovals
337
+ };
338
+ }
339
+ if (status.status === "rejected") {
340
+ }
341
+ if (status.status === "expired") {
342
+ throw new Error(`Approval ${key} has expired`);
343
+ }
344
+ }
345
+ let resumeState = savedState.resumeState;
346
+ for (const key of savedState.pendingApprovals) {
347
+ const status = await approvalStore.getApproval(key);
348
+ if (status.status === "approved") {
349
+ resumeState = injectApproval(resumeState, {
350
+ stepKey: key,
351
+ value: status.value
352
+ });
353
+ } else if (status.status === "edited") {
354
+ resumeState = injectApproval(resumeState, {
355
+ stepKey: key,
356
+ value: status.editedValue
357
+ });
358
+ }
359
+ }
360
+ const collector = createApprovalStateCollector();
361
+ const workflow = workflowFactory({
362
+ resumeState,
363
+ onEvent: collector.handleEvent
364
+ });
365
+ const args = savedState.input;
366
+ const result = await workflow.run(
367
+ async (context) => workflowFn({ ...context, args })
368
+ );
369
+ const newPendingApprovals = collector.getPendingApprovals().map((p) => p.stepKey);
370
+ if (newPendingApprovals.length > 0) {
371
+ const updatedState = {
372
+ ...savedState,
373
+ resumeState: collector.getResumeState(),
374
+ pendingApprovals: newPendingApprovals,
375
+ updatedAt: Date.now()
376
+ };
377
+ await workflowStateStore.save(updatedState);
378
+ for (const key of newPendingApprovals) {
379
+ await approvalStore.createApproval(key, {
380
+ metadata: { runId, workflowName: savedState.workflowName },
381
+ expiresAt: Date.now() + defaultExpirationMs
382
+ });
383
+ }
384
+ logger(`Workflow ${runId} paused again, waiting for: ${newPendingApprovals.join(", ")}`);
385
+ let reason;
386
+ if (!result.ok && isPendingApproval(result.error)) {
387
+ reason = result.error.reason;
388
+ }
389
+ return {
390
+ status: "paused",
391
+ runId,
392
+ pendingApprovals: newPendingApprovals,
393
+ reason
394
+ };
395
+ }
396
+ await workflowStateStore.delete(runId);
397
+ logger(`Workflow ${runId} resumed and completed`);
398
+ return { status: "resumed", runId, result };
399
+ }
400
+ async function grantApprovalFn(approvalKey, value, opts) {
401
+ await approvalStore.grantApproval(approvalKey, value, {
402
+ approvedBy: opts?.approvedBy
403
+ });
404
+ const grantedAt = Date.now();
405
+ const resumedWorkflows = [];
406
+ if (opts?.autoResume !== false) {
407
+ const waitingWorkflows = await workflowStateStore.findByPendingApproval(approvalKey);
408
+ for (const runId of waitingWorkflows) {
409
+ resumedWorkflows.push(runId);
410
+ }
411
+ }
412
+ if (notificationChannel?.onApprovalResolved) {
413
+ await notificationChannel.onApprovalResolved({
414
+ approvalKey,
415
+ action: "approved",
416
+ actorId: opts?.approvedBy,
417
+ resolvedAt: grantedAt,
418
+ value
419
+ });
420
+ }
421
+ logger(`Approval ${approvalKey} granted by ${opts?.approvedBy ?? "unknown"}`);
422
+ return { grantedAt, resumedWorkflows };
423
+ }
424
+ async function rejectApprovalFn(approvalKey, reason, opts) {
425
+ await approvalStore.rejectApproval(approvalKey, reason, {
426
+ rejectedBy: opts?.rejectedBy
427
+ });
428
+ if (notificationChannel?.onApprovalResolved) {
429
+ await notificationChannel.onApprovalResolved({
430
+ approvalKey,
431
+ action: "rejected",
432
+ actorId: opts?.rejectedBy,
433
+ resolvedAt: Date.now(),
434
+ reason
435
+ });
436
+ }
437
+ logger(`Approval ${approvalKey} rejected: ${reason}`);
438
+ }
439
+ async function editApprovalFn(approvalKey, originalValue, editedValue, opts) {
440
+ await approvalStore.editApproval(approvalKey, originalValue, editedValue, {
441
+ editedBy: opts?.editedBy
442
+ });
443
+ const editedAt = Date.now();
444
+ if (notificationChannel?.onApprovalResolved) {
445
+ await notificationChannel.onApprovalResolved({
446
+ approvalKey,
447
+ action: "edited",
448
+ actorId: opts?.editedBy,
449
+ resolvedAt: editedAt,
450
+ value: editedValue,
451
+ originalValue
452
+ });
453
+ }
454
+ logger(`Approval ${approvalKey} edited by ${opts?.editedBy ?? "unknown"}`);
455
+ return { editedAt };
456
+ }
457
+ async function pollApproval(approvalKey, opts) {
458
+ const {
459
+ intervalMs = 1e3,
460
+ maxPolls,
461
+ timeoutMs,
462
+ onPollStart,
463
+ onPollComplete
464
+ } = opts ?? {};
465
+ const startTime = Date.now();
466
+ let pollCount = 0;
467
+ while (true) {
468
+ onPollStart?.();
469
+ const status = await approvalStore.getApproval(approvalKey);
470
+ onPollComplete?.(status);
471
+ if (status.status !== "pending") {
472
+ return status;
473
+ }
474
+ pollCount++;
475
+ if (maxPolls !== void 0 && pollCount >= maxPolls) {
476
+ return { status: "pending" };
477
+ }
478
+ if (timeoutMs !== void 0 && Date.now() - startTime >= timeoutMs) {
479
+ return { status: "pending" };
480
+ }
481
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
482
+ }
483
+ }
484
+ async function getWorkflowStatus(runId) {
485
+ return workflowStateStore.load(runId);
486
+ }
487
+ async function listPendingWorkflows(workflowName) {
488
+ return workflowStateStore.list({
489
+ workflowName,
490
+ hasPendingApprovals: true
491
+ });
492
+ }
493
+ async function cleanup(maxAgeMs) {
494
+ const allWorkflows = await workflowStateStore.list();
495
+ let cleaned = 0;
496
+ const cutoff = Date.now() - maxAgeMs;
497
+ for (const runId of allWorkflows) {
498
+ const state = await workflowStateStore.load(runId);
499
+ if (state && state.updatedAt < cutoff && state.pendingApprovals.length === 0) {
500
+ await workflowStateStore.delete(runId);
501
+ cleaned++;
502
+ }
503
+ }
504
+ logger(`Cleaned up ${cleaned} old workflow states`);
505
+ return cleaned;
506
+ }
507
+ return {
508
+ execute,
509
+ resume,
510
+ grantApproval: grantApprovalFn,
511
+ rejectApproval: rejectApprovalFn,
512
+ editApproval: editApprovalFn,
513
+ pollApproval,
514
+ getWorkflowStatus,
515
+ listPendingWorkflows,
516
+ cleanup
517
+ };
518
+ }
519
+ function createApprovalWebhookHandler(store) {
520
+ return async (request) => {
521
+ const { key, action, value, originalValue, editedValue, reason, actorId } = request;
522
+ try {
523
+ switch (action) {
524
+ case "approve":
525
+ await store.grantApproval(key, value, { approvedBy: actorId });
526
+ return {
527
+ success: true,
528
+ message: `Approval ${key} granted`,
529
+ data: { key, action, timestamp: Date.now() }
530
+ };
531
+ case "reject":
532
+ if (!reason) {
533
+ return { success: false, message: "Reason is required for rejection" };
534
+ }
535
+ await store.rejectApproval(key, reason, { rejectedBy: actorId });
536
+ return {
537
+ success: true,
538
+ message: `Approval ${key} rejected`,
539
+ data: { key, action, timestamp: Date.now() }
540
+ };
541
+ case "edit":
542
+ if (originalValue === void 0 || editedValue === void 0) {
543
+ return { success: false, message: "Both originalValue and editedValue are required for edit" };
544
+ }
545
+ await store.editApproval(key, originalValue, editedValue, { editedBy: actorId });
546
+ return {
547
+ success: true,
548
+ message: `Approval ${key} edited`,
549
+ data: { key, action, timestamp: Date.now() }
550
+ };
551
+ case "cancel":
552
+ await store.cancelApproval(key);
553
+ return {
554
+ success: true,
555
+ message: `Approval ${key} cancelled`,
556
+ data: { key, action, timestamp: Date.now() }
557
+ };
558
+ default:
559
+ return { success: false, message: `Unknown action: ${action}` };
560
+ }
561
+ } catch (error) {
562
+ return {
563
+ success: false,
564
+ message: error instanceof Error ? error.message : String(error)
565
+ };
566
+ }
567
+ };
568
+ }
569
+ function createApprovalChecker(store) {
570
+ return (key) => async () => {
571
+ const status = await store.getApproval(key);
572
+ switch (status.status) {
573
+ case "pending":
574
+ return { status: "pending" };
575
+ case "approved":
576
+ return { status: "approved", value: status.value };
577
+ case "edited":
578
+ return { status: "approved", value: status.editedValue };
579
+ case "rejected":
580
+ return { status: "rejected", reason: status.reason };
581
+ case "expired":
582
+ return { status: "rejected", reason: "Approval request expired" };
583
+ default:
584
+ return { status: "pending" };
585
+ }
586
+ };
587
+ }
588
+ export {
589
+ clearStep,
590
+ createApprovalChecker,
591
+ createApprovalStateCollector,
592
+ createApprovalStep,
593
+ createApprovalWebhookHandler,
594
+ createHITLOrchestrator,
595
+ createMemoryApprovalStore,
596
+ createMemoryWorkflowStateStore,
597
+ gatedStep,
598
+ getPendingApprovals,
599
+ hasPendingApproval,
600
+ injectApproval,
601
+ isApprovalRejected,
602
+ isPendingApproval,
603
+ pendingApproval
604
+ };
605
+ //# sourceMappingURL=hitl.js.map