awaitly 1.31.1 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/adapters.cjs +2 -2
  2. package/dist/adapters.cjs.map +1 -1
  3. package/dist/adapters.d.cts +3 -1
  4. package/dist/adapters.d.ts +3 -1
  5. package/dist/adapters.js +2 -2
  6. package/dist/adapters.js.map +1 -1
  7. package/dist/batch.cjs +2 -2
  8. package/dist/batch.cjs.map +1 -1
  9. package/dist/batch.d.cts +3 -1
  10. package/dist/batch.d.ts +3 -1
  11. package/dist/batch.js +2 -2
  12. package/dist/batch.js.map +1 -1
  13. package/dist/circuit-breaker.cjs +2 -2
  14. package/dist/circuit-breaker.cjs.map +1 -1
  15. package/dist/circuit-breaker.d.cts +3 -1
  16. package/dist/circuit-breaker.d.ts +3 -1
  17. package/dist/circuit-breaker.js +2 -2
  18. package/dist/circuit-breaker.js.map +1 -1
  19. package/dist/conditional.d.cts +3 -1
  20. package/dist/conditional.d.ts +3 -1
  21. package/dist/core.cjs +2 -2
  22. package/dist/core.cjs.map +1 -1
  23. package/dist/core.d.cts +2 -1
  24. package/dist/core.d.ts +2 -1
  25. package/dist/core.js +2 -2
  26. package/dist/core.js.map +1 -1
  27. package/dist/diagnostics.cjs +3 -3
  28. package/dist/diagnostics.cjs.map +1 -1
  29. package/dist/diagnostics.d.cts +3 -1
  30. package/dist/diagnostics.d.ts +3 -1
  31. package/dist/diagnostics.js +3 -3
  32. package/dist/diagnostics.js.map +1 -1
  33. package/dist/durable.cjs +3 -3
  34. package/dist/durable.cjs.map +1 -1
  35. package/dist/durable.d.cts +8 -361
  36. package/dist/durable.d.ts +8 -361
  37. package/dist/durable.js +3 -3
  38. package/dist/durable.js.map +1 -1
  39. package/dist/engine.cjs +11 -0
  40. package/dist/engine.cjs.map +1 -0
  41. package/dist/engine.d.cts +114 -0
  42. package/dist/engine.d.ts +114 -0
  43. package/dist/engine.js +11 -0
  44. package/dist/engine.js.map +1 -0
  45. package/dist/errors-entry-CMH73Eym.d.cts +339 -0
  46. package/dist/errors-entry-DOt5UUl4.d.ts +339 -0
  47. package/dist/errors.cjs +1 -1
  48. package/dist/errors.cjs.map +1 -1
  49. package/dist/errors.d.cts +2 -318
  50. package/dist/errors.d.ts +2 -318
  51. package/dist/errors.js +1 -1
  52. package/dist/errors.js.map +1 -1
  53. package/dist/fetch.cjs +2 -2
  54. package/dist/fetch.cjs.map +1 -1
  55. package/dist/fetch.d.cts +3 -1
  56. package/dist/fetch.d.ts +3 -1
  57. package/dist/fetch.js +2 -2
  58. package/dist/fetch.js.map +1 -1
  59. package/dist/functional.cjs +1 -1
  60. package/dist/functional.cjs.map +1 -1
  61. package/dist/functional.d.cts +2 -0
  62. package/dist/functional.d.ts +2 -0
  63. package/dist/functional.js +1 -1
  64. package/dist/functional.js.map +1 -1
  65. package/dist/{guards-PU64_GKv.d.cts → guards-B79mP5Q8.d.cts} +3 -3
  66. package/dist/{guards-B5lgMJq0.d.ts → guards-BUq6NJCM.d.ts} +3 -3
  67. package/dist/{hitl-Dyiy0R1v.d.cts → hitl-BCqkMAHw.d.cts} +2 -2
  68. package/dist/{hitl-BjeSm1sJ.d.ts → hitl-BZtPx0aU.d.ts} +2 -2
  69. package/dist/hitl.cjs +2 -2
  70. package/dist/hitl.cjs.map +1 -1
  71. package/dist/hitl.d.cts +9 -6
  72. package/dist/hitl.d.ts +9 -6
  73. package/dist/hitl.js +2 -2
  74. package/dist/hitl.js.map +1 -1
  75. package/dist/index-BVUAOWGG.d.ts +417 -0
  76. package/dist/index-CQnpmUcC.d.cts +417 -0
  77. package/dist/index.cjs +1 -1
  78. package/dist/index.cjs.map +1 -1
  79. package/dist/index.d.cts +4 -3
  80. package/dist/index.d.ts +4 -3
  81. package/dist/index.js +1 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/otel.d.cts +3 -1
  84. package/dist/otel.d.ts +3 -1
  85. package/dist/{persistence-entry-B3ukwbb5.d.ts → persistence-entry-ClFhxd2Q.d.ts} +11 -5
  86. package/dist/{persistence-entry-CgVzswbg.d.cts → persistence-entry-jflY61az.d.cts} +11 -5
  87. package/dist/persistence.d.cts +6 -3
  88. package/dist/persistence.d.ts +6 -3
  89. package/dist/policies.d.cts +3 -1
  90. package/dist/policies.d.ts +3 -1
  91. package/dist/ratelimit.cjs +2 -2
  92. package/dist/ratelimit.cjs.map +1 -1
  93. package/dist/ratelimit.d.cts +3 -1
  94. package/dist/ratelimit.d.ts +3 -1
  95. package/dist/ratelimit.js +2 -2
  96. package/dist/ratelimit.js.map +1 -1
  97. package/dist/reliability.cjs +2 -2
  98. package/dist/reliability.cjs.map +1 -1
  99. package/dist/reliability.d.cts +3 -1
  100. package/dist/reliability.d.ts +3 -1
  101. package/dist/reliability.js +2 -2
  102. package/dist/reliability.js.map +1 -1
  103. package/dist/resolver.cjs +2 -2
  104. package/dist/resolver.cjs.map +1 -1
  105. package/dist/resolver.d.cts +5 -3
  106. package/dist/resolver.d.ts +5 -3
  107. package/dist/resolver.js +2 -2
  108. package/dist/resolver.js.map +1 -1
  109. package/dist/resource.cjs +2 -2
  110. package/dist/resource.cjs.map +1 -1
  111. package/dist/resource.d.cts +3 -1
  112. package/dist/resource.d.ts +3 -1
  113. package/dist/resource.js +2 -2
  114. package/dist/resource.js.map +1 -1
  115. package/dist/result/retry.cjs +1 -1
  116. package/dist/result/retry.cjs.map +1 -1
  117. package/dist/result/retry.d.cts +2 -0
  118. package/dist/result/retry.d.ts +2 -0
  119. package/dist/result/retry.js +1 -1
  120. package/dist/result/retry.js.map +1 -1
  121. package/dist/result.cjs +1 -1
  122. package/dist/result.cjs.map +1 -1
  123. package/dist/result.d.cts +8 -23
  124. package/dist/result.d.ts +8 -23
  125. package/dist/result.js +1 -1
  126. package/dist/result.js.map +1 -1
  127. package/dist/{run-entry-C1uFytM6.d.cts → run-entry-rw7zll_G.d.ts} +16 -45
  128. package/dist/{run-entry-C1uFytM6.d.ts → run-entry-yQu63Yj9.d.cts} +16 -45
  129. package/dist/run.cjs +2 -2
  130. package/dist/run.cjs.map +1 -1
  131. package/dist/run.d.cts +3 -1
  132. package/dist/run.d.ts +3 -1
  133. package/dist/run.js +2 -2
  134. package/dist/run.js.map +1 -1
  135. package/dist/saga.cjs +2 -2
  136. package/dist/saga.cjs.map +1 -1
  137. package/dist/saga.d.cts +3 -1
  138. package/dist/saga.d.ts +3 -1
  139. package/dist/saga.js +2 -2
  140. package/dist/saga.js.map +1 -1
  141. package/dist/singleflight.d.cts +3 -1
  142. package/dist/singleflight.d.ts +3 -1
  143. package/dist/streaming.cjs +4 -4
  144. package/dist/streaming.cjs.map +1 -1
  145. package/dist/streaming.d.cts +5 -3
  146. package/dist/streaming.d.ts +5 -3
  147. package/dist/streaming.js +4 -4
  148. package/dist/streaming.js.map +1 -1
  149. package/dist/testing.cjs +8 -4
  150. package/dist/testing.cjs.map +1 -1
  151. package/dist/testing.d.cts +87 -4
  152. package/dist/testing.d.ts +87 -4
  153. package/dist/testing.js +8 -4
  154. package/dist/testing.js.map +1 -1
  155. package/dist/{types-wa_wTOn3.d.ts → types-CuWK5AlK.d.ts} +1 -1
  156. package/dist/{types-DUWrNIJu.d.cts → types-uR3JpwvF.d.cts} +1 -1
  157. package/dist/webhook.cjs +2 -2
  158. package/dist/webhook.cjs.map +1 -1
  159. package/dist/webhook.d.cts +7 -4
  160. package/dist/webhook.d.ts +7 -4
  161. package/dist/webhook.js +2 -2
  162. package/dist/webhook.js.map +1 -1
  163. package/dist/workflow.cjs +3 -3
  164. package/dist/workflow.cjs.map +1 -1
  165. package/dist/workflow.d.cts +47 -11
  166. package/dist/workflow.d.ts +47 -11
  167. package/dist/workflow.js +3 -3
  168. package/dist/workflow.js.map +1 -1
  169. package/package.json +15 -1
@@ -1,6 +1,89 @@
1
- import { c as AsyncResult, R as Result, aj as StepOptions, ah as WorkflowEvent, d as Err, O as Ok } from './run-entry-C1uFytM6.cjs';
2
- import { b as AnyResultFn, E as ErrorsOfDeps } from './persistence-entry-CgVzswbg.cjs';
3
- import './types-DUWrNIJu.cjs';
1
+ import { R as Result, ad as WorkflowEvent, ae as RunStep, c as AsyncResult, ag as StepOptions, d as Err, O as Ok } from './run-entry-yQu63Yj9.cjs';
2
+ import { e as AnyResultFn, E as ErrorsOfDeps, f as WorkflowContext } from './persistence-entry-jflY61az.cjs';
3
+ import { U as UnexpectedError } from './errors-entry-CMH73Eym.cjs';
4
+ import './types-uR3JpwvF.cjs';
5
+ import '@standard-schema/spec';
6
+ import './tagged-error.cjs';
7
+
8
+ /**
9
+ * Simple workflow test runner.
10
+ *
11
+ * Runs a real workflow with real deps, captures per-step results and events,
12
+ * and returns a structured result. No mocking needed.
13
+ *
14
+ * This is a complement to `createWorkflowHarness`, not a replacement.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { testWorkflow } from 'awaitly/testing';
19
+ * import { ok, err } from 'awaitly';
20
+ *
21
+ * const getUser = async (id: string) => ok({ id, name: 'Alice' });
22
+ * const getPosts = async (userId: string) => ok([{ id: 1, title: 'Hello' }]);
23
+ *
24
+ * const result = await testWorkflow(
25
+ * { getUser, getPosts },
26
+ * async ({ step, deps: { getUser, getPosts } }) => {
27
+ * const user = await step('user', () => getUser('1'));
28
+ * const posts = await step('posts', () => getPosts(user.id));
29
+ * return { user, posts };
30
+ * }
31
+ * );
32
+ *
33
+ * expect(result.result.ok).toBe(true);
34
+ * expect(result.steps['user'].result.ok).toBe(true);
35
+ * expect(result.stepOrder).toEqual(['user', 'posts']);
36
+ * ```
37
+ */
38
+
39
+ /**
40
+ * Captured information about a single step execution.
41
+ */
42
+ interface TestStepResult {
43
+ /** The unwrapped output value (from result.value if ok) */
44
+ output: unknown;
45
+ /** Step execution duration in milliseconds */
46
+ durationMs: number;
47
+ /** The full Result of the step */
48
+ result: Result<unknown, unknown>;
49
+ }
50
+ /**
51
+ * Structured result returned by `testWorkflow`.
52
+ */
53
+ interface TestWorkflowResult<T, E> {
54
+ /** The workflow's final result */
55
+ result: Result<T, E | UnexpectedError>;
56
+ /** Per-step results keyed by step key (the step ID) */
57
+ steps: Record<string, TestStepResult>;
58
+ /** All workflow events emitted during execution */
59
+ events: Array<WorkflowEvent<unknown>>;
60
+ /** Total execution duration in milliseconds */
61
+ durationMs: number;
62
+ /** Step keys in execution order */
63
+ stepOrder: string[];
64
+ }
65
+ /**
66
+ * Options for `testWorkflow`.
67
+ */
68
+ interface TestWorkflowOptions {
69
+ /** AbortSignal for cancellation testing */
70
+ signal?: AbortSignal;
71
+ /** Custom metadata to track */
72
+ metadata?: Record<string, unknown>;
73
+ }
74
+ /**
75
+ * Execute a workflow with real deps, capturing all step results and events.
76
+ * No mocking needed — this runs the actual workflow function.
77
+ *
78
+ * Step results are captured from `step_complete` events. Every step emits a
79
+ * `step_complete` event with a `stepKey` equal to the step ID (or the explicit
80
+ * `key` option if provided). These appear in the `steps` record and `stepOrder` array.
81
+ */
82
+ declare function testWorkflow<const Deps extends Readonly<Record<string, AnyResultFn>>, T>(deps: Deps, fn: (context: {
83
+ step: RunStep<ErrorsOfDeps<Deps>>;
84
+ deps: Deps;
85
+ ctx: WorkflowContext;
86
+ }) => T | Promise<T>, options?: TestWorkflowOptions): Promise<TestWorkflowResult<T, ErrorsOfDeps<Deps>>>;
4
87
 
5
88
  /**
6
89
  * awaitly/testing
@@ -456,4 +539,4 @@ declare function formatEvent(event: WorkflowEvent<unknown>): string;
456
539
  */
457
540
  declare function formatEvents(events: WorkflowEvent<unknown>[]): string;
458
541
 
459
- export { type AssertionResult, type CompensationInvocation, type EventAssertionOptions, type MockFunction, type MockSagaContext, type MockStep, type SagaHarness, type SagaStepOptions, type ScriptedOutcome, type StepInvocation, type TestHarnessOptions, type WorkflowHarness, type WorkflowSnapshot, assertEventEmitted, assertEventNotEmitted, assertEventSequence, compareSnapshots, createMockFn, createSagaHarness, createSnapshot, createTestClock, createWorkflowHarness, errOutcome, expectErr, expectOk, formatEvent, formatEvents, formatResult, okOutcome, throwOutcome, unwrapErr, unwrapErrAsync, unwrapOk, unwrapOkAsync };
542
+ export { type AssertionResult, type CompensationInvocation, type EventAssertionOptions, type MockFunction, type MockSagaContext, type MockStep, type SagaHarness, type SagaStepOptions, type ScriptedOutcome, type StepInvocation, type TestHarnessOptions, type TestStepResult, type TestWorkflowOptions, type TestWorkflowResult, type WorkflowHarness, type WorkflowSnapshot, assertEventEmitted, assertEventNotEmitted, assertEventSequence, compareSnapshots, createMockFn, createSagaHarness, createSnapshot, createTestClock, createWorkflowHarness, errOutcome, expectErr, expectOk, formatEvent, formatEvents, formatResult, okOutcome, testWorkflow, throwOutcome, unwrapErr, unwrapErrAsync, unwrapOk, unwrapOkAsync };
package/dist/testing.d.ts CHANGED
@@ -1,6 +1,89 @@
1
- import { c as AsyncResult, R as Result, aj as StepOptions, ah as WorkflowEvent, d as Err, O as Ok } from './run-entry-C1uFytM6.js';
2
- import { b as AnyResultFn, E as ErrorsOfDeps } from './persistence-entry-B3ukwbb5.js';
3
- import './types-wa_wTOn3.js';
1
+ import { R as Result, ad as WorkflowEvent, ae as RunStep, c as AsyncResult, ag as StepOptions, d as Err, O as Ok } from './run-entry-rw7zll_G.js';
2
+ import { e as AnyResultFn, E as ErrorsOfDeps, f as WorkflowContext } from './persistence-entry-ClFhxd2Q.js';
3
+ import { U as UnexpectedError } from './errors-entry-DOt5UUl4.js';
4
+ import './types-CuWK5AlK.js';
5
+ import '@standard-schema/spec';
6
+ import './tagged-error.js';
7
+
8
+ /**
9
+ * Simple workflow test runner.
10
+ *
11
+ * Runs a real workflow with real deps, captures per-step results and events,
12
+ * and returns a structured result. No mocking needed.
13
+ *
14
+ * This is a complement to `createWorkflowHarness`, not a replacement.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { testWorkflow } from 'awaitly/testing';
19
+ * import { ok, err } from 'awaitly';
20
+ *
21
+ * const getUser = async (id: string) => ok({ id, name: 'Alice' });
22
+ * const getPosts = async (userId: string) => ok([{ id: 1, title: 'Hello' }]);
23
+ *
24
+ * const result = await testWorkflow(
25
+ * { getUser, getPosts },
26
+ * async ({ step, deps: { getUser, getPosts } }) => {
27
+ * const user = await step('user', () => getUser('1'));
28
+ * const posts = await step('posts', () => getPosts(user.id));
29
+ * return { user, posts };
30
+ * }
31
+ * );
32
+ *
33
+ * expect(result.result.ok).toBe(true);
34
+ * expect(result.steps['user'].result.ok).toBe(true);
35
+ * expect(result.stepOrder).toEqual(['user', 'posts']);
36
+ * ```
37
+ */
38
+
39
+ /**
40
+ * Captured information about a single step execution.
41
+ */
42
+ interface TestStepResult {
43
+ /** The unwrapped output value (from result.value if ok) */
44
+ output: unknown;
45
+ /** Step execution duration in milliseconds */
46
+ durationMs: number;
47
+ /** The full Result of the step */
48
+ result: Result<unknown, unknown>;
49
+ }
50
+ /**
51
+ * Structured result returned by `testWorkflow`.
52
+ */
53
+ interface TestWorkflowResult<T, E> {
54
+ /** The workflow's final result */
55
+ result: Result<T, E | UnexpectedError>;
56
+ /** Per-step results keyed by step key (the step ID) */
57
+ steps: Record<string, TestStepResult>;
58
+ /** All workflow events emitted during execution */
59
+ events: Array<WorkflowEvent<unknown>>;
60
+ /** Total execution duration in milliseconds */
61
+ durationMs: number;
62
+ /** Step keys in execution order */
63
+ stepOrder: string[];
64
+ }
65
+ /**
66
+ * Options for `testWorkflow`.
67
+ */
68
+ interface TestWorkflowOptions {
69
+ /** AbortSignal for cancellation testing */
70
+ signal?: AbortSignal;
71
+ /** Custom metadata to track */
72
+ metadata?: Record<string, unknown>;
73
+ }
74
+ /**
75
+ * Execute a workflow with real deps, capturing all step results and events.
76
+ * No mocking needed — this runs the actual workflow function.
77
+ *
78
+ * Step results are captured from `step_complete` events. Every step emits a
79
+ * `step_complete` event with a `stepKey` equal to the step ID (or the explicit
80
+ * `key` option if provided). These appear in the `steps` record and `stepOrder` array.
81
+ */
82
+ declare function testWorkflow<const Deps extends Readonly<Record<string, AnyResultFn>>, T>(deps: Deps, fn: (context: {
83
+ step: RunStep<ErrorsOfDeps<Deps>>;
84
+ deps: Deps;
85
+ ctx: WorkflowContext;
86
+ }) => T | Promise<T>, options?: TestWorkflowOptions): Promise<TestWorkflowResult<T, ErrorsOfDeps<Deps>>>;
4
87
 
5
88
  /**
6
89
  * awaitly/testing
@@ -456,4 +539,4 @@ declare function formatEvent(event: WorkflowEvent<unknown>): string;
456
539
  */
457
540
  declare function formatEvents(events: WorkflowEvent<unknown>[]): string;
458
541
 
459
- export { type AssertionResult, type CompensationInvocation, type EventAssertionOptions, type MockFunction, type MockSagaContext, type MockStep, type SagaHarness, type SagaStepOptions, type ScriptedOutcome, type StepInvocation, type TestHarnessOptions, type WorkflowHarness, type WorkflowSnapshot, assertEventEmitted, assertEventNotEmitted, assertEventSequence, compareSnapshots, createMockFn, createSagaHarness, createSnapshot, createTestClock, createWorkflowHarness, errOutcome, expectErr, expectOk, formatEvent, formatEvents, formatResult, okOutcome, throwOutcome, unwrapErr, unwrapErrAsync, unwrapOk, unwrapOkAsync };
542
+ export { type AssertionResult, type CompensationInvocation, type EventAssertionOptions, type MockFunction, type MockSagaContext, type MockStep, type SagaHarness, type SagaStepOptions, type ScriptedOutcome, type StepInvocation, type TestHarnessOptions, type TestStepResult, type TestWorkflowOptions, type TestWorkflowResult, type WorkflowHarness, type WorkflowSnapshot, assertEventEmitted, assertEventNotEmitted, assertEventSequence, compareSnapshots, createMockFn, createSagaHarness, createSnapshot, createTestClock, createWorkflowHarness, errOutcome, expectErr, expectOk, formatEvent, formatEvents, formatResult, okOutcome, testWorkflow, throwOutcome, unwrapErr, unwrapErrAsync, unwrapOk, unwrapOkAsync };
package/dist/testing.js CHANGED
@@ -1,9 +1,13 @@
1
- function _e(e){let a=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!a)return;let s=parseFloat(a[1]),E=a[2].toLowerCase();return{_tag:"Duration",millis:s*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[E]??1)}}var Me="UNEXPECTED_ERROR";function De(e){return Me}function V(e){return{ok:!0,value:e}}function F(e,a){let s=a?.cause;return{ok:!1,error:e,...s!==void 0?{cause:s}:{}}}var ke=e=>e.ok;function Ie(e){if(e==null)return"unknown";if(typeof e=="string")return e.trim()||"unknown";if(typeof e=="object"){let a=e;if(typeof a._tag=="string"){let s=a._tag.trim();if(s)return s}if(typeof a.tag=="string"){let s=a.tag.trim();if(s)return s}if(typeof a.code=="string"){let s=a.code.trim();if(s)return s}else if(typeof a.code=="number")return String(a.code);if(e instanceof Error&&e.name){let s=e.name.trim();if(s)return s}}return"unknown"}function Ue(e,a){if(!(!a||!e))return a[e]}function Ne(e){let{intent:a,domain:s,owner:E,tags:w,stateChanges:f,emits:R,calls:y}=e;if(!a&&!s&&!E&&!w?.length&&!f?.length&&!R?.length&&!y?.length)return;let O={};return a&&(O.intent=a),s&&(O.domain=s),E&&(O.owner=E),w?.length&&(O.tags=w),f?.length&&(O.stateChanges=f),R?.length&&(O.emits=R),y?.length&&(O.calls=y),O}function Y(e,a,s,E,w){let f=Ie(e),R=Ue(f,a),y={tag:f,origin:s};return R!==void 0&&(y.classification=R),E!==void 0&&(y.attempt=E),w!==void 0&&(y.cumulativeDurationMs=w),y}var re=Symbol.for("step_timeout_marker");function de(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:re in e}function je(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let a=e;return{timeoutMs:a.timeoutMs,stepName:a.stepName,stepKey:a.stepKey,attempt:a.attempt}}if(re in e)return e[re]}}var ge=Symbol("early-exit");function Fe(e,a){return{[ge]:!0,error:e,meta:a}}function Ke(e){return typeof e=="object"&&e!==null&&e[ge]===!0}var Re=Symbol("mapper-exception");function te(e){return{[Re]:!0,thrown:e}}function $e(e){return typeof e=="object"&&e!==null&&e[Re]===!0}function me(e,a){let{backoff:s,initialDelay:E,maxDelay:w,jitter:f}=a,R;switch(s){case"fixed":R=E;break;case"linear":R=E*e;break;case"exponential":R=E*Math.pow(2,e-1);break}if(R=Math.min(R,w),f){let y=R*.25*Math.random();R=R+y}return Math.floor(R)}function Ee(e){return new Promise(a=>setTimeout(a,e))}var ye=Symbol("timeout"),ae=Symbol("timeout-option");function We(e){return typeof e=="object"&&e!==null&&e[ae]===!0}async function Le(e,a,s,E){let w=new AbortController,f=a.onTimeout??"error",R=()=>typeof f=="function"?f({name:s.name,key:s.key,ms:a.ms}):a.error??{type:"STEP_TIMEOUT",stepName:s.name,stepKey:s.key,timeoutMs:a.ms,attempt:s.attempt},y;E?.aborted&&w.abort(E.reason);let O;E&&!E.aborted&&(O=()=>w.abort(E.reason),E.addEventListener("abort",O,{once:!0}));let c=new Promise((P,J)=>{y=setTimeout(()=>{if(f!=="disconnect"&&w.abort(),f==="option"){J({[ae]:!0,ms:a.ms});return}J({[ye]:!0,error:R()})},a.ms)}),K;a.signal?K=Promise.resolve(e(w.signal)):K=Promise.resolve(e());try{return await Promise.race([K,c])}catch(P){if(typeof P=="object"&&P!==null&&P[ae]===!0)throw{[ae]:!0,ms:a.ms};if(typeof P=="object"&&P!==null&&P[ye]===!0){f==="disconnect"&&K.catch(()=>{});let J=P.error;if(typeof J=="object"&&J!==null&&J.type!=="STEP_TIMEOUT"){let j={timeoutMs:a.ms,stepName:s.name,stepKey:s.key,attempt:s.attempt};re in J?J[re]=j:Object.defineProperty(J,re,{value:j,enumerable:!1,writable:!0,configurable:!1})}throw J}throw P}finally{clearTimeout(y),O&&E&&E.removeEventListener("abort",O)}}var ne={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function fe(e,a){let{onError:s,onEvent:E,catchUnexpected:w,workflowId:f,workflowName:R,context:y,_workflowSignal:O}=a&&typeof a=="object"?a:{},c=f??crypto.randomUUID(),K=w??De,P=[],J=0,j=i=>i??`step_${++J}`,u=i=>{let N=i.context!==void 0||y===void 0?i:{...i,context:y},W=R!==void 0&&N.workflowName===void 0?{...N,workflowName:R}:N;if(W.type==="step_success"){let H=W.stepId;for(let L=P.length-1;L>=0;L--){let B=P[L];if(B.type==="race"&&!B.winnerId){B.winnerId=H;break}}}E?.(W,y)},M=Fe,$=i=>Ke(i),q=(i,N)=>i,X=i=>typeof i=="function"?!1:!!(i&&typeof i=="object"&&"ok"in i||i&&typeof i=="object"&&"then"in i&&typeof i.then=="function");try{let N=function(o){let p={};for(let[n,r]of Object.entries(o))if(typeof r=="function")p[n]=r;else if(r&&typeof r=="object"&&"fn"in r)p[n]=r.fn;else throw new TypeError(`step.parallel: operation "${n}" must be a function or { fn, errors? } object`);return p},W=function(o,p){let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let r=performance.now(),t=!1;P.push({scopeId:n,type:"parallel"});let l=()=>{if(t)return;t=!0;let m=P.findIndex(d=>d.scopeId===n);m!==-1&&P.splice(m,1),u({type:"scope_end",workflowId:c,scopeId:n,ts:Date.now(),durationMs:performance.now()-r})};u({type:"scope_start",workflowId:c,scopeId:n,scopeType:"parallel",name:o,ts:Date.now()});try{let m=await p();if(l(),!m.ok)throw s?.(m.error,o,y),M(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw l(),m}})()},H=function(o,p){let n=Object.keys(o),r=p.name??`Parallel(${n.join(", ")})`,t=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let l=performance.now(),m=!1;P.push({scopeId:t,type:"parallel"});let d=()=>{if(m)return;m=!0;let T=P.findIndex(k=>k.scopeId===t);T!==-1&&P.splice(T,1),u({type:"scope_end",workflowId:c,scopeId:t,ts:Date.now(),durationMs:performance.now()-l})};u({type:"scope_start",workflowId:c,scopeId:t,scopeType:"parallel",name:r,ts:Date.now()});try{let T=await new Promise(x=>{if(n.length===0){x([]);return}let v=!1,U=n.length,S=new Array(n.length);for(let I=0;I<n.length;I++){let C=n[I],A=I;Promise.resolve(o[C]()).catch(h=>F({type:"PROMISE_REJECTED",cause:h},{cause:{type:"PROMISE_REJECTION",reason:h}})).then(h=>{if(!v){if(!h.ok){v=!0,x([{key:C,result:h}]);return}S[A]={key:C,result:h},U--,U===0&&x(S)}})}});d();let k={};for(let{key:x,result:v}of T){if(!v.ok)throw s?.(v.error,x,y),M(v.error,{origin:"result",resultCause:v.cause});k[x]=v.value}return k}catch(T){throw d(),T}})()};var ee=N,b=W,D=H;let i=(o,p,n)=>(async()=>{if(typeof o!="string"||o.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let r=n??{},t=Ne(r),l=o,m=r.key??o,d=r.key??o,{description:T,retry:k,timeout:x}=r,v=j(m),U=E,S=U?performance.now():0,C=X(p)?()=>p:p,h={attempts:Math.max(1,k?.attempts??1),backoff:k?.backoff??ne.backoff,initialDelay:k?.initialDelay??ne.initialDelay,maxDelay:k?.maxDelay??ne.maxDelay,jitter:k?.jitter??ne.jitter,retryOn:k?.retryOn??ne.retryOn,onRetry:k?.onRetry??ne.onRetry};E&&u({type:"step_start",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),...t&&{metadata:t}});let Z;for(let _=1;_<=h.attempts;_++){let Oe=U?performance.now():0;try{let g;if(x?g=await Le(C,x,{name:l,key:m,attempt:_},O):g=await C(),g.ok){let Q=performance.now()-S;return u({type:"step_success",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:Q,...t&&{metadata:t}}),d&&u({type:"step_complete",workflowId:c,stepKey:d,name:l,description:T,ts:Date.now(),durationMs:Q,result:g,...t&&{metadata:t}}),g.value}if(Z=g,_<h.attempts&&h.retryOn(g.error,_)){let Q=me(_,h);u({type:"step_retry",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:Q,error:g.error,...t&&{metadata:t},diagnostics:Y(g.error,r.errorMeta,"result",_,performance.now()-S)}),h.onRetry(g.error,_,Q),await Ee(Q);continue}h.attempts>1&&u({type:"step_retries_exhausted",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),durationMs:performance.now()-S,attempts:_,lastError:g.error,...t&&{metadata:t},diagnostics:Y(g.error,r.errorMeta,"result",_,performance.now()-S)});break}catch(g){let Q=performance.now()-Oe;if(We(g)){let G=g.ms;u({type:"step_timeout",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),timeoutMs:G,attempt:_,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"timeout",_)}),u({type:"step_success",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:performance.now()-S,...t&&{metadata:t}}),d&&u({type:"step_complete",workflowId:c,stepKey:d,name:l,description:T,ts:Date.now(),durationMs:performance.now()-S,result:V(void 0),...t&&{metadata:t}});return}if($(g))throw u({type:"step_aborted",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:Q,...t&&{metadata:t}}),g;if(de(g)){let G=je(g),Pe=x?.ms??G?.timeoutMs??0;if(u({type:"step_timeout",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),timeoutMs:Pe,attempt:_,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"timeout",_)}),_<h.attempts&&h.retryOn(g,_)){let le=me(_,h);u({type:"step_retry",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:le,error:g,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"timeout",_,performance.now()-S)}),h.onRetry(g,_,le),await Ee(le);continue}h.attempts>1&&u({type:"step_retries_exhausted",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),durationMs:performance.now()-S,attempts:_,lastError:g,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"timeout",_,performance.now()-S)});let pe=performance.now()-S;throw u({type:"step_error",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:pe,error:g,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"timeout",_,pe)}),d&&u({type:"step_complete",workflowId:c,stepKey:d,name:l,description:T,ts:Date.now(),durationMs:pe,result:F(g,{cause:g}),meta:{origin:"throw",thrown:g},...t&&{metadata:t}}),s?.(g,l,y),M(g,{origin:"throw",thrown:g})}if(_<h.attempts&&h.retryOn(g,_)){let G=me(_,h);u({type:"step_retry",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:G,error:g,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"throw",_,performance.now()-S)}),h.onRetry(g,_,G),await Ee(G);continue}h.attempts>1&&!de(g)&&u({type:"step_retries_exhausted",workflowId:c,stepId:v,stepKey:m,name:l,ts:Date.now(),durationMs:performance.now()-S,attempts:_,lastError:g,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"throw",_,performance.now()-S)});let ce=performance.now()-S,se;try{se=K(g)}catch(G){throw te(G)}throw u({type:"step_error",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:ce,error:se,...t&&{metadata:t},diagnostics:Y(g,r.errorMeta,"throw",_,ce)}),d&&u({type:"step_complete",workflowId:c,stepKey:d,name:l,description:T,ts:Date.now(),durationMs:ce,result:F(se,{cause:g}),meta:{origin:"throw",thrown:g},...t&&{metadata:t}}),s?.(se,l,y),M(se,{origin:"throw",thrown:g})}}let z=Z,ie=performance.now()-S,ue=q(z.error,{origin:"result",resultCause:z.cause});throw u({type:"step_error",workflowId:c,stepId:v,stepKey:m,name:l,description:T,ts:Date.now(),durationMs:ie,error:ue,...t&&{metadata:t},diagnostics:Y(z.error,r.errorMeta,"result",h.attempts,ie)}),d&&u({type:"step_complete",workflowId:c,stepKey:d,name:l,description:T,ts:Date.now(),durationMs:ie,result:z,meta:{origin:"result",resultCause:z.cause},...t&&{metadata:t}}),s?.(ue,l,y),M(ue,{origin:"result",resultCause:z.cause})})();i.try=(o,p,n)=>{if(typeof o!="string"||o.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 r=n.key??o,t=o,l=o,m="error"in n?()=>n.error:n.onError,d=E;return(async()=>{let T=d?performance.now():0;E&&u({type:"step_start",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now()});try{let k=await p(),x=performance.now()-T;return u({type:"step_success",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:x}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:x,result:V(k)}),k}catch(k){let x=m(k),v=performance.now()-T,U=q(x,{origin:"throw",thrown:k});throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:v,error:U}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:v,result:F(x,{cause:k}),meta:{origin:"throw",thrown:k}}),s?.(U,t,y),M(U,{origin:"throw",thrown:k})}})()},i.fromResult=(o,p,n)=>{if(typeof o!="string"||o.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 r=n.key??o,t=o,l=o,m="error"in n?()=>n.error:n.onError,d=E;return(async()=>{let T=d?performance.now():0;E&&u({type:"step_start",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now()});let k=await p();if(k.ok){let x=performance.now()-T;return u({type:"step_success",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:x}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:x,result:V(k.value)}),k.value}else{let x=m(k.error),v=performance.now()-T,U=q(x,{origin:"result",resultCause:k.error});throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:v,error:U}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:v,result:F(x,{cause:k.error}),meta:{origin:"result",resultCause:k.error}}),s?.(U,t,y),M(U,{origin:"result",resultCause:k.error})}})()},i.fromNullable=(o,p,n,r)=>{if(typeof o!="string"||o.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 i(o,async()=>{let t=await p();return t!=null?V(t):F(n())},r)},i.retry=(o,p,n)=>{if(typeof o!="string"||o.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 i(o,p,{key:n.key??o,retry:{attempts:n.attempts,backoff:n.backoff,initialDelay:n.initialDelay,maxDelay:n.maxDelay,jitter:n.jitter,retryOn:n.retryOn,onRetry:n.onRetry},timeout:n.timeout})},i.withTimeout=(o,p,n)=>{if(typeof o!="string"||o.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 i(o,p,{key:n.key??o,timeout:n})},i.sleep=(o,p,n)=>{if(typeof o!="string"||o.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let r=typeof p=="string"?_e(p):p;if(!r)throw new Error(`step.sleep: invalid duration '${p}'`);let t=r.millis,l=n?.signal;return i(o,async()=>{if(O?.aborted||l?.aborted){let m=new Error("Sleep aborted");throw m.name="AbortError",m}return new Promise((m,d)=>{let T={timeoutId:void 0},k=()=>{T.timeoutId&&clearTimeout(T.timeoutId);let x=new Error("Sleep aborted");x.name="AbortError",d(x)};O?.addEventListener("abort",k,{once:!0}),l?.addEventListener("abort",k,{once:!0}),T.timeoutId=setTimeout(()=>{O?.removeEventListener("abort",k),l?.removeEventListener("abort",k),m(V(void 0))},t)})},{key:n?.key??o,description:n?.description})},i.parallel=((...o)=>{if(typeof o[0]!="string")throw new TypeError("step.parallel(name, ...): first argument must be a string (step name). Example: step.parallel('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let p=o[0],n=o[1];if(typeof n=="function")return W(p,n);if(n&&typeof n=="object"&&!Array.isArray(n)){let t=N(n);return H(t,{name:p})}throw new TypeError("step.parallel(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),i.race=(o,p)=>{let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let r=performance.now(),t=!1,l={scopeId:n,type:"race",winnerId:void 0};P.push(l);let m=()=>{if(t)return;t=!0;let d=P.findIndex(T=>T.scopeId===n);d!==-1&&P.splice(d,1),u({type:"scope_end",workflowId:c,scopeId:n,ts:Date.now(),durationMs:performance.now()-r,winnerId:l.winnerId})};u({type:"scope_start",workflowId:c,scopeId:n,scopeType:"race",name:o,ts:Date.now()});try{let d=await p();if(m(),!d.ok)throw s?.(d.error,o,y),M(d.error,{origin:"result",resultCause:d.cause});return d.value}catch(d){throw m(),d}})()},i.allSettled=(o,p)=>{let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let r=performance.now(),t=!1;P.push({scopeId:n,type:"allSettled"});let l=()=>{if(t)return;t=!0;let m=P.findIndex(d=>d.scopeId===n);m!==-1&&P.splice(m,1),u({type:"scope_end",workflowId:c,scopeId:n,ts:Date.now(),durationMs:performance.now()-r})};u({type:"scope_start",workflowId:c,scopeId:n,scopeType:"allSettled",name:o,ts:Date.now()});try{let m=await p();if(l(),!m.ok)throw s?.(m.error,o,y),M(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw l(),m}})()},i.if=(o,p,n)=>n(),i.label=i.if,i.branch=async(o,p)=>{let{condition:n,then:r,else:t}=p;if(n())return await r();if(t)return await t()},i.arm=(o,p)=>({fn:o,errors:p}),i.forEach=async(o,p,n)=>{let r=[],t=n.maxIterations,l=0,m="run"in n,d=Symbol.asyncIterator in p?p:(async function*(){yield*p})();for await(let T of d){if(t!==void 0&&l>=t)break;let k;m?k=await n.run(T,l):k=await n.item.handler(T,l,i),r.push(k),l++}return r},i.item=o=>({__forEachItemHandler:!0,handler:o}),i.dep=(o,p)=>p,i.run=(o,p,n)=>i(o,()=>p,n),i.workflow=(o,p,n)=>i(o,p,n),i.andThen=(o,p,n,r)=>i(o,()=>n(p),r),i.match=async(o,p,n,r)=>i(o,async()=>{let t=await p;return t.ok?V(await n.ok(t.value)):V(await n.err(t.error,t.cause))},r),i.all=i.parallel,i.map=async(o,p,n,r)=>{let t=r?.concurrency??p.length;return i(o,()=>t>=p.length?Te(p.map((l,m)=>n(l,m))):(async()=>{let l=[];for(let m=0;m<p.length;m+=t){let d=p.slice(m,m+t),T=await Te(d.map((k,x)=>n(k,m+x)));if(!T.ok)return T;l.push(...T.value)}return V(l)})(),{key:r?.key})},i.withFallback=(o,p,n)=>{if(typeof o!="string"||o.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 r=n.key??o,t=o,l=j(r),m=E;return(async()=>{let d=m?performance.now():0;E&&u({type:"step_start",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now()});let T;try{T=await p()}catch(S){if($(S))throw u({type:"step_aborted",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:performance.now()-d}),S;let I;try{I=K(S)}catch(A){throw te(A)}if(n.on!==void 0&&n.on!==I){let A=performance.now()-d;throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:A,error:I}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:A,result:F(I,{cause:S}),meta:{origin:"throw",thrown:S}}),s?.(I,t,y),M(I,{origin:"throw",thrown:S})}let C;try{C=await n.fallback()}catch(A){if($(A))throw u({type:"step_aborted",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:performance.now()-d}),A;let h;try{h=K(A)}catch(z){throw te(z)}let Z=performance.now()-d;throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:Z,error:h}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:Z,result:F(h,{cause:A}),meta:{origin:"throw",thrown:A}}),s?.(h,t,y),M(h,{origin:"throw",thrown:A})}if(C.ok){let A=performance.now()-d;return u({type:"step_success",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:A}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:A,result:C,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(I)}}),C.value}else{let A=performance.now()-d,h=q(C.error,{origin:"result",resultCause:C.cause});throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:A,error:h}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:A,result:C,meta:{origin:"result",resultCause:C.cause}}),s?.(h,t,y),M(h,{origin:"result",resultCause:C.cause})}}if(T.ok){let S=performance.now()-d;return u({type:"step_success",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:S}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:S,result:T}),T.value}let k=T.error;if(n.on!==void 0&&n.on!==k){let S=performance.now()-d,I=q(k,{origin:"result",resultCause:T.cause});throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:S,error:I}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:S,result:T,meta:{origin:"result",resultCause:T.cause}}),s?.(I,t,y),M(I,{origin:"result",resultCause:T.cause})}let x;try{x=await n.fallback()}catch(S){if($(S))throw u({type:"step_aborted",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:performance.now()-d}),S;let I;try{I=K(S)}catch(A){throw te(A)}let C=performance.now()-d;throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:C,error:I}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:C,result:F(I,{cause:S}),meta:{origin:"throw",thrown:S}}),s?.(I,t,y),M(I,{origin:"throw",thrown:S})}if(x.ok){let S=performance.now()-d;return u({type:"step_success",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:S}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:S,result:x,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(k)}}),x.value}let v=performance.now()-d,U=q(x.error,{origin:"result",resultCause:x.cause});throw u({type:"step_error",workflowId:c,stepId:l,stepKey:r,name:t,ts:Date.now(),durationMs:v,error:U}),r&&u({type:"step_complete",workflowId:c,stepKey:r,name:t,ts:Date.now(),durationMs:v,result:x,meta:{origin:"result",resultCause:x.cause}}),s?.(U,t,y),M(U,{origin:"result",resultCause:x.cause})})()},i.withResource=(o,p)=>{if(typeof o!="string"||o.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 n=o,r=o,t=j(n),l=E;return(async()=>{let m=l?performance.now():0;E&&u({type:"step_start",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now()});let d;try{d=await p.acquire()}catch(C){if($(C))throw u({type:"step_aborted",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:performance.now()-m}),C;let A;try{A=K(C)}catch(Z){throw te(Z)}let h=performance.now()-m;throw u({type:"step_error",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:h,error:A}),n&&u({type:"step_complete",workflowId:c,stepKey:n,name:r,ts:Date.now(),durationMs:h,result:F(A,{cause:C}),meta:{origin:"throw",thrown:C}}),s?.(A,r,y),M(A,{origin:"throw",thrown:C})}if(!d.ok){let C=performance.now()-m,A=q(d.error,{origin:"result",resultCause:d.cause});throw u({type:"step_error",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:C,error:A}),n&&u({type:"step_complete",workflowId:c,stepKey:n,name:r,ts:Date.now(),durationMs:C,result:d,meta:{origin:"result",resultCause:d.cause}}),s?.(A,r,y),M(A,{origin:"result",resultCause:d.cause})}let T=d.value,k,x,v=!1;try{k=await p.use(T)}catch(C){if($(C)){try{await p.release(T)}catch(A){console.warn(`[awaitly] step.withResource("${o}"): release threw after earlyExit:`,A)}throw C}x=C,v=!0}try{await p.release(T)}catch(C){console.warn(`[awaitly] step.withResource("${o}"): release threw:`,C)}if(v){let C;try{C=K(x)}catch(h){throw te(h)}let A=performance.now()-m;throw u({type:"step_error",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:A,error:C}),n&&u({type:"step_complete",workflowId:c,stepKey:n,name:r,ts:Date.now(),durationMs:A,result:F(C,{cause:x}),meta:{origin:"throw",thrown:x}}),s?.(C,r,y),M(C,{origin:"throw",thrown:x})}let U=k;if(U.ok){let C=performance.now()-m;return u({type:"step_success",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:C}),n&&u({type:"step_complete",workflowId:c,stepKey:n,name:r,ts:Date.now(),durationMs:C,result:U}),U.value}let S=performance.now()-m,I=q(U.error,{origin:"result",resultCause:U.cause});throw u({type:"step_error",workflowId:c,stepId:t,stepKey:n,name:r,ts:Date.now(),durationMs:S,error:I}),n&&u({type:"step_complete",workflowId:c,stepKey:n,name:r,ts:Date.now(),durationMs:S,result:U,meta:{origin:"result",resultCause:U.cause}}),s?.(I,r,y),M(I,{origin:"result",resultCause:U.cause})})()};let B=await e({step:i});if(process.env.NODE_ENV!=="production"&&B!==null&&typeof B=="object"&&"ok"in B&&typeof B.ok=="boolean"){let o=B;(o.ok===!0&&"value"in o||o.ok===!1&&"error"in o)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
1
+ var We=class extends Error{_tag};function ye(e,t){return class extends We{_tag=e;constructor(r,f){let p=t?.message?t.message(r??{}):e;if(super(p),this.name=e,Object.setPrototypeOf(this,new.target.prototype),r&&typeof r=="object"){let{_tag:y,name:A,message:S,stack:K,...i}=r,Y=Object.prototype.hasOwnProperty.call(i,"cause"),v=Y?i.cause:void 0;Y&&delete i.cause;let x=f?.cause!==void 0;if(Y&&x)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,i),Y&&(this.cause=v),x&&(this.cause=f?.cause)}else f?.cause!==void 0&&(this.cause=f.cause)}}}Object.defineProperty(ye,Symbol.hasInstance,{value:e=>e instanceof We});(p=>{function e(y){return y instanceof Error}p.isError=e;function t(y){return y instanceof We}p.isTaggedError=t;function r(y,A){let S=y._tag,K=A[S];return K(y)}p.match=r;function f(y,A,S){let K=y._tag,i=A[K];return i?i(y):S(y)}p.matchPartial=f})(ye||={});var Ze=class extends ye("TimeoutError",{message:t=>t.operation?`TimeoutError: ${t.operation} timed out after ${t.ms}ms`:`TimeoutError: Operation timed out after ${t.ms}ms`}){},et=class extends ye("RetryExhaustedError",{message:t=>t.operation?`RetryExhaustedError: ${t.operation} failed after ${t.attempts} attempts`:`RetryExhaustedError: Operation failed after ${t.attempts} attempts`}){},tt=class extends ye("RateLimitError",{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 ye("CircuitBreakerOpenError",{message:t=>`CircuitBreakerOpenError: Circuit ${t.circuitName} is ${t.state??"OPEN"}${t.retryAfterMs?`, retry after ${Math.ceil(t.retryAfterMs/1e3)}s`:""}`}){},nt=class extends ye("ValidationError",{message:t=>`ValidationError: Invalid ${t.field} - ${t.reason}`}){},ot=class extends ye("NotFoundError",{message:t=>t.id?`NotFoundError: ${t.resource} with id ${t.id} not found`:`NotFoundError: ${t.resource} not found`}){},st=class extends ye("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 ye("NetworkError",{message:t=>t.url?`NetworkError: ${t.reason} (${t.url})`:`NetworkError: ${t.reason}`}){},it=class extends ye("CompensationError",{message:t=>`CompensationError: Failed to compensate step ${t.step}`}){},Se=class extends ye("UnexpectedError",{message:t=>`UnexpectedError: ${t.cause instanceof Error?t.cause.message:String(t.cause??"unknown")}`}){};function Ot(e){let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let r=parseFloat(t[1]),f=t[2].toLowerCase();return{_tag:"Duration",millis:r*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[f]??1)}}function Fe(e){return new Se({cause:e})}function z(e){return{ok:!0,value:e}}function U(e,t){let r=t?.cause;return{ok:!1,error:e,...r!==void 0?{cause:r}:{}}}var pt=e=>e.ok;var mt=e=>e instanceof Se||typeof e=="object"&&e!==null&&"_tag"in e&&e._tag==="UnexpectedError";function _t(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 r=t._tag.trim();if(r)return r}if(typeof t.tag=="string"){let r=t.tag.trim();if(r)return r}if(typeof t.code=="string"){let r=t.code.trim();if(r)return r}else if(typeof t.code=="number")return String(t.code);if(e instanceof Error&&e.name){let r=e.name.trim();if(r)return r}}return"unknown"}function Pt(e,t){if(!(!t||!e))return t[e]}function He(e){let{intent:t,domain:r,owner:f,tags:p,stateChanges:y,emits:A,calls:S}=e;if(!t&&!r&&!f&&!p?.length&&!y?.length&&!A?.length&&!S?.length)return;let K={};return t&&(K.intent=t),r&&(K.domain=r),f&&(K.owner=f),p?.length&&(K.tags=p),y?.length&&(K.stateChanges=y),A?.length&&(K.emits=A),S?.length&&(K.calls=S),K}function ge(e,t,r,f,p){let y=_t(e),A=Pt(y,t),S={tag:y,origin:r};return A!==void 0&&(S.classification=A),f!==void 0&&(S.attempt=f),p!==void 0&&(S.cumulativeDurationMs=p),S}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 Dt(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 dt=Symbol("early-exit");function _e(e,t){return{[dt]:!0,error:e,meta:t}}function be(e){return typeof e=="object"&&e!==null&&e[dt]===!0}var ft=Symbol("mapper-exception");function ve(e){return{[ft]:!0,thrown:e}}function Mt(e){return typeof e=="object"&&e!==null&&e[ft]===!0}function Ve(e,t){let{backoff:r,initialDelay:f,maxDelay:p,jitter:y}=t,A;switch(r){case"fixed":A=f;break;case"linear":A=f*e;break;case"exponential":A=f*Math.pow(2,e-1);break}if(A=Math.min(A,p),y){let S=A*.25*Math.random();A=A+S}return Math.floor(A)}function Le(e){return new Promise(t=>setTimeout(t,e))}var lt=Symbol("timeout"),Ne=Symbol("timeout-option");function It(e){return typeof e=="object"&&e!==null&&e[Ne]===!0}async function Wt(e,t,r,f){let p=new AbortController,y=t.onTimeout??"error",A=()=>typeof y=="function"?y({name:r.name,key:r.key,ms:t.ms}):t.error??{type:"STEP_TIMEOUT",stepName:r.name,stepKey:r.key,timeoutMs:t.ms,attempt:r.attempt},S;f?.aborted&&p.abort(f.reason);let K;f&&!f.aborted&&(K=()=>p.abort(f.reason),f.addEventListener("abort",K,{once:!0}));let i=new Promise((v,x)=>{S=setTimeout(()=>{if(y!=="disconnect"&&p.abort(),y==="option"){x({[Ne]:!0,ms:t.ms});return}x({[lt]:!0,error:A()})},t.ms)}),Y;t.signal?Y=Promise.resolve(e(p.signal)):Y=Promise.resolve(e());try{return await Promise.race([Y,i])}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"&&Y.catch(()=>{});let x=v.error;if(typeof x=="object"&&x!==null&&x.type!=="STEP_TIMEOUT"){let G={timeoutMs:t.ms,stepName:r.name,stepKey:r.key,attempt:r.attempt};Oe in x?x[Oe]=G:Object.defineProperty(x,Oe,{value:G,enumerable:!1,writable:!0,configurable:!1})}throw x}throw v}finally{clearTimeout(S),K&&f&&f.removeEventListener("abort",K)}}var Ae={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function je(e,t){let{onError:r,onEvent:f,catchUnexpected:p,workflowId:y,workflowName:A,context:S,_workflowSignal:K}=t&&typeof t=="object"?t:{},i=y??crypto.randomUUID(),Y=p??Fe,v=[],x=0,G=c=>c??`step_${++x}`,d=c=>{let X=c.context!==void 0||S===void 0?c:{...c,context:S},se=A!==void 0&&X.workflowName===void 0?{...X,workflowName:A}:X;if(se.type==="step_success"){let we=se.stepId;for(let ie=v.length-1;ie>=0;ie--){let ue=v[ie];if(ue.type==="race"&&!ue.winnerId){ue.winnerId=we;break}}}f?.(se,S)},$=_e,P=c=>be(c),ce=(c,X)=>c,Ee=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 X=function(l){let u={};for(let[o,s]of Object.entries(l))if(typeof s=="function")u[o]=s;else if(s&&typeof s=="object"&&"fn"in s)u[o]=s.fn;else throw new TypeError(`step.parallel: operation "${o}" must be a function or { fn, errors? } object`);return u},se=function(l,u){let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1;v.push({scopeId:o,type:"parallel"});let k=()=>{if(n)return;n=!0;let T=v.findIndex(m=>m.scopeId===o);T!==-1&&v.splice(T,1),d({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};d({type:"scope_start",workflowId:i,scopeId:o,scopeType:"parallel",name:l,ts:Date.now()});try{let T=await u();if(k(),!T.ok)throw r?.(T.error,l,S),$(T.error,{origin:"result",resultCause:T.cause});return T.value}catch(T){throw k(),T}})()},we=function(l,u){let o=Object.keys(l),s=u.name??`Parallel(${o.join(", ")})`,n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let k=performance.now(),T=!1;v.push({scopeId:n,type:"parallel"});let m=()=>{if(T)return;T=!0;let O=v.findIndex(D=>D.scopeId===n);O!==-1&&v.splice(O,1),d({type:"scope_end",workflowId:i,scopeId:n,ts:Date.now(),durationMs:performance.now()-k})};d({type:"scope_start",workflowId:i,scopeId:n,scopeType:"parallel",name:s,ts:Date.now()});try{let O=await new Promise(N=>{if(o.length===0){N([]);return}let J=!1,ee=o.length,M=new Array(o.length);for(let re=0;re<o.length;re++){let F=o[re],W=re;Promise.resolve(l[F]()).catch(V=>U({type:"PROMISE_REJECTED",cause:V},{cause:{type:"PROMISE_REJECTION",reason:V}})).then(V=>{if(!J){if(!V.ok){J=!0,N([{key:F,result:V}]);return}M[W]={key:F,result:V},ee--,ee===0&&N(M)}})}});m();let D={};for(let{key:N,result:J}of O){if(!J.ok)throw r?.(J.error,N,S),$(J.error,{origin:"result",resultCause:J.cause});D[N]=J.value}return D}catch(O){throw m(),O}})()};var ke=X,B=se,q=we;let c=(l,u,o)=>(async()=>{if(typeof l!="string"||l.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=He(s),k=l,T=s.key??l,m=s.key??l,{description:O,retry:D,timeout:N}=s,J=G(T),ee=f,M=ee?performance.now():0,F=Ee(u)?()=>u:u,V={attempts:Math.max(1,D?.attempts??1),backoff:D?.backoff??Ae.backoff,initialDelay:D?.initialDelay??Ae.initialDelay,maxDelay:D?.maxDelay??Ae.maxDelay,jitter:D?.jitter??Ae.jitter,retryOn:D?.retryOn??Ae.retryOn,onRetry:D?.onRetry??Ae.onRetry};f&&d({type:"step_start",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),...n&&{metadata:n}});let Te;for(let a=1;a<=V.attempts;a++){let Q=ee?performance.now():0;try{let R;if(N?R=await Wt(F,N,{name:k,key:T,attempt:a},K):R=await F(),R.ok){let E=performance.now()-M;return d({type:"step_success",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:E,...n&&{metadata:n}}),m&&d({type:"step_complete",workflowId:i,stepKey:m,name:k,description:O,ts:Date.now(),durationMs:E,result:R,...n&&{metadata:n}}),R.value}if(Te=R,a<V.attempts&&V.retryOn(R.error,a)){let E=Ve(a,V);d({type:"step_retry",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),attempt:a+1,maxAttempts:V.attempts,delayMs:E,error:R.error,...n&&{metadata:n},diagnostics:ge(R.error,s.errorMeta,"result",a,performance.now()-M)}),V.onRetry(R.error,a,E),await Le(E);continue}V.attempts>1&&d({type:"step_retries_exhausted",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),durationMs:performance.now()-M,attempts:a,lastError:R.error,...n&&{metadata:n},diagnostics:ge(R.error,s.errorMeta,"result",a,performance.now()-M)});break}catch(R){let E=performance.now()-Q;if(It(R)){let h=R.ms;d({type:"step_timeout",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),timeoutMs:h,attempt:a,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"timeout",a)}),d({type:"step_success",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:performance.now()-M,...n&&{metadata:n}}),m&&d({type:"step_complete",workflowId:i,stepKey:m,name:k,description:O,ts:Date.now(),durationMs:performance.now()-M,result:z(void 0),...n&&{metadata:n}});return}if(P(R))throw d({type:"step_aborted",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:E,...n&&{metadata:n}}),R;if(ut(R)){let h=Dt(R),_=N?.ms??h?.timeoutMs??0;if(d({type:"step_timeout",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),timeoutMs:_,attempt:a,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"timeout",a)}),a<V.attempts&&V.retryOn(R,a)){let g=Ve(a,V);d({type:"step_retry",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),attempt:a+1,maxAttempts:V.attempts,delayMs:g,error:R,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"timeout",a,performance.now()-M)}),V.onRetry(R,a,g),await Le(g);continue}V.attempts>1&&d({type:"step_retries_exhausted",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),durationMs:performance.now()-M,attempts:a,lastError:R,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"timeout",a,performance.now()-M)});let j=performance.now()-M;throw d({type:"step_error",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:j,error:R,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"timeout",a,j)}),m&&d({type:"step_complete",workflowId:i,stepKey:m,name:k,description:O,ts:Date.now(),durationMs:j,result:U(R,{cause:R}),meta:{origin:"throw",thrown:R},...n&&{metadata:n}}),r?.(R,k,S),$(R,{origin:"throw",thrown:R})}if(a<V.attempts&&V.retryOn(R,a)){let h=Ve(a,V);d({type:"step_retry",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),attempt:a+1,maxAttempts:V.attempts,delayMs:h,error:R,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"throw",a,performance.now()-M)}),V.onRetry(R,a,h),await Le(h);continue}V.attempts>1&&!ut(R)&&d({type:"step_retries_exhausted",workflowId:i,stepId:J,stepKey:T,name:k,ts:Date.now(),durationMs:performance.now()-M,attempts:a,lastError:R,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"throw",a,performance.now()-M)});let C=performance.now()-M,b;try{b=Y(R)}catch(h){throw ve(h)}throw d({type:"step_error",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:C,error:b,...n&&{metadata:n},diagnostics:ge(R,s.errorMeta,"throw",a,C)}),m&&d({type:"step_complete",workflowId:i,stepKey:m,name:k,description:O,ts:Date.now(),durationMs:C,result:U(b,{cause:R}),meta:{origin:"throw",thrown:R},...n&&{metadata:n}}),r?.(b,k,S),$(b,{origin:"throw",thrown:R})}}let le=Te,xe=performance.now()-M,w=ce(le.error,{origin:"result",resultCause:le.cause});throw d({type:"step_error",workflowId:i,stepId:J,stepKey:T,name:k,description:O,ts:Date.now(),durationMs:xe,error:w,...n&&{metadata:n},diagnostics:ge(le.error,s.errorMeta,"result",V.attempts,xe)}),m&&d({type:"step_complete",workflowId:i,stepKey:m,name:k,description:O,ts:Date.now(),durationMs:xe,result:le,meta:{origin:"result",resultCause:le.cause},...n&&{metadata:n}}),r?.(w,k,S),$(w,{origin:"result",resultCause:le.cause})})();c.try=(l,u,o)=>{if(typeof l!="string"||l.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=o.key??l,n=l,k=l,T="error"in o?()=>o.error:o.onError,m=f;return(async()=>{let O=m?performance.now():0;f&&d({type:"step_start",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now()});try{let D=await u(),N=performance.now()-O;return d({type:"step_success",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:N}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:N,result:z(D)}),D}catch(D){let N=T(D),J=performance.now()-O,ee=ce(N,{origin:"throw",thrown:D});throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:J,error:ee}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:J,result:U(N,{cause:D}),meta:{origin:"throw",thrown:D}}),r?.(ee,n,S),$(ee,{origin:"throw",thrown:D})}})()},c.fromResult=(l,u,o)=>{if(typeof l!="string"||l.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??l,n=l,k=l,T="error"in o?()=>o.error:o.onError,m=f;return(async()=>{let O=m?performance.now():0;f&&d({type:"step_start",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now()});let D=await u();if(D.ok){let N=performance.now()-O;return d({type:"step_success",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:N}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:N,result:z(D.value)}),D.value}else{let N=T(D.error),J=performance.now()-O,ee=ce(N,{origin:"result",resultCause:D.error});throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:J,error:ee}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:J,result:U(N,{cause:D.error}),meta:{origin:"result",resultCause:D.error}}),r?.(ee,n,S),$(ee,{origin:"result",resultCause:D.error})}})()},c.fromNullable=(l,u,o,s)=>{if(typeof l!="string"||l.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(l,async()=>{let n=await u();return n!=null?z(n):U(o())},s)},c.retry=(l,u,o)=>{if(typeof l!="string"||l.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(l,u,{key:o.key??l,retry:{attempts:o.attempts,backoff:o.backoff,initialDelay:o.initialDelay,maxDelay:o.maxDelay,jitter:o.jitter,retryOn:o.retryOn,onRetry:o.onRetry},timeout:o.timeout})},c.withTimeout=(l,u,o)=>{if(typeof l!="string"||l.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(l,u,{key:o.key??l,timeout:o})},c.sleep=(l,u,o)=>{if(typeof l!="string"||l.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 u=="string"?Ot(u):u;if(!s)throw new Error(`step.sleep: invalid duration '${u}'`);let n=s.millis,k=o?.signal;return c(l,async()=>{if(K?.aborted||k?.aborted){let T=new Error("Sleep aborted");throw T.name="AbortError",T}return new Promise((T,m)=>{let O={timeoutId:void 0},D=()=>{O.timeoutId&&clearTimeout(O.timeoutId);let N=new Error("Sleep aborted");N.name="AbortError",m(N)};K?.addEventListener("abort",D,{once:!0}),k?.addEventListener("abort",D,{once:!0}),O.timeoutId=setTimeout(()=>{K?.removeEventListener("abort",D),k?.removeEventListener("abort",D),T(z(void 0))},n)})},{key:o?.key??l,description:o?.description})},c.parallel=((...l)=>{if(typeof l[0]!="string")throw new TypeError("step.parallel(name, ...): first argument must be a string (step name). Example: step.parallel('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let u=l[0],o=l[1];if(typeof o=="function")return se(u,o);if(o&&typeof o=="object"&&!Array.isArray(o)){let n=X(o);return we(n,{name:u})}throw new TypeError("step.parallel(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),c.race=(l,u)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1,k={scopeId:o,type:"race",winnerId:void 0};v.push(k);let T=()=>{if(n)return;n=!0;let m=v.findIndex(O=>O.scopeId===o);m!==-1&&v.splice(m,1),d({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s,winnerId:k.winnerId})};d({type:"scope_start",workflowId:i,scopeId:o,scopeType:"race",name:l,ts:Date.now()});try{let m=await u();if(T(),!m.ok)throw r?.(m.error,l,S),$(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw T(),m}})()},c.allSettled=(l,u)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),n=!1;v.push({scopeId:o,type:"allSettled"});let k=()=>{if(n)return;n=!0;let T=v.findIndex(m=>m.scopeId===o);T!==-1&&v.splice(T,1),d({type:"scope_end",workflowId:i,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};d({type:"scope_start",workflowId:i,scopeId:o,scopeType:"allSettled",name:l,ts:Date.now()});try{let T=await u();if(k(),!T.ok)throw r?.(T.error,l,S),$(T.error,{origin:"result",resultCause:T.cause});return T.value}catch(T){throw k(),T}})()},c.if=(l,u,o)=>o(),c.label=c.if,c.branch=async(l,u)=>{let{condition:o,then:s,else:n}=u;if(o())return await s();if(n)return await n()},c.arm=(l,u)=>({fn:l,errors:u}),c.forEach=async(l,u,o)=>{let s=[],n=o.maxIterations,k=0,T="run"in o,m=Symbol.asyncIterator in u?u:(async function*(){yield*u})();for await(let O of m){if(n!==void 0&&k>=n)break;let D;T?D=await o.run(O,k):D=await o.item.handler(O,k,c),s.push(D),k++}return s},c.item=l=>({__forEachItemHandler:!0,handler:l}),c.dep=(l,u)=>u,c.run=(l,u,o)=>c(l,()=>u,o),c.workflow=(l,u,o)=>c(l,u,o),c.andThen=(l,u,o,s)=>c(l,()=>o(u),s),c.match=async(l,u,o,s)=>c(l,async()=>{let n=await u;return n.ok?z(await o.ok(n.value)):z(await o.err(n.error,n.cause))},s),c.all=c.parallel,c.map=async(l,u,o,s)=>{let n=s?.concurrency??u.length;return c(l,()=>n>=u.length?ct(u.map((k,T)=>o(k,T))):(async()=>{let k=[];for(let T=0;T<u.length;T+=n){let m=u.slice(T,T+n),O=await ct(m.map((D,N)=>o(D,T+N)));if(!O.ok)return O;k.push(...O.value)}return z(k)})(),{key:s?.key})},c.withFallback=(l,u,o)=>{if(typeof l!="string"||l.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??l,n=l,k=G(s),T=f;return(async()=>{let m=T?performance.now():0;f&&d({type:"step_start",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now()});let O;try{O=await u()}catch(M){if(P(M))throw d({type:"step_aborted",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-m}),M;let re;try{re=Y(M)}catch(W){throw ve(W)}if(o.on!==void 0&&o.on!==re){let W=performance.now()-m;throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:W,error:re}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:W,result:U(re,{cause:M}),meta:{origin:"throw",thrown:M}}),r?.(re,n,S),$(re,{origin:"throw",thrown:M})}let F;try{F=await o.fallback()}catch(W){if(P(W))throw d({type:"step_aborted",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-m}),W;let V;try{V=Y(W)}catch(le){throw ve(le)}let Te=performance.now()-m;throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:Te,error:V}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:Te,result:U(V,{cause:W}),meta:{origin:"throw",thrown:W}}),r?.(V,n,S),$(V,{origin:"throw",thrown:W})}if(F.ok){let W=performance.now()-m;return d({type:"step_success",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:W}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:W,result:F,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(re)}}),F.value}else{let W=performance.now()-m,V=ce(F.error,{origin:"result",resultCause:F.cause});throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:W,error:V}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:W,result:F,meta:{origin:"result",resultCause:F.cause}}),r?.(V,n,S),$(V,{origin:"result",resultCause:F.cause})}}if(O.ok){let M=performance.now()-m;return d({type:"step_success",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:M}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:M,result:O}),O.value}let D=O.error;if(o.on!==void 0&&o.on!==D){let M=performance.now()-m,re=ce(D,{origin:"result",resultCause:O.cause});throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:M,error:re}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:M,result:O,meta:{origin:"result",resultCause:O.cause}}),r?.(re,n,S),$(re,{origin:"result",resultCause:O.cause})}let N;try{N=await o.fallback()}catch(M){if(P(M))throw d({type:"step_aborted",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:performance.now()-m}),M;let re;try{re=Y(M)}catch(W){throw ve(W)}let F=performance.now()-m;throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:F,error:re}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:F,result:U(re,{cause:M}),meta:{origin:"throw",thrown:M}}),r?.(re,n,S),$(re,{origin:"throw",thrown:M})}if(N.ok){let M=performance.now()-m;return d({type:"step_success",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:M}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:M,result:N,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(D)}}),N.value}let J=performance.now()-m,ee=ce(N.error,{origin:"result",resultCause:N.cause});throw d({type:"step_error",workflowId:i,stepId:k,stepKey:s,name:n,ts:Date.now(),durationMs:J,error:ee}),s&&d({type:"step_complete",workflowId:i,stepKey:s,name:n,ts:Date.now(),durationMs:J,result:N,meta:{origin:"result",resultCause:N.cause}}),r?.(ee,n,S),$(ee,{origin:"result",resultCause:N.cause})})()},c.withResource=(l,u)=>{if(typeof l!="string"||l.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=l,s=l,n=G(o),k=f;return(async()=>{let T=k?performance.now():0;f&&d({type:"step_start",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now()});let m;try{m=await u.acquire()}catch(F){if(P(F))throw d({type:"step_aborted",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:performance.now()-T}),F;let W;try{W=Y(F)}catch(Te){throw ve(Te)}let V=performance.now()-T;throw d({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:V,error:W}),o&&d({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:V,result:U(W,{cause:F}),meta:{origin:"throw",thrown:F}}),r?.(W,s,S),$(W,{origin:"throw",thrown:F})}if(!m.ok){let F=performance.now()-T,W=ce(m.error,{origin:"result",resultCause:m.cause});throw d({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:F,error:W}),o&&d({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:F,result:m,meta:{origin:"result",resultCause:m.cause}}),r?.(W,s,S),$(W,{origin:"result",resultCause:m.cause})}let O=m.value,D,N,J=!1;try{D=await u.use(O)}catch(F){if(P(F)){try{await u.release(O)}catch(W){console.warn(`[awaitly] step.withResource("${l}"): release threw after earlyExit:`,W)}throw F}N=F,J=!0}try{await u.release(O)}catch(F){console.warn(`[awaitly] step.withResource("${l}"): release threw:`,F)}if(J){let F;try{F=Y(N)}catch(V){throw ve(V)}let W=performance.now()-T;throw d({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:W,error:F}),o&&d({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:W,result:U(F,{cause:N}),meta:{origin:"throw",thrown:N}}),r?.(F,s,S),$(F,{origin:"throw",thrown:N})}let ee=D;if(ee.ok){let F=performance.now()-T;return d({type:"step_success",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:F}),o&&d({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:F,result:ee}),ee.value}let M=performance.now()-T,re=ce(ee.error,{origin:"result",resultCause:ee.cause});throw d({type:"step_error",workflowId:i,stepId:n,stepKey:o,name:s,ts:Date.now(),durationMs:M,error:re}),o&&d({type:"step_complete",workflowId:i,stepKey:o,name:s,ts:Date.now(),durationMs:M,result:ee,meta:{origin:"result",resultCause:ee.cause}}),r?.(re,s,S),$(re,{origin:"result",resultCause:ee.cause})})()};let ue=await e({step:c});if(process.env.NODE_ENV!=="production"&&ue!==null&&typeof ue=="object"&&"ok"in ue&&typeof ue.ok=="boolean"){let l=ue;(l.ok===!0&&"value"in l||l.ok===!1&&"error"in l)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
2
2
 
3
3
  Incorrect: return ok({ data });
4
4
  Correct: return { data };
5
5
 
6
- See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return V(B)}catch(i){if($e(i))throw i.thrown;if($(i)){let W=i.meta.origin==="throw"?i.meta.thrown:i.meta.origin==="result"?i.meta.resultCause:void 0;return F(i.error,{cause:W})}let N=K(i);return s?.(N,"unexpected",y),F(N,{cause:i})}}fe.strict=(e,a)=>fe(e,a);async function Te(e){return e.length===0?V([]):new Promise(a=>{let s=!1,E=e.length,w=new Array(e.length);for(let f=0;f<e.length;f++){let R=f;Promise.resolve(e[R]).catch(y=>F({type:"PROMISE_REJECTED",cause:y},{cause:{type:"PROMISE_REJECTION",reason:y}})).then(y=>{if(!s){if(!y.ok){s=!0,a(y);return}w[R]=y.value,E--,E===0&&a(V(w))}})}})}function we(e){return typeof e=="object"&&e!==null&&"__earlyExit"in e&&e.__earlyExit===!0}function xe(e,a={}){let{recordInvocations:s=!0,clock:E=Date.now}=a,w=[],f=new Map,R=0,y=[];function O(b){w=[...b],R=0,f.clear()}function c(b,D){f.set(b,D)}function K(b){if(b&&f.has(b))return f.get(b);if(R<w.length)return w[R++]}function P(){let b=async(D,i,N)=>{let W,H,L;typeof D=="string"?(W=D,H=i,L=N??{}):(H=D,typeof i=="string"?(W=i,L={}):(L=i??{},W=L.key??"step"));let B=E(),o={name:W,key:L.key,order:y.length,timestamp:B};s&&y.push(o);let p=K(W);if(p)switch(o.durationMs=E()-B,p.type){case"ok":return o.result=V(p.value),p.value;case"err":throw o.result=F(p.error),{__earlyExit:!0,error:p.error};case"throw":throw p.error}let n=typeof H=="function"?await H():await H;if(o.durationMs=E()-B,o.result=n,!n.ok)throw{__earlyExit:!0,error:n.error};return n.value};return b.try=async(D,i,N)=>{let W,H,L;typeof D=="string"?(W=D,H=i,L=N):(H=D,L=i,W=L.key??"step");let B=E(),o={name:W,key:"key"in L?L.key:void 0,order:y.length,timestamp:B};s&&y.push(o);let p=K(W);if(p)switch(o.durationMs=E()-B,p.type){case"ok":return o.result=V(p.value),p.value;case"err":throw o.result=F(p.error),{__earlyExit:!0,error:p.error};case"throw":throw p.error}try{let n=await H();return o.durationMs=E()-B,o.result=V(n),n}catch(n){o.durationMs=E()-B;let r="error"in L?L.error:L.onError(n);throw o.result=F(r),{__earlyExit:!0,error:r}}},b}async function J(b){let D=P();try{let i=await b({step:D,deps:e});return V(i)}catch(i){return we(i)?F(i.error):F({type:"UNEXPECTED_ERROR",cause:i})}}async function j(b,D){let i=P();try{let N=await D({step:i,deps:e,input:b});return V(N)}catch(N){return we(N)?F(N.error):F({type:"UNEXPECTED_ERROR",cause:N})}}function u(){return[...y]}function M(b){let D=y.map(N=>N.name??N.key??"unnamed").filter(N=>N!=="unnamed"),i=JSON.stringify(D)===JSON.stringify(b);return{passed:i,message:i?`Steps invoked in order: ${b.join(", ")}`:`Expected steps [${b.join(", ")}] but got [${D.join(", ")}]`,expected:b,actual:D}}function $(b){let D=y.some(i=>i.name===b||i.key===b);return{passed:D,message:D?`Step "${b}" was invoked`:`Step "${b}" was NOT invoked`,expected:b,actual:D}}function q(b){let D=y.some(i=>i.name===b||i.key===b);return{passed:!D,message:D?`Step "${b}" was invoked but should not have been`:`Step "${b}" was correctly NOT invoked`,expected:"not called",actual:D?"called":"not called"}}function X(b,D){let i=b.ok===D.ok&&(b.ok?JSON.stringify(b.value)===JSON.stringify(D.value):JSON.stringify(b.error)===JSON.stringify(D.error));return{passed:i,message:i?"Result matches expected":"Result does not match expected",expected:D,actual:b}}function ee(){w=[],f.clear(),R=0,y=[]}return{script:O,scriptStep:c,run:J,runWithInput:j,getInvocations:u,assertSteps:M,assertStepCalled:$,assertStepNotCalled:q,assertResult:X,reset:ee}}function Be(){let e,a=[],s=[],E=((...w)=>{if(s.push(w),a.length>0)return Promise.resolve(a.shift());if(e)return Promise.resolve(e);throw new Error("Mock function called without configured return value")});return E.returns=w=>(e=w,E),E.returnsOnce=w=>(a.push(w),E),E.getCalls=()=>[...s],E.getCallCount=()=>s.length,E.reset=()=>{e=void 0,a.length=0,s.length=0},E}function Ve(e,a,s){let E=e.reduce((w,f)=>w+(f.durationMs??0),0);return{invocations:e.map(w=>({...w,timestamp:0})),result:a,events:s?.map(w=>({...w,ts:0})),durationMs:E}}function Je(e,a){let s=[];e.invocations.length!==a.invocations.length&&s.push(`Invocation count: ${e.invocations.length} vs ${a.invocations.length}`);let E=Math.max(e.invocations.length,a.invocations.length);for(let w=0;w<E;w++){let f=e.invocations[w],R=a.invocations[w];if(!f){s.push(`Step ${w}: missing in first snapshot`);continue}if(!R){s.push(`Step ${w}: missing in second snapshot`);continue}f.name!==R.name&&s.push(`Step ${w} name: "${f.name}" vs "${R.name}"`),f.key!==R.key&&s.push(`Step ${w} key: "${f.key}" vs "${R.key}"`),f.result?.ok!==R.result?.ok&&s.push(`Step ${w} result: ${f.result?.ok?"ok":"err"} vs ${R.result?.ok?"ok":"err"}`)}return e.result.ok!==a.result.ok&&s.push(`Final result: ${e.result.ok?"ok":"err"} vs ${a.result.ok?"ok":"err"}`),{equal:s.length===0,differences:s}}function qe(e=0){let a=e;return{now:()=>a,advance:s=>{a+=s},set:s=>{a=s},reset:()=>{a=e}}}function He(e){return{type:"ok",value:e}}function Xe(e){return{type:"err",error:e}}function Ye(e){return{type:"throw",error:e}}function Ge(e,a={}){let{clock:s=Date.now}=a,E=xe(e,a),w=[],f=[];async function R(j){w=[],f=[];let u={step:async($,q)=>{try{let X=await E.run(async({step:ee})=>ee("saga-step",$));if(!X.ok)throw await M(),{__earlyExit:!0,error:X.error};return q?.compensate&&f.push({value:X.value,compensate:q.compensate}),X.value}catch(X){throw f.length>0&&await M(),X}}};async function M(){let $=[...f].reverse();f=[];for(let{name:q,value:X,compensate:ee}of $)try{await ee(X),w.push({stepName:q,order:w.length,value:X,timestamp:s()})}catch(b){console.error(`Compensation failed for step "${q}":`,b)}}try{let $=await j({saga:u,deps:e});return V($)}catch($){return we($)?F($.error):(await M(),F({type:"UNEXPECTED_ERROR",cause:$}))}}function y(){return[...w]}function O(j){let u=w.map($=>$.stepName),M=JSON.stringify(u)===JSON.stringify(j);return{passed:M,message:M?`Compensations ran in order: ${j.join(" \u2192 ")}`:`Expected compensations [${j.join(" \u2192 ")}] but got [${u.join(" \u2192 ")}]`,expected:j,actual:u}}function c(j){let u=w.some(M=>M.stepName===j);return{passed:u,message:u?`Step "${j}" was compensated`:`Step "${j}" was NOT compensated`,expected:j,actual:u}}function K(j){let u=w.some(M=>M.stepName===j);return{passed:!u,message:u?`Step "${j}" was compensated but should not have been`:`Step "${j}" was correctly NOT compensated`,expected:"not compensated",actual:u?"compensated":"not compensated"}}let P=E.reset;function J(){P(),w=[],f=[]}return{...E,reset:J,getCompensations:y,assertCompensationOrder:O,assertCompensated:c,assertNotCompensated:K,runSaga:R}}function ze(e,a,s={}){let{strict:E=!0}=s,w=a.map(O=>{let[c,K]=O.split(":");return{type:c,name:K}}),R=(E?e:e.filter(O=>w.some(c=>O.type===c.type))).map(O=>{let c="name"in O?O.name:void 0,K="stepKey"in O?O.stepKey:void 0,P=c??K;return P?`${O.type}:${P}`:O.type}),y=JSON.stringify(R)===JSON.stringify(a);return{passed:y,message:y?`Event sequence matches: ${a.join(" \u2192 ")}`:`Event sequence mismatch.
7
- Expected: ${a.join(" \u2192 ")}
8
- Actual: ${R.join(" \u2192 ")}`,expected:a,actual:R}}function Se(e,a){let s=e.find(E=>Object.entries(a).every(([w,f])=>{let R=E[w];return typeof f=="object"&&f!==null?JSON.stringify(R)===JSON.stringify(f):R===f}));return{passed:!!s,message:s?`Event matching ${JSON.stringify(a)} was emitted`:`No event matching ${JSON.stringify(a)} was found`,expected:a,actual:s??"not found"}}function Qe(e,a){let s=Se(e,a);return{passed:!s.passed,message:s.passed?`Event matching ${JSON.stringify(a)} was found but should not have been`:`Correctly, no event matching ${JSON.stringify(a)} was emitted`,expected:"not emitted",actual:s.actual}}function Ce(e){if(!e.ok)throw new Error(`Expected Ok result, got Err: ${JSON.stringify(e.error,null,2)}`)}function he(e){if(e.ok)throw new Error(`Expected Err result, got Ok: ${JSON.stringify(e.value,null,2)}`)}function be(e){return Ce(e),e.value}function Ae(e){return he(e),e.error}async function Ze(e){return be(await e)}async function et(e){return Ae(await e)}function tt(e){return ke(e)?`Ok(${oe(e.value)})`:`Err(${oe(e.error)})`}function oe(e){if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e=="string")return`'${e}'`;if(typeof e=="number"||typeof e=="boolean")return String(e);if(typeof e=="function")return`[Function: ${e.name||"anonymous"}]`;if(Array.isArray(e))return e.length===0?"[]":e.length<=3?`[${e.map(oe).join(", ")}]`:`[${e.slice(0,3).map(oe).join(", ")}, ... (${e.length} items)]`;if(typeof e=="object"){let a=e,s=Object.keys(a);return s.length===0?"{}":s.length<=4?`{ ${s.map(f=>`${f}: ${oe(a[f])}`).join(", ")} }`:`{ ${s.slice(0,3).map(w=>`${w}: ${oe(a[w])}`).join(", ")}, ... (${s.length} keys) }`}return String(e)}function ve(e){let a=e.type,s="name"in e?e.name:void 0,E="stepKey"in e?e.stepKey:void 0,w=s??E;return w?`${a}:${w}`:a}function nt(e){return e.map(ve).join(" \u2192 ")}export{Se as assertEventEmitted,Qe as assertEventNotEmitted,ze as assertEventSequence,Je as compareSnapshots,Be as createMockFn,Ge as createSagaHarness,Ve as createSnapshot,qe as createTestClock,xe as createWorkflowHarness,Xe as errOutcome,he as expectErr,Ce as expectOk,ve as formatEvent,nt as formatEvents,tt as formatResult,He as okOutcome,Ye as throwOutcome,Ae as unwrapErr,et as unwrapErrAsync,be as unwrapOk,Ze as unwrapOkAsync};
6
+ See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return z(ue)}catch(c){if(Mt(c))throw c.thrown;if(P(c)){let se=c.meta.origin==="throw"?c.meta.thrown:c.meta.origin==="result"?c.meta.resultCause:void 0;return U(c.error,{cause:se})}let X=Y(c);return r?.(X,"unexpected",S),U(X,{cause:c})}}je.strict=(e,t)=>je(e,t);async function ct(e){return e.length===0?z([]):new Promise(t=>{let r=!1,f=e.length,p=new Array(e.length);for(let y=0;y<e.length;y++){let A=y;Promise.resolve(e[A]).catch(S=>U({type:"PROMISE_REJECTED",cause:S},{cause:{type:"PROMISE_REJECTION",reason:S}})).then(S=>{if(!r){if(!S.ok){r=!0,t(S);return}p[A]=S.value,f--,f===0&&t(z(p))}})}})}function Et(e){return e.type==="step_complete"}function Je(e){return typeof e=="object"&&e!==null&&e.type==="WORKFLOW_CANCELLED"}var Ke=class extends Error{constructor(r,f,p){super(r);this.stepId=f;this.originalError=p;this.name="SnapshotDecodeError"}};function qe(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=qe(e.cause)),t}return e.value!==void 0?e.value:e.stringRepresentation}function Ut(e){return typeof e=="object"&&e!==null&&e.__cachedMeta===!0}function Ce(e,t,r){return U(e,{cause:{__cachedMeta:!0,originalCause:r,meta:t}})}function Ue(e){return Ut(e)?e.meta:{origin:"result",resultCause:e}}function wt(){let e=new Map;return{handleEvent:t=>{Et(t)&&e.set(t.stepKey,{result:t.result,meta:t.meta})},getResumeState:()=>({steps:new Map(e)}),clear:()=>e.clear()}}var Nt="STREAM_WRITE_ERROR",jt="STREAM_READ_ERROR",Ft="STREAM_CLOSE_ERROR";var Kt="STREAM_ENDED";function $e(e,t,r){return{type:Nt,reason:e,message:t,...r!==void 0?{cause:r}:{}}}function ze(e,t,r){return{type:jt,reason:e,message:t,...r!==void 0?{cause:r}:{}}}function Ye(e,t,r){return{type:Ft,reason:e,message:t,...r!==void 0?{cause:r}:{}}}function Be(e){return{type:Kt,finalPosition:e}}function yt(e={}){let t=e.highWaterMark??16,r=e.lowWaterMark??Math.floor(t/2),f=e.onStateChange,p="flowing",y=0,A=[];function S(i){if(p!==i&&(p=i,f?.(i),i==="flowing"&&A.length>0)){let Y=A;A=[];for(let v of Y)v()}}function K(){p==="flowing"&&y>=t?S("paused"):p==="paused"&&y<=r&&S("flowing")}return{get state(){return p},get bufferedCount(){return y},get highWaterMark(){return t},get lowWaterMark(){return r},increment(){y++,K()},decrement(){y>0&&(y--,K())},setCount(i){y=Math.max(0,i),K()},waitForDrain(){return p==="flowing"?Promise.resolve():new Promise(i=>{A.push(i)})},reset(){y=0,A=[],S("flowing")}}}function $t(e){return{_tag:"Duration",millis:e}}function Bt(e){return{_tag:"Duration",millis:e*1e3}}function Vt(e){return{_tag:"Duration",millis:e*60*1e3}}function Lt(e){return{_tag:"Duration",millis:e*60*60*1e3}}function Ht(e){return{_tag:"Duration",millis:e*24*60*60*1e3}}function kt(e){return e.millis}function gt(e){let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let r=parseFloat(t[1]);switch(t[2].toLowerCase()){case"ms":return $t(r);case"s":return Bt(r);case"m":return Vt(r);case"h":return Lt(r);case"d":return Ht(r);default:return}}async function Tt(e,t){let r=e["~standard"].validate(t),f=r instanceof Promise?await r:r;return f.issues?U({type:"INPUT_VALIDATION_ERROR",issues:f.issues.map(p=>({message:p.message,path:p.path?.map(y=>typeof y=="object"?y.key:y)})),message:`Input validation failed: ${f.issues.map(p=>p.message).join(", ")}`}):z(f.value)}function Ge(e,t,r){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 f=t??{},p=r;async function y(i,Y,v){let x=i??crypto.randomUUID(),G=v?.deps?{...f,...v.deps}:f,d=v?.createContext??p?.createContext,$=d?await d():void 0,P=v?.signal??p?.signal,ce=v?.onEvent??p?.onEvent,Ee=v?.onError??p?.onError,ke=v?.shouldRun??p?.shouldRun,B=v?.onBeforeStart??p?.onBeforeStart,q=v?.onAfterStep??p?.onAfterStep,c=v?.resumeState??p?.resumeState,X=p?.catchUnexpected??Fe,se={},we=(v?.devWarnings??p?.devWarnings)===!0&&process.env.NODE_ENV!=="production",ie=new Set,ue=new Set,l={workflowId:x,onEvent:ce,context:$!==void 0?$:void 0,signal:P,input:{},ref:w=>se[w],set:(w,a)=>{we&&!ie.has(w)&&(ie.add(w),console.warn(`awaitly: ctx.set('${w}', ...) is deprecated for static analysis. Use step('id', fn, { out: '${w}' }) instead.`)),se[w]=a},get:w=>(we&&!ue.has(w)&&(ue.add(w),console.warn(`awaitly: ctx.get('${w}') is deprecated for static analysis. Use ctx.ref('${w}') instead for tracked dependencies.`)),se[w])},u=w=>{let a=w.context!==void 0||$===void 0?w:{...w,context:$},Q=a.workflowName===void 0?{...a,workflowName:e}:a;ce?.(Q,$)},o=(w,a)=>{let Q={type:"WORKFLOW_CANCELLED",reason:w,lastStepKey:a};return U(X(Q),{cause:Q})};if(P?.aborted){let w=typeof P.reason=="string"?P.reason:P.reason instanceof Error?P.reason.message:void 0;return u({type:"workflow_cancelled",workflowId:x,ts:Date.now(),durationMs:0,reason:w}),o(w)}if(ke){let w=performance.now();try{let a=await ke(x,$),Q=performance.now()-w;if(u({type:"hook_should_run",workflowId:x,ts:Date.now(),durationMs:Q,result:a,skipped:!a}),!a){let R=new Error("Workflow skipped by shouldRun hook");return U(X(R),{cause:R})}}catch(a){let Q=performance.now()-w;return u({type:"hook_should_run_error",workflowId:x,ts:Date.now(),durationMs:Q,error:a}),U(X(a),{cause:a})}}if(B){let w=performance.now();try{let a=await B(x,$),Q=performance.now()-w;if(u({type:"hook_before_start",workflowId:x,ts:Date.now(),durationMs:Q,result:a,skipped:!a}),!a){let R=new Error("Workflow skipped by onBeforeStart hook");return U(X(R),{cause:R})}}catch(a){let Q=performance.now()-w;return u({type:"hook_before_start_error",workflowId:x,ts:Date.now(),durationMs:Q,error:a}),U(X(a),{cause:a})}}let s=p?.inputSchema,n=p?.input;if(s&&n!==void 0){let w=await Tt(s,n);if(!w.ok)return U(w.error);l.input=w.value}else n!==void 0&&(l.input=n);let k=Date.now(),T=performance.now();u({type:"workflow_start",workflowId:x,ts:k});let m=v?.cache??p?.cache,O=v?.streamStore??p?.streamStore;if(c&&!m&&(m=new Map),c&&m){let w=typeof c=="function"?await c():c;w.steps instanceof Map||(console.warn(`awaitly: resumeState.steps is not a Map (got ${typeof w.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 w.steps=="object"&&w.steps!==null&&(w.steps=new Map(Object.entries(w.steps))));for(let[a,Q]of w.steps){let{result:R,meta:E}=Q;if(R.ok)m.set(a,R);else{let C=E??{origin:"result",resultCause:R.cause};m.set(a,Ce(R.error,C,R.cause))}}}let D=v?.snapshot??p?.snapshot,N=p?.serialization;if(D&&!c){m||(m=new Map);let w=D,a=N?.decode;for(let[Q,R]of Object.entries(w.steps))if(Object.prototype.hasOwnProperty.call(w.steps,Q))try{if(R.ok){let E=a?a(R.value):R.value;m.set(Q,z(E))}else{let E=a?a(R.error):R.error,C=qe(R.cause),b=R.meta?.origin==="throw"?{origin:"throw",thrown:C}:{origin:"result",resultCause:C};m.set(Q,Ce(E,b,C))}}catch(E){throw new Ke(`Failed to decode step "${Q}": ${E instanceof Error?E.message:String(E)}`,Q,E instanceof Error?E:void 0)}}let J=!1,ee,M,re=()=>{J=!0,ee=typeof P?.reason=="string"?P.reason:P?.reason instanceof Error?P.reason.message:void 0};P&&!P.aborted&&P.addEventListener("abort",re,{once:!0});let F=()=>{if(J||P?.aborted)throw{type:"WORKFLOW_CANCELLED",reason:ee??(typeof P?.reason=="string"?P.reason:P?.reason instanceof Error?P.reason.message:void 0),lastStepKey:M}},W=async(w,a,Q)=>{if(!q)return;let R=performance.now();try{await q(w,a,x,$);let E=performance.now()-R;u({type:"hook_after_step",workflowId:x,stepKey:w,ts:Date.now(),durationMs:E})}catch(E){let C=performance.now()-R;throw u({type:"hook_after_step_error",workflowId:x,stepKey:w,ts:Date.now(),durationMs:C,error:E}),E}},V=w=>{let a=async(E,C,b)=>{if(typeof E!="string")throw new Error('[awaitly] step() requires a string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let h=E,_=b??{},j=h,g=Object.prototype.hasOwnProperty.call(_,"key")?_.key:h,{ttl:L,out:ne}=_;F();let te=He(_);if(g&&m&&m.has(g)){u({type:"step_cache_hit",workflowId:x,stepKey:g,name:j,ts:Date.now(),...te&&{metadata:te}});let I=m.get(g);if(I.ok)return M=g,ne&&(se[ne]=I.value),I.value;let H=Ue(I.cause);throw _e(I.error,H)}g&&m&&u({type:"step_cache_miss",workflowId:x,stepKey:g,name:j,ts:Date.now(),...te&&{metadata:te}});try{let I=await w(h,C,_);return ne&&(se[ne]=I),g&&(M=g,m&&m.set(g,z(I),L?{ttl:L}:void 0),await W(g,z(I))),I}catch(I){if(g&&be(I)){let H=I,pe=H.meta.origin==="result"?H.meta.resultCause:H.meta.origin==="throw"?H.meta.thrown:void 0,Z=Ce(H.error,H.meta,pe);m&&m.set(g,Z,L?{ttl:L}:void 0),await W(g,Z,H.meta)}throw I}};a.try=async(E,C,b)=>{let{ttl:h}=b,_=b.key??E,j=E;if(m&&m.has(_)){u({type:"step_cache_hit",workflowId:x,stepKey:_,name:j,ts:Date.now()});let g=m.get(_);if(g.ok)return g.value;let L=Ue(g.cause);throw _e(g.error,L)}m&&u({type:"step_cache_miss",workflowId:x,stepKey:_,name:j,ts:Date.now()});try{let g=await w.try(E,C,{...b,key:_});return m&&m.set(_,z(g),h?{ttl:h}:void 0),await W(_,z(g)),g}catch(g){if(be(g)){let L=g,ne=L.meta.origin==="result"?L.meta.resultCause:L.meta.origin==="throw"?L.meta.thrown:void 0,te=Ce(L.error,L.meta,ne);m&&m.set(_,te,h?{ttl:h}:void 0),await W(_,te,L.meta)}throw g}},a.fromResult=async(E,C,b)=>{let{ttl:h}=b,_=b.key??E,j=E;if(m&&m.has(_)){u({type:"step_cache_hit",workflowId:x,stepKey:_,name:j,ts:Date.now()});let g=m.get(_);if(g.ok)return g.value;let L=Ue(g.cause);throw _e(g.error,L)}m&&u({type:"step_cache_miss",workflowId:x,stepKey:_,name:j,ts:Date.now()});try{let g=await w.fromResult(E,C,{...b,key:_});return m&&m.set(_,z(g),h?{ttl:h}:void 0),await W(_,z(g)),g}catch(g){if(be(g)){let L=g,ne=L.meta.origin==="result"?L.meta.resultCause:L.meta.origin==="throw"?L.meta.thrown:void 0,te=Ce(L.error,L.meta,ne);m&&m.set(_,te,h?{ttl:h}:void 0),await W(_,te,L.meta)}throw g}},a.parallel=w.parallel,a.race=w.race,a.allSettled=w.allSettled,a.withFallback=async(E,C,b)=>{let h=b.key??E,_=E;if(m&&m.has(h)){u({type:"step_cache_hit",workflowId:x,stepKey:h,name:_,ts:Date.now()});let j=m.get(h);if(j.ok)return j.value;let g=Ue(j.cause);throw _e(j.error,g)}m&&u({type:"step_cache_miss",workflowId:x,stepKey:h,name:_,ts:Date.now()});try{let j=await w.withFallback(E,C,b);return m&&m.set(h,z(j)),await W(h,z(j)),j}catch(j){if(be(j)){let g=j,L=g.meta.origin==="result"?g.meta.resultCause:g.meta.origin==="throw"?g.meta.thrown:void 0,ne=Ce(g.error,g.meta,L);m&&m.set(h,ne),await W(h,ne,g.meta)}throw j}},a.withResource=async(E,C)=>{let b=E;try{let h=await w.withResource(E,C);return await W(b,z(h)),h}catch(h){if(be(h)){let _=h,j=_.meta.origin==="result"?_.meta.resultCause:_.meta.origin==="throw"?_.meta.thrown:void 0,g=Ce(_.error,_.meta,j);await W(b,g,_.meta)}throw h}},a.retry=(E,C,b)=>{let h={key:b.key,retry:{attempts:b.attempts,backoff:b.backoff,initialDelay:b.initialDelay,maxDelay:b.maxDelay,jitter:b.jitter,retryOn:b.retryOn,onRetry:b.onRetry},timeout:b.timeout,ttl:b.ttl};return a(E,C,h)},a.withTimeout=(E,C,b)=>{let h={key:b.key,timeout:b,ttl:b.ttl};return a(E,C,h)},a.sleep=(E,C,b)=>{if(typeof E!="string"||E.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let h=typeof C=="string"?gt(C):C;if(!h)throw new Error(`step.sleep: invalid duration '${C}'`);let _=kt(h),j=b?.signal;return a(E,async()=>{if(P?.aborted||j?.aborted){let L=new Error("Sleep aborted");throw L.name="AbortError",L}return new Promise((L,ne)=>{let te={timeoutId:void 0},I=()=>{te.timeoutId&&clearTimeout(te.timeoutId);let H=new Error("Sleep aborted");H.name="AbortError",ne(H)};P?.addEventListener("abort",I,{once:!0}),j?.addEventListener("abort",I,{once:!0}),te.timeoutId=setTimeout(()=>{P?.removeEventListener("abort",I),j?.removeEventListener("abort",I),L(z(void 0))},_)})},{key:b?.key,ttl:b?.ttl,description:b?.description})};let Q=new Map,R=new Map;return a.getWritable=E=>{let C=E?.namespace??"default",b=E?.highWaterMark??16;if(!O)throw new Error("streamStore is required to use getWritable(). Pass a streamStore to createWorkflow options.");let h=`${x}:${C}`,_=Q.get(h);if(_&&!_.closed&&!_.aborted)return _.writer;let j=yt({highWaterMark:b,onStateChange:H=>{u({type:"stream_backpressure",workflowId:x,namespace:C,bufferedCount:j.bufferedCount,state:H,ts:Date.now()})}}),g=0,L=!0,ne=!1,te=!1;u({type:"stream_created",workflowId:x,namespace:C,ts:Date.now()});let I={async write(H){if(te)return U($e("closed","Stream is closed"));if(ne)return U($e("aborted","Stream was aborted"));j.state==="paused"&&await j.waitForDrain();let pe={value:H,position:g,ts:Date.now()},Z=await O.append(x,C,pe);return Z.ok?(u({type:"stream_write",workflowId:x,namespace:C,position:g,ts:Date.now()}),g++,j.increment(),z(void 0)):(u({type:"stream_error",workflowId:x,namespace:C,error:Z.error,position:g,ts:Date.now()}),U($e("store_error",Z.error.message,Z.error)))},async close(){if(te)return U(Ye("already_closed","Stream is already closed"));let H=await O.closeStream(x,C);return H.ok?(te=!0,L=!1,u({type:"stream_close",workflowId:x,namespace:C,finalPosition:g,ts:Date.now()}),Q.delete(h),z(void 0)):U(Ye("store_error",H.error.message,H.error))},abort(H){ne=!0,L=!1,te=!0,u({type:"stream_error",workflowId:x,namespace:C,error:H,position:g,ts:Date.now()}),Q.delete(h)},get writable(){return L},get position(){return g},get namespace(){return C}};return Q.set(h,{writer:I,backpressure:j,aborted:ne,closed:te}),I},a.getReadable=E=>{let C=E?.namespace??"default",b=E?.startIndex??0,h=E?.pollInterval??10,_=E?.pollTimeout??3e4;if(!O)throw new Error("streamStore is required to use getReadable(). Pass a streamStore to createWorkflow options.");let j=`${x}:${C}:${b}`,g=R.get(j);if(g&&!g.closed)return g.reader;let L=()=>{let Re=`${x}:${C}`,ae=Q.get(Re);ae&&ae.backpressure.decrement()},ne=b,te=!0,I=!1,H=[],pe=0,Z={async read(){if(I)return U(ze("closed","Reader is closed"));if(pe<H.length){let fe=H[pe++];return ne=fe.position+1,L(),u({type:"stream_read",workflowId:x,namespace:C,position:fe.position,ts:Date.now()}),z(fe.value)}let Re=`${x}:${C}`,ae=Date.now(),de=Q.has(Re),oe=await O.getMetadata(x,C),me=oe.ok&&oe.value!==void 0;for(;Date.now()-ae<_;){let fe=await O.read(x,C,ne,100);if(!fe.ok)return U(ze("store_error",fe.error.message,fe.error));let De=fe.value;if(De.length>0){H=De,pe=1;let Ie=De[0];return ne=Ie.position+1,L(),u({type:"stream_read",workflowId:x,namespace:C,position:Ie.position,ts:Date.now()}),z(Ie.value)}let Me=Q.has(Re),he=await O.getMetadata(x,C),Qe=he.ok&&he.value!==void 0;if(Me&&(de=!0),Qe&&(me=!0),he.ok&&he.value?.closed)return te=!1,U(Be(ne));if(de&&!Me&&!Qe)return te=!1,U(Be(ne));me&&!Me&&he.ok&&he.value?.closed,await new Promise(Ie=>setTimeout(Ie,h))}return te=!1,U(Be(ne))},close(){I=!0,te=!1,H=[],R.delete(j)},get readable(){return te},get position(){return ne},get namespace(){return C}};return R.set(j,{reader:Z,position:ne,closed:I}),Z},a.streamForEach=async(E,C,b)=>{let h=b?.checkpointInterval??1,_=b?.concurrency??1,j=[],g=0,L=-1,ne=I=>typeof I=="object"&&I!==null&&"read"in I&&typeof I.read=="function",te=async(I,H,pe,Z)=>{let ae=h>0&&H%h===0?`stream-foreach:${Z}:pos-${pe}`:void 0,de=ae??`stream-item-${pe}`,oe=await a(de,()=>C(I,H),{key:ae});return{index:H,position:pe,result:oe}};if(ne(E))if(_<=1){let I=E.position,H=await E.read();for(;H.ok;){let pe=H.value,{result:Z}=await te(pe,g,I,E.namespace);j.push(Z),L=I,g++,I=E.position,H=await E.read()}}else{let I=new Map,H=0,pe=0,Z=new Array(_).fill(null),Re=async()=>{for(let fe=0;fe<Z.length;fe++)if(Z[fe]===null)return fe;let oe=Z.filter(fe=>fe!==null),me=await Promise.race(oe);return I.set(me.index,{position:me.position,result:me.result}),Z[me.slotIndex]=null,me.slotIndex},ae=E.position,de=await E.read();for(;de.ok;){let oe=await Re(),me=H,fe=ae,De=de.value,Me=oe;Z[oe]=te(De,me,fe,E.namespace).then(he=>({slotIndex:Me,...he})),pe++,H++,ae=E.position,de=await E.read()}for(let oe=0;oe<Z.length;oe++)if(Z[oe]!==null){let me=await Z[oe];I.set(me.index,{position:me.position,result:me.result})}for(let oe=0;oe<pe;oe++){let me=I.get(oe);me&&(j.push(me.result),L=me.position,g++)}}else if(_<=1){let I=0;for await(let H of E){let{result:pe}=await te(H,I,I,"async-iterable");j.push(pe),L=I,g++,I++}}else{let I=new Map,H=0,pe=0,Z=new Array(_).fill(null),Re=async()=>{for(let oe=0;oe<Z.length;oe++)if(Z[oe]===null)return oe;let ae=Z.filter(oe=>oe!==null),de=await Promise.race(ae);return I.set(de.index,de.result),Z[de.slotIndex]=null,de.slotIndex};for await(let ae of E){let de=await Re(),oe=H,me=de;Z[de]=te(ae,oe,oe,"async-iterable").then(fe=>({slotIndex:me,...fe})),pe++,H++}for(let ae=0;ae<Z.length;ae++)if(Z[ae]!==null){let de=await Z[ae];I.set(de.index,de.result)}for(let ae=0;ae<pe;ae++)I.has(ae)&&(j.push(I.get(ae)),L=ae,g++)}return{results:j,processedCount:g,lastPosition:L}},a.if=w.if,a.label=w.label,a.branch=w.branch,a.arm=w.arm,a.forEach=w.forEach,a.item=w.item,a.dep=w.dep,a.run=(E,C,b)=>a(E,typeof C=="function"?C:()=>C,b),a.workflow=(E,C,b)=>a(E,C,b),a.andThen=(E,C,b,h)=>a(E,()=>b(C),h),a.match=(E,C,b,h)=>a(E,async()=>{let _=await C;return _.ok?z(await b.ok(_.value)):z(await b.err(_.error,_.cause))},h),a.all=(E,C,b)=>{let h=b!==void 0&&Object.prototype.hasOwnProperty.call(b,"key")?b:{...b,key:void 0};return a(E,async()=>z(await w.all(E,C)),h)},a.map=(E,C,b,h)=>{let _=h!==void 0&&Object.prototype.hasOwnProperty.call(h,"key")?h:{...h,key:void 0};return a(E,async()=>z(await w.map(E,C,b,h)),_)},a},Te=({step:w})=>Y({step:V(w),deps:G,ctx:l}),le;try{le=await je(Te,{onError:Ee,onEvent:ce,catchUnexpected:X,workflowId:x,workflowName:e,context:$,_workflowSignal:P})}finally{P&&P.removeEventListener("abort",re)}let xe=performance.now()-T;if(!le.ok){let w;if(Je(le.cause)&&(w=le.cause),!w&&J&&mt(le.error)){let a=le.cause;a!=null&&typeof a=="object"&&"name"in a&&a.name==="AbortError"&&(w={type:"WORKFLOW_CANCELLED",reason:ee??(typeof P?.reason=="string"?P.reason:P?.reason instanceof Error?P.reason.message:void 0),lastStepKey:M})}if(w)return u({type:"workflow_cancelled",workflowId:x,ts:Date.now(),durationMs:xe,reason:w.reason,lastStepKey:w.lastStepKey}),w&&!Je(le.cause)?U(le.error,{cause:w}):le}if(le.ok&&J){let w=ee??(typeof P?.reason=="string"?P.reason:P?.reason instanceof Error?P.reason.message:void 0);u({type:"workflow_cancelled",workflowId:x,ts:Date.now(),durationMs:xe,reason:w,lastStepKey:M});let a={type:"WORKFLOW_CANCELLED",reason:w,lastStepKey:M};return U(X(a),{cause:a})}return le.ok?u({type:"workflow_success",workflowId:x,ts:Date.now(),durationMs:xe}):u({type:"workflow_error",workflowId:x,ts:Date.now(),durationMs:xe,error:le.error}),le}function A(i,Y,v){let x,G,d;return typeof i=="string"?(x=i,G=Y,d=v):(G=i,d=Y),y(x,G,d)}async function S(i,Y,v){let x,G,d;typeof i=="string"?(x=i,G=Y,d=v):(G=i,d=Y);let $=wt(),P=d?.onEvent,Ee={...d,onEvent:(q,c)=>{$.handleEvent(q);try{P?.(q,c)}catch{}}},ke,B;try{ke=await y(x,G,Ee)}catch(q){let c=p?.catchUnexpected??Fe;ke=U(c(q),{cause:q})}finally{B=$.getResumeState()}return{result:ke,resumeState:B}}return{run:A,runWithState:S}}async function Rt(e,t,r){let f=[],p={},y=[],A=v=>{if(f.push(v),v.type==="step_complete"&&v.stepKey){let x={output:v.result.ok?v.result.value:void 0,durationMs:v.durationMs,result:v.result};p[v.stepKey]=x,y.push(v.stepKey)}},S=Ge("test-workflow",e),K=performance.now(),i=await S.run(t,{onEvent:A,signal:r?.signal}),Y=performance.now()-K;return{result:i,steps:p,events:f,durationMs:Y,stepOrder:y}}function Xe(e){return typeof e=="object"&&e!==null&&"__earlyExit"in e&&e.__earlyExit===!0}function St(e,t={}){let{recordInvocations:r=!0,clock:f=Date.now}=t,p=[],y=new Map,A=0,S=[];function K(B){p=[...B],A=0,y.clear()}function i(B,q){y.set(B,q)}function Y(B){if(B&&y.has(B))return y.get(B);if(A<p.length)return p[A++]}function v(){let B=async(q,c,X)=>{let se,we,ie;typeof q=="string"?(se=q,we=c,ie=X??{}):(we=q,typeof c=="string"?(se=c,ie={}):(ie=c??{},se=ie.key??"step"));let ue=f(),l={name:se,key:ie.key,order:S.length,timestamp:ue};r&&S.push(l);let u=Y(se);if(u)switch(l.durationMs=f()-ue,u.type){case"ok":return l.result=z(u.value),u.value;case"err":throw l.result=U(u.error),{__earlyExit:!0,error:u.error};case"throw":throw u.error}let o=typeof we=="function"?await we():await we;if(l.durationMs=f()-ue,l.result=o,!o.ok)throw{__earlyExit:!0,error:o.error};return o.value};return B.try=async(q,c,X)=>{let se,we,ie;typeof q=="string"?(se=q,we=c,ie=X):(we=q,ie=c,se=ie.key??"step");let ue=f(),l={name:se,key:"key"in ie?ie.key:void 0,order:S.length,timestamp:ue};r&&S.push(l);let u=Y(se);if(u)switch(l.durationMs=f()-ue,u.type){case"ok":return l.result=z(u.value),u.value;case"err":throw l.result=U(u.error),{__earlyExit:!0,error:u.error};case"throw":throw u.error}try{let o=await we();return l.durationMs=f()-ue,l.result=z(o),o}catch(o){l.durationMs=f()-ue;let s="error"in ie?ie.error:ie.onError(o);throw l.result=U(s),{__earlyExit:!0,error:s}}},B}async function x(B){let q=v();try{let c=await B({step:q,deps:e});return z(c)}catch(c){return Xe(c)?U(c.error):U(new Se({cause:c}))}}async function G(B,q){let c=v();try{let X=await q({step:c,deps:e,input:B});return z(X)}catch(X){return Xe(X)?U(X.error):U(new Se({cause:X}))}}function d(){return[...S]}function $(B){let q=S.map(X=>X.name??X.key??"unnamed").filter(X=>X!=="unnamed"),c=JSON.stringify(q)===JSON.stringify(B);return{passed:c,message:c?`Steps invoked in order: ${B.join(", ")}`:`Expected steps [${B.join(", ")}] but got [${q.join(", ")}]`,expected:B,actual:q}}function P(B){let q=S.some(c=>c.name===B||c.key===B);return{passed:q,message:q?`Step "${B}" was invoked`:`Step "${B}" was NOT invoked`,expected:B,actual:q}}function ce(B){let q=S.some(c=>c.name===B||c.key===B);return{passed:!q,message:q?`Step "${B}" was invoked but should not have been`:`Step "${B}" was correctly NOT invoked`,expected:"not called",actual:q?"called":"not called"}}function Ee(B,q){let c=B.ok===q.ok&&(B.ok?JSON.stringify(B.value)===JSON.stringify(q.value):JSON.stringify(B.error)===JSON.stringify(q.error));return{passed:c,message:c?"Result matches expected":"Result does not match expected",expected:q,actual:B}}function ke(){p=[],y.clear(),A=0,S=[]}return{script:K,scriptStep:i,run:x,runWithInput:G,getInvocations:d,assertSteps:$,assertStepCalled:P,assertStepNotCalled:ce,assertResult:Ee,reset:ke}}function Jt(){let e,t=[],r=[],f=((...p)=>{if(r.push(p),t.length>0)return Promise.resolve(t.shift());if(e)return Promise.resolve(e);throw new Error("Mock function called without configured return value")});return f.returns=p=>(e=p,f),f.returnsOnce=p=>(t.push(p),f),f.getCalls=()=>[...r],f.getCallCount=()=>r.length,f.reset=()=>{e=void 0,t.length=0,r.length=0},f}function qt(e,t,r){let f=e.reduce((p,y)=>p+(y.durationMs??0),0);return{invocations:e.map(p=>({...p,timestamp:0})),result:t,events:r?.map(p=>({...p,ts:0})),durationMs:f}}function zt(e,t){let r=[];e.invocations.length!==t.invocations.length&&r.push(`Invocation count: ${e.invocations.length} vs ${t.invocations.length}`);let f=Math.max(e.invocations.length,t.invocations.length);for(let p=0;p<f;p++){let y=e.invocations[p],A=t.invocations[p];if(!y){r.push(`Step ${p}: missing in first snapshot`);continue}if(!A){r.push(`Step ${p}: missing in second snapshot`);continue}y.name!==A.name&&r.push(`Step ${p} name: "${y.name}" vs "${A.name}"`),y.key!==A.key&&r.push(`Step ${p} key: "${y.key}" vs "${A.key}"`),y.result?.ok!==A.result?.ok&&r.push(`Step ${p} result: ${y.result?.ok?"ok":"err"} vs ${A.result?.ok?"ok":"err"}`)}return e.result.ok!==t.result.ok&&r.push(`Final result: ${e.result.ok?"ok":"err"} vs ${t.result.ok?"ok":"err"}`),{equal:r.length===0,differences:r}}function Yt(e=0){let t=e;return{now:()=>t,advance:r=>{t+=r},set:r=>{t=r},reset:()=>{t=e}}}function Gt(e){return{type:"ok",value:e}}function Xt(e){return{type:"err",error:e}}function Qt(e){return{type:"throw",error:e}}function Zt(e,t={}){let{clock:r=Date.now}=t,f=St(e,t),p=[],y=[];async function A(G){p=[],y=[];let d={step:async(P,ce)=>{try{let Ee=await f.run(async({step:ke})=>ke("saga-step",P));if(!Ee.ok)throw await $(),{__earlyExit:!0,error:Ee.error};return ce?.compensate&&y.push({value:Ee.value,compensate:ce.compensate}),Ee.value}catch(Ee){throw y.length>0&&await $(),Ee}}};async function $(){let P=[...y].reverse();y=[];for(let{name:ce,value:Ee,compensate:ke}of P)try{await ke(Ee),p.push({stepName:ce,order:p.length,value:Ee,timestamp:r()})}catch(B){console.error(`Compensation failed for step "${ce}":`,B)}}try{let P=await G({saga:d,deps:e});return z(P)}catch(P){return Xe(P)?U(P.error):(await $(),U(new Se({cause:P})))}}function S(){return[...p]}function K(G){let d=p.map(P=>P.stepName),$=JSON.stringify(d)===JSON.stringify(G);return{passed:$,message:$?`Compensations ran in order: ${G.join(" \u2192 ")}`:`Expected compensations [${G.join(" \u2192 ")}] but got [${d.join(" \u2192 ")}]`,expected:G,actual:d}}function i(G){let d=p.some($=>$.stepName===G);return{passed:d,message:d?`Step "${G}" was compensated`:`Step "${G}" was NOT compensated`,expected:G,actual:d}}function Y(G){let d=p.some($=>$.stepName===G);return{passed:!d,message:d?`Step "${G}" was compensated but should not have been`:`Step "${G}" was correctly NOT compensated`,expected:"not compensated",actual:d?"compensated":"not compensated"}}let v=f.reset;function x(){v(),p=[],y=[]}return{...f,reset:x,getCompensations:S,assertCompensationOrder:K,assertCompensated:i,assertNotCompensated:Y,runSaga:A}}function er(e,t,r={}){let{strict:f=!0}=r,p=t.map(K=>{let[i,Y]=K.split(":");return{type:i,name:Y}}),A=(f?e:e.filter(K=>p.some(i=>K.type===i.type))).map(K=>{let i="name"in K?K.name:void 0,Y="stepKey"in K?K.stepKey:void 0,v=i??Y;return v?`${K.type}:${v}`:K.type}),S=JSON.stringify(A)===JSON.stringify(t);return{passed:S,message:S?`Event sequence matches: ${t.join(" \u2192 ")}`:`Event sequence mismatch.
11
+ Expected: ${t.join(" \u2192 ")}
12
+ Actual: ${A.join(" \u2192 ")}`,expected:t,actual:A}}function xt(e,t){let r=e.find(f=>Object.entries(t).every(([p,y])=>{let A=f[p];return typeof y=="object"&&y!==null?JSON.stringify(A)===JSON.stringify(y):A===y}));return{passed:!!r,message:r?`Event matching ${JSON.stringify(t)} was emitted`:`No event matching ${JSON.stringify(t)} was found`,expected:t,actual:r??"not found"}}function tr(e,t){let r=xt(e,t);return{passed:!r.passed,message:r.passed?`Event matching ${JSON.stringify(t)} was found but should not have been`:`Correctly, no event matching ${JSON.stringify(t)} was emitted`,expected:"not emitted",actual:r.actual}}function ht(e){if(!e.ok)throw new Error(`Expected Ok result, got Err: ${JSON.stringify(e.error,null,2)}`)}function Ct(e){if(e.ok)throw new Error(`Expected Err result, got Ok: ${JSON.stringify(e.value,null,2)}`)}function bt(e){return ht(e),e.value}function vt(e){return Ct(e),e.error}async function rr(e){return bt(await e)}async function nr(e){return vt(await e)}function or(e){return pt(e)?`Ok(${Pe(e.value)})`:`Err(${Pe(e.error)})`}function Pe(e){if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e=="string")return`'${e}'`;if(typeof e=="number"||typeof e=="boolean")return String(e);if(typeof e=="function")return`[Function: ${e.name||"anonymous"}]`;if(Array.isArray(e))return e.length===0?"[]":e.length<=3?`[${e.map(Pe).join(", ")}]`:`[${e.slice(0,3).map(Pe).join(", ")}, ... (${e.length} items)]`;if(typeof e=="object"){let t=e,r=Object.keys(t);return r.length===0?"{}":r.length<=4?`{ ${r.map(y=>`${y}: ${Pe(t[y])}`).join(", ")} }`:`{ ${r.slice(0,3).map(p=>`${p}: ${Pe(t[p])}`).join(", ")}, ... (${r.length} keys) }`}return String(e)}function At(e){let t=e.type,r="name"in e?e.name:void 0,f="stepKey"in e?e.stepKey:void 0,p=r??f;return p?`${t}:${p}`:t}function sr(e){return e.map(At).join(" \u2192 ")}export{xt as assertEventEmitted,tr as assertEventNotEmitted,er as assertEventSequence,zt as compareSnapshots,Jt as createMockFn,Zt as createSagaHarness,qt as createSnapshot,Yt as createTestClock,St as createWorkflowHarness,Xt as errOutcome,Ct as expectErr,ht as expectOk,At as formatEvent,sr as formatEvents,or as formatResult,Gt as okOutcome,Rt as testWorkflow,Qt as throwOutcome,vt as unwrapErr,nr as unwrapErrAsync,bt as unwrapOk,rr as unwrapOkAsync};
9
13
  //# sourceMappingURL=testing.js.map