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.
- package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +29 -4
- package/dist/result.d.ts +29 -4
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
- package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -168
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-By77n4Fa.d.ts +0 -15
- package/dist/di-OJfsohf-.d.cts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-4sV7mTqj.d.cts +0 -72
- package/dist/guards-BIX05ALH.d.ts +0 -72
- package/dist/hitl-DFn4Xa_l.d.cts +0 -468
- package/dist/hitl-DU5VpKq7.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-CnvBryQB.d.ts +0 -417
- package/dist/index-DEZEf8Fs.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
- package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-BziYHFkD.d.ts +0 -323
- package/dist/types-C5jLEUqY.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/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
|