awaitly 1.34.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +35 -5
- package/dist/result.d.ts +35 -5
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
- package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +13 -178
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-COl5oFnR.d.cts +0 -15
- package/dist/di-CyDj_JyZ.d.ts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-BodHXLzX.d.cts +0 -72
- package/dist/guards-CeWoQ8fn.d.ts +0 -72
- package/dist/hitl-BPE_1UiM.d.cts +0 -468
- package/dist/hitl-byp570uC.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-BYT3amEz.d.ts +0 -417
- package/dist/index-C_ak66jy.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-DOMx3woy.d.ts +0 -822
- package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-DQmzO9f4.d.ts +0 -323
- package/dist/types-qBUOYi-4.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/hitl-byp570uC.d.ts
DELETED
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
import { ag as WorkflowEvent, c as AsyncResult, d as Err } from './run-entry-Dduz-is2.js';
|
|
2
|
-
import { R as ResumeState, P as PendingApproval, b as ApprovalStepOptions, A as ApprovalRejected, G as GatedStepOptions } from './persistence-entry-DOMx3woy.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Resume state helpers: collectors and state manipulation for workflow replay.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Create a collector for step results to build resume state.
|
|
10
|
-
*
|
|
11
|
-
* ## When to Use
|
|
12
|
-
*
|
|
13
|
-
* Use `createResumeStateCollector` when you need to:
|
|
14
|
-
* - **Save workflow state** for later replay/resume
|
|
15
|
-
* - **Persist step results** to a database or file system
|
|
16
|
-
* - **Build resume state** from workflow execution
|
|
17
|
-
* - **Enable workflow replay** after application restarts
|
|
18
|
-
*
|
|
19
|
-
* ## Why Use This Instead of Manual Collection
|
|
20
|
-
*
|
|
21
|
-
* - **Automatic filtering**: Only collects `step_complete` events (ignores other events)
|
|
22
|
-
* - **Metadata preservation**: Captures both result and meta for proper error replay
|
|
23
|
-
* - **Type-safe**: Returns properly typed `ResumeState`
|
|
24
|
-
* - **Convenient API**: Simple `handleEvent` → `getResumeState` pattern
|
|
25
|
-
*
|
|
26
|
-
* ## How It Works
|
|
27
|
-
*
|
|
28
|
-
* 1. Create collector and pass `handleEvent` to workflow's `onEvent` option
|
|
29
|
-
* 2. Workflow emits `step_complete` events for keyed steps
|
|
30
|
-
* 3. Collector automatically captures these events
|
|
31
|
-
* 4. Call `getResumeState()` to get the collected `ResumeState`
|
|
32
|
-
* 5. Persist state (e.g., to database) for later resume
|
|
33
|
-
*
|
|
34
|
-
* ## When step_complete Events Are Emitted
|
|
35
|
-
*
|
|
36
|
-
* Events are emitted for ANY step that has a `key` option, regardless of calling pattern:
|
|
37
|
-
*
|
|
38
|
-
* ```typescript
|
|
39
|
-
* // Function-wrapped pattern - emits step_complete
|
|
40
|
-
* await step(() => fetchUser("1"), { key: "user:1" });
|
|
41
|
-
*
|
|
42
|
-
* // Direct AsyncResult pattern - also emits step_complete
|
|
43
|
-
* await step(fetchUser("1"), { key: "user:1" });
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* Both patterns above will emit `step_complete` events and be captured by the collector.
|
|
47
|
-
*
|
|
48
|
-
* ## Important Notes
|
|
49
|
-
*
|
|
50
|
-
* - Only steps with a `key` option are collected (unkeyed steps are not saved)
|
|
51
|
-
* - The collector preserves error metadata for proper replay behavior
|
|
52
|
-
* - State can be serialized to JSON (but complex cause types may need custom handling)
|
|
53
|
-
*
|
|
54
|
-
* @returns An object with:
|
|
55
|
-
* - `handleEvent`: Function to pass to workflow's `onEvent` option
|
|
56
|
-
* - `getResumeState`: Get collected resume state (call after workflow execution)
|
|
57
|
-
* - `clear`: Clears the collector's internal recorded entries (does not mutate workflow state)
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```typescript
|
|
61
|
-
* // Collect state during workflow execution
|
|
62
|
-
* const collector = createResumeStateCollector();
|
|
63
|
-
*
|
|
64
|
-
* const workflow = createWorkflow({ fetchUser, fetchPosts }, {
|
|
65
|
-
* onEvent: collector.handleEvent, // Pass collector's handler
|
|
66
|
-
* });
|
|
67
|
-
*
|
|
68
|
-
* await workflow(async ({ step }) => {
|
|
69
|
-
* // Only keyed steps are collected
|
|
70
|
-
* const user = await step(() => fetchUser("1"), { key: "user:1" });
|
|
71
|
-
* const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` });
|
|
72
|
-
* return { user, posts };
|
|
73
|
-
* });
|
|
74
|
-
*
|
|
75
|
-
* // Get collected state for persistence
|
|
76
|
-
* const state = collector.getResumeState();
|
|
77
|
-
* // state.steps contains: 'user:1' and 'posts:1' entries
|
|
78
|
-
*
|
|
79
|
-
* // Save to database
|
|
80
|
-
* await db.saveWorkflowState(workflowId, state);
|
|
81
|
-
* ```
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```typescript
|
|
85
|
-
* // Resume workflow from saved state
|
|
86
|
-
* const savedState = await db.loadWorkflowState(workflowId);
|
|
87
|
-
* const workflow = createWorkflow({ fetchUser, fetchPosts }, {
|
|
88
|
-
* resumeState: savedState // Pre-populate cache from saved state
|
|
89
|
-
* });
|
|
90
|
-
*
|
|
91
|
-
* // Cached steps skip execution, new steps run normally
|
|
92
|
-
* await workflow(async ({ step }) => {
|
|
93
|
-
* const user = await step(() => fetchUser("1"), { key: "user:1" }); // Cache hit
|
|
94
|
-
* const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` }); // Cache hit
|
|
95
|
-
* return { user, posts };
|
|
96
|
-
* });
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
declare function createResumeStateCollector(): {
|
|
100
|
-
/** Handle workflow events. Pass this to workflow's `onEvent` option. */
|
|
101
|
-
handleEvent: (event: WorkflowEvent<unknown>) => void;
|
|
102
|
-
/** Get the collected resume state. Call after workflow execution. */
|
|
103
|
-
getResumeState: () => ResumeState;
|
|
104
|
-
/** Clears the collector's internal recorded entries (does not mutate workflow state). */
|
|
105
|
-
clear: () => void;
|
|
106
|
-
};
|
|
107
|
-
/**
|
|
108
|
-
* Inject an approved value into resume state.
|
|
109
|
-
* Use this when an external approval is granted and you want to resume the workflow.
|
|
110
|
-
*
|
|
111
|
-
* @param state - The resume state to update
|
|
112
|
-
* @param options - Object with stepKey and the approved value
|
|
113
|
-
* @returns A new ResumeState with the approval injected
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* // When approval is granted externally:
|
|
118
|
-
* const updatedState = injectApproval(savedState, {
|
|
119
|
-
* stepKey: 'deploy:prod',
|
|
120
|
-
* value: { approvedBy: 'admin', approvedAt: Date.now() }
|
|
121
|
-
* });
|
|
122
|
-
*
|
|
123
|
-
* // Resume workflow with the approval injected
|
|
124
|
-
* const workflow = createWorkflow({ ... }, { resumeState: updatedState });
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
declare function injectApproval<T>(state: ResumeState, options: {
|
|
128
|
-
stepKey: string;
|
|
129
|
-
value: T;
|
|
130
|
-
}): ResumeState;
|
|
131
|
-
/**
|
|
132
|
-
* Remove a step from resume state (e.g., to force re-execution).
|
|
133
|
-
* This is an immutable operation - returns a new ResumeState without modifying the original.
|
|
134
|
-
*
|
|
135
|
-
* @param state - The resume state to update
|
|
136
|
-
* @param stepKey - The key of the step to remove
|
|
137
|
-
* @returns A new ResumeState with the step removed (original is unchanged)
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```typescript
|
|
141
|
-
* // Force a step to re-execute on resume
|
|
142
|
-
* const updatedState = clearStep(savedState, 'approval:123');
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
declare function clearStep(state: ResumeState, stepKey: string): ResumeState;
|
|
146
|
-
/**
|
|
147
|
-
* Check if a step in resume state has a pending approval error.
|
|
148
|
-
*
|
|
149
|
-
* @param state - The resume state to check
|
|
150
|
-
* @param stepKey - The key of the step to check
|
|
151
|
-
* @returns `true` if the step has a pending approval, `false` otherwise
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```typescript
|
|
155
|
-
* if (hasPendingApproval(savedState, 'deploy:prod')) {
|
|
156
|
-
* // Show approval UI
|
|
157
|
-
* }
|
|
158
|
-
* ```
|
|
159
|
-
*/
|
|
160
|
-
declare function hasPendingApproval(state: ResumeState, stepKey: string): boolean;
|
|
161
|
-
/**
|
|
162
|
-
* Get all pending approval step keys from resume state.
|
|
163
|
-
*
|
|
164
|
-
* @param state - The resume state to check
|
|
165
|
-
* @returns Array of step keys that have pending approvals
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```typescript
|
|
169
|
-
* const pendingKeys = getPendingApprovals(savedState);
|
|
170
|
-
* // ['deploy:prod', 'deploy:staging']
|
|
171
|
-
* ```
|
|
172
|
-
*/
|
|
173
|
-
declare function getPendingApprovals(state: ResumeState): string[];
|
|
174
|
-
/**
|
|
175
|
-
* Inject a hook callback value into resume state.
|
|
176
|
-
* Call this when the app receives the HTTP callback (e.g. POST /hook/:hookId) and pass the request body as value.
|
|
177
|
-
*
|
|
178
|
-
* @param state - The resume state to update
|
|
179
|
-
* @param options - hookId (from the callback URL) and value (e.g. request body)
|
|
180
|
-
* @returns A new ResumeState with the hook step set to ok(value)
|
|
181
|
-
*/
|
|
182
|
-
declare function injectHook<T>(state: ResumeState, options: {
|
|
183
|
-
hookId: string;
|
|
184
|
-
value: T;
|
|
185
|
-
}): ResumeState;
|
|
186
|
-
/**
|
|
187
|
-
* Check if a step in resume state has a pending hook error.
|
|
188
|
-
*
|
|
189
|
-
* @param state - The resume state to check
|
|
190
|
-
* @param hookId - The hook id (from createHook() or the callback URL)
|
|
191
|
-
* @returns `true` if that hook step is pending, `false` otherwise
|
|
192
|
-
*/
|
|
193
|
-
declare function hasPendingHook(state: ResumeState, hookId: string): boolean;
|
|
194
|
-
/**
|
|
195
|
-
* Get all pending hook hookIds from resume state.
|
|
196
|
-
*
|
|
197
|
-
* @param state - The resume state to check
|
|
198
|
-
* @returns Array of hookIds that have pending callbacks
|
|
199
|
-
*/
|
|
200
|
-
declare function getPendingHooks(state: ResumeState): string[];
|
|
201
|
-
/**
|
|
202
|
-
* Extended resume state collector that tracks pending approvals.
|
|
203
|
-
* Use this for human-in-the-loop workflows that need to track approval state.
|
|
204
|
-
*
|
|
205
|
-
* @returns An object with methods to handle events, get state, and manage approvals
|
|
206
|
-
*
|
|
207
|
-
* @example
|
|
208
|
-
* ```typescript
|
|
209
|
-
* const collector = createApprovalStateCollector();
|
|
210
|
-
*
|
|
211
|
-
* const workflow = createWorkflow({ fetchUser, requireApproval }, {
|
|
212
|
-
* onEvent: collector.handleEvent,
|
|
213
|
-
* });
|
|
214
|
-
*
|
|
215
|
-
* const result = await workflow(async ({ step }) => {
|
|
216
|
-
* const user = await step(() => fetchUser("1"), { key: "user:1" });
|
|
217
|
-
* const approval = await step(requireApproval, { key: "approval:1" });
|
|
218
|
-
* return { user, approval };
|
|
219
|
-
* });
|
|
220
|
-
*
|
|
221
|
-
* // Check for pending approvals
|
|
222
|
-
* if (collector.hasPendingApprovals()) {
|
|
223
|
-
* const pending = collector.getPendingApprovals();
|
|
224
|
-
* // pending: [{ stepKey: 'approval:1', error: PendingApproval }]
|
|
225
|
-
* await saveToDatabase(collector.getResumeState());
|
|
226
|
-
* }
|
|
227
|
-
*
|
|
228
|
-
* // Later, when approved:
|
|
229
|
-
* const resumeState = collector.injectApproval('approval:1', { approvedBy: 'admin' });
|
|
230
|
-
* ```
|
|
231
|
-
*/
|
|
232
|
-
declare function createApprovalStateCollector(): {
|
|
233
|
-
/** Handle workflow events. Pass this to workflow's `onEvent` option. */
|
|
234
|
-
handleEvent: (event: WorkflowEvent<unknown>) => void;
|
|
235
|
-
/** Get the collected resume state. Call after workflow execution. */
|
|
236
|
-
getResumeState: () => ResumeState;
|
|
237
|
-
/** Clears the collector's internal recorded entries (does not mutate workflow state). */
|
|
238
|
-
clear: () => void;
|
|
239
|
-
/** Check if any steps have pending approvals */
|
|
240
|
-
hasPendingApprovals: () => boolean;
|
|
241
|
-
/** Get all pending approval entries with their errors */
|
|
242
|
-
getPendingApprovals: () => Array<{
|
|
243
|
-
stepKey: string;
|
|
244
|
-
error: PendingApproval;
|
|
245
|
-
}>;
|
|
246
|
-
/** Inject an approval result, updating the collector's internal state. Returns a copy for use as resumeState. */
|
|
247
|
-
injectApproval: <T>(stepKey: string, value: T) => ResumeState;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Human-in-the-Loop (HITL) helpers: pendingApproval, createApprovalStep, gatedStep.
|
|
252
|
-
*/
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Create a PendingApproval error result.
|
|
256
|
-
* Convenience helper for approval-gated steps.
|
|
257
|
-
*
|
|
258
|
-
* @param stepKey - Stable key for this approval step (used for resume)
|
|
259
|
-
* @param options - Optional reason and metadata for the pending approval
|
|
260
|
-
* @returns A Result with a PendingApproval error
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* ```typescript
|
|
264
|
-
* const requireApproval = async (userId: string) => {
|
|
265
|
-
* const status = await db.getApproval(userId);
|
|
266
|
-
* if (!status) return pendingApproval(`approval:${userId}`);
|
|
267
|
-
* return ok(status);
|
|
268
|
-
* };
|
|
269
|
-
* ```
|
|
270
|
-
*/
|
|
271
|
-
declare function pendingApproval(stepKey: string, options?: {
|
|
272
|
-
reason?: string;
|
|
273
|
-
metadata?: Record<string, unknown>;
|
|
274
|
-
}): Err<PendingApproval>;
|
|
275
|
-
/**
|
|
276
|
-
* Create a Result-returning function that checks external approval status.
|
|
277
|
-
*
|
|
278
|
-
* ## When to Use
|
|
279
|
-
*
|
|
280
|
-
* Use `createApprovalStep` when you need:
|
|
281
|
-
* - **Human-in-the-loop workflows**: Steps that require human approval
|
|
282
|
-
* - **External approval systems**: Integrate with approval databases/APIs
|
|
283
|
-
* - **Workflow pausing**: Workflows that pause and resume after approval
|
|
284
|
-
* - **Approval tracking**: Track who approved what and when
|
|
285
|
-
*
|
|
286
|
-
* ## Why Use This Instead of Manual Approval Checks
|
|
287
|
-
*
|
|
288
|
-
* - **Standardized pattern**: Consistent approval step interface
|
|
289
|
-
* - **Type-safe**: Returns typed `PendingApproval` or `ApprovalRejected` errors
|
|
290
|
-
* - **Resume-friendly**: Works seamlessly with `injectApproval()` and resume state
|
|
291
|
-
* - **Metadata support**: Can include approval reason and metadata
|
|
292
|
-
*
|
|
293
|
-
* ## How It Works
|
|
294
|
-
*
|
|
295
|
-
* 1. Create approval step with `checkApproval` function
|
|
296
|
-
* 2. `checkApproval` returns one of:
|
|
297
|
-
* - `{ status: 'pending' }` - Approval not yet granted (workflow pauses)
|
|
298
|
-
* - `{ status: 'approved', value: T }` - Approval granted (workflow continues)
|
|
299
|
-
* - `{ status: 'rejected', reason: string }` - Approval rejected (workflow fails)
|
|
300
|
-
* 3. Use in workflow with `step()` - workflow pauses if pending
|
|
301
|
-
* 4. When approval granted externally, use `injectApproval()` to resume
|
|
302
|
-
*
|
|
303
|
-
* ## Typical Approval Flow
|
|
304
|
-
*
|
|
305
|
-
* 1. Workflow executes → reaches approval step
|
|
306
|
-
* 2. `checkApproval()` called → returns `{ status: 'pending' }`
|
|
307
|
-
* 3. Workflow returns `PendingApproval` error
|
|
308
|
-
* 4. Save workflow state → persist for later resume
|
|
309
|
-
* 5. Show approval UI → user sees pending approval
|
|
310
|
-
* 6. User grants/rejects → update approval system
|
|
311
|
-
* 7. Inject approval → call `injectApproval()` with approved value
|
|
312
|
-
* 8. Resume workflow → continue from approval step
|
|
313
|
-
*
|
|
314
|
-
* @param options - Configuration for the approval step:
|
|
315
|
-
* - `key`: Stable key for this approval (must match step key in workflow)
|
|
316
|
-
* - `checkApproval`: Async function that checks current approval status
|
|
317
|
-
* - `pendingReason`: Optional reason shown when approval is pending
|
|
318
|
-
* - `metadata`: Optional metadata attached to the approval request
|
|
319
|
-
*
|
|
320
|
-
* @returns A function that returns an AsyncResult checking approval status.
|
|
321
|
-
* The function can be used directly with `step()` in workflows.
|
|
322
|
-
*
|
|
323
|
-
* @example
|
|
324
|
-
* ```typescript
|
|
325
|
-
* // Create approval step that checks database
|
|
326
|
-
* const requireManagerApproval = createApprovalStep<{ approvedBy: string }>({
|
|
327
|
-
* key: 'manager-approval',
|
|
328
|
-
* checkApproval: async () => {
|
|
329
|
-
* const approval = await db.getApproval('manager-approval');
|
|
330
|
-
* if (!approval) {
|
|
331
|
-
* return { status: 'pending' }; // Workflow pauses here
|
|
332
|
-
* }
|
|
333
|
-
* if (approval.rejected) {
|
|
334
|
-
* return { status: 'rejected', reason: approval.reason };
|
|
335
|
-
* }
|
|
336
|
-
* return {
|
|
337
|
-
* status: 'approved',
|
|
338
|
-
* value: { approvedBy: approval.approvedBy }
|
|
339
|
-
* };
|
|
340
|
-
* },
|
|
341
|
-
* pendingReason: 'Waiting for manager approval',
|
|
342
|
-
* });
|
|
343
|
-
*
|
|
344
|
-
* // Use in workflow
|
|
345
|
-
* const workflow = createWorkflow({ requireManagerApproval });
|
|
346
|
-
* const result = await workflow(async ({ step }) => {
|
|
347
|
-
* const approval = await step(requireManagerApproval, { key: 'manager-approval' });
|
|
348
|
-
* // If pending, workflow exits with PendingApproval error
|
|
349
|
-
* // If approved, continues with approval value
|
|
350
|
-
* return approval;
|
|
351
|
-
* });
|
|
352
|
-
*
|
|
353
|
-
* // Handle pending state
|
|
354
|
-
* if (!result.ok && isPendingApproval(result.error)) {
|
|
355
|
-
* // Workflow paused - show approval UI
|
|
356
|
-
* showApprovalUI(result.error.stepKey);
|
|
357
|
-
* }
|
|
358
|
-
* ```
|
|
359
|
-
*
|
|
360
|
-
* @example
|
|
361
|
-
* ```typescript
|
|
362
|
-
* // With approval injection for resume
|
|
363
|
-
* const collector = createApprovalStateCollector();
|
|
364
|
-
* const workflow = createWorkflow({ requireApproval }, {
|
|
365
|
-
* onEvent: collector.handleEvent,
|
|
366
|
-
* });
|
|
367
|
-
*
|
|
368
|
-
* const result = await workflow(async ({ step }) => {
|
|
369
|
-
* const approval = await step(requireApproval, { key: 'approval:1' });
|
|
370
|
-
* return approval;
|
|
371
|
-
* });
|
|
372
|
-
*
|
|
373
|
-
* // When approval granted externally
|
|
374
|
-
* if (collector.hasPendingApprovals()) {
|
|
375
|
-
* const resumeState = collector.injectApproval('approval:1', {
|
|
376
|
-
* approvedBy: 'admin@example.com'
|
|
377
|
-
* });
|
|
378
|
-
*
|
|
379
|
-
* // Resume workflow
|
|
380
|
-
* const workflow2 = createWorkflow({ requireApproval }, { resumeState });
|
|
381
|
-
* const result2 = await workflow2(async ({ step }) => {
|
|
382
|
-
* const approval = await step(requireApproval, { key: 'approval:1' });
|
|
383
|
-
* return approval; // Now succeeds with injected value
|
|
384
|
-
* });
|
|
385
|
-
* }
|
|
386
|
-
* ```
|
|
387
|
-
*/
|
|
388
|
-
declare function createApprovalStep<T>(options: ApprovalStepOptions<T>): () => AsyncResult<T, PendingApproval | ApprovalRejected>;
|
|
389
|
-
/**
|
|
390
|
-
* Create a gated step that requires approval before execution.
|
|
391
|
-
*
|
|
392
|
-
* This is the AI SDK / LangChain-style pattern where you intercept
|
|
393
|
-
* tool calls *before* they execute, allowing humans to see the args
|
|
394
|
-
* and approve, edit, or reject before the operation runs.
|
|
395
|
-
*
|
|
396
|
-
* ## When to Use
|
|
397
|
-
*
|
|
398
|
-
* Use `gatedStep` when you want to:
|
|
399
|
-
* - **Show args before execution**: Let humans see what the operation will do
|
|
400
|
-
* - **Allow editing args**: Humans can modify args before operation runs
|
|
401
|
-
* - **Conditional gating**: Only require approval for certain conditions
|
|
402
|
-
* - **AI safety**: Gate dangerous AI tool calls (send email, delete file, etc.)
|
|
403
|
-
*
|
|
404
|
-
* ## Difference from createApprovalStep
|
|
405
|
-
*
|
|
406
|
-
* - `createApprovalStep`: Checks external approval status, operation already defined
|
|
407
|
-
* - `gatedStep`: Gates before operation, shows args, allows editing, then executes
|
|
408
|
-
*
|
|
409
|
-
* ## Flow
|
|
410
|
-
*
|
|
411
|
-
* 1. Call gatedStep with args
|
|
412
|
-
* 2. Check if approval is required (based on requiresApproval condition)
|
|
413
|
-
* 3. If required and not approved:
|
|
414
|
-
* - Return PendingApproval with args visible in metadata
|
|
415
|
-
* - Human sees: "Send email to external@example.com with subject X"
|
|
416
|
-
* - Human can approve (run as-is), edit (modify args), or reject
|
|
417
|
-
* 4. If approved or not required:
|
|
418
|
-
* - Execute the operation with (potentially edited) args
|
|
419
|
-
*
|
|
420
|
-
* @param operation - The operation to gate (a function returning AsyncResult)
|
|
421
|
-
* @param options - Gating configuration
|
|
422
|
-
* @returns A gated function that checks approval before execution
|
|
423
|
-
*
|
|
424
|
-
* @example
|
|
425
|
-
* ```typescript
|
|
426
|
-
* // Gate external email sends
|
|
427
|
-
* const sendEmail = async (to: string, subject: string, body: string) => { ... };
|
|
428
|
-
*
|
|
429
|
-
* const gatedSendEmail = gatedStep(
|
|
430
|
-
* sendEmail,
|
|
431
|
-
* {
|
|
432
|
-
* key: 'email',
|
|
433
|
-
* requiresApproval: (args) => !args.to.endsWith('@mycompany.com'),
|
|
434
|
-
* description: (args) => `Send email to ${args.to}: "${args.subject}"`,
|
|
435
|
-
* }
|
|
436
|
-
* );
|
|
437
|
-
*
|
|
438
|
-
* // In workflow:
|
|
439
|
-
* const result = await step(
|
|
440
|
-
* () => gatedSendEmail({ to: 'external@other.com', subject: 'Hello', body: '...' }),
|
|
441
|
-
* { key: 'send-welcome-email' }
|
|
442
|
-
* );
|
|
443
|
-
*
|
|
444
|
-
* // If gated, returns PendingApproval with:
|
|
445
|
-
* // {
|
|
446
|
-
* // stepKey: 'email',
|
|
447
|
-
* // reason: 'Send email to external@other.com: "Hello"',
|
|
448
|
-
* // metadata: { pendingArgs: { to: '...', subject: '...', body: '...' } }
|
|
449
|
-
* // }
|
|
450
|
-
* ```
|
|
451
|
-
*
|
|
452
|
-
* @example
|
|
453
|
-
* ```typescript
|
|
454
|
-
* // Gate file deletion with explicit approval check
|
|
455
|
-
* const gatedDelete = gatedStep(
|
|
456
|
-
* (path: string) => deleteFile(path),
|
|
457
|
-
* {
|
|
458
|
-
* key: 'delete-file',
|
|
459
|
-
* requiresApproval: true, // Always require approval
|
|
460
|
-
* description: (args) => `Delete file: ${args.path}`,
|
|
461
|
-
* checkApproval: () => approvalStore.getApproval('delete-file'),
|
|
462
|
-
* }
|
|
463
|
-
* );
|
|
464
|
-
* ```
|
|
465
|
-
*/
|
|
466
|
-
declare function gatedStep<TArgs extends Record<string, unknown>, T, E>(operation: (args: TArgs) => AsyncResult<T, E>, options: GatedStepOptions<TArgs, T>): (args: TArgs) => AsyncResult<T, E | PendingApproval | ApprovalRejected>;
|
|
467
|
-
|
|
468
|
-
export { createApprovalStateCollector as a, createApprovalStep as b, clearStep as c, getPendingApprovals as d, createResumeStateCollector as e, getPendingHooks as f, gatedStep as g, hasPendingApproval as h, injectApproval as i, hasPendingHook as j, injectHook as k, pendingApproval as p };
|
package/dist/hitl.cjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";var Ee=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Qe=Object.getOwnPropertyNames;var Ze=Object.prototype.hasOwnProperty;var et=(t,e)=>{for(var r in e)Ee(t,r,{get:e[r],enumerable:!0})},tt=(t,e,r,u)=>{if(e&&typeof e=="object"||typeof e=="function")for(let k of Qe(e))!Ze.call(t,k)&&k!==r&&Ee(t,k,{get:()=>e[k],enumerable:!(u=Xe(e,k))||u.enumerable});return t};var rt=t=>tt(Ee({},"__esModule",{value:!0}),t);var yt={};et(yt,{clearStep:()=>xe,createApprovalChecker:()=>ze,createApprovalStateCollector:()=>ie,createApprovalStep:()=>Se,createApprovalWebhookHandler:()=>Ye,createHITLOrchestrator:()=>qe,createMemoryApprovalStore:()=>Ve,createMemoryWorkflowStateStore:()=>$e,gatedStep:()=>Ce,getPendingApprovals:()=>he,hasPendingApproval:()=>Ae,injectApproval:()=>ae,isApprovalRejected:()=>Re,isPendingApproval:()=>Q,pendingApproval:()=>ve});module.exports=rt(yt);var nt={"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 be(t){return`https://jagreehal.github.io/awaitly/rules/#${t}`}var gt=Object.keys(nt);var pe=class extends Error{_tag};function z(t,e){return class extends pe{_tag=t;constructor(r,u){let k=e?.message?e.message(r??{}):t;if(super(k),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:be(e.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),r&&typeof r=="object"){let f;if(e?.slug!==void 0){let{_tag:i,name:$,message:D,stack:q,code:J,hint:l,docsUrl:g,...I}=r;f=I}else{let{_tag:i,name:$,message:D,stack:q,...J}=r;f=J}let S=Object.prototype.hasOwnProperty.call(f,"cause"),E=S?f.cause:void 0;S&&delete f.cause;let _=u?.cause!==void 0;if(S&&_)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,f),S&&(this.cause=E),_&&(this.cause=u?.cause)}else u?.cause!==void 0&&(this.cause=u.cause)}}}Object.defineProperty(z,Symbol.hasInstance,{value:t=>t instanceof pe});(k=>{function t(f){return f instanceof Error}k.isError=t;function e(f){return f instanceof pe}k.isTaggedError=e;function r(f,S){let E=f._tag,_=S[E];return _(f)}k.match=r;function u(f,S,E){let _=f._tag,i=S[_];return i?i(f):E(f)}k.matchPartial=u})(z||={});var Pe=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`}){},_e=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`}){},Oe=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`:""}`}){},Ie=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`:""}`}){},Me=class extends z("ValidationError",{message:e=>`ValidationError: Invalid ${e.field} - ${e.reason}`}){},De=class extends z("NotFoundError",{message:e=>e.id?`NotFoundError: ${e.resource} with id ${e.id} not found`:`NotFoundError: ${e.resource} not found`}){},Ue=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"}){},je=class extends z("NetworkError",{message:e=>e.url?`NetworkError: ${e.reason} (${e.url})`:`NetworkError: ${e.reason}`}){},Ne=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}`}){},le=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 ot(t){let e=t.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!e)return;let r=parseFloat(e[1]),u=e[2].toLowerCase();return{_tag:"Duration",millis:r*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[u]??1)}}function st(t){return new le({cause:t})}function Y(t){return{ok:!0,value:t}}function B(t,e){let r=e?.cause;return{ok:!1,error:t,...r!==void 0?{cause:r}:{}}}function at(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 it(t,e){if(!(!e||!t))return e[t]}function ut(t){let{intent:e,domain:r,owner:u,tags:k,stateChanges:f,emits:S,calls:E}=t;if(!e&&!r&&!u&&!k?.length&&!f?.length&&!S?.length&&!E?.length)return;let _={};return e&&(_.intent=e),r&&(_.domain=r),u&&(_.owner=u),k?.length&&(_.tags=k),f?.length&&(_.stateChanges=f),S?.length&&(_.emits=S),E?.length&&(_.calls=E),_}function X(t,e,r,u,k){let f=at(t),S=it(f,e),E={tag:f,origin:r};return S!==void 0&&(E.classification=S),u!==void 0&&(E.attempt=u),k!==void 0&&(E.cumulativeDurationMs=k),E}var se=Symbol.for("step_timeout_marker");function We(t){return typeof t!="object"||t===null?!1:t.type==="STEP_TIMEOUT"?!0:se in t}function pt(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(se in t)return t[se]}}var Le=Symbol("early-exit");function lt(t,e){return{[Le]:!0,error:t,meta:e}}function ct(t){return typeof t=="object"&&t!==null&&t[Le]===!0}var He=Symbol("mapper-exception");function ne(t){return{[He]:!0,thrown:t}}function dt(t){return typeof t=="object"&&t!==null&&t[He]===!0}function ge(t,e){let{backoff:r,initialDelay:u,maxDelay:k,jitter:f}=e,S;switch(r){case"fixed":S=u;break;case"linear":S=u*t;break;case"exponential":S=u*Math.pow(2,t-1);break}if(S=Math.min(S,k),f){let E=S*.25*Math.random();S=S+E}return Math.floor(S)}function ke(t){return new Promise(e=>setTimeout(e,t))}var Ke=Symbol("timeout"),ce=Symbol("timeout-option");function mt(t){return typeof t=="object"&&t!==null&&t[ce]===!0}async function wt(t,e,r,u){let k=new AbortController,f=e.onTimeout??"error",S=()=>typeof f=="function"?f({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},E;u?.aborted&&k.abort(u.reason);let _;u&&!u.aborted&&(_=()=>k.abort(u.reason),u.addEventListener("abort",_,{once:!0}));let i=new Promise((D,q)=>{E=setTimeout(()=>{if(f!=="disconnect"&&k.abort(),f==="option"){q({[ce]:!0,ms:e.ms});return}q({[Ke]:!0,error:S()})},e.ms)}),$;e.signal?$=Promise.resolve(t(k.signal)):$=Promise.resolve(t());try{return await Promise.race([$,i])}catch(D){if(typeof D=="object"&&D!==null&&D[ce]===!0)throw{[ce]:!0,ms:e.ms};if(typeof D=="object"&&D!==null&&D[Ke]===!0){f==="disconnect"&&$.catch(()=>{});let q=D.error;if(typeof q=="object"&&q!==null&&q.type!=="STEP_TIMEOUT"){let J={timeoutMs:e.ms,stepName:r.name,stepKey:r.key,attempt:r.attempt};se in q?q[se]=J:Object.defineProperty(q,se,{value:J,enumerable:!1,writable:!0,configurable:!1})}throw q}throw D}finally{clearTimeout(E),_&&u&&u.removeEventListener("abort",_)}}var oe={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function Fe(t,e){let{onError:r,onEvent:u,catchUnexpected:k,workflowId:f,workflowName:S,context:E,_workflowSignal:_}=e&&typeof e=="object"?e:{},i=f??crypto.randomUUID(),$=k??st,D=[],q=0,J=c=>c??`step_${++q}`,l=c=>{let L=c.context!==void 0||E===void 0?c:{...c,context:E},W=S!==void 0&&L.workflowName===void 0?{...L,workflowName:S}:L;if(W.type==="step_success"){let U=W.stepId;for(let F=D.length-1;F>=0;F--){let V=D[F];if(V.type==="race"&&!V.winnerId){V.winnerId=U;break}}}u?.(W,E)},g=lt,I=c=>ct(c),O=(c,L)=>c,N=c=>typeof c=="function"?!1:!!(c&&typeof c=="object"&&"ok"in c||c&&typeof c=="object"&&"then"in c&&typeof c.then=="function");try{let L=function(a){let m={};for(let[o,s]of Object.entries(a))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},W=function(a,m){let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1;D.push({scopeId:o,type:"parallel"});let p=()=>{if(n)return;n=!0;let d=D.findIndex(w=>w.scopeId===o);d!==-1&&D.splice(d,1),l({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};l({type:"scope_start",workflowId:i,scopeId:o,scopeType:"parallel",name:a,ts:Date.now()});try{let d=await m();if(p(),!d.ok)throw r?.(d.error,a,E),g(d.error,{origin:"result",resultCause:d.cause});return d.value}catch(d){throw p(),d}})()},U=function(a,m){let o=Object.keys(a),s=m.name??`Parallel(${o.join(", ")})`,n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let p=performance.now(),d=!1;D.push({scopeId:n,type:"parallel"});let w=()=>{if(d)return;d=!0;let y=D.findIndex(T=>T.scopeId===n);y!==-1&&D.splice(y,1),l({type:"scope_end",workflowId:i,scopeId:n,ts:Date.now(),durationMs:performance.now()-p})};l({type:"scope_start",workflowId:i,scopeId:n,scopeType:"parallel",name:s,ts:Date.now()});try{let y=await new Promise(x=>{if(o.length===0){x([]);return}let b=!1,j=o.length,A=new Array(o.length);for(let M=0;M<o.length;M++){let h=o[M],C=M;Promise.resolve(a[h]()).catch(v=>B({type:"PROMISE_REJECTED",cause:v},{cause:{type:"PROMISE_REJECTION",reason:v}})).then(v=>{if(!b){if(!v.ok){b=!0,x([{key:h,result:v}]);return}A[C]={key:h,result:v},j--,j===0&&x(A)}})}});w();let T={};for(let{key:x,result:b}of y){if(!b.ok)throw r?.(b.error,x,E),g(b.error,{origin:"result",resultCause:b.cause});T[x]=b.value}return T}catch(y){throw w(),y}})()};var K=L,H=W,G=U;let c=(a,m,o)=>(async()=>{if(typeof a!="string"||a.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=ut(s),p=a,d=s.key??a,w=s.key??a,{description:y,retry:T,timeout:x}=s,b=J(d),j=u,A=j?performance.now():0,h=N(m)?()=>m:m,v={attempts:Math.max(1,T?.attempts??1),backoff:T?.backoff??oe.backoff,initialDelay:T?.initialDelay??oe.initialDelay,maxDelay:T?.maxDelay??oe.maxDelay,jitter:T?.jitter??oe.jitter,shouldRetry:T?.shouldRetry??oe.shouldRetry,onRetry:T?.onRetry??oe.onRetry};u&&l({type:"step_start",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),...n&&{metadata:n}});let re;for(let P=1;P<=v.attempts;P++){let Je=j?performance.now():0;try{let R;if(x?R=await wt(h,x,{name:p,key:d,attempt:P},_):R=await h(),R.ok){let te=performance.now()-A;return l({type:"step_success",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:te,...n&&{metadata:n}}),w&&l({type:"step_complete",workflowId:i,stepKey:w,name:p,description:y,ts:Date.now(),durationMs:te,result:R,...n&&{metadata:n}}),R.value}if(re=R,P<v.attempts&&v.shouldRetry(R.error,P)){let te=ge(P,v);l({type:"step_retry",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),attempt:P+1,maxAttempts:v.attempts,delayMs:te,error:R.error,...n&&{metadata:n},diagnostics:X(R.error,s.errorMeta,"result",P,performance.now()-A)}),v.onRetry(R.error,P,te),await ke(te);continue}v.attempts>1&&l({type:"step_retries_exhausted",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),durationMs:performance.now()-A,attempts:P,lastError:R.error,...n&&{metadata:n},diagnostics:X(R.error,s.errorMeta,"result",P,performance.now()-A)});break}catch(R){let te=performance.now()-Je;if(mt(R)){let Z=R.ms;l({type:"step_timeout",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),timeoutMs:Z,attempt:P,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"timeout",P)}),l({type:"step_success",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:performance.now()-A,...n&&{metadata:n}}),w&&l({type:"step_complete",workflowId:i,stepKey:w,name:p,description:y,ts:Date.now(),durationMs:performance.now()-A,result:Y(void 0),...n&&{metadata:n}});return}if(I(R))throw l({type:"step_aborted",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:te,...n&&{metadata:n}}),R;if(We(R)){let Z=pt(R),Ge=x?.ms??Z?.timeoutMs??0;if(l({type:"step_timeout",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),timeoutMs:Ge,attempt:P,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"timeout",P)}),P<v.attempts&&v.shouldRetry(R,P)){let ye=ge(P,v);l({type:"step_retry",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),attempt:P+1,maxAttempts:v.attempts,delayMs:ye,error:R,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"timeout",P,performance.now()-A)}),v.onRetry(R,P,ye),await ke(ye);continue}v.attempts>1&&l({type:"step_retries_exhausted",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),durationMs:performance.now()-A,attempts:P,lastError:R,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"timeout",P,performance.now()-A)});let fe=performance.now()-A;throw l({type:"step_error",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:fe,error:R,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"timeout",P,fe)}),w&&l({type:"step_complete",workflowId:i,stepKey:w,name:p,description:y,ts:Date.now(),durationMs:fe,result:B(R,{cause:R}),meta:{origin:"throw",thrown:R},...n&&{metadata:n}}),r?.(R,p,E),g(R,{origin:"throw",thrown:R})}if(P<v.attempts&&v.shouldRetry(R,P)){let Z=ge(P,v);l({type:"step_retry",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),attempt:P+1,maxAttempts:v.attempts,delayMs:Z,error:R,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"throw",P,performance.now()-A)}),v.onRetry(R,P,Z),await ke(Z);continue}v.attempts>1&&!We(R)&&l({type:"step_retries_exhausted",workflowId:i,stepId:b,stepKey:d,name:p,ts:Date.now(),durationMs:performance.now()-A,attempts:P,lastError:R,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"throw",P,performance.now()-A)});let we=performance.now()-A,ue;try{ue=$(R)}catch(Z){throw ne(Z)}throw l({type:"step_error",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:we,error:ue,...n&&{metadata:n},diagnostics:X(R,s.errorMeta,"throw",P,we)}),w&&l({type:"step_complete",workflowId:i,stepKey:w,name:p,description:y,ts:Date.now(),durationMs:we,result:B(ue,{cause:R}),meta:{origin:"throw",thrown:R},...n&&{metadata:n}}),r?.(ue,p,E),g(ue,{origin:"throw",thrown:R})}}let ee=re,de=performance.now()-A,me=O(ee.error,{origin:"result",resultCause:ee.cause});throw l({type:"step_error",workflowId:i,stepId:b,stepKey:d,name:p,description:y,ts:Date.now(),durationMs:de,error:me,...n&&{metadata:n},diagnostics:X(ee.error,s.errorMeta,"result",v.attempts,de)}),w&&l({type:"step_complete",workflowId:i,stepKey:w,name:p,description:y,ts:Date.now(),durationMs:de,result:ee,meta:{origin:"result",resultCause:ee.cause},...n&&{metadata:n}}),r?.(me,p,E),g(me,{origin:"result",resultCause:ee.cause})})();c.try=(a,m,o)=>{if(typeof a!="string"||a.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 c.retry(a,async()=>{try{return Y(await m())}catch(y){return B(s(y),{cause:y})}},{attempts:o.retry?.attempts??1,...o.retry??{},key:o.key,timeout:o.timeout});let n=o.key??a,p=a,d=a,w=u;return(async()=>{let y=w?performance.now():0;u&&l({type:"step_start",workflowId:i,stepId:d,stepKey:n,name:p,ts:Date.now()});try{let T=await m(),x=performance.now()-y;return l({type:"step_success",workflowId:i,stepId:d,stepKey:n,name:p,ts:Date.now(),durationMs:x}),n&&l({type:"step_complete",workflowId:i,stepKey:n,name:p,ts:Date.now(),durationMs:x,result:Y(T)}),T}catch(T){let x=s(T),b=performance.now()-y,j=O(x,{origin:"throw",thrown:T});throw l({type:"step_error",workflowId:i,stepId:d,stepKey:n,name:p,ts:Date.now(),durationMs:b,error:j}),n&&l({type:"step_complete",workflowId:i,stepKey:n,name:p,ts:Date.now(),durationMs:b,result:B(x,{cause:T}),meta:{origin:"throw",thrown:T}}),r?.(j,p,E),g(j,{origin:"throw",thrown:T})}})()},c.fromResult=(a,m,o)=>{if(typeof a!="string"||a.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??a,n=a,p=a,d="error"in o?()=>o.error:o.onError,w=u;return(async()=>{let y=w?performance.now():0;u&&l({type:"step_start",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now()});let T=await m();if(T.ok){let x=performance.now()-y;return l({type:"step_success",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:x}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:x,result:Y(T.value)}),T.value}else{let x=d(T.error),b=performance.now()-y,j=O(x,{origin:"result",resultCause:T.error});throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:b,error:j}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:b,result:B(x,{cause:T.error}),meta:{origin:"result",resultCause:T.error}}),r?.(j,n,E),g(j,{origin:"result",resultCause:T.error})}})()},c.fromNullable=(a,m,o,s)=>{if(typeof a!="string"||a.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 c(a,async()=>{let n=await m();return n!=null?Y(n):B(o())},s)},c.retry=(a,m,o)=>{if(typeof a!="string"||a.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 c(a,m,{key:o.key??a,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})},c.withTimeout=(a,m,o)=>{if(typeof a!="string"||a.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 c(a,m,{key:o.key??a,timeout:o})},c.sleep=(a,m,o)=>{if(typeof a!="string"||a.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"?ot(m):m;if(!s)throw new Error(`step.sleep: invalid duration '${m}'`);let n=s.millis,p=o?.signal;return c(a,async()=>{if(_?.aborted||p?.aborted){let d=new Error("Sleep aborted");throw d.name="AbortError",d}return new Promise((d,w)=>{let y={timeoutId:void 0},T=()=>{y.timeoutId&&clearTimeout(y.timeoutId);let x=new Error("Sleep aborted");x.name="AbortError",w(x)};_?.addEventListener("abort",T,{once:!0}),p?.addEventListener("abort",T,{once:!0}),y.timeoutId=setTimeout(()=>{_?.removeEventListener("abort",T),p?.removeEventListener("abort",T),d(Y(void 0))},n)})},{key:o?.key??a,description:o?.description})},c.all=((...a)=>{if(typeof a[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=a[0],o=a[1];if(typeof o=="function")return W(m,o);if(o&&typeof o=="object"&&!Array.isArray(o)){let n=L(o);return U(n,{name:m})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),c.race=(a,m)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1,p={scopeId:o,type:"race",winnerId:void 0};D.push(p);let d=()=>{if(n)return;n=!0;let w=D.findIndex(y=>y.scopeId===o);w!==-1&&D.splice(w,1),l({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s,winnerId:p.winnerId})};l({type:"scope_start",workflowId:i,scopeId:o,scopeType:"race",name:a,ts:Date.now()});try{let w=await m();if(d(),!w.ok)throw r?.(w.error,a,E),g(w.error,{origin:"result",resultCause:w.cause});return w.value}catch(w){throw d(),w}})()},c.if=(a,m,o)=>o(),c.label=c.if,c.branch=async(a,m)=>{let{condition:o,then:s,else:n}=m;if(o())return await s();if(n)return await n()},c.arm=(a,m)=>({fn:a,errors:m}),c.forEach=async(a,m,o)=>{let s=[],n=o.maxIterations,p=0,d="run"in o,w=Symbol.asyncIterator in m?m:(async function*(){yield*m})();for await(let y of w){if(n!==void 0&&p>=n)break;let T;d?T=await o.run(y,p):T=await o.item.handler(y,p,c),s.push(T),p++}return s},c.item=a=>({__forEachItemHandler:!0,handler:a}),c.dep=(a,m)=>m,c.workflow=(a,m,o)=>c(a,m,o),c.map=async(a,m,o,s)=>{let n=s?.concurrency??m.length;return c(a,()=>n>=m.length?Be(m.map((p,d)=>o(p,d))):(async()=>{let p=[];for(let d=0;d<m.length;d+=n){let w=m.slice(d,d+n),y=await Be(w.map((T,x)=>o(T,d+x)));if(!y.ok)return y;p.push(...y.value)}return Y(p)})(),{key:s?.key})},c.withFallback=(a,m,o)=>{if(typeof a!="string"||a.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??a,n=a,p=J(s),d=u;return(async()=>{let w=d?performance.now():0;u&&l({type:"step_start",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now()});let y;try{y=await m()}catch(A){if(I(A))throw l({type:"step_aborted",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-w}),A;let M;try{M=$(A)}catch(C){throw ne(C)}if(o.on!==void 0&&o.on!==M){let C=performance.now()-w;throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:C,error:M}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:C,result:B(M,{cause:A}),meta:{origin:"throw",thrown:A}}),r?.(M,n,E),g(M,{origin:"throw",thrown:A})}let h;try{h=await o.fallback()}catch(C){if(I(C))throw l({type:"step_aborted",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-w}),C;let v;try{v=$(C)}catch(ee){throw ne(ee)}let re=performance.now()-w;throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:re,error:v}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:re,result:B(v,{cause:C}),meta:{origin:"throw",thrown:C}}),r?.(v,n,E),g(v,{origin:"throw",thrown:C})}if(h.ok){let C=performance.now()-w;return l({type:"step_success",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:C}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:C,result:h,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(M)}}),h.value}else{let C=performance.now()-w,v=O(h.error,{origin:"result",resultCause:h.cause});throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:C,error:v}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:C,result:h,meta:{origin:"result",resultCause:h.cause}}),r?.(v,n,E),g(v,{origin:"result",resultCause:h.cause})}}if(y.ok){let A=performance.now()-w;return l({type:"step_success",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:A}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:A,result:y}),y.value}let T=y.error;if(o.on!==void 0&&o.on!==T){let A=performance.now()-w,M=O(T,{origin:"result",resultCause:y.cause});throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:A,error:M}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:A,result:y,meta:{origin:"result",resultCause:y.cause}}),r?.(M,n,E),g(M,{origin:"result",resultCause:y.cause})}let x;try{x=await o.fallback()}catch(A){if(I(A))throw l({type:"step_aborted",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-w}),A;let M;try{M=$(A)}catch(C){throw ne(C)}let h=performance.now()-w;throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:h,error:M}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:h,result:B(M,{cause:A}),meta:{origin:"throw",thrown:A}}),r?.(M,n,E),g(M,{origin:"throw",thrown:A})}if(x.ok){let A=performance.now()-w;return l({type:"step_success",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:A}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:A,result:x,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(T)}}),x.value}let b=performance.now()-w,j=O(x.error,{origin:"result",resultCause:x.cause});throw l({type:"step_error",workflowId:i,stepId:p,stepKey:s,name:n,ts:Date.now(),durationMs:b,error:j}),s&&l({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:b,result:x,meta:{origin:"result",resultCause:x.cause}}),r?.(j,n,E),g(j,{origin:"result",resultCause:x.cause})})()},c.withResource=(a,m)=>{if(typeof a!="string"||a.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=a,s=a,n=J(o),p=u;return(async()=>{let d=p?performance.now():0;u&&l({type:"step_start",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now()});let w;try{w=await m.acquire()}catch(h){if(I(h))throw l({type:"step_aborted",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:performance.now()-d}),h;let C;try{C=$(h)}catch(re){throw ne(re)}let v=performance.now()-d;throw l({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:v,error:C}),o&&l({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:v,result:B(C,{cause:h}),meta:{origin:"throw",thrown:h}}),r?.(C,s,E),g(C,{origin:"throw",thrown:h})}if(!w.ok){let h=performance.now()-d,C=O(w.error,{origin:"result",resultCause:w.cause});throw l({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:h,error:C}),o&&l({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:h,result:w,meta:{origin:"result",resultCause:w.cause}}),r?.(C,s,E),g(C,{origin:"result",resultCause:w.cause})}let y=w.value,T,x,b=!1;try{T=await m.use(y)}catch(h){if(I(h)){try{await m.release(y)}catch(C){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,C)}throw h}x=h,b=!0}try{await m.release(y)}catch(h){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,h)}if(b){let h;try{h=$(x)}catch(v){throw ne(v)}let C=performance.now()-d;throw l({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:C,error:h}),o&&l({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:C,result:B(h,{cause:x}),meta:{origin:"throw",thrown:x}}),r?.(h,s,E),g(h,{origin:"throw",thrown:x})}let j=T;if(j.ok){let h=performance.now()-d;return l({type:"step_success",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:h}),o&&l({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:h,result:j}),j.value}let A=performance.now()-d,M=O(j.error,{origin:"result",resultCause:j.cause});throw l({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:A,error:M}),o&&l({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:A,result:j,meta:{origin:"result",resultCause:j.cause}}),r?.(M,s,E),g(M,{origin:"result",resultCause:j.cause})})()};let V=await t({step:c});if(process.env.NODE_ENV!=="production"&&V!==null&&typeof V=="object"&&"ok"in V&&typeof V.ok=="boolean"){let a=V;(a.ok===!0&&"value"in a||a.ok===!1&&"error"in a)&&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 Y(V)}catch(c){if(dt(c))throw c.thrown;if(I(c)){let W=c.meta.origin==="throw"?c.meta.thrown:c.meta.origin==="result"?c.meta.resultCause:void 0;return B(c.error,{cause:W})}let L=$(c);return r?.(L,"unexpected",E),B(L,{cause:c})}}Fe.strict=(t,e)=>Fe(t,e);async function Be(t){return t.length===0?Y([]):new Promise(e=>{let r=!1,u=t.length,k=new Array(t.length);for(let f=0;f<t.length;f++){let S=f;Promise.resolve(t[S]).catch(E=>B({type:"PROMISE_REJECTED",cause:E},{cause:{type:"PROMISE_REJECTION",reason:E}})).then(E=>{if(!r){if(!E.ok){r=!0,e(E);return}k[S]=E.value,u--,u===0&&e(Y(k))}})}})}function Te(t){return t.type==="step_complete"}function Q(t){return typeof t=="object"&&t!==null&&t.type==="PENDING_APPROVAL"}function Re(t){return typeof t=="object"&&t!==null&&t.type==="APPROVAL_REJECTED"}function ae(t,e){let r=new Map(t.steps);return r.set(e.stepKey,{result:Y(e.value)}),{steps:r}}function xe(t,e){let r=new Map(t.steps);return r.delete(e),{steps:r}}function Ae(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,u]of t.steps)!u.result.ok&&Q(u.result.error)&&e.push(r);return e}function ie(){let t=new Map;return{handleEvent:e=>{Te(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,u]of t)!u.result.ok&&Q(u.result.error)&&e.push({stepKey:r,error:u.result.error});return e},injectApproval:(e,r)=>(t.set(e,{result:Y(r)}),{steps:new Map(t)})}}function ve(t,e){return B({type:"PENDING_APPROVAL",stepKey:t,reason:e?.reason,metadata:e?.metadata})}function Se(t){return async()=>{let e=await t.checkApproval();switch(e.status){case"pending":return B({type:"PENDING_APPROVAL",stepKey:t.key,reason:t.pendingReason,metadata:t.metadata});case"rejected":return B({type:"APPROVAL_REJECTED",stepKey:t.key,reason:e.reason});case"approved":return Y(e.value)}}}function Ce(t,e){return async r=>{if(!(typeof e.requiresApproval=="function"?await e.requiresApproval(r):e.requiresApproval))return t(r);if(e.checkApproval){let f=await e.checkApproval();switch(f.status){case"approved":return t(r);case"rejected":return B({type:"APPROVAL_REJECTED",stepKey:e.key,reason:f.reason});case"pending":break}}let k=typeof e.description=="function"?e.description(r):e.description;return B({type:"PENDING_APPROVAL",stepKey:e.key,reason:k,metadata:{...e.metadata,pendingArgs:r,gatedOperation:!0}})}}function Ve(){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,u){t.set(e,{status:"approved",value:r,approvedBy:u?.approvedBy,approvedAt:Date.now()})},async rejectApproval(e,r,u){t.set(e,{status:"rejected",reason:r,rejectedBy:u?.rejectedBy,rejectedAt:Date.now()})},async editApproval(e,r,u,k){t.set(e,{status:"edited",originalValue:r,editedValue:u,editedBy:k?.editedBy,editedAt:Date.now()})},async cancelApproval(e){t.delete(e)},async listPending(e){let r=[];for(let[u,k]of t)k.status==="pending"&&(!e?.prefix||u.startsWith(e.prefix))&&r.push(u);return r}}}function $e(){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[u,k]of t)if(!(e?.workflowName&&k.workflowName!==e.workflowName)){if(e?.hasPendingApprovals!==void 0){let f=k.pendingApprovals.length>0;if(e.hasPendingApprovals!==f)continue}r.push(u)}return r},async findByPendingApproval(e){let r=[];for(let[u,k]of t)k.pendingApprovals.includes(e)&&r.push(u);return r}}}function qe(t){let{approvalStore:e,workflowStateStore:r,defaultExpirationMs:u=10080*60*1e3,logger:k=()=>{},notificationChannel:f}=t;async function S(g,I,O,N,K){let H=K?.runId??crypto.randomUUID(),G=ie(),c=I({onEvent:G.handleEvent}),L=N,W=await c.run(async F=>O({...F,args:L})),U=G.getPendingApprovals().map(F=>F.stepKey);if(U.length>0){let F={runId:H,workflowName:g,resumeState:G.getResumeState(),pendingApprovals:U,input:N,metadata:K?.metadata,startedAt:Date.now(),updatedAt:Date.now()};await r.save(F);let V,a;!W.ok&&Q(W.error)&&(V=W.error.reason,a=W.error.metadata);let m=Date.now()+u;for(let o of U)await e.createApproval(o,{metadata:{...a,runId:H,workflowName:g},expiresAt:m});if(f)for(let o of U)try{let s=G.getPendingApprovals().find(n=>n.stepKey===o);await f.onApprovalNeeded({approvalKey:o,runId:H,workflowName:g,reason:V,metadata:{...K?.metadata,...a},expiresAt:m,summary:V??`Approval needed for ${o}`,pendingArgs:s?.error.metadata})}catch(s){k(`Failed to notify for approval ${o}: ${s}`)}return k(`Workflow ${H} paused, waiting for: ${U.join(", ")}`),{status:"paused",runId:H,pendingApprovals:U,reason:V}}return k(`Workflow ${H} completed`),{status:"completed",result:W}}async function E(g,I,O){let N=await r.load(g);if(!N)throw new Error(`Workflow run not found: ${g}`);for(let U of N.pendingApprovals){let F=await e.getApproval(U);if(F.status==="pending")return{status:"paused",runId:g,pendingApprovals:N.pendingApprovals};if(F.status,F.status==="expired")throw new Error(`Approval ${U} has expired`)}let K=N.resumeState;for(let U of N.pendingApprovals){let F=await e.getApproval(U);F.status==="approved"?K=ae(K,{stepKey:U,value:F.value}):F.status==="edited"&&(K=ae(K,{stepKey:U,value:F.editedValue}))}let H=ie(),G=I({resumeState:K,onEvent:H.handleEvent}),c=N.input,L=await G.run(async U=>O({...U,args:c})),W=H.getPendingApprovals().map(U=>U.stepKey);if(W.length>0){let U={...N,resumeState:H.getResumeState(),pendingApprovals:W,updatedAt:Date.now()};await r.save(U);for(let V of W)await e.createApproval(V,{metadata:{runId:g,workflowName:N.workflowName},expiresAt:Date.now()+u});k(`Workflow ${g} paused again, waiting for: ${W.join(", ")}`);let F;return!L.ok&&Q(L.error)&&(F=L.error.reason),{status:"paused",runId:g,pendingApprovals:W,reason:F}}return await r.delete(g),k(`Workflow ${g} resumed and completed`),{status:"resumed",runId:g,result:L}}async function _(g,I,O){await e.grantApproval(g,I,{approvedBy:O?.approvedBy});let N=Date.now(),K=[];if(O?.autoResume!==!1){let H=await r.findByPendingApproval(g);for(let G of H)K.push(G)}return f?.onApprovalResolved&&await f.onApprovalResolved({approvalKey:g,action:"approved",actorId:O?.approvedBy,resolvedAt:N,value:I}),k(`Approval ${g} granted by ${O?.approvedBy??"unknown"}`),{grantedAt:N,resumedWorkflows:K}}async function i(g,I,O){await e.rejectApproval(g,I,{rejectedBy:O?.rejectedBy}),f?.onApprovalResolved&&await f.onApprovalResolved({approvalKey:g,action:"rejected",actorId:O?.rejectedBy,resolvedAt:Date.now(),reason:I}),k(`Approval ${g} rejected: ${I}`)}async function $(g,I,O,N){await e.editApproval(g,I,O,{editedBy:N?.editedBy});let K=Date.now();return f?.onApprovalResolved&&await f.onApprovalResolved({approvalKey:g,action:"edited",actorId:N?.editedBy,resolvedAt:K,value:O,originalValue:I}),k(`Approval ${g} edited by ${N?.editedBy??"unknown"}`),{editedAt:K}}async function D(g,I){let{intervalMs:O=1e3,maxPolls:N,timeoutMs:K,onPollStart:H,onPollComplete:G}=I??{},c=Date.now(),L=0;for(;;){H?.();let W=await e.getApproval(g);if(G?.(W),W.status!=="pending")return W;if(L++,N!==void 0&&L>=N)return{status:"pending"};if(K!==void 0&&Date.now()-c>=K)return{status:"pending"};await new Promise(U=>setTimeout(U,O))}}async function q(g){return r.load(g)}async function J(g){return r.list({workflowName:g,hasPendingApprovals:!0})}async function l(g){let I=await r.list(),O=0,N=Date.now()-g;for(let K of I){let H=await r.load(K);H&&H.updatedAt<N&&H.pendingApprovals.length===0&&(await r.delete(K),O++)}return k(`Cleaned up ${O} old workflow states`),O}return{execute:S,resume:E,grantApproval:_,rejectApproval:i,editApproval:$,pollApproval:D,getWorkflowStatus:q,listPendingWorkflows:J,cleanup:l}}function Ye(t){return async e=>{let{key:r,action:u,value:k,originalValue:f,editedValue:S,reason:E,actorId:_}=e;try{switch(u){case"approve":return await t.grantApproval(r,k,{approvedBy:_}),{success:!0,message:`Approval ${r} granted`,data:{key:r,action:u,timestamp:Date.now()}};case"reject":return E?(await t.rejectApproval(r,E,{rejectedBy:_}),{success:!0,message:`Approval ${r} rejected`,data:{key:r,action:u,timestamp:Date.now()}}):{success:!1,message:"Reason is required for rejection"};case"edit":return f===void 0||S===void 0?{success:!1,message:"Both originalValue and editedValue are required for edit"}:(await t.editApproval(r,f,S,{editedBy:_}),{success:!0,message:`Approval ${r} edited`,data:{key:r,action:u,timestamp:Date.now()}});case"cancel":return await t.cancelApproval(r),{success:!0,message:`Approval ${r} cancelled`,data:{key:r,action:u,timestamp:Date.now()}};default:return{success:!1,message:`Unknown action: ${u}`}}}catch(i){return{success:!1,message:i instanceof Error?i.message:String(i)}}}}function ze(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"}}}}0&&(module.exports={clearStep,createApprovalChecker,createApprovalStateCollector,createApprovalStep,createApprovalWebhookHandler,createHITLOrchestrator,createMemoryApprovalStore,createMemoryWorkflowStateStore,gatedStep,getPendingApprovals,hasPendingApproval,injectApproval,isApprovalRejected,isPendingApproval,pendingApproval});
|
|
7
|
-
//# sourceMappingURL=hitl.cjs.map
|