awaitly 1.35.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
  2. package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
  3. package/dist/errors-DtXvrCiO.d.cts +708 -0
  4. package/dist/errors-DtXvrCiO.d.ts +708 -0
  5. package/dist/index.cjs +4594 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +1970 -141
  8. package/dist/index.d.ts +1970 -141
  9. package/dist/index.js +4398 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/result.cjs +641 -1
  12. package/dist/result.cjs.map +1 -1
  13. package/dist/result.d.cts +29 -4
  14. package/dist/result.d.ts +29 -4
  15. package/dist/result.js +561 -1
  16. package/dist/result.js.map +1 -1
  17. package/dist/testing.cjs +4202 -8
  18. package/dist/testing.cjs.map +1 -1
  19. package/dist/testing.d.cts +2 -6
  20. package/dist/testing.d.ts +2 -6
  21. package/dist/testing.js +4154 -8
  22. package/dist/testing.js.map +1 -1
  23. package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
  24. package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
  25. package/dist/workflow.cjs +7096 -6
  26. package/dist/workflow.cjs.map +1 -1
  27. package/dist/workflow.d.cts +3346 -22
  28. package/dist/workflow.d.ts +3346 -22
  29. package/dist/workflow.js +6929 -6
  30. package/dist/workflow.js.map +1 -1
  31. package/package.json +3 -168
  32. package/dist/adapters.cjs +0 -7
  33. package/dist/adapters.cjs.map +0 -1
  34. package/dist/adapters.d.cts +0 -179
  35. package/dist/adapters.d.ts +0 -179
  36. package/dist/adapters.js +0 -7
  37. package/dist/adapters.js.map +0 -1
  38. package/dist/batch.cjs +0 -7
  39. package/dist/batch.cjs.map +0 -1
  40. package/dist/batch.d.cts +0 -200
  41. package/dist/batch.d.ts +0 -200
  42. package/dist/batch.js +0 -7
  43. package/dist/batch.js.map +0 -1
  44. package/dist/bind-deps.cjs +0 -2
  45. package/dist/bind-deps.cjs.map +0 -1
  46. package/dist/bind-deps.d.cts +0 -28
  47. package/dist/bind-deps.d.ts +0 -28
  48. package/dist/bind-deps.js +0 -2
  49. package/dist/bind-deps.js.map +0 -1
  50. package/dist/cache.cjs +0 -2
  51. package/dist/cache.cjs.map +0 -1
  52. package/dist/cache.d.cts +0 -269
  53. package/dist/cache.d.ts +0 -269
  54. package/dist/cache.js +0 -2
  55. package/dist/cache.js.map +0 -1
  56. package/dist/circuit-breaker.cjs +0 -7
  57. package/dist/circuit-breaker.cjs.map +0 -1
  58. package/dist/circuit-breaker.d.cts +0 -211
  59. package/dist/circuit-breaker.d.ts +0 -211
  60. package/dist/circuit-breaker.js +0 -7
  61. package/dist/circuit-breaker.js.map +0 -1
  62. package/dist/conditional.cjs +0 -2
  63. package/dist/conditional.cjs.map +0 -1
  64. package/dist/conditional.d.cts +0 -252
  65. package/dist/conditional.d.ts +0 -252
  66. package/dist/conditional.js +0 -2
  67. package/dist/conditional.js.map +0 -1
  68. package/dist/core.cjs +0 -7
  69. package/dist/core.cjs.map +0 -1
  70. package/dist/core.d.cts +0 -5
  71. package/dist/core.d.ts +0 -5
  72. package/dist/core.js +0 -7
  73. package/dist/core.js.map +0 -1
  74. package/dist/di-By77n4Fa.d.ts +0 -15
  75. package/dist/di-OJfsohf-.d.cts +0 -15
  76. package/dist/diagnostics.cjs +0 -8
  77. package/dist/diagnostics.cjs.map +0 -1
  78. package/dist/diagnostics.d.cts +0 -68
  79. package/dist/diagnostics.d.ts +0 -68
  80. package/dist/diagnostics.js +0 -8
  81. package/dist/diagnostics.js.map +0 -1
  82. package/dist/durable.cjs +0 -11
  83. package/dist/durable.cjs.map +0 -1
  84. package/dist/durable.d.cts +0 -9
  85. package/dist/durable.d.ts +0 -9
  86. package/dist/durable.js +0 -11
  87. package/dist/durable.js.map +0 -1
  88. package/dist/duration.cjs +0 -2
  89. package/dist/duration.cjs.map +0 -1
  90. package/dist/duration.js +0 -2
  91. package/dist/duration.js.map +0 -1
  92. package/dist/engine.cjs +0 -11
  93. package/dist/engine.cjs.map +0 -1
  94. package/dist/engine.d.cts +0 -115
  95. package/dist/engine.d.ts +0 -115
  96. package/dist/engine.js +0 -11
  97. package/dist/engine.js.map +0 -1
  98. package/dist/errors.cjs +0 -2
  99. package/dist/errors.cjs.map +0 -1
  100. package/dist/errors.d.cts +0 -361
  101. package/dist/errors.d.ts +0 -361
  102. package/dist/errors.js +0 -2
  103. package/dist/errors.js.map +0 -1
  104. package/dist/fetch.cjs +0 -7
  105. package/dist/fetch.cjs.map +0 -1
  106. package/dist/fetch.d.cts +0 -86
  107. package/dist/fetch.d.ts +0 -86
  108. package/dist/fetch.js +0 -7
  109. package/dist/fetch.js.map +0 -1
  110. package/dist/flow.cjs +0 -7
  111. package/dist/flow.cjs.map +0 -1
  112. package/dist/flow.d.cts +0 -163
  113. package/dist/flow.d.ts +0 -163
  114. package/dist/flow.js +0 -7
  115. package/dist/flow.js.map +0 -1
  116. package/dist/functional.cjs +0 -2
  117. package/dist/functional.cjs.map +0 -1
  118. package/dist/functional.d.cts +0 -444
  119. package/dist/functional.d.ts +0 -444
  120. package/dist/functional.js +0 -2
  121. package/dist/functional.js.map +0 -1
  122. package/dist/guards-4sV7mTqj.d.cts +0 -72
  123. package/dist/guards-BIX05ALH.d.ts +0 -72
  124. package/dist/hitl-DFn4Xa_l.d.cts +0 -468
  125. package/dist/hitl-DU5VpKq7.d.ts +0 -468
  126. package/dist/hitl.cjs +0 -7
  127. package/dist/hitl.cjs.map +0 -1
  128. package/dist/hitl.d.cts +0 -442
  129. package/dist/hitl.d.ts +0 -442
  130. package/dist/hitl.js +0 -7
  131. package/dist/hitl.js.map +0 -1
  132. package/dist/index-CnvBryQB.d.ts +0 -417
  133. package/dist/index-DEZEf8Fs.d.cts +0 -417
  134. package/dist/match-entry-DjI2bLpD.d.cts +0 -209
  135. package/dist/match-entry-DjI2bLpD.d.ts +0 -209
  136. package/dist/match.cjs +0 -2
  137. package/dist/match.cjs.map +0 -1
  138. package/dist/match.d.cts +0 -1
  139. package/dist/match.d.ts +0 -1
  140. package/dist/match.js +0 -2
  141. package/dist/match.js.map +0 -1
  142. package/dist/otel.cjs +0 -2
  143. package/dist/otel.cjs.map +0 -1
  144. package/dist/otel.d.cts +0 -188
  145. package/dist/otel.d.ts +0 -188
  146. package/dist/otel.js +0 -2
  147. package/dist/otel.js.map +0 -1
  148. package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
  149. package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
  150. package/dist/persistence.cjs +0 -2
  151. package/dist/persistence.cjs.map +0 -1
  152. package/dist/persistence.d.cts +0 -7
  153. package/dist/persistence.d.ts +0 -7
  154. package/dist/persistence.js +0 -2
  155. package/dist/persistence.js.map +0 -1
  156. package/dist/policies.cjs +0 -2
  157. package/dist/policies.cjs.map +0 -1
  158. package/dist/policies.d.cts +0 -379
  159. package/dist/policies.d.ts +0 -379
  160. package/dist/policies.js +0 -2
  161. package/dist/policies.js.map +0 -1
  162. package/dist/ratelimit.cjs +0 -7
  163. package/dist/ratelimit.cjs.map +0 -1
  164. package/dist/ratelimit.d.cts +0 -458
  165. package/dist/ratelimit.d.ts +0 -458
  166. package/dist/ratelimit.js +0 -7
  167. package/dist/ratelimit.js.map +0 -1
  168. package/dist/reliability.cjs +0 -11
  169. package/dist/reliability.cjs.map +0 -1
  170. package/dist/reliability.d.cts +0 -11
  171. package/dist/reliability.d.ts +0 -11
  172. package/dist/reliability.js +0 -11
  173. package/dist/reliability.js.map +0 -1
  174. package/dist/resolver.cjs +0 -7
  175. package/dist/resolver.cjs.map +0 -1
  176. package/dist/resolver.d.cts +0 -68
  177. package/dist/resolver.d.ts +0 -68
  178. package/dist/resolver.js +0 -7
  179. package/dist/resolver.js.map +0 -1
  180. package/dist/resource.cjs +0 -7
  181. package/dist/resource.cjs.map +0 -1
  182. package/dist/resource.d.cts +0 -174
  183. package/dist/resource.d.ts +0 -174
  184. package/dist/resource.js +0 -7
  185. package/dist/resource.js.map +0 -1
  186. package/dist/result/retry.cjs +0 -2
  187. package/dist/result/retry.cjs.map +0 -1
  188. package/dist/result/retry.d.cts +0 -70
  189. package/dist/result/retry.d.ts +0 -70
  190. package/dist/result/retry.js +0 -2
  191. package/dist/result/retry.js.map +0 -1
  192. package/dist/retry.cjs +0 -2
  193. package/dist/retry.cjs.map +0 -1
  194. package/dist/retry.d.cts +0 -388
  195. package/dist/retry.d.ts +0 -388
  196. package/dist/retry.js +0 -2
  197. package/dist/retry.js.map +0 -1
  198. package/dist/run.cjs +0 -7
  199. package/dist/run.cjs.map +0 -1
  200. package/dist/run.d.cts +0 -4
  201. package/dist/run.d.ts +0 -4
  202. package/dist/run.js +0 -7
  203. package/dist/run.js.map +0 -1
  204. package/dist/saga.cjs +0 -11
  205. package/dist/saga.cjs.map +0 -1
  206. package/dist/saga.d.cts +0 -164
  207. package/dist/saga.d.ts +0 -164
  208. package/dist/saga.js +0 -11
  209. package/dist/saga.js.map +0 -1
  210. package/dist/singleflight.cjs +0 -2
  211. package/dist/singleflight.cjs.map +0 -1
  212. package/dist/singleflight.d.cts +0 -145
  213. package/dist/singleflight.d.ts +0 -145
  214. package/dist/singleflight.js +0 -2
  215. package/dist/singleflight.js.map +0 -1
  216. package/dist/slugs.cjs +0 -2
  217. package/dist/slugs.cjs.map +0 -1
  218. package/dist/slugs.d.cts +0 -67
  219. package/dist/slugs.d.ts +0 -67
  220. package/dist/slugs.js +0 -2
  221. package/dist/slugs.js.map +0 -1
  222. package/dist/streaming.cjs +0 -9
  223. package/dist/streaming.cjs.map +0 -1
  224. package/dist/streaming.d.cts +0 -596
  225. package/dist/streaming.d.ts +0 -596
  226. package/dist/streaming.js +0 -9
  227. package/dist/streaming.js.map +0 -1
  228. package/dist/tagged-error.cjs +0 -2
  229. package/dist/tagged-error.cjs.map +0 -1
  230. package/dist/tagged-error.d.cts +0 -275
  231. package/dist/tagged-error.d.ts +0 -275
  232. package/dist/tagged-error.js +0 -2
  233. package/dist/tagged-error.js.map +0 -1
  234. package/dist/types-BziYHFkD.d.ts +0 -323
  235. package/dist/types-C5jLEUqY.d.cts +0 -323
  236. package/dist/webhook.cjs +0 -7
  237. package/dist/webhook.cjs.map +0 -1
  238. package/dist/webhook.d.cts +0 -499
  239. package/dist/webhook.d.ts +0 -499
  240. package/dist/webhook.js +0 -7
  241. package/dist/webhook.js.map +0 -1
package/dist/flow.d.cts DELETED
@@ -1,163 +0,0 @@
1
- import { ae as WorkflowEvent, R as Result, c as AsyncResult } from './run-entry-DGs0tySr.cjs';
2
- import { UnexpectedError } from './errors.cjs';
3
- import './tagged-error.cjs';
4
- import './slugs.cjs';
5
-
6
- /**
7
- * awaitly/flow
8
- *
9
- * The closest thing to `Effect.gen(function* () { ... })` that stays in plain
10
- * `async/await`. You pass a deps object up front; every method becomes a
11
- * step automatically — the step ID is the deps-object key. The workflow body
12
- * calls deps directly:
13
- *
14
- * ```typescript
15
- * import { flow } from 'awaitly/flow';
16
- *
17
- * const result = await flow({ getUser, createOrder }, async (d) => {
18
- * const user = await d.getUser(userId); // → step('getUser', () => getUser(userId))
19
- * const order = await d.createOrder(user); // → step('createOrder', () => createOrder(user))
20
- * return order;
21
- * });
22
- * ```
23
- *
24
- * ## Per-call escape hatch (`c`)
25
- *
26
- * The body accepts an optional second argument — the flow context — for the
27
- * two cases the unwrapped form can't express:
28
- *
29
- * ```typescript
30
- * await flow({ getUser, getPosts }, async (d, c) => {
31
- * // Custom step id (overrides the auto-id 'getUser'):
32
- * const u = await c.key('user:1', () => c.raw.getUser('1'));
33
- *
34
- * // Parallel execution with named results:
35
- * const { posts, profile } = await c.all('fetchUserData', {
36
- * posts: () => c.raw.getPosts(u.id),
37
- * profile: () => c.raw.getProfile(u.id),
38
- * });
39
- * });
40
- * ```
41
- *
42
- * `c.raw` is the original deps object (functions still return `Result`); pass
43
- * it to `c.key` / `c.all` so the engine sees a single step boundary.
44
- *
45
- * ## Trade-offs vs. `run()`
46
- *
47
- * - **No per-call retry/timeout/cache.** Those still live in `run()` + the
48
- * `step.*` helpers. Use `run()` directly when you need them.
49
- * - **Loosely typed events.** `onEvent` exposes `WorkflowEvent<unknown>`. Use
50
- * `run()` if you need fully typed event payloads.
51
- *
52
- * ## Gains
53
- *
54
- * - The workflow body reads like ordinary `async/await` code — the step
55
- * boundary is implicit and ids are property names.
56
- * - Errors are inferred from the deps shape; `UnexpectedError` is included
57
- * unless `catchUnexpected` is set.
58
- * - Non-function values on the deps object pass through untouched, so you
59
- * can attach constants or helper objects alongside the dep functions.
60
- */
61
-
62
- type AnyFunction = (...args: any[]) => unknown;
63
- type ErrorOfResult<R> = R extends {
64
- ok: false;
65
- error: infer E;
66
- } ? E : never;
67
- type ErrorOfFn<F> = F extends AnyFunction ? ErrorOfResult<Awaited<ReturnType<F>>> : never;
68
- /** Loose record: function values get stepified, anything else passes through. */
69
- type DepsRecord = Record<string, unknown>;
70
- /**
71
- * The deps object as seen from inside the flow body. Function deps that
72
- * return `AsyncResult<T, E>` (or `Result<T, E>`) become `(...args) =>
73
- * Promise<T>` — the unwrapped success value, with the Err short-circuiting
74
- * the flow. Non-function entries are kept as-is.
75
- */
76
- type Flowed<D extends DepsRecord> = {
77
- [K in keyof D]: D[K] extends (...args: infer Args) => infer R ? R extends Promise<{
78
- ok: true;
79
- value: infer V;
80
- } | {
81
- ok: false;
82
- error: unknown;
83
- }> ? (...args: Args) => Promise<V> : R extends {
84
- ok: true;
85
- value: infer V;
86
- } | {
87
- ok: false;
88
- error: unknown;
89
- } ? (...args: Args) => Promise<V> : D[K] : D[K];
90
- };
91
- /** Union of error types from any function-valued keys on `D`. */
92
- type FlowErrors<D extends DepsRecord> = {
93
- [K in keyof D]: ErrorOfFn<D[K]>;
94
- }[keyof D];
95
- /**
96
- * Per-call escape hatch passed to the flow body as the optional second
97
- * argument. Use these when the implicit auto-step form can't express what
98
- * you need (custom step id, parallel execution).
99
- *
100
- * Inside `key` / `all` callbacks, call deps through `c.raw` (the original
101
- * Result-returning deps) so the engine sees a single step boundary. Calling
102
- * the wrapped form (`d.*`) from within a `key` / `all` callback would
103
- * produce a nested auto-step and is not the intended use.
104
- */
105
- interface FlowContext<D extends DepsRecord> {
106
- /**
107
- * The original deps object — functions still return `Result` / `AsyncResult`.
108
- * Pass calls to these into `c.key` / `c.all`; pass `d.*` for the default
109
- * unwrapped/auto-stepped path.
110
- */
111
- raw: D;
112
- /**
113
- * Run a Result-returning op with a custom step id. The id replaces the
114
- * deps-object key for tracing, caching, and replay — useful when the same
115
- * dep is called multiple times in one flow.
116
- *
117
- * The callback's error type is constrained to `FlowErrors<D>` so it
118
- * composes with the flow's inferred error union.
119
- */
120
- key: <T, E extends FlowErrors<D>>(id: string, fn: () => Result<T, E> | AsyncResult<T, E>) => Promise<T>;
121
- /**
122
- * Execute a set of Result-returning ops in parallel under a single named
123
- * scope (mirrors `step.all`'s object form). Returns the unwrapped values
124
- * keyed by the same names.
125
- */
126
- all: <TOps extends Record<string, () => Result<unknown, FlowErrors<D>> | AsyncResult<unknown, FlowErrors<D>>>>(name: string, operations: TOps) => Promise<{
127
- [K in keyof TOps]: TOps[K] extends () => Result<infer V, FlowErrors<D>> | AsyncResult<infer V, FlowErrors<D>> ? V : never;
128
- }>;
129
- }
130
- /**
131
- * Options for a single `flow()` call.
132
- *
133
- * `onEvent` is typed as `WorkflowEvent<unknown>` deliberately — keeps this
134
- * surface small. If you need typed event payloads, use `run()`.
135
- */
136
- interface FlowOptions<U = UnexpectedError> {
137
- /**
138
- * Replace `UnexpectedError` with a custom type at the boundary. Any
139
- * exception escaping a dep is mapped through this fn; the flow's error
140
- * type becomes `FlowErrors<deps> | U` instead of
141
- * `FlowErrors<deps> | UnexpectedError`.
142
- */
143
- catchUnexpected?: (cause: unknown) => U;
144
- /**
145
- * Step lifecycle events (start/success/error/aborted). The deps-object key
146
- * is the step id emitted here — handy for tracing.
147
- */
148
- onEvent?: (event: WorkflowEvent<unknown>) => void;
149
- }
150
- /**
151
- * Run a flow over a deps object. Each function dep call becomes a step using
152
- * the property name as the step id; non-function deps pass through.
153
- *
154
- * @param deps - Result-returning functions (plus optional non-fn values) keyed by step id
155
- * @param body - Workflow body; receives the wrapped deps
156
- * @param options - Optional flow-level options
157
- */
158
- declare function flow<D extends DepsRecord, T>(deps: D, body: (d: Flowed<D>, c: FlowContext<D>) => Promise<T> | T): Promise<Result<T, FlowErrors<D> | UnexpectedError>>;
159
- declare function flow<D extends DepsRecord, T, U>(deps: D, body: (d: Flowed<D>, c: FlowContext<D>) => Promise<T> | T, options: FlowOptions<U> & {
160
- catchUnexpected: (cause: unknown) => U;
161
- }): Promise<Result<T, FlowErrors<D> | U>>;
162
-
163
- export { type FlowOptions, type Flowed, flow };
package/dist/flow.d.ts DELETED
@@ -1,163 +0,0 @@
1
- import { ae as WorkflowEvent, R as Result, c as AsyncResult } from './run-entry-BOuNyVoO.js';
2
- import { UnexpectedError } from './errors.js';
3
- import './tagged-error.js';
4
- import './slugs.js';
5
-
6
- /**
7
- * awaitly/flow
8
- *
9
- * The closest thing to `Effect.gen(function* () { ... })` that stays in plain
10
- * `async/await`. You pass a deps object up front; every method becomes a
11
- * step automatically — the step ID is the deps-object key. The workflow body
12
- * calls deps directly:
13
- *
14
- * ```typescript
15
- * import { flow } from 'awaitly/flow';
16
- *
17
- * const result = await flow({ getUser, createOrder }, async (d) => {
18
- * const user = await d.getUser(userId); // → step('getUser', () => getUser(userId))
19
- * const order = await d.createOrder(user); // → step('createOrder', () => createOrder(user))
20
- * return order;
21
- * });
22
- * ```
23
- *
24
- * ## Per-call escape hatch (`c`)
25
- *
26
- * The body accepts an optional second argument — the flow context — for the
27
- * two cases the unwrapped form can't express:
28
- *
29
- * ```typescript
30
- * await flow({ getUser, getPosts }, async (d, c) => {
31
- * // Custom step id (overrides the auto-id 'getUser'):
32
- * const u = await c.key('user:1', () => c.raw.getUser('1'));
33
- *
34
- * // Parallel execution with named results:
35
- * const { posts, profile } = await c.all('fetchUserData', {
36
- * posts: () => c.raw.getPosts(u.id),
37
- * profile: () => c.raw.getProfile(u.id),
38
- * });
39
- * });
40
- * ```
41
- *
42
- * `c.raw` is the original deps object (functions still return `Result`); pass
43
- * it to `c.key` / `c.all` so the engine sees a single step boundary.
44
- *
45
- * ## Trade-offs vs. `run()`
46
- *
47
- * - **No per-call retry/timeout/cache.** Those still live in `run()` + the
48
- * `step.*` helpers. Use `run()` directly when you need them.
49
- * - **Loosely typed events.** `onEvent` exposes `WorkflowEvent<unknown>`. Use
50
- * `run()` if you need fully typed event payloads.
51
- *
52
- * ## Gains
53
- *
54
- * - The workflow body reads like ordinary `async/await` code — the step
55
- * boundary is implicit and ids are property names.
56
- * - Errors are inferred from the deps shape; `UnexpectedError` is included
57
- * unless `catchUnexpected` is set.
58
- * - Non-function values on the deps object pass through untouched, so you
59
- * can attach constants or helper objects alongside the dep functions.
60
- */
61
-
62
- type AnyFunction = (...args: any[]) => unknown;
63
- type ErrorOfResult<R> = R extends {
64
- ok: false;
65
- error: infer E;
66
- } ? E : never;
67
- type ErrorOfFn<F> = F extends AnyFunction ? ErrorOfResult<Awaited<ReturnType<F>>> : never;
68
- /** Loose record: function values get stepified, anything else passes through. */
69
- type DepsRecord = Record<string, unknown>;
70
- /**
71
- * The deps object as seen from inside the flow body. Function deps that
72
- * return `AsyncResult<T, E>` (or `Result<T, E>`) become `(...args) =>
73
- * Promise<T>` — the unwrapped success value, with the Err short-circuiting
74
- * the flow. Non-function entries are kept as-is.
75
- */
76
- type Flowed<D extends DepsRecord> = {
77
- [K in keyof D]: D[K] extends (...args: infer Args) => infer R ? R extends Promise<{
78
- ok: true;
79
- value: infer V;
80
- } | {
81
- ok: false;
82
- error: unknown;
83
- }> ? (...args: Args) => Promise<V> : R extends {
84
- ok: true;
85
- value: infer V;
86
- } | {
87
- ok: false;
88
- error: unknown;
89
- } ? (...args: Args) => Promise<V> : D[K] : D[K];
90
- };
91
- /** Union of error types from any function-valued keys on `D`. */
92
- type FlowErrors<D extends DepsRecord> = {
93
- [K in keyof D]: ErrorOfFn<D[K]>;
94
- }[keyof D];
95
- /**
96
- * Per-call escape hatch passed to the flow body as the optional second
97
- * argument. Use these when the implicit auto-step form can't express what
98
- * you need (custom step id, parallel execution).
99
- *
100
- * Inside `key` / `all` callbacks, call deps through `c.raw` (the original
101
- * Result-returning deps) so the engine sees a single step boundary. Calling
102
- * the wrapped form (`d.*`) from within a `key` / `all` callback would
103
- * produce a nested auto-step and is not the intended use.
104
- */
105
- interface FlowContext<D extends DepsRecord> {
106
- /**
107
- * The original deps object — functions still return `Result` / `AsyncResult`.
108
- * Pass calls to these into `c.key` / `c.all`; pass `d.*` for the default
109
- * unwrapped/auto-stepped path.
110
- */
111
- raw: D;
112
- /**
113
- * Run a Result-returning op with a custom step id. The id replaces the
114
- * deps-object key for tracing, caching, and replay — useful when the same
115
- * dep is called multiple times in one flow.
116
- *
117
- * The callback's error type is constrained to `FlowErrors<D>` so it
118
- * composes with the flow's inferred error union.
119
- */
120
- key: <T, E extends FlowErrors<D>>(id: string, fn: () => Result<T, E> | AsyncResult<T, E>) => Promise<T>;
121
- /**
122
- * Execute a set of Result-returning ops in parallel under a single named
123
- * scope (mirrors `step.all`'s object form). Returns the unwrapped values
124
- * keyed by the same names.
125
- */
126
- all: <TOps extends Record<string, () => Result<unknown, FlowErrors<D>> | AsyncResult<unknown, FlowErrors<D>>>>(name: string, operations: TOps) => Promise<{
127
- [K in keyof TOps]: TOps[K] extends () => Result<infer V, FlowErrors<D>> | AsyncResult<infer V, FlowErrors<D>> ? V : never;
128
- }>;
129
- }
130
- /**
131
- * Options for a single `flow()` call.
132
- *
133
- * `onEvent` is typed as `WorkflowEvent<unknown>` deliberately — keeps this
134
- * surface small. If you need typed event payloads, use `run()`.
135
- */
136
- interface FlowOptions<U = UnexpectedError> {
137
- /**
138
- * Replace `UnexpectedError` with a custom type at the boundary. Any
139
- * exception escaping a dep is mapped through this fn; the flow's error
140
- * type becomes `FlowErrors<deps> | U` instead of
141
- * `FlowErrors<deps> | UnexpectedError`.
142
- */
143
- catchUnexpected?: (cause: unknown) => U;
144
- /**
145
- * Step lifecycle events (start/success/error/aborted). The deps-object key
146
- * is the step id emitted here — handy for tracing.
147
- */
148
- onEvent?: (event: WorkflowEvent<unknown>) => void;
149
- }
150
- /**
151
- * Run a flow over a deps object. Each function dep call becomes a step using
152
- * the property name as the step id; non-function deps pass through.
153
- *
154
- * @param deps - Result-returning functions (plus optional non-fn values) keyed by step id
155
- * @param body - Workflow body; receives the wrapped deps
156
- * @param options - Optional flow-level options
157
- */
158
- declare function flow<D extends DepsRecord, T>(deps: D, body: (d: Flowed<D>, c: FlowContext<D>) => Promise<T> | T): Promise<Result<T, FlowErrors<D> | UnexpectedError>>;
159
- declare function flow<D extends DepsRecord, T, U>(deps: D, body: (d: Flowed<D>, c: FlowContext<D>) => Promise<T> | T, options: FlowOptions<U> & {
160
- catchUnexpected: (cause: unknown) => U;
161
- }): Promise<Result<T, FlowErrors<D> | U>>;
162
-
163
- export { type FlowOptions, type Flowed, flow };
package/dist/flow.js DELETED
@@ -1,7 +0,0 @@
1
- var Ke={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function ye(r){return`https://jagreehal.github.io/awaitly/rules/#${r}`}var nr=Object.keys(Ke);var te=class extends Error{_tag};function K(r,n){return class extends te{_tag=r;constructor(w,C){let A=n?.message?n.message(w??{}):r;if(super(A),this.name=r,n?.slug!==void 0){if(!n.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${n.slug}")`);Object.defineProperty(this,"code",{value:n.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:n.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:ye(n.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),w&&typeof w=="object"){let c;if(n?.slug!==void 0){let{_tag:M,name:O,message:I,stack:s,code:N,hint:B,docsUrl:we,...re}=w;c=re}else{let{_tag:M,name:O,message:I,stack:s,...N}=w;c=N}let y=Object.prototype.hasOwnProperty.call(c,"cause"),P=y?c.cause:void 0;y&&delete c.cause;let S=C?.cause!==void 0;if(y&&S)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,c),y&&(this.cause=P),S&&(this.cause=C?.cause)}else C?.cause!==void 0&&(this.cause=C.cause)}}}Object.defineProperty(K,Symbol.hasInstance,{value:r=>r instanceof te});(A=>{function r(c){return c instanceof Error}A.isError=r;function n(c){return c instanceof te}A.isTaggedError=n;function w(c,y){let P=c._tag,S=y[P];return S(c)}A.match=w;function C(c,y,P){let S=c._tag,M=y[S];return M?M(c):P(c)}A.matchPartial=C})(K||={});var fe=class extends K("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:n=>n.operation?`TimeoutError: ${n.operation} timed out after ${n.ms}ms`:`TimeoutError: Operation timed out after ${n.ms}ms`}){},ke=class extends K("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:n=>n.operation?`RetryExhaustedError: ${n.operation} failed after ${n.attempts} attempts`:`RetryExhaustedError: Operation failed after ${n.attempts} attempts`}){},Te=class extends K("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:n=>n.limiterName?`RateLimitError: Rate limit exceeded for ${n.limiterName}${n.retryAfterMs?`, retry after ${n.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${n.retryAfterMs?`, retry after ${n.retryAfterMs}ms`:""}`}){},Re=class extends K("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:n=>`CircuitBreakerOpenError: Circuit ${n.circuitName} is ${n.state??"OPEN"}${n.retryAfterMs?`, retry after ${Math.ceil(n.retryAfterMs/1e3)}s`:""}`}){},ge=class extends K("ValidationError",{message:n=>`ValidationError: Invalid ${n.field} - ${n.reason}`}){},xe=class extends K("NotFoundError",{message:n=>n.id?`NotFoundError: ${n.resource} with id ${n.id} not found`:`NotFoundError: ${n.resource} not found`}){},Ce=class extends K("UnauthorizedError",{message:n=>n.reason?`UnauthorizedError: ${n.reason}`:n.action&&n.resource?`UnauthorizedError: Not authorized to ${n.action} ${n.resource}`:"UnauthorizedError: Access denied"}){},he=class extends K("NetworkError",{message:n=>n.url?`NetworkError: ${n.reason} (${n.url})`:`NetworkError: ${n.reason}`}){},be=class extends K("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:n=>`CompensationError: Failed to compensate step ${n.step}`}){},se=class extends K("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:n=>`UnexpectedError: ${n.cause instanceof Error?n.cause.message:String(n.cause??"unknown")}`}){};function Ae(r){return{ok:!0,value:r}}var Ne=r=>typeof r=="object"&&r!==null&&"ok"in r&&typeof r.ok=="boolean"&&(r.ok?"value"in r:"error"in r),Se=(r,n)=>{let w={},C=new Map;for(let A of Object.keys(r)){let c=r[A];typeof c=="function"&&(w[A]=(...y)=>{let P=(C.get(A)??0)+1;C.set(A,P);let S=P===1?A:`${A}#${P}`;return n(S,async()=>{let M=await c(...y);return Ne(M)?M:Ae(M)})})}return w};function je(r){let n=r.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!n)return;let w=parseFloat(n[1]),C=n[2].toLowerCase();return{_tag:"Duration",millis:w*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[C]??1)}}function Be(r){return new se({cause:r})}function W(r){return{ok:!0,value:r}}function F(r,n){let w=n?.cause;return{ok:!1,error:r,...w!==void 0?{cause:w}:{}}}function Le(r){if(r==null)return"unknown";if(typeof r=="string")return r.trim()||"unknown";if(typeof r=="object"){let n=r;if(typeof n._tag=="string"){let w=n._tag.trim();if(w)return w}if(typeof n.tag=="string"){let w=n.tag.trim();if(w)return w}if(typeof n.code=="string"){let w=n.code.trim();if(w)return w}else if(typeof n.code=="number")return String(n.code);if(r instanceof Error&&r.name){let w=r.name.trim();if(w)return w}}return"unknown"}function Ve(r,n){if(!(!n||!r))return n[r]}function We(r){let{intent:n,domain:w,owner:C,tags:A,stateChanges:c,emits:y,calls:P}=r;if(!n&&!w&&!C&&!A?.length&&!c?.length&&!y?.length&&!P?.length)return;let S={};return n&&(S.intent=n),w&&(S.domain=w),C&&(S.owner=C),A?.length&&(S.tags=A),c?.length&&(S.stateChanges=c),y?.length&&(S.emits=y),P?.length&&(S.calls=P),S}function L(r,n,w,C,A){let c=Le(r),y=Ve(c,n),P={tag:c,origin:w};return y!==void 0&&(P.classification=y),C!==void 0&&(P.attempt=C),A!==void 0&&(P.cumulativeDurationMs=A),P}var ee=Symbol.for("step_timeout_marker");function Pe(r){return typeof r!="object"||r===null?!1:r.type==="STEP_TIMEOUT"?!0:ee in r}function $e(r){if(!(typeof r!="object"||r===null)){if(r.type==="STEP_TIMEOUT"){let n=r;return{timeoutMs:n.timeoutMs,stepName:n.stepName,stepKey:n.stepKey,attempt:n.attempt}}if(ee in r)return r[ee]}}var _e=Symbol("early-exit");function He(r,n){return{[_e]:!0,error:r,meta:n}}function qe(r){return typeof r=="object"&&r!==null&&r[_e]===!0}var De=Symbol("mapper-exception");function Z(r){return{[De]:!0,thrown:r}}function Ye(r){return typeof r=="object"&&r!==null&&r[De]===!0}function de(r,n){let{backoff:w,initialDelay:C,maxDelay:A,jitter:c}=n,y;switch(w){case"fixed":y=C;break;case"linear":y=C*r;break;case"exponential":y=C*Math.pow(2,r-1);break}if(y=Math.min(y,A),c){let P=y*.25*Math.random();y=y+P}return Math.floor(y)}function me(r){return new Promise(n=>setTimeout(n,r))}var ve=Symbol("timeout"),ae=Symbol("timeout-option");function ze(r){return typeof r=="object"&&r!==null&&r[ae]===!0}async function Je(r,n,w,C){let A=new AbortController,c=n.onTimeout??"error",y=()=>typeof c=="function"?c({name:w.name,key:w.key,ms:n.ms}):n.error??{type:"STEP_TIMEOUT",stepName:w.name,stepKey:w.key,timeoutMs:n.ms,attempt:w.attempt},P;C?.aborted&&A.abort(C.reason);let S;C&&!C.aborted&&(S=()=>A.abort(C.reason),C.addEventListener("abort",S,{once:!0}));let M=new Promise((I,s)=>{P=setTimeout(()=>{if(c!=="disconnect"&&A.abort(),c==="option"){s({[ae]:!0,ms:n.ms});return}s({[ve]:!0,error:y()})},n.ms)}),O;n.signal?O=Promise.resolve(r(A.signal)):O=Promise.resolve(r());try{return await Promise.race([O,M])}catch(I){if(typeof I=="object"&&I!==null&&I[ae]===!0)throw{[ae]:!0,ms:n.ms};if(typeof I=="object"&&I!==null&&I[ve]===!0){c==="disconnect"&&O.catch(()=>{});let s=I.error;if(typeof s=="object"&&s!==null&&s.type!=="STEP_TIMEOUT"){let N={timeoutMs:n.ms,stepName:w.name,stepKey:w.key,attempt:w.attempt};ee in s?s[ee]=N:Object.defineProperty(s,ee,{value:N,enumerable:!1,writable:!0,configurable:!1})}throw s}throw I}finally{clearTimeout(P),S&&C&&C.removeEventListener("abort",S)}}var Q={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function ue(r,n,w){if(typeof r!="function"){let p=r,j=n;if(typeof j!="function")throw new TypeError("[awaitly] run(deps, fn) requires a callback as the second argument. Example: run({ getUser }, async (s) => s.getUser(id))");return ue(({step:G})=>j(Se(p,G),{step:G}),w)}let C=r,A=n,{onError:c,onEvent:y,catchUnexpected:P,workflowId:S,workflowName:M,context:O,_workflowSignal:I}=A&&typeof A=="object"?A:{},s=S??crypto.randomUUID(),N=P??Be,B=[],we=0,re=p=>p??`step_${++we}`,i=p=>{let j=p.context!==void 0||O===void 0?p:{...p,context:O},$=M!==void 0&&j.workflowName===void 0?{...j,workflowName:M}:j;if($.type==="step_success"){let G=$.stepId;for(let oe=B.length-1;oe>=0;oe--){let V=B[oe];if(V.type==="race"&&!V.winnerId){V.winnerId=G;break}}}y?.($,O)},U=He,J=p=>qe(p),q=(p,j)=>p,Ie=p=>typeof p=="function"?!1:!!(p&&typeof p=="object"&&"ok"in p||p&&typeof p=="object"&&"then"in p&&typeof p.then=="function");try{let j=function(a){let E={};for(let[t,o]of Object.entries(a))if(typeof o=="function")E[t]=o;else if(o&&typeof o=="object"&&"fn"in o)E[t]=o.fn;else throw new TypeError(`step.all: operation "${t}" must be a function or { fn, errors? } object`);return E},$=function(a,E){let t=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),e=!1;B.push({scopeId:t,type:"parallel"});let u=()=>{if(e)return;e=!0;let l=B.findIndex(d=>d.scopeId===t);l!==-1&&B.splice(l,1),i({type:"scope_end",workflowId:s,scopeId:t,ts:Date.now(),durationMs:performance.now()-o})};i({type:"scope_start",workflowId:s,scopeId:t,scopeType:"parallel",name:a,ts:Date.now()});try{let l=await E();if(u(),!l.ok)throw c?.(l.error,a,O),U(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw u(),l}})()},G=function(a,E){let t=Object.keys(a),o=E.name??`Parallel(${t.join(", ")})`,e=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),l=!1;B.push({scopeId:e,type:"parallel"});let d=()=>{if(l)return;l=!0;let m=B.findIndex(f=>f.scopeId===e);m!==-1&&B.splice(m,1),i({type:"scope_end",workflowId:s,scopeId:e,ts:Date.now(),durationMs:performance.now()-u})};i({type:"scope_start",workflowId:s,scopeId:e,scopeType:"parallel",name:o,ts:Date.now()});try{let m=await new Promise(T=>{if(t.length===0){T([]);return}let b=!1,D=t.length,R=new Array(t.length);for(let _=0;_<t.length;_++){let g=t[_],h=_;Promise.resolve(a[g]()).catch(x=>F({type:"PROMISE_REJECTED",cause:x},{cause:{type:"PROMISE_REJECTION",reason:x}})).then(x=>{if(!b){if(!x.ok){b=!0,T([{key:g,result:x}]);return}R[h]={key:g,result:x},D--,D===0&&T(R)}})}});d();let f={};for(let{key:T,result:b}of m){if(!b.ok)throw c?.(b.error,T,O),U(b.error,{origin:"result",resultCause:b.cause});f[T]=b.value}return f}catch(m){throw d(),m}})()};var Qe=j,er=$,rr=G;let p=(a,E,t)=>(async()=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let o=t??{},e=We(o),u=a,l=o.key??a,d=o.key??a,{description:m,retry:f,timeout:T}=o,b=re(l),D=y,R=D?performance.now():0,g=Ie(E)?()=>E:E,x={attempts:Math.max(1,f?.attempts??1),backoff:f?.backoff??Q.backoff,initialDelay:f?.initialDelay??Q.initialDelay,maxDelay:f?.maxDelay??Q.maxDelay,jitter:f?.jitter??Q.jitter,shouldRetry:f?.shouldRetry??Q.shouldRetry,onRetry:f?.onRetry??Q.onRetry};y&&i({type:"step_start",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),...e&&{metadata:e}});let X;for(let v=1;v<=x.attempts;v++){let Ue=D?performance.now():0;try{let k;if(T?k=await Je(g,T,{name:u,key:l,attempt:v},I):k=await g(),k.ok){let z=performance.now()-R;return i({type:"step_success",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:z,...e&&{metadata:e}}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:m,ts:Date.now(),durationMs:z,result:k,...e&&{metadata:e}}),k.value}if(X=k,v<x.attempts&&x.shouldRetry(k.error,v)){let z=de(v,x);i({type:"step_retry",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),attempt:v+1,maxAttempts:x.attempts,delayMs:z,error:k.error,...e&&{metadata:e},diagnostics:L(k.error,o.errorMeta,"result",v,performance.now()-R)}),x.onRetry(k.error,v,z),await me(z);continue}x.attempts>1&&i({type:"step_retries_exhausted",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:k.error,...e&&{metadata:e},diagnostics:L(k.error,o.errorMeta,"result",v,performance.now()-R)});break}catch(k){let z=performance.now()-Ue;if(ze(k)){let H=k.ms;i({type:"step_timeout",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),timeoutMs:H,attempt:v,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"timeout",v)}),i({type:"step_success",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:performance.now()-R,...e&&{metadata:e}}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:m,ts:Date.now(),durationMs:performance.now()-R,result:W(void 0),...e&&{metadata:e}});return}if(J(k))throw i({type:"step_aborted",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:z,...e&&{metadata:e}}),k;if(Pe(k)){let H=$e(k),Fe=T?.ms??H?.timeoutMs??0;if(i({type:"step_timeout",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),timeoutMs:Fe,attempt:v,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"timeout",v)}),v<x.attempts&&x.shouldRetry(k,v)){let Ee=de(v,x);i({type:"step_retry",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),attempt:v+1,maxAttempts:x.attempts,delayMs:Ee,error:k,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"timeout",v,performance.now()-R)}),x.onRetry(k,v,Ee),await me(Ee);continue}x.attempts>1&&i({type:"step_retries_exhausted",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:k,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"timeout",v,performance.now()-R)});let pe=performance.now()-R;throw i({type:"step_error",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:pe,error:k,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"timeout",v,pe)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:m,ts:Date.now(),durationMs:pe,result:F(k,{cause:k}),meta:{origin:"throw",thrown:k},...e&&{metadata:e}}),c?.(k,u,O),U(k,{origin:"throw",thrown:k})}if(v<x.attempts&&x.shouldRetry(k,v)){let H=de(v,x);i({type:"step_retry",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),attempt:v+1,maxAttempts:x.attempts,delayMs:H,error:k,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"throw",v,performance.now()-R)}),x.onRetry(k,v,H),await me(H);continue}x.attempts>1&&!Pe(k)&&i({type:"step_retries_exhausted",workflowId:s,stepId:b,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:k,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"throw",v,performance.now()-R)});let ce=performance.now()-R,ne;try{ne=N(k)}catch(H){throw Z(H)}throw i({type:"step_error",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:ce,error:ne,...e&&{metadata:e},diagnostics:L(k,o.errorMeta,"throw",v,ce)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:m,ts:Date.now(),durationMs:ce,result:F(ne,{cause:k}),meta:{origin:"throw",thrown:k},...e&&{metadata:e}}),c?.(ne,u,O),U(ne,{origin:"throw",thrown:k})}}let Y=X,ie=performance.now()-R,le=q(Y.error,{origin:"result",resultCause:Y.cause});throw i({type:"step_error",workflowId:s,stepId:b,stepKey:l,name:u,description:m,ts:Date.now(),durationMs:ie,error:le,...e&&{metadata:e},diagnostics:L(Y.error,o.errorMeta,"result",x.attempts,ie)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:m,ts:Date.now(),durationMs:ie,result:Y,meta:{origin:"result",resultCause:Y.cause},...e&&{metadata:e}}),c?.(le,u,O),U(le,{origin:"result",resultCause:Y.cause})})();p.try=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.try() requires an explicit string ID as the first argument. Example: step.try("parse", () => JSON.parse(str), { error: "PARSE_ERROR" })');let o="error"in t?()=>t.error:t.onError;if(t.retry||t.timeout)return p.retry(a,async()=>{try{return W(await E())}catch(m){return F(o(m),{cause:m})}},{attempts:t.retry?.attempts??1,...t.retry??{},key:t.key,timeout:t.timeout});let e=t.key??a,u=a,l=a,d=y;return(async()=>{let m=d?performance.now():0;y&&i({type:"step_start",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now()});try{let f=await E(),T=performance.now()-m;return i({type:"step_success",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now(),durationMs:T}),e&&i({type:"step_complete",workflowId:s,stepKey:e,name:u,ts:Date.now(),durationMs:T,result:W(f)}),f}catch(f){let T=o(f),b=performance.now()-m,D=q(T,{origin:"throw",thrown:f});throw i({type:"step_error",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now(),durationMs:b,error:D}),e&&i({type:"step_complete",workflowId:s,stepKey:e,name:u,ts:Date.now(),durationMs:b,result:F(T,{cause:f}),meta:{origin:"throw",thrown:f}}),c?.(D,u,O),U(D,{origin:"throw",thrown:f})}})()},p.fromResult=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.fromResult() requires an explicit string ID as the first argument. Example: step.fromResult("callProvider", () => callProvider(input), { onError: (e) => ({ type: "FAILED" }) })');let o=t.key??a,e=a,u=a,l="error"in t?()=>t.error:t.onError,d=y;return(async()=>{let m=d?performance.now():0;y&&i({type:"step_start",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now()});let f=await E();if(f.ok){let T=performance.now()-m;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:T}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:T,result:W(f.value)}),f.value}else{let T=l(f.error),b=performance.now()-m,D=q(T,{origin:"result",resultCause:f.error});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:b,error:D}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:b,result:F(T,{cause:f.error}),meta:{origin:"result",resultCause:f.error}}),c?.(D,e,O),U(D,{origin:"result",resultCause:f.error})}})()},p.fromNullable=(a,E,t,o)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.fromNullable() requires an explicit string ID as the first argument. Example: step.fromNullable("getUser", () => db.find(id), () => ({ type: "NOT_FOUND" }))');return p(a,async()=>{let e=await E();return e!=null?W(e):F(t())},o)},p.retry=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.retry() requires an explicit string ID as the first argument. Example: step.retry("fetchData", () => fetchData(), { attempts: 3 })');return p(a,E,{key:t.key??a,retry:{attempts:t.attempts,backoff:t.backoff,initialDelay:t.initialDelay,maxDelay:t.maxDelay,jitter:t.jitter,shouldRetry:t.shouldRetry,onRetry:t.onRetry},timeout:t.timeout})},p.withTimeout=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withTimeout() requires an explicit string ID as the first argument. Example: step.withTimeout("slowOp", () => slowOp(), { ms: 5000 })');return p(a,E,{key:t.key??a,timeout:t})},p.sleep=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let o=typeof E=="string"?je(E):E;if(!o)throw new Error(`step.sleep: invalid duration '${E}'`);let e=o.millis,u=t?.signal;return p(a,async()=>{if(I?.aborted||u?.aborted){let l=new Error("Sleep aborted");throw l.name="AbortError",l}return new Promise((l,d)=>{let m={timeoutId:void 0},f=()=>{m.timeoutId&&clearTimeout(m.timeoutId);let T=new Error("Sleep aborted");T.name="AbortError",d(T)};I?.addEventListener("abort",f,{once:!0}),u?.addEventListener("abort",f,{once:!0}),m.timeoutId=setTimeout(()=>{I?.removeEventListener("abort",f),u?.removeEventListener("abort",f),l(W(void 0))},e)})},{key:t?.key??a,description:t?.description})},p.all=((...a)=>{if(typeof a[0]!="string")throw new TypeError("step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let E=a[0],t=a[1];if(typeof t=="function")return $(E,t);if(t&&typeof t=="object"&&!Array.isArray(t)){let e=j(t);return G(e,{name:E})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(a,E)=>{let t=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),e=!1,u={scopeId:t,type:"race",winnerId:void 0};B.push(u);let l=()=>{if(e)return;e=!0;let d=B.findIndex(m=>m.scopeId===t);d!==-1&&B.splice(d,1),i({type:"scope_end",workflowId:s,scopeId:t,ts:Date.now(),durationMs:performance.now()-o,winnerId:u.winnerId})};i({type:"scope_start",workflowId:s,scopeId:t,scopeType:"race",name:a,ts:Date.now()});try{let d=await E();if(l(),!d.ok)throw c?.(d.error,a,O),U(d.error,{origin:"result",resultCause:d.cause});return d.value}catch(d){throw l(),d}})()},p.if=(a,E,t)=>t(),p.label=p.if,p.branch=async(a,E)=>{let{condition:t,then:o,else:e}=E;if(t())return await o();if(e)return await e()},p.arm=(a,E)=>({fn:a,errors:E}),p.forEach=async(a,E,t)=>{let o=[],e=t.maxIterations,u=0,l="run"in t,d=Symbol.asyncIterator in E?E:(async function*(){yield*E})();for await(let m of d){if(e!==void 0&&u>=e)break;let f;l?f=await t.run(m,u):f=await t.item.handler(m,u,p),o.push(f),u++}return o},p.item=a=>({__forEachItemHandler:!0,handler:a}),p.dep=(a,E)=>E,p.workflow=(a,E,t)=>p(a,E,t),p.map=async(a,E,t,o)=>{let e=o?.concurrency??E.length;return p(a,()=>e>=E.length?Oe(E.map((u,l)=>t(u,l))):(async()=>{let u=[];for(let l=0;l<E.length;l+=e){let d=E.slice(l,l+e),m=await Oe(d.map((f,T)=>t(f,l+T)));if(!m.ok)return m;u.push(...m.value)}return W(u)})(),{key:o?.key})},p.withFallback=(a,E,t)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withFallback() requires an explicit string ID as the first argument. Example: step.withFallback("getUser", () => fetchUser(id), { fallback: () => fetchFromCache(id) })');let o=t.key??a,e=a,u=re(o),l=y;return(async()=>{let d=l?performance.now():0;y&&i({type:"step_start",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now()});let m;try{m=await E()}catch(R){if(J(R))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),R;let _;try{_=N(R)}catch(h){throw Z(h)}if(t.on!==void 0&&t.on!==_){let h=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:h,error:_}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:h,result:F(_,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(_,e,O),U(_,{origin:"throw",thrown:R})}let g;try{g=await t.fallback()}catch(h){if(J(h))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),h;let x;try{x=N(h)}catch(Y){throw Z(Y)}let X=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:X,error:x}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:X,result:F(x,{cause:h}),meta:{origin:"throw",thrown:h}}),c?.(x,e,O),U(x,{origin:"throw",thrown:h})}if(g.ok){let h=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:h}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:h,result:g,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(_)}}),g.value}else{let h=performance.now()-d,x=q(g.error,{origin:"result",resultCause:g.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:h,error:x}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:h,result:g,meta:{origin:"result",resultCause:g.cause}}),c?.(x,e,O),U(x,{origin:"result",resultCause:g.cause})}}if(m.ok){let R=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:R}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:R,result:m}),m.value}let f=m.error;if(t.on!==void 0&&t.on!==f){let R=performance.now()-d,_=q(f,{origin:"result",resultCause:m.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:R,error:_}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:R,result:m,meta:{origin:"result",resultCause:m.cause}}),c?.(_,e,O),U(_,{origin:"result",resultCause:m.cause})}let T;try{T=await t.fallback()}catch(R){if(J(R))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),R;let _;try{_=N(R)}catch(h){throw Z(h)}let g=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:g,error:_}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:g,result:F(_,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(_,e,O),U(_,{origin:"throw",thrown:R})}if(T.ok){let R=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:R}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:R,result:T,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(f)}}),T.value}let b=performance.now()-d,D=q(T.error,{origin:"result",resultCause:T.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:b,error:D}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:b,result:T,meta:{origin:"result",resultCause:T.cause}}),c?.(D,e,O),U(D,{origin:"result",resultCause:T.cause})})()},p.withResource=(a,E)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withResource() requires an explicit string ID as the first argument. Example: step.withResource("useDb", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })');let t=a,o=a,e=re(t),u=y;return(async()=>{let l=u?performance.now():0;y&&i({type:"step_start",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now()});let d;try{d=await E.acquire()}catch(g){if(J(g))throw i({type:"step_aborted",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:performance.now()-l}),g;let h;try{h=N(g)}catch(X){throw Z(X)}let x=performance.now()-l;throw i({type:"step_error",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:x,error:h}),t&&i({type:"step_complete",workflowId:s,stepKey:t,name:o,ts:Date.now(),durationMs:x,result:F(h,{cause:g}),meta:{origin:"throw",thrown:g}}),c?.(h,o,O),U(h,{origin:"throw",thrown:g})}if(!d.ok){let g=performance.now()-l,h=q(d.error,{origin:"result",resultCause:d.cause});throw i({type:"step_error",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:g,error:h}),t&&i({type:"step_complete",workflowId:s,stepKey:t,name:o,ts:Date.now(),durationMs:g,result:d,meta:{origin:"result",resultCause:d.cause}}),c?.(h,o,O),U(h,{origin:"result",resultCause:d.cause})}let m=d.value,f,T,b=!1;try{f=await E.use(m)}catch(g){if(J(g)){try{await E.release(m)}catch(h){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,h)}throw g}T=g,b=!0}try{await E.release(m)}catch(g){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,g)}if(b){let g;try{g=N(T)}catch(x){throw Z(x)}let h=performance.now()-l;throw i({type:"step_error",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:h,error:g}),t&&i({type:"step_complete",workflowId:s,stepKey:t,name:o,ts:Date.now(),durationMs:h,result:F(g,{cause:T}),meta:{origin:"throw",thrown:T}}),c?.(g,o,O),U(g,{origin:"throw",thrown:T})}let D=f;if(D.ok){let g=performance.now()-l;return i({type:"step_success",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:g}),t&&i({type:"step_complete",workflowId:s,stepKey:t,name:o,ts:Date.now(),durationMs:g,result:D}),D.value}let R=performance.now()-l,_=q(D.error,{origin:"result",resultCause:D.cause});throw i({type:"step_error",workflowId:s,stepId:e,stepKey:t,name:o,ts:Date.now(),durationMs:R,error:_}),t&&i({type:"step_complete",workflowId:s,stepKey:t,name:o,ts:Date.now(),durationMs:R,result:D,meta:{origin:"result",resultCause:D.cause}}),c?.(_,o,O),U(_,{origin:"result",resultCause:D.cause})})()};let V=await C({step:p});if(process.env.NODE_ENV!=="production"&&V!==null&&typeof V=="object"&&"ok"in V&&typeof V.ok=="boolean"){let a=V;(a.ok===!0&&"value"in a||a.ok===!1&&"error"in a)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
2
-
3
- Incorrect: return ok({ data });
4
- Correct: return { data };
5
-
6
- See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return W(V)}catch(p){if(Ye(p))throw p.thrown;if(J(p)){let $=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return F(p.error,{cause:$})}let j=N(p);return c?.(j,"unexpected",O),F(j,{cause:p})}}var Me=ue;ue.strict=(r,n)=>ue(r,n);async function Oe(r){return r.length===0?W([]):new Promise(n=>{let w=!1,C=r.length,A=new Array(r.length);for(let c=0;c<r.length;c++){let y=c;Promise.resolve(r[y]).catch(P=>F({type:"PROMISE_REJECTED",cause:P},{cause:{type:"PROMISE_REJECTION",reason:P}})).then(P=>{if(!w){if(!P.ok){w=!0,n(P);return}A[y]=P.value,C--,C===0&&n(W(A))}})}})}var Ge=r=>typeof r=="object"&&r!==null,Xe=r=>Ge(r)&&r.ok===!1&&!("error"in r);function Ze(r,n,w){return Me(async({step:C})=>{let A=C,c=C,y={};for(let S of Object.keys(r)){let M=r[S];if(typeof M=="function"){let O=M;y[S]=(...I)=>A(S,async()=>{let s=await Reflect.apply(O,r,I);if(Xe(s))throw new TypeError(`flow(${S}) expected Err to include an error field`);return s})}else y[S]=M}return n(y,{raw:r,key:((S,M)=>A(S,M)),all:((S,M)=>c.all(S,M))})},{catchUnexpected:w?.catchUnexpected,onEvent:w?.onEvent})}export{Ze as flow};
7
- //# sourceMappingURL=flow.js.map