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/saga.d.cts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { R as Result, c as AsyncResult } from './run-entry-D2MmJFj9.cjs';
|
|
2
|
-
import { a as Workflow, e as AnyResultFn, h as WorkflowOptions, E as ErrorsOfDeps } from './persistence-entry-ymCA4iDu.cjs';
|
|
3
|
-
import { UnexpectedError } from './errors.cjs';
|
|
4
|
-
import './types-qBUOYi-4.cjs';
|
|
5
|
-
import '@standard-schema/spec';
|
|
6
|
-
import './tagged-error.cjs';
|
|
7
|
-
import './slugs.cjs';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Saga / Compensation Pattern
|
|
11
|
-
*
|
|
12
|
-
* Compensation is a first-class step option on every workflow. Pass `{ compensate }`
|
|
13
|
-
* to any step and the workflow will run compensations in reverse order if anything
|
|
14
|
-
* downstream fails.
|
|
15
|
-
*
|
|
16
|
-
* `createSagaWorkflow` is a thin alias for `createWorkflow` whose result error union
|
|
17
|
-
* also includes `SagaCompensationError` — useful when you know you'll be using
|
|
18
|
-
* compensation and want the type system to remind you.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { createSagaWorkflow, isSagaCompensationError } from 'awaitly/saga';
|
|
23
|
-
*
|
|
24
|
-
* const checkout = createSagaWorkflow('checkout', {
|
|
25
|
-
* reserveInventory, releaseInventory,
|
|
26
|
-
* chargeCard, refundPayment,
|
|
27
|
-
* sendEmail,
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* const result = await checkout.run(async ({ step, deps }) => {
|
|
31
|
-
* const r = await step('reserve', () => deps.reserveInventory(items), {
|
|
32
|
-
* compensate: (r) => deps.releaseInventory(r.id),
|
|
33
|
-
* });
|
|
34
|
-
* const p = await step('charge', () => deps.chargeCard(amount), {
|
|
35
|
-
* compensate: (p) => deps.refundPayment(p.id),
|
|
36
|
-
* });
|
|
37
|
-
* await step('notify', () => deps.sendEmail(userId));
|
|
38
|
-
* return { r, p };
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* if (!result.ok && isSagaCompensationError(result.error)) {
|
|
42
|
-
* // result.error.originalError — what triggered the rollback
|
|
43
|
-
* // result.error.compensationErrors — which cleanups failed
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
/** A compensation action to run on rollback. */
|
|
49
|
-
type CompensationAction<T> = (value: T) => void | Promise<void>;
|
|
50
|
-
/** Options for a saga step (kept for back-compat — `compensate` lives on `StepOptions`). */
|
|
51
|
-
interface SagaStepOptions<T> {
|
|
52
|
-
compensate?: CompensationAction<T>;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* @deprecated Use `WorkflowOptions` from `awaitly/workflow`. Kept as an alias for back-compat.
|
|
56
|
-
*/
|
|
57
|
-
type SagaWorkflowOptions<E> = {
|
|
58
|
-
onError?: (error: E | UnexpectedError | SagaCompensationError, stepName?: string) => void;
|
|
59
|
-
onEvent?: (event: unknown) => void;
|
|
60
|
-
throwOnCompensationFailure?: boolean;
|
|
61
|
-
};
|
|
62
|
-
/** Error returned when one or more compensation actions fail. */
|
|
63
|
-
interface SagaCompensationError {
|
|
64
|
-
type: "SAGA_COMPENSATION_ERROR";
|
|
65
|
-
/** The original error that triggered the rollback. */
|
|
66
|
-
originalError: unknown;
|
|
67
|
-
/** Errors from failed compensation actions. */
|
|
68
|
-
compensationErrors: Array<{
|
|
69
|
-
stepName?: string;
|
|
70
|
-
error: unknown;
|
|
71
|
-
}>;
|
|
72
|
-
}
|
|
73
|
-
/** Type guard for SagaCompensationError. */
|
|
74
|
-
declare function isSagaCompensationError(error: unknown): error is SagaCompensationError;
|
|
75
|
-
/**
|
|
76
|
-
* A `Workflow` whose result error union includes `SagaCompensationError`.
|
|
77
|
-
* Identical to `Workflow` at runtime — only the static type is widened.
|
|
78
|
-
*/
|
|
79
|
-
type SagaWorkflow<E, U = UnexpectedError, Deps = unknown, C = void> = Workflow<E | SagaCompensationError, U, Deps, C>;
|
|
80
|
-
/**
|
|
81
|
-
* Create a workflow that uses compensation. Identical to `createWorkflow` —
|
|
82
|
-
* only the result type is widened to include `SagaCompensationError`.
|
|
83
|
-
*
|
|
84
|
-
* Prefer this when you intend to use `step(..., { compensate })` so the type
|
|
85
|
-
* system reminds you to handle the SAGA_COMPENSATION_ERROR case.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const saga = createSagaWorkflow('checkout', { reserve, release, charge, refund });
|
|
90
|
-
*
|
|
91
|
-
* const result = await saga.run(async ({ step, deps }) => {
|
|
92
|
-
* const r = await step('reserve', () => deps.reserve(...), {
|
|
93
|
-
* compensate: (r) => deps.release(r.id),
|
|
94
|
-
* });
|
|
95
|
-
* await step('charge', () => deps.charge(...), {
|
|
96
|
-
* compensate: (p) => deps.refund(p.id),
|
|
97
|
-
* });
|
|
98
|
-
* return r;
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
declare function createSagaWorkflow<const Deps extends Readonly<Record<string, AnyResultFn>>, U = UnexpectedError, C = void>(workflowName: string, deps: Deps, options?: WorkflowOptions<ErrorsOfDeps<Deps>, U, C>): SagaWorkflow<ErrorsOfDeps<Deps>, U, Deps, C>;
|
|
103
|
-
/** Saga events emitted by `runSaga` for observability. */
|
|
104
|
-
type SagaEvent = {
|
|
105
|
-
type: "saga_start";
|
|
106
|
-
sagaId: string;
|
|
107
|
-
ts: number;
|
|
108
|
-
} | {
|
|
109
|
-
type: "saga_success";
|
|
110
|
-
sagaId: string;
|
|
111
|
-
ts: number;
|
|
112
|
-
durationMs: number;
|
|
113
|
-
} | {
|
|
114
|
-
type: "saga_error";
|
|
115
|
-
sagaId: string;
|
|
116
|
-
ts: number;
|
|
117
|
-
durationMs: number;
|
|
118
|
-
error: unknown;
|
|
119
|
-
} | {
|
|
120
|
-
type: "saga_compensation_start";
|
|
121
|
-
sagaId: string;
|
|
122
|
-
ts: number;
|
|
123
|
-
stepCount: number;
|
|
124
|
-
} | {
|
|
125
|
-
type: "saga_compensation_step";
|
|
126
|
-
sagaId: string;
|
|
127
|
-
stepName?: string;
|
|
128
|
-
ts: number;
|
|
129
|
-
success: boolean;
|
|
130
|
-
error?: unknown;
|
|
131
|
-
} | {
|
|
132
|
-
type: "saga_compensation_end";
|
|
133
|
-
sagaId: string;
|
|
134
|
-
ts: number;
|
|
135
|
-
durationMs: number;
|
|
136
|
-
success: boolean;
|
|
137
|
-
failedCount: number;
|
|
138
|
-
};
|
|
139
|
-
type SagaResult<T, E> = Result<T, E | UnexpectedError | SagaCompensationError, unknown>;
|
|
140
|
-
/** Saga step function — like RunStep but every step takes an optional compensate. */
|
|
141
|
-
interface SagaStep<E = unknown> {
|
|
142
|
-
<T, StepE extends E, StepC = unknown>(name: string, operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>, options?: SagaStepOptions<T>): Promise<T>;
|
|
143
|
-
try: <T, Err extends E>(name: string, operation: () => T | Promise<T>, options: {
|
|
144
|
-
error: Err;
|
|
145
|
-
compensate?: CompensationAction<T>;
|
|
146
|
-
} | {
|
|
147
|
-
onError: (cause: unknown) => Err;
|
|
148
|
-
compensate?: CompensationAction<T>;
|
|
149
|
-
}) => Promise<T>;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Run a saga with explicit error typing — for cases where you don't have a
|
|
153
|
-
* deps object to infer errors from. Most users should reach for
|
|
154
|
-
* `createSagaWorkflow` (or just `createWorkflow` with `step({ compensate })`).
|
|
155
|
-
*/
|
|
156
|
-
declare function runSaga<T, E>(fn: (context: {
|
|
157
|
-
step: SagaStep<E>;
|
|
158
|
-
}) => Promise<T>, options?: {
|
|
159
|
-
onError?: (error: E | UnexpectedError | SagaCompensationError) => void;
|
|
160
|
-
onEvent?: (event: SagaEvent) => void;
|
|
161
|
-
throwOnCompensationFailure?: boolean;
|
|
162
|
-
}): Promise<SagaResult<T, E>>;
|
|
163
|
-
|
|
164
|
-
export { type CompensationAction, type SagaCompensationError, type SagaEvent, type SagaResult, type SagaStep, type SagaStepOptions, type SagaWorkflow, type SagaWorkflowOptions, createSagaWorkflow, isSagaCompensationError, runSaga };
|
package/dist/saga.d.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { R as Result, c as AsyncResult } from './run-entry-Dduz-is2.js';
|
|
2
|
-
import { a as Workflow, e as AnyResultFn, h as WorkflowOptions, E as ErrorsOfDeps } from './persistence-entry-DOMx3woy.js';
|
|
3
|
-
import { UnexpectedError } from './errors.js';
|
|
4
|
-
import './types-DQmzO9f4.js';
|
|
5
|
-
import '@standard-schema/spec';
|
|
6
|
-
import './tagged-error.js';
|
|
7
|
-
import './slugs.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Saga / Compensation Pattern
|
|
11
|
-
*
|
|
12
|
-
* Compensation is a first-class step option on every workflow. Pass `{ compensate }`
|
|
13
|
-
* to any step and the workflow will run compensations in reverse order if anything
|
|
14
|
-
* downstream fails.
|
|
15
|
-
*
|
|
16
|
-
* `createSagaWorkflow` is a thin alias for `createWorkflow` whose result error union
|
|
17
|
-
* also includes `SagaCompensationError` — useful when you know you'll be using
|
|
18
|
-
* compensation and want the type system to remind you.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { createSagaWorkflow, isSagaCompensationError } from 'awaitly/saga';
|
|
23
|
-
*
|
|
24
|
-
* const checkout = createSagaWorkflow('checkout', {
|
|
25
|
-
* reserveInventory, releaseInventory,
|
|
26
|
-
* chargeCard, refundPayment,
|
|
27
|
-
* sendEmail,
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* const result = await checkout.run(async ({ step, deps }) => {
|
|
31
|
-
* const r = await step('reserve', () => deps.reserveInventory(items), {
|
|
32
|
-
* compensate: (r) => deps.releaseInventory(r.id),
|
|
33
|
-
* });
|
|
34
|
-
* const p = await step('charge', () => deps.chargeCard(amount), {
|
|
35
|
-
* compensate: (p) => deps.refundPayment(p.id),
|
|
36
|
-
* });
|
|
37
|
-
* await step('notify', () => deps.sendEmail(userId));
|
|
38
|
-
* return { r, p };
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* if (!result.ok && isSagaCompensationError(result.error)) {
|
|
42
|
-
* // result.error.originalError — what triggered the rollback
|
|
43
|
-
* // result.error.compensationErrors — which cleanups failed
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
/** A compensation action to run on rollback. */
|
|
49
|
-
type CompensationAction<T> = (value: T) => void | Promise<void>;
|
|
50
|
-
/** Options for a saga step (kept for back-compat — `compensate` lives on `StepOptions`). */
|
|
51
|
-
interface SagaStepOptions<T> {
|
|
52
|
-
compensate?: CompensationAction<T>;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* @deprecated Use `WorkflowOptions` from `awaitly/workflow`. Kept as an alias for back-compat.
|
|
56
|
-
*/
|
|
57
|
-
type SagaWorkflowOptions<E> = {
|
|
58
|
-
onError?: (error: E | UnexpectedError | SagaCompensationError, stepName?: string) => void;
|
|
59
|
-
onEvent?: (event: unknown) => void;
|
|
60
|
-
throwOnCompensationFailure?: boolean;
|
|
61
|
-
};
|
|
62
|
-
/** Error returned when one or more compensation actions fail. */
|
|
63
|
-
interface SagaCompensationError {
|
|
64
|
-
type: "SAGA_COMPENSATION_ERROR";
|
|
65
|
-
/** The original error that triggered the rollback. */
|
|
66
|
-
originalError: unknown;
|
|
67
|
-
/** Errors from failed compensation actions. */
|
|
68
|
-
compensationErrors: Array<{
|
|
69
|
-
stepName?: string;
|
|
70
|
-
error: unknown;
|
|
71
|
-
}>;
|
|
72
|
-
}
|
|
73
|
-
/** Type guard for SagaCompensationError. */
|
|
74
|
-
declare function isSagaCompensationError(error: unknown): error is SagaCompensationError;
|
|
75
|
-
/**
|
|
76
|
-
* A `Workflow` whose result error union includes `SagaCompensationError`.
|
|
77
|
-
* Identical to `Workflow` at runtime — only the static type is widened.
|
|
78
|
-
*/
|
|
79
|
-
type SagaWorkflow<E, U = UnexpectedError, Deps = unknown, C = void> = Workflow<E | SagaCompensationError, U, Deps, C>;
|
|
80
|
-
/**
|
|
81
|
-
* Create a workflow that uses compensation. Identical to `createWorkflow` —
|
|
82
|
-
* only the result type is widened to include `SagaCompensationError`.
|
|
83
|
-
*
|
|
84
|
-
* Prefer this when you intend to use `step(..., { compensate })` so the type
|
|
85
|
-
* system reminds you to handle the SAGA_COMPENSATION_ERROR case.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const saga = createSagaWorkflow('checkout', { reserve, release, charge, refund });
|
|
90
|
-
*
|
|
91
|
-
* const result = await saga.run(async ({ step, deps }) => {
|
|
92
|
-
* const r = await step('reserve', () => deps.reserve(...), {
|
|
93
|
-
* compensate: (r) => deps.release(r.id),
|
|
94
|
-
* });
|
|
95
|
-
* await step('charge', () => deps.charge(...), {
|
|
96
|
-
* compensate: (p) => deps.refund(p.id),
|
|
97
|
-
* });
|
|
98
|
-
* return r;
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
declare function createSagaWorkflow<const Deps extends Readonly<Record<string, AnyResultFn>>, U = UnexpectedError, C = void>(workflowName: string, deps: Deps, options?: WorkflowOptions<ErrorsOfDeps<Deps>, U, C>): SagaWorkflow<ErrorsOfDeps<Deps>, U, Deps, C>;
|
|
103
|
-
/** Saga events emitted by `runSaga` for observability. */
|
|
104
|
-
type SagaEvent = {
|
|
105
|
-
type: "saga_start";
|
|
106
|
-
sagaId: string;
|
|
107
|
-
ts: number;
|
|
108
|
-
} | {
|
|
109
|
-
type: "saga_success";
|
|
110
|
-
sagaId: string;
|
|
111
|
-
ts: number;
|
|
112
|
-
durationMs: number;
|
|
113
|
-
} | {
|
|
114
|
-
type: "saga_error";
|
|
115
|
-
sagaId: string;
|
|
116
|
-
ts: number;
|
|
117
|
-
durationMs: number;
|
|
118
|
-
error: unknown;
|
|
119
|
-
} | {
|
|
120
|
-
type: "saga_compensation_start";
|
|
121
|
-
sagaId: string;
|
|
122
|
-
ts: number;
|
|
123
|
-
stepCount: number;
|
|
124
|
-
} | {
|
|
125
|
-
type: "saga_compensation_step";
|
|
126
|
-
sagaId: string;
|
|
127
|
-
stepName?: string;
|
|
128
|
-
ts: number;
|
|
129
|
-
success: boolean;
|
|
130
|
-
error?: unknown;
|
|
131
|
-
} | {
|
|
132
|
-
type: "saga_compensation_end";
|
|
133
|
-
sagaId: string;
|
|
134
|
-
ts: number;
|
|
135
|
-
durationMs: number;
|
|
136
|
-
success: boolean;
|
|
137
|
-
failedCount: number;
|
|
138
|
-
};
|
|
139
|
-
type SagaResult<T, E> = Result<T, E | UnexpectedError | SagaCompensationError, unknown>;
|
|
140
|
-
/** Saga step function — like RunStep but every step takes an optional compensate. */
|
|
141
|
-
interface SagaStep<E = unknown> {
|
|
142
|
-
<T, StepE extends E, StepC = unknown>(name: string, operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>, options?: SagaStepOptions<T>): Promise<T>;
|
|
143
|
-
try: <T, Err extends E>(name: string, operation: () => T | Promise<T>, options: {
|
|
144
|
-
error: Err;
|
|
145
|
-
compensate?: CompensationAction<T>;
|
|
146
|
-
} | {
|
|
147
|
-
onError: (cause: unknown) => Err;
|
|
148
|
-
compensate?: CompensationAction<T>;
|
|
149
|
-
}) => Promise<T>;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Run a saga with explicit error typing — for cases where you don't have a
|
|
153
|
-
* deps object to infer errors from. Most users should reach for
|
|
154
|
-
* `createSagaWorkflow` (or just `createWorkflow` with `step({ compensate })`).
|
|
155
|
-
*/
|
|
156
|
-
declare function runSaga<T, E>(fn: (context: {
|
|
157
|
-
step: SagaStep<E>;
|
|
158
|
-
}) => Promise<T>, options?: {
|
|
159
|
-
onError?: (error: E | UnexpectedError | SagaCompensationError) => void;
|
|
160
|
-
onEvent?: (event: SagaEvent) => void;
|
|
161
|
-
throwOnCompensationFailure?: boolean;
|
|
162
|
-
}): Promise<SagaResult<T, E>>;
|
|
163
|
-
|
|
164
|
-
export { type CompensationAction, type SagaCompensationError, type SagaEvent, type SagaResult, type SagaStep, type SagaStepOptions, type SagaWorkflow, type SagaWorkflowOptions, createSagaWorkflow, isSagaCompensationError, runSaga };
|
package/dist/saga.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
var Rt={"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 Ze(e){return`https://jagreehal.github.io/awaitly/rules/#${e}`}var Lt=Object.keys(Rt);var Ue=class extends Error{_tag};function pe(e,t){return class extends Ue{_tag=e;constructor(i,h){let R=t?.message?t.message(i??{}):e;if(super(R),this.name=e,t?.slug!==void 0){if(!t.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${t.slug}")`);Object.defineProperty(this,"code",{value:t.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:t.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:Ze(t.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),i&&typeof i=="object"){let y;if(t?.slug!==void 0){let{_tag:o,name:J,message:v,stack:E,code:G,hint:l,docsUrl:X,...ne}=i;y=ne}else{let{_tag:o,name:J,message:v,stack:E,...G}=i;y=G}let N=Object.prototype.hasOwnProperty.call(y,"cause"),C=N?y.cause:void 0;N&&delete y.cause;let H=h?.cause!==void 0;if(N&&H)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,y),N&&(this.cause=C),H&&(this.cause=h?.cause)}else h?.cause!==void 0&&(this.cause=h.cause)}}}Object.defineProperty(pe,Symbol.hasInstance,{value:e=>e instanceof Ue});(R=>{function e(y){return y instanceof Error}R.isError=e;function t(y){return y instanceof Ue}R.isTaggedError=t;function i(y,N){let C=y._tag,H=N[C];return H(y)}R.match=i;function h(y,N,C){let H=y._tag,o=N[H];return o?o(y):C(y)}R.matchPartial=h})(pe||={});var Qe=class extends pe("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:t=>t.operation?`TimeoutError: ${t.operation} timed out after ${t.ms}ms`:`TimeoutError: Operation timed out after ${t.ms}ms`}){},et=class extends pe("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:t=>t.operation?`RetryExhaustedError: ${t.operation} failed after ${t.attempts} attempts`:`RetryExhaustedError: Operation failed after ${t.attempts} attempts`}){},tt=class extends pe("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:t=>t.limiterName?`RateLimitError: Rate limit exceeded for ${t.limiterName}${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`}){},rt=class extends pe("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:t=>`CircuitBreakerOpenError: Circuit ${t.circuitName} is ${t.state??"OPEN"}${t.retryAfterMs?`, retry after ${Math.ceil(t.retryAfterMs/1e3)}s`:""}`}){},nt=class extends pe("ValidationError",{message:t=>`ValidationError: Invalid ${t.field} - ${t.reason}`}){},ot=class extends pe("NotFoundError",{message:t=>t.id?`NotFoundError: ${t.resource} with id ${t.id} not found`:`NotFoundError: ${t.resource} not found`}){},st=class extends pe("UnauthorizedError",{message:t=>t.reason?`UnauthorizedError: ${t.reason}`:t.action&&t.resource?`UnauthorizedError: Not authorized to ${t.action} ${t.resource}`:"UnauthorizedError: Access denied"}){},at=class extends pe("NetworkError",{message:t=>t.url?`NetworkError: ${t.reason} (${t.url})`:`NetworkError: ${t.reason}`}){},it=class extends pe("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:t=>`CompensationError: Failed to compensate step ${t.step}`}){},be=class extends pe("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:t=>`UnexpectedError: ${t.cause instanceof Error?t.cause.message:String(t.cause??"unknown")}`}){};function xt(e){let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let i=parseFloat(t[1]),h=t[2].toLowerCase();return{_tag:"Duration",millis:i*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[h]??1)}}function Ke(e){return new be({cause:e})}function Y(e){return{ok:!0,value:e}}function K(e,t){let i=t?.cause;return{ok:!1,error:e,...i!==void 0?{cause:i}:{}}}var pt=e=>e instanceof be||typeof e=="object"&&e!==null&&"_tag"in e&&e._tag==="UnexpectedError";function ht(e){if(e==null)return"unknown";if(typeof e=="string")return e.trim()||"unknown";if(typeof e=="object"){let t=e;if(typeof t._tag=="string"){let i=t._tag.trim();if(i)return i}if(typeof t.tag=="string"){let i=t.tag.trim();if(i)return i}if(typeof t.code=="string"){let i=t.code.trim();if(i)return i}else if(typeof t.code=="number")return String(t.code);if(e instanceof Error&&e.name){let i=e.name.trim();if(i)return i}}return"unknown"}function St(e,t){if(!(!t||!e))return t[e]}function He(e){let{intent:t,domain:i,owner:h,tags:R,stateChanges:y,emits:N,calls:C}=e;if(!t&&!i&&!h&&!R?.length&&!y?.length&&!N?.length&&!C?.length)return;let H={};return t&&(H.intent=t),i&&(H.domain=i),h&&(H.owner=h),R?.length&&(H.tags=R),y?.length&&(H.stateChanges=y),N?.length&&(H.emits=N),C?.length&&(H.calls=C),H}function de(e,t,i,h,R){let y=ht(e),N=St(y,t),C={tag:y,origin:i};return N!==void 0&&(C.classification=N),h!==void 0&&(C.attempt=h),R!==void 0&&(C.cumulativeDurationMs=R),C}var Oe=Symbol.for("step_timeout_marker");function ut(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:Oe in e}function Ct(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let t=e;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(Oe in e)return e[Oe]}}var mt=Symbol("early-exit");function Te(e,t){return{[mt]:!0,error:e,meta:t}}function we(e){return typeof e=="object"&&e!==null&&e[mt]===!0}var dt=Symbol("mapper-exception");function _e(e){return{[dt]:!0,thrown:e}}function bt(e){return typeof e=="object"&&e!==null&&e[dt]===!0}function Be(e,t){let{backoff:i,initialDelay:h,maxDelay:R,jitter:y}=t,N;switch(i){case"fixed":N=h;break;case"linear":N=h*e;break;case"exponential":N=h*Math.pow(2,e-1);break}if(N=Math.min(N,R),y){let C=N*.25*Math.random();N=N+C}return Math.floor(N)}function $e(e){return new Promise(t=>setTimeout(t,e))}var lt=Symbol("timeout"),Ne=Symbol("timeout-option");function vt(e){return typeof e=="object"&&e!==null&&e[Ne]===!0}async function At(e,t,i,h){let R=new AbortController,y=t.onTimeout??"error",N=()=>typeof y=="function"?y({name:i.name,key:i.key,ms:t.ms}):t.error??{type:"STEP_TIMEOUT",stepName:i.name,stepKey:i.key,timeoutMs:t.ms,attempt:i.attempt},C;h?.aborted&&R.abort(h.reason);let H;h&&!h.aborted&&(H=()=>R.abort(h.reason),h.addEventListener("abort",H,{once:!0}));let o=new Promise((v,E)=>{C=setTimeout(()=>{if(y!=="disconnect"&&R.abort(),y==="option"){E({[Ne]:!0,ms:t.ms});return}E({[lt]:!0,error:N()})},t.ms)}),J;t.signal?J=Promise.resolve(e(R.signal)):J=Promise.resolve(e());try{return await Promise.race([J,o])}catch(v){if(typeof v=="object"&&v!==null&&v[Ne]===!0)throw{[Ne]:!0,ms:t.ms};if(typeof v=="object"&&v!==null&&v[lt]===!0){y==="disconnect"&&J.catch(()=>{});let E=v.error;if(typeof E=="object"&&E!==null&&E.type!=="STEP_TIMEOUT"){let G={timeoutMs:t.ms,stepName:i.name,stepKey:i.key,attempt:i.attempt};Oe in E?E[Oe]=G:Object.defineProperty(E,Oe,{value:G,enumerable:!1,writable:!0,configurable:!1})}throw E}throw v}finally{clearTimeout(C),H&&h&&h.removeEventListener("abort",H)}}var De={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function je(e,t){let{onError:i,onEvent:h,catchUnexpected:R,workflowId:y,workflowName:N,context:C,_workflowSignal:H}=t&&typeof t=="object"?t:{},o=y??crypto.randomUUID(),J=R??Ke,v=[],E=0,G=g=>g??`step_${++E}`,l=g=>{let le=g.context!==void 0||C===void 0?g:{...g,context:C},ce=N!==void 0&&le.workflowName===void 0?{...le,workflowName:N}:le;if(ce.type==="step_success"){let fe=ce.stepId;for(let Ce=v.length-1;Ce>=0;Ce--){let me=v[Ce];if(me.type==="race"&&!me.winnerId){me.winnerId=fe;break}}}h?.(ce,C)},X=Te,ne=g=>we(g),V=(g,le)=>g,Se=g=>typeof g=="function"?!1:!!(g&&typeof g=="object"&&"ok"in g||g&&typeof g=="object"&&"then"in g&&typeof g.then=="function");try{let le=function(c){let x={};for(let[r,a]of Object.entries(c))if(typeof a=="function")x[r]=a;else if(a&&typeof a=="object"&&"fn"in a)x[r]=a.fn;else throw new TypeError(`step.all: operation "${r}" must be a function or { fn, errors? } object`);return x},ce=function(c,x){let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let a=performance.now(),n=!1;v.push({scopeId:r,type:"parallel"});let d=()=>{if(n)return;n=!0;let k=v.findIndex(b=>b.scopeId===r);k!==-1&&v.splice(k,1),l({type:"scope_end",workflowId:o,scopeId:r,ts:Date.now(),durationMs:performance.now()-a})};l({type:"scope_start",workflowId:o,scopeId:r,scopeType:"parallel",name:c,ts:Date.now()});try{let k=await x();if(d(),!k.ok)throw i?.(k.error,c,C),X(k.error,{origin:"result",resultCause:k.cause});return k.value}catch(k){throw d(),k}})()},fe=function(c,x){let r=Object.keys(c),a=x.name??`Parallel(${r.join(", ")})`,n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let d=performance.now(),k=!1;v.push({scopeId:n,type:"parallel"});let b=()=>{if(k)return;k=!0;let u=v.findIndex(_=>_.scopeId===n);u!==-1&&v.splice(u,1),l({type:"scope_end",workflowId:o,scopeId:n,ts:Date.now(),durationMs:performance.now()-d})};l({type:"scope_start",workflowId:o,scopeId:n,scopeType:"parallel",name:a,ts:Date.now()});try{let u=await new Promise(U=>{if(r.length===0){U([]);return}let B=!1,Z=r.length,M=new Array(r.length);for(let q=0;q<r.length;q++){let W=r[q],L=q;Promise.resolve(c[W]()).catch(O=>K({type:"PROMISE_REJECTED",cause:O},{cause:{type:"PROMISE_REJECTION",reason:O}})).then(O=>{if(!B){if(!O.ok){B=!0,U([{key:W,result:O}]);return}M[L]={key:W,result:O},Z--,Z===0&&U(M)}})}});b();let _={};for(let{key:U,result:B}of u){if(!B.ok)throw i?.(B.error,U,C),X(B.error,{origin:"result",resultCause:B.cause});_[U]=B.value}return _}catch(u){throw b(),u}})()};var ve=le,Ae=ce,ye=fe;let g=(c,x,r)=>(async()=>{if(typeof c!="string"||c.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let a=r??{},n=He(a),d=c,k=a.key??c,b=a.key??c,{description:u,retry:_,timeout:U}=a,B=G(k),Z=h,M=Z?performance.now():0,W=Se(x)?()=>x:x,O={attempts:Math.max(1,_?.attempts??1),backoff:_?.backoff??De.backoff,initialDelay:_?.initialDelay??De.initialDelay,maxDelay:_?.maxDelay??De.maxDelay,jitter:_?.jitter??De.jitter,shouldRetry:_?.shouldRetry??De.shouldRetry,onRetry:_?.onRetry??De.onRetry};h&&l({type:"step_start",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),...n&&{metadata:n}});let ge;for(let s=1;s<=O.attempts;s++){let m=Z?performance.now():0;try{let p;if(U?p=await At(W,U,{name:d,key:k,attempt:s},H):p=await W(),p.ok){let $=performance.now()-M;return l({type:"step_success",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:$,...n&&{metadata:n}}),b&&l({type:"step_complete",workflowId:o,stepKey:b,name:d,description:u,ts:Date.now(),durationMs:$,result:p,...n&&{metadata:n}}),p.value}if(ge=p,s<O.attempts&&O.shouldRetry(p.error,s)){let $=Be(s,O);l({type:"step_retry",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),attempt:s+1,maxAttempts:O.attempts,delayMs:$,error:p.error,...n&&{metadata:n},diagnostics:de(p.error,a.errorMeta,"result",s,performance.now()-M)}),O.onRetry(p.error,s,$),await $e($);continue}O.attempts>1&&l({type:"step_retries_exhausted",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),durationMs:performance.now()-M,attempts:s,lastError:p.error,...n&&{metadata:n},diagnostics:de(p.error,a.errorMeta,"result",s,performance.now()-M)});break}catch(p){let $=performance.now()-m;if(vt(p)){let T=p.ms;l({type:"step_timeout",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),timeoutMs:T,attempt:s,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"timeout",s)}),l({type:"step_success",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:performance.now()-M,...n&&{metadata:n}}),b&&l({type:"step_complete",workflowId:o,stepKey:b,name:d,description:u,ts:Date.now(),durationMs:performance.now()-M,result:Y(void 0),...n&&{metadata:n}});return}if(ne(p))throw l({type:"step_aborted",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:$,...n&&{metadata:n}}),p;if(ut(p)){let T=Ct(p),D=U?.ms??T?.timeoutMs??0;if(l({type:"step_timeout",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),timeoutMs:D,attempt:s,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"timeout",s)}),s<O.attempts&&O.shouldRetry(p,s)){let I=Be(s,O);l({type:"step_retry",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),attempt:s+1,maxAttempts:O.attempts,delayMs:I,error:p,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"timeout",s,performance.now()-M)}),O.onRetry(p,s,I),await $e(I);continue}O.attempts>1&&l({type:"step_retries_exhausted",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),durationMs:performance.now()-M,attempts:s,lastError:p,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"timeout",s,performance.now()-M)});let A=performance.now()-M;throw l({type:"step_error",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:A,error:p,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"timeout",s,A)}),b&&l({type:"step_complete",workflowId:o,stepKey:b,name:d,description:u,ts:Date.now(),durationMs:A,result:K(p,{cause:p}),meta:{origin:"throw",thrown:p},...n&&{metadata:n}}),i?.(p,d,C),X(p,{origin:"throw",thrown:p})}if(s<O.attempts&&O.shouldRetry(p,s)){let T=Be(s,O);l({type:"step_retry",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),attempt:s+1,maxAttempts:O.attempts,delayMs:T,error:p,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"throw",s,performance.now()-M)}),O.onRetry(p,s,T),await $e(T);continue}O.attempts>1&&!ut(p)&&l({type:"step_retries_exhausted",workflowId:o,stepId:B,stepKey:k,name:d,ts:Date.now(),durationMs:performance.now()-M,attempts:s,lastError:p,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"throw",s,performance.now()-M)});let f=performance.now()-M,S;try{S=J(p)}catch(T){throw _e(T)}throw l({type:"step_error",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:f,error:S,...n&&{metadata:n},diagnostics:de(p,a.errorMeta,"throw",s,f)}),b&&l({type:"step_complete",workflowId:o,stepKey:b,name:d,description:u,ts:Date.now(),durationMs:f,result:K(S,{cause:p}),meta:{origin:"throw",thrown:p},...n&&{metadata:n}}),i?.(S,d,C),X(S,{origin:"throw",thrown:p})}}let Ee=ge,oe=performance.now()-M,Re=V(Ee.error,{origin:"result",resultCause:Ee.cause});throw l({type:"step_error",workflowId:o,stepId:B,stepKey:k,name:d,description:u,ts:Date.now(),durationMs:oe,error:Re,...n&&{metadata:n},diagnostics:de(Ee.error,a.errorMeta,"result",O.attempts,oe)}),b&&l({type:"step_complete",workflowId:o,stepKey:b,name:d,description:u,ts:Date.now(),durationMs:oe,result:Ee,meta:{origin:"result",resultCause:Ee.cause},...n&&{metadata:n}}),i?.(Re,d,C),X(Re,{origin:"result",resultCause:Ee.cause})})();g.try=(c,x,r)=>{if(typeof c!="string"||c.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 a="error"in r?()=>r.error:r.onError;if(r.retry||r.timeout)return g.retry(c,async()=>{try{return Y(await x())}catch(u){return K(a(u),{cause:u})}},{attempts:r.retry?.attempts??1,...r.retry??{},key:r.key,timeout:r.timeout});let n=r.key??c,d=c,k=c,b=h;return(async()=>{let u=b?performance.now():0;h&&l({type:"step_start",workflowId:o,stepId:k,stepKey:n,name:d,ts:Date.now()});try{let _=await x(),U=performance.now()-u;return l({type:"step_success",workflowId:o,stepId:k,stepKey:n,name:d,ts:Date.now(),durationMs:U}),n&&l({type:"step_complete",workflowId:o,stepKey:n,name:d,ts:Date.now(),durationMs:U,result:Y(_)}),_}catch(_){let U=a(_),B=performance.now()-u,Z=V(U,{origin:"throw",thrown:_});throw l({type:"step_error",workflowId:o,stepId:k,stepKey:n,name:d,ts:Date.now(),durationMs:B,error:Z}),n&&l({type:"step_complete",workflowId:o,stepKey:n,name:d,ts:Date.now(),durationMs:B,result:K(U,{cause:_}),meta:{origin:"throw",thrown:_}}),i?.(Z,d,C),X(Z,{origin:"throw",thrown:_})}})()},g.fromResult=(c,x,r)=>{if(typeof c!="string"||c.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 a=r.key??c,n=c,d=c,k="error"in r?()=>r.error:r.onError,b=h;return(async()=>{let u=b?performance.now():0;h&&l({type:"step_start",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now()});let _=await x();if(_.ok){let U=performance.now()-u;return l({type:"step_success",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:U}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:U,result:Y(_.value)}),_.value}else{let U=k(_.error),B=performance.now()-u,Z=V(U,{origin:"result",resultCause:_.error});throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:B,error:Z}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:B,result:K(U,{cause:_.error}),meta:{origin:"result",resultCause:_.error}}),i?.(Z,n,C),X(Z,{origin:"result",resultCause:_.error})}})()},g.fromNullable=(c,x,r,a)=>{if(typeof c!="string"||c.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 g(c,async()=>{let n=await x();return n!=null?Y(n):K(r())},a)},g.retry=(c,x,r)=>{if(typeof c!="string"||c.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 g(c,x,{key:r.key??c,retry:{attempts:r.attempts,backoff:r.backoff,initialDelay:r.initialDelay,maxDelay:r.maxDelay,jitter:r.jitter,shouldRetry:r.shouldRetry,onRetry:r.onRetry},timeout:r.timeout})},g.withTimeout=(c,x,r)=>{if(typeof c!="string"||c.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 g(c,x,{key:r.key??c,timeout:r})},g.sleep=(c,x,r)=>{if(typeof c!="string"||c.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let a=typeof x=="string"?xt(x):x;if(!a)throw new Error(`step.sleep: invalid duration '${x}'`);let n=a.millis,d=r?.signal;return g(c,async()=>{if(H?.aborted||d?.aborted){let k=new Error("Sleep aborted");throw k.name="AbortError",k}return new Promise((k,b)=>{let u={timeoutId:void 0},_=()=>{u.timeoutId&&clearTimeout(u.timeoutId);let U=new Error("Sleep aborted");U.name="AbortError",b(U)};H?.addEventListener("abort",_,{once:!0}),d?.addEventListener("abort",_,{once:!0}),u.timeoutId=setTimeout(()=>{H?.removeEventListener("abort",_),d?.removeEventListener("abort",_),k(Y(void 0))},n)})},{key:r?.key??c,description:r?.description})},g.all=((...c)=>{if(typeof c[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 x=c[0],r=c[1];if(typeof r=="function")return ce(x,r);if(r&&typeof r=="object"&&!Array.isArray(r)){let n=le(r);return fe(n,{name:x})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),g.race=(c,x)=>{let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let a=performance.now(),n=!1,d={scopeId:r,type:"race",winnerId:void 0};v.push(d);let k=()=>{if(n)return;n=!0;let b=v.findIndex(u=>u.scopeId===r);b!==-1&&v.splice(b,1),l({type:"scope_end",workflowId:o,scopeId:r,ts:Date.now(),durationMs:performance.now()-a,winnerId:d.winnerId})};l({type:"scope_start",workflowId:o,scopeId:r,scopeType:"race",name:c,ts:Date.now()});try{let b=await x();if(k(),!b.ok)throw i?.(b.error,c,C),X(b.error,{origin:"result",resultCause:b.cause});return b.value}catch(b){throw k(),b}})()},g.if=(c,x,r)=>r(),g.label=g.if,g.branch=async(c,x)=>{let{condition:r,then:a,else:n}=x;if(r())return await a();if(n)return await n()},g.arm=(c,x)=>({fn:c,errors:x}),g.forEach=async(c,x,r)=>{let a=[],n=r.maxIterations,d=0,k="run"in r,b=Symbol.asyncIterator in x?x:(async function*(){yield*x})();for await(let u of b){if(n!==void 0&&d>=n)break;let _;k?_=await r.run(u,d):_=await r.item.handler(u,d,g),a.push(_),d++}return a},g.item=c=>({__forEachItemHandler:!0,handler:c}),g.dep=(c,x)=>x,g.workflow=(c,x,r)=>g(c,x,r),g.map=async(c,x,r,a)=>{let n=a?.concurrency??x.length;return g(c,()=>n>=x.length?ct(x.map((d,k)=>r(d,k))):(async()=>{let d=[];for(let k=0;k<x.length;k+=n){let b=x.slice(k,k+n),u=await ct(b.map((_,U)=>r(_,k+U)));if(!u.ok)return u;d.push(...u.value)}return Y(d)})(),{key:a?.key})},g.withFallback=(c,x,r)=>{if(typeof c!="string"||c.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 a=r.key??c,n=c,d=G(a),k=h;return(async()=>{let b=k?performance.now():0;h&&l({type:"step_start",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now()});let u;try{u=await x()}catch(M){if(ne(M))throw l({type:"step_aborted",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:performance.now()-b}),M;let q;try{q=J(M)}catch(L){throw _e(L)}if(r.on!==void 0&&r.on!==q){let L=performance.now()-b;throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:L,error:q}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:L,result:K(q,{cause:M}),meta:{origin:"throw",thrown:M}}),i?.(q,n,C),X(q,{origin:"throw",thrown:M})}let W;try{W=await r.fallback()}catch(L){if(ne(L))throw l({type:"step_aborted",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:performance.now()-b}),L;let O;try{O=J(L)}catch(Ee){throw _e(Ee)}let ge=performance.now()-b;throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:ge,error:O}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:ge,result:K(O,{cause:L}),meta:{origin:"throw",thrown:L}}),i?.(O,n,C),X(O,{origin:"throw",thrown:L})}if(W.ok){let L=performance.now()-b;return l({type:"step_success",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:L}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:L,result:W,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(q)}}),W.value}else{let L=performance.now()-b,O=V(W.error,{origin:"result",resultCause:W.cause});throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:L,error:O}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:L,result:W,meta:{origin:"result",resultCause:W.cause}}),i?.(O,n,C),X(O,{origin:"result",resultCause:W.cause})}}if(u.ok){let M=performance.now()-b;return l({type:"step_success",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:M}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:M,result:u}),u.value}let _=u.error;if(r.on!==void 0&&r.on!==_){let M=performance.now()-b,q=V(_,{origin:"result",resultCause:u.cause});throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:M,error:q}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:M,result:u,meta:{origin:"result",resultCause:u.cause}}),i?.(q,n,C),X(q,{origin:"result",resultCause:u.cause})}let U;try{U=await r.fallback()}catch(M){if(ne(M))throw l({type:"step_aborted",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:performance.now()-b}),M;let q;try{q=J(M)}catch(L){throw _e(L)}let W=performance.now()-b;throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:W,error:q}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:W,result:K(q,{cause:M}),meta:{origin:"throw",thrown:M}}),i?.(q,n,C),X(q,{origin:"throw",thrown:M})}if(U.ok){let M=performance.now()-b;return l({type:"step_success",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:M}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:M,result:U,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(_)}}),U.value}let B=performance.now()-b,Z=V(U.error,{origin:"result",resultCause:U.cause});throw l({type:"step_error",workflowId:o,stepId:d,stepKey:a,name:n,ts:Date.now(),durationMs:B,error:Z}),a&&l({type:"step_complete",workflowId:o,stepKey:a,name:n,ts:Date.now(),durationMs:B,result:U,meta:{origin:"result",resultCause:U.cause}}),i?.(Z,n,C),X(Z,{origin:"result",resultCause:U.cause})})()},g.withResource=(c,x)=>{if(typeof c!="string"||c.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 r=c,a=c,n=G(r),d=h;return(async()=>{let k=d?performance.now():0;h&&l({type:"step_start",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now()});let b;try{b=await x.acquire()}catch(W){if(ne(W))throw l({type:"step_aborted",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:performance.now()-k}),W;let L;try{L=J(W)}catch(ge){throw _e(ge)}let O=performance.now()-k;throw l({type:"step_error",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:O,error:L}),r&&l({type:"step_complete",workflowId:o,stepKey:r,name:a,ts:Date.now(),durationMs:O,result:K(L,{cause:W}),meta:{origin:"throw",thrown:W}}),i?.(L,a,C),X(L,{origin:"throw",thrown:W})}if(!b.ok){let W=performance.now()-k,L=V(b.error,{origin:"result",resultCause:b.cause});throw l({type:"step_error",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:W,error:L}),r&&l({type:"step_complete",workflowId:o,stepKey:r,name:a,ts:Date.now(),durationMs:W,result:b,meta:{origin:"result",resultCause:b.cause}}),i?.(L,a,C),X(L,{origin:"result",resultCause:b.cause})}let u=b.value,_,U,B=!1;try{_=await x.use(u)}catch(W){if(ne(W)){try{await x.release(u)}catch(L){console.warn(`[awaitly] step.withResource("${c}"): release threw after earlyExit:`,L)}throw W}U=W,B=!0}try{await x.release(u)}catch(W){console.warn(`[awaitly] step.withResource("${c}"): release threw:`,W)}if(B){let W;try{W=J(U)}catch(O){throw _e(O)}let L=performance.now()-k;throw l({type:"step_error",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:L,error:W}),r&&l({type:"step_complete",workflowId:o,stepKey:r,name:a,ts:Date.now(),durationMs:L,result:K(W,{cause:U}),meta:{origin:"throw",thrown:U}}),i?.(W,a,C),X(W,{origin:"throw",thrown:U})}let Z=_;if(Z.ok){let W=performance.now()-k;return l({type:"step_success",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:W}),r&&l({type:"step_complete",workflowId:o,stepKey:r,name:a,ts:Date.now(),durationMs:W,result:Z}),Z.value}let M=performance.now()-k,q=V(Z.error,{origin:"result",resultCause:Z.cause});throw l({type:"step_error",workflowId:o,stepId:n,stepKey:r,name:a,ts:Date.now(),durationMs:M,error:q}),r&&l({type:"step_complete",workflowId:o,stepKey:r,name:a,ts:Date.now(),durationMs:M,result:Z,meta:{origin:"result",resultCause:Z.cause}}),i?.(q,a,C),X(q,{origin:"result",resultCause:Z.cause})})()};let me=await e({step:g});if(process.env.NODE_ENV!=="production"&&me!==null&&typeof me=="object"&&"ok"in me&&typeof me.ok=="boolean"){let c=me;(c.ok===!0&&"value"in c||c.ok===!1&&"error"in c)&&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(me)}catch(g){if(bt(g))throw g.thrown;if(ne(g)){let ce=g.meta.origin==="throw"?g.meta.thrown:g.meta.origin==="result"?g.meta.resultCause:void 0;return K(g.error,{cause:ce})}let le=J(g);return i?.(le,"unexpected",C),K(le,{cause:g})}}je.strict=(e,t)=>je(e,t);async function ct(e){return e.length===0?Y([]):new Promise(t=>{let i=!1,h=e.length,R=new Array(e.length);for(let y=0;y<e.length;y++){let N=y;Promise.resolve(e[N]).catch(C=>K({type:"PROMISE_REJECTED",cause:C},{cause:{type:"PROMISE_REJECTION",reason:C}})).then(C=>{if(!i){if(!C.ok){i=!0,t(C);return}R[N]=C.value,h--,h===0&&t(Y(R))}})}})}var _t="STREAM_WRITE_ERROR",Dt="STREAM_READ_ERROR",Ot="STREAM_CLOSE_ERROR";var Pt="STREAM_ENDED";function Fe(e,t,i){return{type:_t,reason:e,message:t,...i!==void 0?{cause:i}:{}}}function qe(e,t,i){return{type:Dt,reason:e,message:t,...i!==void 0?{cause:i}:{}}}function Je(e,t,i){return{type:Ot,reason:e,message:t,...i!==void 0?{cause:i}:{}}}function Ve(e){return{type:Pt,finalPosition:e}}function ft(e={}){let t=e.highWaterMark??16,i=e.lowWaterMark??Math.floor(t/2),h=e.onStateChange,R="flowing",y=0,N=[];function C(o){if(R!==o&&(R=o,h?.(o),o==="flowing"&&N.length>0)){let J=N;N=[];for(let v of J)v()}}function H(){R==="flowing"&&y>=t?C("paused"):R==="paused"&&y<=i&&C("flowing")}return{get state(){return R},get bufferedCount(){return y},get highWaterMark(){return t},get lowWaterMark(){return i},increment(){y++,H()},decrement(){y>0&&(y--,H())},setCount(o){y=Math.max(0,o),H()},waitForDrain(){return R==="flowing"?Promise.resolve():new Promise(o=>{N.push(o)})},reset(){y=0,N=[],C("flowing")}}}function Mt(e){return{_tag:"Duration",millis:e}}function It(e){return{_tag:"Duration",millis:e*1e3}}function Ut(e){return{_tag:"Duration",millis:e*60*1e3}}function Wt(e){return{_tag:"Duration",millis:e*60*60*1e3}}function Nt(e){return{_tag:"Duration",millis:e*24*60*60*1e3}}function Et(e){return e.millis}function wt(e){let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let i=parseFloat(t[1]);switch(t[2].toLowerCase()){case"ms":return Mt(i);case"s":return It(i);case"m":return Ut(i);case"h":return Wt(i);case"d":return Nt(i);default:return}}function yt(e){return e.type==="step_complete"}function ze(e){return typeof e=="object"&&e!==null&&e.type==="WORKFLOW_CANCELLED"}function gt(){let e=new Map;return{handleEvent:t=>{yt(t)&&e.set(t.stepKey,{result:t.result,meta:t.meta})},getResumeState:()=>({steps:new Map(e)}),clear:()=>e.clear()}}function jt(e){return typeof e=="object"&&e!==null&&e.__cachedMeta===!0}function he(e,t,i){return K(e,{cause:{__cachedMeta:!0,originalCause:i,meta:t}})}function We(e){return jt(e)?e.meta:{origin:"result",resultCause:e}}async function kt(e,t){let i=e["~standard"].validate(t),h=i instanceof Promise?await i:i;return h.issues?K({type:"INPUT_VALIDATION_ERROR",issues:h.issues.map(R=>({message:R.message,path:R.path?.map(y=>typeof y=="object"?y.key:y)})),message:`Input validation failed: ${h.issues.map(R=>R.message).join(", ")}`}):Y(h.value)}function Ye(e,t){let i=h=>((...R)=>{let y=R.at(-1),N=R.length>0&&typeof y=="object"&&y!==null&&!Array.isArray(y)&&typeof y!="function",C=N?y:void 0,H=N?R.slice(0,-1):R,o={...t,...C?.deps??{}},J=C?{...C,deps:o}:{deps:o};return e[h](...H,J)});return{run:i("run"),runWithState:i("runWithState"),withDeps(h){return Ye(e,{...t,...h})}}}var Le=class extends Error{constructor(i,h,R){super(i);this.stepId=h;this.originalError=R;this.name="SnapshotDecodeError"}};function Ge(e){if(e.type==="error"){let t=new Error(e.message);return t.name=e.name,e.stack&&(t.stack=e.stack),e.cause&&(t.cause=Ge(e.cause)),t}return e.value!==void 0?e.value:e.stringRepresentation}function Tt(e,t,i){if(typeof e!="string"||e.length===0)throw new TypeError("createWorkflow(workflowName, deps, options?): first argument must be a non-empty string. Example: createWorkflow('checkout', { chargeCard, sendEmail })");let h=t??{},R=i;async function y(o,J,v){let E=o??crypto.randomUUID(),G=v?.deps?{...h,...v.deps}:h,l=[],X=v?.createContext??R?.createContext,ne=X?await X():void 0,V=v?.signal??R?.signal,Se=v?.onEvent??R?.onEvent,ve=v?.onError??R?.onError,Ae=v?.shouldRun??R?.shouldRun,ye=v?.onBeforeStart??R?.onBeforeStart,g=v?.onAfterStep??R?.onAfterStep,le=v?.resumeState??R?.resumeState,ce=R?.catchUnexpected??Ke,fe={},Ce=(v?.devWarnings??R?.devWarnings)===!0&&process.env.NODE_ENV!=="production",me=new Set,c=new Set,x={workflowId:E,onEvent:Se,context:ne!==void 0?ne:void 0,signal:V,input:{},ref:s=>fe[s],set:(s,m)=>{Ce&&!me.has(s)&&(me.add(s),console.warn(`awaitly: ctx.set('${s}', ...) is deprecated for static analysis. Use step('id', fn, { out: '${s}' }) instead.`)),fe[s]=m},get:s=>(Ce&&!c.has(s)&&(c.add(s),console.warn(`awaitly: ctx.get('${s}') is deprecated for static analysis. Use ctx.ref('${s}') instead for tracked dependencies.`)),fe[s])},r=s=>{let m=s.context!==void 0||ne===void 0?s:{...s,context:ne},p=m.workflowName===void 0?{...m,workflowName:e}:m;Se?.(p,ne)},a=(s,m)=>{let p={type:"WORKFLOW_CANCELLED",reason:s,lastStepKey:m};return K(ce(p),{cause:p})};if(V?.aborted){let s=typeof V.reason=="string"?V.reason:V.reason instanceof Error?V.reason.message:void 0;return r({type:"workflow_cancelled",workflowId:E,ts:Date.now(),durationMs:0,reason:s}),a(s)}if(Ae){let s=performance.now();try{let m=await Ae(E,ne),p=performance.now()-s;if(r({type:"hook_should_run",workflowId:E,ts:Date.now(),durationMs:p,result:m,skipped:!m}),!m){let $=new Error("Workflow skipped by shouldRun hook");return K(ce($),{cause:$})}}catch(m){let p=performance.now()-s;return r({type:"hook_should_run_error",workflowId:E,ts:Date.now(),durationMs:p,error:m}),K(ce(m),{cause:m})}}if(ye){let s=performance.now();try{let m=await ye(E,ne),p=performance.now()-s;if(r({type:"hook_before_start",workflowId:E,ts:Date.now(),durationMs:p,result:m,skipped:!m}),!m){let $=new Error("Workflow skipped by onBeforeStart hook");return K(ce($),{cause:$})}}catch(m){let p=performance.now()-s;return r({type:"hook_before_start_error",workflowId:E,ts:Date.now(),durationMs:p,error:m}),K(ce(m),{cause:m})}}let n=R?.inputSchema,d=R?.input;if(n){let s=await kt(n,d);if(!s.ok)return K(s.error);x.input=s.value}else d!==void 0&&(x.input=d);let k=Date.now(),b=performance.now();r({type:"workflow_start",workflowId:E,ts:k});let u=v?.cache??R?.cache,_=v?.streamStore??R?.streamStore;if(le&&!u&&(u=new Map),le&&u){let s=typeof le=="function"?await le():le;s.steps instanceof Map||(console.warn(`awaitly: resumeState.steps is not a Map (got ${typeof s.steps}). This usually happens when state is serialized with JSON.stringify() directly.
|
|
7
|
-
Use stringifyState() and parseState() from 'awaitly/persistence' instead:
|
|
8
|
-
import { stringifyState, parseState } from 'awaitly/persistence';
|
|
9
|
-
const json = stringifyState(state); // Save this
|
|
10
|
-
const restored = parseState(json); // Load this`),typeof s.steps=="object"&&s.steps!==null&&(s.steps=new Map(Object.entries(s.steps))));for(let[m,p]of s.steps){let{result:$,meta:f}=p;if($.ok)u.set(m,$);else{let S=f??{origin:"result",resultCause:$.cause};u.set(m,he($.error,S,$.cause))}}}let U=v?.snapshot??R?.snapshot,B=R?.serialization;if(U&&!le){u||(u=new Map);let s=U,m=B?.decode;for(let[p,$]of Object.entries(s.steps))if(Object.prototype.hasOwnProperty.call(s.steps,p))try{if($.ok){let f=m?m($.value):$.value;u.set(p,Y(f))}else{let f=m?m($.error):$.error,S=Ge($.cause),T=$.meta?.origin==="throw"?{origin:"throw",thrown:S}:{origin:"result",resultCause:S};u.set(p,he(f,T,S))}}catch(f){throw new Le(`Failed to decode step "${p}": ${f instanceof Error?f.message:String(f)}`,p,f instanceof Error?f:void 0)}}let Z=!1,M,q,W=()=>{Z=!0,M=typeof V?.reason=="string"?V.reason:V?.reason instanceof Error?V.reason.message:void 0};V&&!V.aborted&&V.addEventListener("abort",W,{once:!0});let L=()=>{if(Z||V?.aborted)throw{type:"WORKFLOW_CANCELLED",reason:M??(typeof V?.reason=="string"?V.reason:V?.reason instanceof Error?V.reason.message:void 0),lastStepKey:q}},O=async(s,m,p)=>{if(!g)return;let $=performance.now();try{await g(s,m,E,ne);let f=performance.now()-$;r({type:"hook_after_step",workflowId:E,stepKey:s,ts:Date.now(),durationMs:f})}catch(f){let S=performance.now()-$;throw r({type:"hook_after_step_error",workflowId:E,stepKey:s,ts:Date.now(),durationMs:S,error:f}),f}},ge=s=>{let m=async(f,S,T)=>{if(typeof f!="string")throw new Error('[awaitly] step() requires a string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let D=f,A=T??{},I=D,w=Object.prototype.hasOwnProperty.call(A,"key")?A.key:D,{ttl:j,out:ee}=A;L();let Q=He(A);if(w&&u&&u.has(w)){r({type:"step_cache_hit",workflowId:E,stepKey:w,name:I,ts:Date.now(),...Q&&{metadata:Q}});let P=u.get(w);if(P.ok)return q=w,ee&&(fe[ee]=P.value),P.value;let F=We(P.cause);throw Te(P.error,F)}w&&u&&r({type:"step_cache_miss",workflowId:E,stepKey:w,name:I,ts:Date.now(),...Q&&{metadata:Q}});try{let P=await s(D,S,A);return ee&&(fe[ee]=P),A.compensate&&l.push({stepName:I,value:P,compensate:A.compensate}),w&&(q=w,u&&u.set(w,Y(P),j?{ttl:j}:void 0),await O(w,Y(P))),P}catch(P){if(w&&we(P)){let F=P,se=F.meta.origin==="result"?F.meta.resultCause:F.meta.origin==="throw"?F.meta.thrown:void 0,z=he(F.error,F.meta,se);u&&u.set(w,z,j?{ttl:j}:void 0),await O(w,z,F.meta)}throw P}};m.try=async(f,S,T)=>{let{ttl:D}=T,A=T.key??f,I=f;if(u&&u.has(A)){r({type:"step_cache_hit",workflowId:E,stepKey:A,name:I,ts:Date.now()});let w=u.get(A);if(w.ok)return w.value;let j=We(w.cause);throw Te(w.error,j)}u&&r({type:"step_cache_miss",workflowId:E,stepKey:A,name:I,ts:Date.now()});try{let w=await s.try(f,S,{...T,key:A});return T.compensate&&l.push({stepName:I,value:w,compensate:T.compensate}),u&&u.set(A,Y(w),D?{ttl:D}:void 0),await O(A,Y(w)),w}catch(w){if(we(w)){let j=w,ee=j.meta.origin==="result"?j.meta.resultCause:j.meta.origin==="throw"?j.meta.thrown:void 0,Q=he(j.error,j.meta,ee);u&&u.set(A,Q,D?{ttl:D}:void 0),await O(A,Q,j.meta)}throw w}},m.fromResult=async(f,S,T)=>{let{ttl:D}=T,A=T.key??f,I=f;if(u&&u.has(A)){r({type:"step_cache_hit",workflowId:E,stepKey:A,name:I,ts:Date.now()});let w=u.get(A);if(w.ok)return w.value;let j=We(w.cause);throw Te(w.error,j)}u&&r({type:"step_cache_miss",workflowId:E,stepKey:A,name:I,ts:Date.now()});try{let w=await s.fromResult(f,S,{...T,key:A});return u&&u.set(A,Y(w),D?{ttl:D}:void 0),await O(A,Y(w)),w}catch(w){if(we(w)){let j=w,ee=j.meta.origin==="result"?j.meta.resultCause:j.meta.origin==="throw"?j.meta.thrown:void 0,Q=he(j.error,j.meta,ee);u&&u.set(A,Q,D?{ttl:D}:void 0),await O(A,Q,j.meta)}throw w}},m.race=s.race,m.withFallback=async(f,S,T)=>{let D=T.key??f,A=f;if(u&&u.has(D)){r({type:"step_cache_hit",workflowId:E,stepKey:D,name:A,ts:Date.now()});let I=u.get(D);if(I.ok)return I.value;let w=We(I.cause);throw Te(I.error,w)}u&&r({type:"step_cache_miss",workflowId:E,stepKey:D,name:A,ts:Date.now()});try{let I=await s.withFallback(f,S,T);return u&&u.set(D,Y(I)),await O(D,Y(I)),I}catch(I){if(we(I)){let w=I,j=w.meta.origin==="result"?w.meta.resultCause:w.meta.origin==="throw"?w.meta.thrown:void 0,ee=he(w.error,w.meta,j);u&&u.set(D,ee),await O(D,ee,w.meta)}throw I}},m.withResource=async(f,S)=>{let T=f;try{let D=await s.withResource(f,S);return await O(T,Y(D)),D}catch(D){if(we(D)){let A=D,I=A.meta.origin==="result"?A.meta.resultCause:A.meta.origin==="throw"?A.meta.thrown:void 0,w=he(A.error,A.meta,I);await O(T,w,A.meta)}throw D}},m.retry=(f,S,T)=>{let D={key:T.key,retry:{attempts:T.attempts,backoff:T.backoff,initialDelay:T.initialDelay,maxDelay:T.maxDelay,jitter:T.jitter,shouldRetry:T.shouldRetry,onRetry:T.onRetry},timeout:T.timeout,ttl:T.ttl};return m(f,S,D)},m.withTimeout=(f,S,T)=>{let D={key:T.key,timeout:T,ttl:T.ttl};return m(f,S,D)},m.sleep=(f,S,T)=>{if(typeof f!="string"||f.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let D=typeof S=="string"?wt(S):S;if(!D)throw new Error(`step.sleep: invalid duration '${S}'`);let A=Et(D),I=T?.signal;return m(f,async()=>{if(V?.aborted||I?.aborted){let j=new Error("Sleep aborted");throw j.name="AbortError",j}return new Promise((j,ee)=>{let Q={timeoutId:void 0},P=()=>{Q.timeoutId&&clearTimeout(Q.timeoutId);let F=new Error("Sleep aborted");F.name="AbortError",ee(F)};V?.addEventListener("abort",P,{once:!0}),I?.addEventListener("abort",P,{once:!0}),Q.timeoutId=setTimeout(()=>{V?.removeEventListener("abort",P),I?.removeEventListener("abort",P),j(Y(void 0))},A)})},{key:T?.key,ttl:T?.ttl,description:T?.description})};let p=new Map,$=new Map;return m.getWritable=f=>{let S=f?.namespace??"default",T=f?.highWaterMark??16;if(!_)throw new Error("streamStore is required to use getWritable(). Pass a streamStore to createWorkflow options.");let D=`${E}:${S}`,A=p.get(D);if(A&&!A.closed&&!A.aborted)return A.writer;let I=ft({highWaterMark:T,onStateChange:F=>{r({type:"stream_backpressure",workflowId:E,namespace:S,bufferedCount:I.bufferedCount,state:F,ts:Date.now()})}}),w=0,j=!0,ee=!1,Q=!1;r({type:"stream_created",workflowId:E,namespace:S,ts:Date.now()});let P={async write(F){if(Q)return K(Fe("closed","Stream is closed"));if(ee)return K(Fe("aborted","Stream was aborted"));I.state==="paused"&&await I.waitForDrain();let se={value:F,position:w,ts:Date.now()},z=await _.append(E,S,se);return z.ok?(r({type:"stream_write",workflowId:E,namespace:S,position:w,ts:Date.now()}),w++,I.increment(),Y(void 0)):(r({type:"stream_error",workflowId:E,namespace:S,error:z.error,position:w,ts:Date.now()}),K(Fe("store_error",z.error.message,z.error)))},async close(){if(Q)return K(Je("already_closed","Stream is already closed"));let F=await _.closeStream(E,S);return F.ok?(Q=!0,j=!1,r({type:"stream_close",workflowId:E,namespace:S,finalPosition:w,ts:Date.now()}),p.delete(D),Y(void 0)):K(Je("store_error",F.error.message,F.error))},abort(F){ee=!0,j=!1,Q=!0,r({type:"stream_error",workflowId:E,namespace:S,error:F,position:w,ts:Date.now()}),p.delete(D)},get writable(){return j},get position(){return w},get namespace(){return S}};return p.set(D,{writer:P,backpressure:I,aborted:ee,closed:Q}),P},m.getReadable=f=>{let S=f?.namespace??"default",T=f?.startIndex??0,D=f?.pollInterval??10,A=f?.pollTimeout??3e4;if(!_)throw new Error("streamStore is required to use getReadable(). Pass a streamStore to createWorkflow options.");let I=`${E}:${S}:${T}`,w=$.get(I);if(w&&!w.closed)return w.reader;let j=()=>{let ke=`${E}:${S}`,re=p.get(ke);re&&re.backpressure.decrement()},ee=T,Q=!0,P=!1,F=[],se=0,z={async read(){if(P)return K(qe("closed","Reader is closed"));if(se<F.length){let ue=F[se++];return ee=ue.position+1,j(),r({type:"stream_read",workflowId:E,namespace:S,position:ue.position,ts:Date.now()}),Y(ue.value)}let ke=`${E}:${S}`,re=Date.now(),ie=p.has(ke),te=await _.getMetadata(E,S),ae=te.ok&&te.value!==void 0;for(;Date.now()-re<A;){let ue=await _.read(E,S,ee,100);if(!ue.ok)return K(qe("store_error",ue.error.message,ue.error));let Pe=ue.value;if(Pe.length>0){F=Pe,se=1;let Ie=Pe[0];return ee=Ie.position+1,j(),r({type:"stream_read",workflowId:E,namespace:S,position:Ie.position,ts:Date.now()}),Y(Ie.value)}let Me=p.has(ke),xe=await _.getMetadata(E,S),Xe=xe.ok&&xe.value!==void 0;if(Me&&(ie=!0),Xe&&(ae=!0),xe.ok&&xe.value?.closed)return Q=!1,K(Ve(ee));if(ie&&!Me&&!Xe)return Q=!1,K(Ve(ee));ae&&!Me&&xe.ok&&xe.value?.closed,await new Promise(Ie=>setTimeout(Ie,D))}return Q=!1,K(Ve(ee))},close(){P=!0,Q=!1,F=[],$.delete(I)},get readable(){return Q},get position(){return ee},get namespace(){return S}};return $.set(I,{reader:z,position:ee,closed:P}),z},m.streamForEach=async(f,S,T)=>{let D=T?.checkpointInterval??1,A=T?.concurrency??1,I=[],w=0,j=-1,ee=P=>typeof P=="object"&&P!==null&&"read"in P&&typeof P.read=="function",Q=async(P,F,se,z)=>{let re=D>0&&F%D===0?`stream-foreach:${z}:pos-${se}`:void 0,ie=re??`stream-item-${se}`,te=await m(ie,()=>S(P,F),{key:re});return{index:F,position:se,result:te}};if(ee(f))if(A<=1){let P=f.position,F=await f.read();for(;F.ok;){let se=F.value,{result:z}=await Q(se,w,P,f.namespace);I.push(z),j=P,w++,P=f.position,F=await f.read()}}else{let P=new Map,F=0,se=0,z=new Array(A).fill(null),ke=async()=>{for(let ue=0;ue<z.length;ue++)if(z[ue]===null)return ue;let te=z.filter(ue=>ue!==null),ae=await Promise.race(te);return P.set(ae.index,{position:ae.position,result:ae.result}),z[ae.slotIndex]=null,ae.slotIndex},re=f.position,ie=await f.read();for(;ie.ok;){let te=await ke(),ae=F,ue=re,Pe=ie.value,Me=te;z[te]=Q(Pe,ae,ue,f.namespace).then(xe=>({slotIndex:Me,...xe})),se++,F++,re=f.position,ie=await f.read()}for(let te=0;te<z.length;te++)if(z[te]!==null){let ae=await z[te];P.set(ae.index,{position:ae.position,result:ae.result})}for(let te=0;te<se;te++){let ae=P.get(te);ae&&(I.push(ae.result),j=ae.position,w++)}}else if(A<=1){let P=0;for await(let F of f){let{result:se}=await Q(F,P,P,"async-iterable");I.push(se),j=P,w++,P++}}else{let P=new Map,F=0,se=0,z=new Array(A).fill(null),ke=async()=>{for(let te=0;te<z.length;te++)if(z[te]===null)return te;let re=z.filter(te=>te!==null),ie=await Promise.race(re);return P.set(ie.index,ie.result),z[ie.slotIndex]=null,ie.slotIndex};for await(let re of f){let ie=await ke(),te=F,ae=ie;z[ie]=Q(re,te,te,"async-iterable").then(ue=>({slotIndex:ae,...ue})),se++,F++}for(let re=0;re<z.length;re++)if(z[re]!==null){let ie=await z[re];P.set(ie.index,ie.result)}for(let re=0;re<se;re++)P.has(re)&&(I.push(P.get(re)),j=re,w++)}return{results:I,processedCount:w,lastPosition:j}},m.if=s.if,m.label=s.label,m.branch=s.branch,m.arm=s.arm,m.forEach=s.forEach,m.item=s.item,m.dep=s.dep,m.workflow=(f,S,T)=>m(f,S,T),m.all=(f,S,T)=>{let D=T!==void 0&&Object.prototype.hasOwnProperty.call(T,"key")?T:{...T,key:void 0};return m(f,async()=>Y(await s.all(f,S)),D)},m.map=(f,S,T,D)=>{let A=D!==void 0&&Object.prototype.hasOwnProperty.call(D,"key")?D:{...D,key:void 0};return m(f,async()=>Y(await s.map(f,S,T,D)),A)},m},Ee=({step:s})=>J({step:ge(s),deps:G,ctx:x}),oe;try{oe=await je(Ee,{onError:ve,onEvent:Se,catchUnexpected:ce,workflowId:E,workflowName:e,context:ne,_workflowSignal:V})}finally{V&&V.removeEventListener("abort",W)}if(!oe.ok&&l.length>0){let s=[];for(let m=l.length-1;m>=0;m--){let p=l[m];try{await p.compensate(p.value)}catch($){s.push({stepName:p.stepName,error:$})}}if(s.length>0){let m={type:"SAGA_COMPENSATION_ERROR",originalError:oe.error,compensationErrors:s};oe=K(m,{cause:oe.cause})}}let Re=performance.now()-b;if(!oe.ok){let s;if(ze(oe.cause)&&(s=oe.cause),!s&&Z&&pt(oe.error)){let m=oe.cause;m!=null&&typeof m=="object"&&"name"in m&&m.name==="AbortError"&&(s={type:"WORKFLOW_CANCELLED",reason:M??(typeof V?.reason=="string"?V.reason:V?.reason instanceof Error?V.reason.message:void 0),lastStepKey:q})}if(s)return r({type:"workflow_cancelled",workflowId:E,ts:Date.now(),durationMs:Re,reason:s.reason,lastStepKey:s.lastStepKey}),s&&!ze(oe.cause)?K(oe.error,{cause:s}):oe}if(oe.ok&&Z){let s=M??(typeof V?.reason=="string"?V.reason:V?.reason instanceof Error?V.reason.message:void 0);r({type:"workflow_cancelled",workflowId:E,ts:Date.now(),durationMs:Re,reason:s,lastStepKey:q});let m={type:"WORKFLOW_CANCELLED",reason:s,lastStepKey:q};return K(ce(m),{cause:m})}return oe.ok?r({type:"workflow_success",workflowId:E,ts:Date.now(),durationMs:Re}):r({type:"workflow_error",workflowId:E,ts:Date.now(),durationMs:Re,error:oe.error}),oe}function N(o,J,v){let E,G,l;return typeof o=="string"?(E=o,G=J,l=v):(G=o,l=J),y(E,G,l)}async function C(o,J,v){let E,G,l;typeof o=="string"?(E=o,G=J,l=v):(G=o,l=J);let X=gt(),ne=l?.onEvent,Se={...l,onEvent:(ye,g)=>{X.handleEvent(ye);try{ne?.(ye,g)}catch{}}},ve,Ae;try{ve=await y(E,G,Se)}catch(ye){let g=R?.catchUnexpected??Ke;ve=K(g(ye),{cause:ye})}finally{Ae=X.getResumeState()}return{result:ve,resumeState:Ae}}let H={withDeps:o=>Ye(H,o),run:N,runWithState:C};return H}function Kt(e){return typeof e=="object"&&e!==null&&e.type==="SAGA_COMPENSATION_ERROR"}function Ft(e,t,i){return Tt(e,t,i)}async function Vt(e,t){let i=crypto.randomUUID(),h=performance.now(),R=[],y=o=>t?.onEvent?.(o);y({type:"saga_start",sagaId:i,ts:Date.now()});let H=Object.assign(async(o,J,v)=>{if(typeof o!="string"||o.length===0)throw new TypeError("step(name, operation, options?): first argument must be a string.");let E=await J();if(E.ok)return v?.compensate&&R.push({name:o,value:E.value,compensate:v.compensate}),E.value;throw Te(E.error,{origin:"result",resultCause:E.cause})},{try:async(o,J,v)=>{if(typeof o!="string"||o.length===0)throw new TypeError("step.try(name, operation, options): first argument must be a string.");let E="error"in v?()=>v.error:v.onError;try{let G=await J();return v.compensate&&R.push({name:o,value:G,compensate:v.compensate}),G}catch(G){let l=E(G);throw Te(l,{origin:"throw",thrown:G})}}});try{let o=await e({step:H});return y({type:"saga_success",sagaId:i,ts:Date.now(),durationMs:performance.now()-h}),Y(o)}catch(o){let J=performance.now()-h,v=we(o)?o.error:o;y({type:"saga_error",sagaId:i,ts:Date.now(),durationMs:J,error:v}),y({type:"saga_compensation_start",sagaId:i,ts:Date.now(),stepCount:R.length});let E=performance.now(),G=[];for(let l=R.length-1;l>=0;l--){let X=R[l];try{await X.compensate(X.value),y({type:"saga_compensation_step",sagaId:i,stepName:X.name,ts:Date.now(),success:!0})}catch(ne){G.push({stepName:X.name,error:ne}),y({type:"saga_compensation_step",sagaId:i,stepName:X.name,ts:Date.now(),success:!1,error:ne})}}if(y({type:"saga_compensation_end",sagaId:i,ts:Date.now(),durationMs:performance.now()-E,success:G.length===0,failedCount:G.length}),G.length>0){let l={type:"SAGA_COMPENSATION_ERROR",originalError:v,compensationErrors:G};if(t?.onError?.(l),t?.throwOnCompensationFailure)throw l;return K(l)}return t?.onError?.(v),we(o)?K(v):K(new be({cause:o}))}}export{Ft as createSagaWorkflow,Kt as isSagaCompensationError,Vt as runSaga};
|
|
11
|
-
//# sourceMappingURL=saga.js.map
|