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