awaitly 1.34.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +35 -5
- package/dist/result.d.ts +35 -5
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
- package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +13 -178
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-COl5oFnR.d.cts +0 -15
- package/dist/di-CyDj_JyZ.d.ts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-BodHXLzX.d.cts +0 -72
- package/dist/guards-CeWoQ8fn.d.ts +0 -72
- package/dist/hitl-BPE_1UiM.d.cts +0 -468
- package/dist/hitl-byp570uC.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-BYT3amEz.d.ts +0 -417
- package/dist/index-C_ak66jy.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-DOMx3woy.d.ts +0 -822
- package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-DQmzO9f4.d.ts +0 -323
- package/dist/types-qBUOYi-4.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/flow.d.cts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { ag as WorkflowEvent, R as Result, c as AsyncResult } from './run-entry-D2MmJFj9.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 { ag as WorkflowEvent, R as Result, c as AsyncResult } from './run-entry-Dduz-is2.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 De={"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 me(o){return`https://jagreehal.github.io/awaitly/rules/#${o}`}var Ge=Object.keys(De);var ee=class extends Error{_tag};function N(o,t){return class extends ee{_tag=o;constructor(c,k){let D=t?.message?t.message(c??{}):o;if(super(D),this.name=o,t?.slug!==void 0){if(!t.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${t.slug}")`);Object.defineProperty(this,"code",{value:t.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:t.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:me(t.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),c&&typeof c=="object"){let h;if(t?.slug!==void 0){let{_tag:s,name:U,message:v,stack:I,code:V,hint:u,docsUrl:M,...$}=c;h=$}else{let{_tag:s,name:U,message:v,stack:I,...V}=c;h=V}let C=Object.prototype.hasOwnProperty.call(h,"cause"),w=C?h.cause:void 0;C&&delete h.cause;let A=k?.cause!==void 0;if(C&&A)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,h),C&&(this.cause=w),A&&(this.cause=k?.cause)}else k?.cause!==void 0&&(this.cause=k.cause)}}}Object.defineProperty(N,Symbol.hasInstance,{value:o=>o instanceof ee});(D=>{function o(h){return h instanceof Error}D.isError=o;function t(h){return h instanceof ee}D.isTaggedError=t;function c(h,C){let w=h._tag,A=C[w];return A(h)}D.match=c;function k(h,C,w){let A=h._tag,s=C[A];return s?s(h):w(h)}D.matchPartial=k})(N||={});var Ee=class extends N("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:t=>t.operation?`TimeoutError: ${t.operation} timed out after ${t.ms}ms`:`TimeoutError: Operation timed out after ${t.ms}ms`}){},we=class extends N("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:t=>t.operation?`RetryExhaustedError: ${t.operation} failed after ${t.attempts} attempts`:`RetryExhaustedError: Operation failed after ${t.attempts} attempts`}){},ye=class extends N("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:t=>t.limiterName?`RateLimitError: Rate limit exceeded for ${t.limiterName}${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`}){},fe=class extends N("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:t=>`CircuitBreakerOpenError: Circuit ${t.circuitName} is ${t.state??"OPEN"}${t.retryAfterMs?`, retry after ${Math.ceil(t.retryAfterMs/1e3)}s`:""}`}){},ke=class extends N("ValidationError",{message:t=>`ValidationError: Invalid ${t.field} - ${t.reason}`}){},ge=class extends N("NotFoundError",{message:t=>t.id?`NotFoundError: ${t.resource} with id ${t.id} not found`:`NotFoundError: ${t.resource} not found`}){},Te=class extends N("UnauthorizedError",{message:t=>t.reason?`UnauthorizedError: ${t.reason}`:t.action&&t.resource?`UnauthorizedError: Not authorized to ${t.action} ${t.resource}`:"UnauthorizedError: Access denied"}){},Re=class extends N("NetworkError",{message:t=>t.url?`NetworkError: ${t.reason} (${t.url})`:`NetworkError: ${t.reason}`}){},xe=class extends N("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:t=>`CompensationError: Failed to compensate step ${t.step}`}){},ne=class extends N("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:t=>`UnexpectedError: ${t.cause instanceof Error?t.cause.message:String(t.cause??"unknown")}`}){};function Me(o){let t=o.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let c=parseFloat(t[1]),k=t[2].toLowerCase();return{_tag:"Duration",millis:c*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[k]??1)}}function Ie(o){return new ne({cause:o})}function B(o){return{ok:!0,value:o}}function F(o,t){let c=t?.cause;return{ok:!1,error:o,...c!==void 0?{cause:c}:{}}}function Ue(o){if(o==null)return"unknown";if(typeof o=="string")return o.trim()||"unknown";if(typeof o=="object"){let t=o;if(typeof t._tag=="string"){let c=t._tag.trim();if(c)return c}if(typeof t.tag=="string"){let c=t.tag.trim();if(c)return c}if(typeof t.code=="string"){let c=t.code.trim();if(c)return c}else if(typeof t.code=="number")return String(t.code);if(o instanceof Error&&o.name){let c=o.name.trim();if(c)return c}}return"unknown"}function Fe(o,t){if(!(!t||!o))return t[o]}function Ne(o){let{intent:t,domain:c,owner:k,tags:D,stateChanges:h,emits:C,calls:w}=o;if(!t&&!c&&!k&&!D?.length&&!h?.length&&!C?.length&&!w?.length)return;let A={};return t&&(A.intent=t),c&&(A.domain=c),k&&(A.owner=k),D?.length&&(A.tags=D),h?.length&&(A.stateChanges=h),C?.length&&(A.emits=C),w?.length&&(A.calls=w),A}function K(o,t,c,k,D){let h=Ue(o),C=Fe(h,t),w={tag:h,origin:c};return C!==void 0&&(w.classification=C),k!==void 0&&(w.attempt=k),D!==void 0&&(w.cumulativeDurationMs=D),w}var Q=Symbol.for("step_timeout_marker");function he(o){return typeof o!="object"||o===null?!1:o.type==="STEP_TIMEOUT"?!0:Q in o}function Ke(o){if(!(typeof o!="object"||o===null)){if(o.type==="STEP_TIMEOUT"){let t=o;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(Q in o)return o[Q]}}var Se=Symbol("early-exit");function je(o,t){return{[Se]:!0,error:o,meta:t}}function Le(o){return typeof o=="object"&&o!==null&&o[Se]===!0}var Ae=Symbol("mapper-exception");function G(o){return{[Ae]:!0,thrown:o}}function Be(o){return typeof o=="object"&&o!==null&&o[Ae]===!0}function le(o,t){let{backoff:c,initialDelay:k,maxDelay:D,jitter:h}=t,C;switch(c){case"fixed":C=k;break;case"linear":C=k*o;break;case"exponential":C=k*Math.pow(2,o-1);break}if(C=Math.min(C,D),h){let w=C*.25*Math.random();C=C+w}return Math.floor(C)}function pe(o){return new Promise(t=>setTimeout(t,o))}var Ce=Symbol("timeout"),oe=Symbol("timeout-option");function Ve(o){return typeof o=="object"&&o!==null&&o[oe]===!0}async function $e(o,t,c,k){let D=new AbortController,h=t.onTimeout??"error",C=()=>typeof h=="function"?h({name:c.name,key:c.key,ms:t.ms}):t.error??{type:"STEP_TIMEOUT",stepName:c.name,stepKey:c.key,timeoutMs:t.ms,attempt:c.attempt},w;k?.aborted&&D.abort(k.reason);let A;k&&!k.aborted&&(A=()=>D.abort(k.reason),k.addEventListener("abort",A,{once:!0}));let s=new Promise((v,I)=>{w=setTimeout(()=>{if(h!=="disconnect"&&D.abort(),h==="option"){I({[oe]:!0,ms:t.ms});return}I({[Ce]:!0,error:C()})},t.ms)}),U;t.signal?U=Promise.resolve(o(D.signal)):U=Promise.resolve(o());try{return await Promise.race([U,s])}catch(v){if(typeof v=="object"&&v!==null&&v[oe]===!0)throw{[oe]:!0,ms:t.ms};if(typeof v=="object"&&v!==null&&v[Ce]===!0){h==="disconnect"&&U.catch(()=>{});let I=v.error;if(typeof I=="object"&&I!==null&&I.type!=="STEP_TIMEOUT"){let V={timeoutMs:t.ms,stepName:c.name,stepKey:c.key,attempt:c.attempt};Q in I?I[Q]=V:Object.defineProperty(I,Q,{value:V,enumerable:!1,writable:!0,configurable:!1})}throw I}throw v}finally{clearTimeout(w),A&&k&&k.removeEventListener("abort",A)}}var X={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function de(o,t){let{onError:c,onEvent:k,catchUnexpected:D,workflowId:h,workflowName:C,context:w,_workflowSignal:A}=t&&typeof t=="object"?t:{},s=h??crypto.randomUUID(),U=D??Ie,v=[],I=0,V=p=>p??`step_${++I}`,u=p=>{let j=p.context!==void 0||w===void 0?p:{...p,context:w},q=C!==void 0&&j.workflowName===void 0?{...j,workflowName:C}:j;if(q.type==="step_success"){let te=q.stepId;for(let re=v.length-1;re>=0;re--){let L=v[re];if(L.type==="race"&&!L.winnerId){L.winnerId=te;break}}}k?.(q,w)},M=je,$=p=>Le(p),H=(p,j)=>p,_e=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 d={};for(let[r,n]of Object.entries(a))if(typeof n=="function")d[r]=n;else if(n&&typeof n=="object"&&"fn"in n)d[r]=n.fn;else throw new TypeError(`step.all: operation "${r}" must be a function or { fn, errors? } object`);return d},q=function(a,d){let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),e=!1;v.push({scopeId:r,type:"parallel"});let i=()=>{if(e)return;e=!0;let l=v.findIndex(m=>m.scopeId===r);l!==-1&&v.splice(l,1),u({type:"scope_end",workflowId:s,scopeId:r,ts:Date.now(),durationMs:performance.now()-n})};u({type:"scope_start",workflowId:s,scopeId:r,scopeType:"parallel",name:a,ts:Date.now()});try{let l=await d();if(i(),!l.ok)throw c?.(l.error,a,w),M(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw i(),l}})()},te=function(a,d){let r=Object.keys(a),n=d.name??`Parallel(${r.join(", ")})`,e=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let i=performance.now(),l=!1;v.push({scopeId:e,type:"parallel"});let m=()=>{if(l)return;l=!0;let E=v.findIndex(y=>y.scopeId===e);E!==-1&&v.splice(E,1),u({type:"scope_end",workflowId:s,scopeId:e,ts:Date.now(),durationMs:performance.now()-i})};u({type:"scope_start",workflowId:s,scopeId:e,scopeType:"parallel",name:n,ts:Date.now()});try{let E=await new Promise(g=>{if(r.length===0){g([]);return}let S=!1,O=r.length,T=new Array(r.length);for(let _=0;_<r.length;_++){let R=r[_],b=_;Promise.resolve(a[R]()).catch(x=>F({type:"PROMISE_REJECTED",cause:x},{cause:{type:"PROMISE_REJECTION",reason:x}})).then(x=>{if(!S){if(!x.ok){S=!0,g([{key:R,result:x}]);return}T[b]={key:R,result:x},O--,O===0&&g(T)}})}});m();let y={};for(let{key:g,result:S}of E){if(!S.ok)throw c?.(S.error,g,w),M(S.error,{origin:"result",resultCause:S.cause});y[g]=S.value}return y}catch(E){throw m(),E}})()};var Ye=j,ze=q,Je=te;let p=(a,d,r)=>(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 n=r??{},e=Ne(n),i=a,l=n.key??a,m=n.key??a,{description:E,retry:y,timeout:g}=n,S=V(l),O=k,T=O?performance.now():0,R=_e(d)?()=>d:d,x={attempts:Math.max(1,y?.attempts??1),backoff:y?.backoff??X.backoff,initialDelay:y?.initialDelay??X.initialDelay,maxDelay:y?.maxDelay??X.maxDelay,jitter:y?.jitter??X.jitter,shouldRetry:y?.shouldRetry??X.shouldRetry,onRetry:y?.onRetry??X.onRetry};k&&u({type:"step_start",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),...e&&{metadata:e}});let J;for(let P=1;P<=x.attempts;P++){let ve=O?performance.now():0;try{let f;if(g?f=await $e(R,g,{name:i,key:l,attempt:P},A):f=await R(),f.ok){let z=performance.now()-T;return u({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:z,...e&&{metadata:e}}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:E,ts:Date.now(),durationMs:z,result:f,...e&&{metadata:e}}),f.value}if(J=f,P<x.attempts&&x.shouldRetry(f.error,P)){let z=le(P,x);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:P+1,maxAttempts:x.attempts,delayMs:z,error:f.error,...e&&{metadata:e},diagnostics:K(f.error,n.errorMeta,"result",P,performance.now()-T)}),x.onRetry(f.error,P,z),await pe(z);continue}x.attempts>1&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-T,attempts:P,lastError:f.error,...e&&{metadata:e},diagnostics:K(f.error,n.errorMeta,"result",P,performance.now()-T)});break}catch(f){let z=performance.now()-ve;if(Ve(f)){let W=f.ms;u({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),timeoutMs:W,attempt:P,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"timeout",P)}),u({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:performance.now()-T,...e&&{metadata:e}}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:E,ts:Date.now(),durationMs:performance.now()-T,result:B(void 0),...e&&{metadata:e}});return}if($(f))throw u({type:"step_aborted",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:z,...e&&{metadata:e}}),f;if(he(f)){let W=Ke(f),Oe=g?.ms??W?.timeoutMs??0;if(u({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),timeoutMs:Oe,attempt:P,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"timeout",P)}),P<x.attempts&&x.shouldRetry(f,P)){let ce=le(P,x);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:P+1,maxAttempts:x.attempts,delayMs:ce,error:f,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"timeout",P,performance.now()-T)}),x.onRetry(f,P,ce),await pe(ce);continue}x.attempts>1&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-T,attempts:P,lastError:f,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"timeout",P,performance.now()-T)});let ue=performance.now()-T;throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:ue,error:f,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"timeout",P,ue)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:E,ts:Date.now(),durationMs:ue,result:F(f,{cause:f}),meta:{origin:"throw",thrown:f},...e&&{metadata:e}}),c?.(f,i,w),M(f,{origin:"throw",thrown:f})}if(P<x.attempts&&x.shouldRetry(f,P)){let W=le(P,x);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:P+1,maxAttempts:x.attempts,delayMs:W,error:f,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"throw",P,performance.now()-T)}),x.onRetry(f,P,W),await pe(W);continue}x.attempts>1&&!he(f)&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-T,attempts:P,lastError:f,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"throw",P,performance.now()-T)});let ie=performance.now()-T,Z;try{Z=U(f)}catch(W){throw G(W)}throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:ie,error:Z,...e&&{metadata:e},diagnostics:K(f,n.errorMeta,"throw",P,ie)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:E,ts:Date.now(),durationMs:ie,result:F(Z,{cause:f}),meta:{origin:"throw",thrown:f},...e&&{metadata:e}}),c?.(Z,i,w),M(Z,{origin:"throw",thrown:f})}}let Y=J,se=performance.now()-T,ae=H(Y.error,{origin:"result",resultCause:Y.cause});throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:E,ts:Date.now(),durationMs:se,error:ae,...e&&{metadata:e},diagnostics:K(Y.error,n.errorMeta,"result",x.attempts,se)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:E,ts:Date.now(),durationMs:se,result:Y,meta:{origin:"result",resultCause:Y.cause},...e&&{metadata:e}}),c?.(ae,i,w),M(ae,{origin:"result",resultCause:Y.cause})})();p.try=(a,d,r)=>{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 n="error"in r?()=>r.error:r.onError;if(r.retry||r.timeout)return p.retry(a,async()=>{try{return B(await d())}catch(E){return F(n(E),{cause:E})}},{attempts:r.retry?.attempts??1,...r.retry??{},key:r.key,timeout:r.timeout});let e=r.key??a,i=a,l=a,m=k;return(async()=>{let E=m?performance.now():0;k&&u({type:"step_start",workflowId:s,stepId:l,stepKey:e,name:i,ts:Date.now()});try{let y=await d(),g=performance.now()-E;return u({type:"step_success",workflowId:s,stepId:l,stepKey:e,name:i,ts:Date.now(),durationMs:g}),e&&u({type:"step_complete",workflowId:s,stepKey:e,name:i,ts:Date.now(),durationMs:g,result:B(y)}),y}catch(y){let g=n(y),S=performance.now()-E,O=H(g,{origin:"throw",thrown:y});throw u({type:"step_error",workflowId:s,stepId:l,stepKey:e,name:i,ts:Date.now(),durationMs:S,error:O}),e&&u({type:"step_complete",workflowId:s,stepKey:e,name:i,ts:Date.now(),durationMs:S,result:F(g,{cause:y}),meta:{origin:"throw",thrown:y}}),c?.(O,i,w),M(O,{origin:"throw",thrown:y})}})()},p.fromResult=(a,d,r)=>{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 n=r.key??a,e=a,i=a,l="error"in r?()=>r.error:r.onError,m=k;return(async()=>{let E=m?performance.now():0;k&&u({type:"step_start",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now()});let y=await d();if(y.ok){let g=performance.now()-E;return u({type:"step_success",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:g}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:g,result:B(y.value)}),y.value}else{let g=l(y.error),S=performance.now()-E,O=H(g,{origin:"result",resultCause:y.error});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:S,error:O}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:S,result:F(g,{cause:y.error}),meta:{origin:"result",resultCause:y.error}}),c?.(O,e,w),M(O,{origin:"result",resultCause:y.error})}})()},p.fromNullable=(a,d,r,n)=>{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 d();return e!=null?B(e):F(r())},n)},p.retry=(a,d,r)=>{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,d,{key:r.key??a,retry:{attempts:r.attempts,backoff:r.backoff,initialDelay:r.initialDelay,maxDelay:r.maxDelay,jitter:r.jitter,shouldRetry:r.shouldRetry,onRetry:r.onRetry},timeout:r.timeout})},p.withTimeout=(a,d,r)=>{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,d,{key:r.key??a,timeout:r})},p.sleep=(a,d,r)=>{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 n=typeof d=="string"?Me(d):d;if(!n)throw new Error(`step.sleep: invalid duration '${d}'`);let e=n.millis,i=r?.signal;return p(a,async()=>{if(A?.aborted||i?.aborted){let l=new Error("Sleep aborted");throw l.name="AbortError",l}return new Promise((l,m)=>{let E={timeoutId:void 0},y=()=>{E.timeoutId&&clearTimeout(E.timeoutId);let g=new Error("Sleep aborted");g.name="AbortError",m(g)};A?.addEventListener("abort",y,{once:!0}),i?.addEventListener("abort",y,{once:!0}),E.timeoutId=setTimeout(()=>{A?.removeEventListener("abort",y),i?.removeEventListener("abort",y),l(B(void 0))},e)})},{key:r?.key??a,description:r?.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 d=a[0],r=a[1];if(typeof r=="function")return q(d,r);if(r&&typeof r=="object"&&!Array.isArray(r)){let e=j(r);return te(e,{name:d})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(a,d)=>{let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),e=!1,i={scopeId:r,type:"race",winnerId:void 0};v.push(i);let l=()=>{if(e)return;e=!0;let m=v.findIndex(E=>E.scopeId===r);m!==-1&&v.splice(m,1),u({type:"scope_end",workflowId:s,scopeId:r,ts:Date.now(),durationMs:performance.now()-n,winnerId:i.winnerId})};u({type:"scope_start",workflowId:s,scopeId:r,scopeType:"race",name:a,ts:Date.now()});try{let m=await d();if(l(),!m.ok)throw c?.(m.error,a,w),M(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw l(),m}})()},p.if=(a,d,r)=>r(),p.label=p.if,p.branch=async(a,d)=>{let{condition:r,then:n,else:e}=d;if(r())return await n();if(e)return await e()},p.arm=(a,d)=>({fn:a,errors:d}),p.forEach=async(a,d,r)=>{let n=[],e=r.maxIterations,i=0,l="run"in r,m=Symbol.asyncIterator in d?d:(async function*(){yield*d})();for await(let E of m){if(e!==void 0&&i>=e)break;let y;l?y=await r.run(E,i):y=await r.item.handler(E,i,p),n.push(y),i++}return n},p.item=a=>({__forEachItemHandler:!0,handler:a}),p.dep=(a,d)=>d,p.workflow=(a,d,r)=>p(a,d,r),p.map=async(a,d,r,n)=>{let e=n?.concurrency??d.length;return p(a,()=>e>=d.length?be(d.map((i,l)=>r(i,l))):(async()=>{let i=[];for(let l=0;l<d.length;l+=e){let m=d.slice(l,l+e),E=await be(m.map((y,g)=>r(y,l+g)));if(!E.ok)return E;i.push(...E.value)}return B(i)})(),{key:n?.key})},p.withFallback=(a,d,r)=>{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 n=r.key??a,e=a,i=V(n),l=k;return(async()=>{let m=l?performance.now():0;k&&u({type:"step_start",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now()});let E;try{E=await d()}catch(T){if($(T))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:performance.now()-m}),T;let _;try{_=U(T)}catch(b){throw G(b)}if(r.on!==void 0&&r.on!==_){let b=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:b,error:_}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:b,result:F(_,{cause:T}),meta:{origin:"throw",thrown:T}}),c?.(_,e,w),M(_,{origin:"throw",thrown:T})}let R;try{R=await r.fallback()}catch(b){if($(b))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:performance.now()-m}),b;let x;try{x=U(b)}catch(Y){throw G(Y)}let J=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:J,error:x}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:J,result:F(x,{cause:b}),meta:{origin:"throw",thrown:b}}),c?.(x,e,w),M(x,{origin:"throw",thrown:b})}if(R.ok){let b=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:b}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:b,result:R,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(_)}}),R.value}else{let b=performance.now()-m,x=H(R.error,{origin:"result",resultCause:R.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:b,error:x}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:b,result:R,meta:{origin:"result",resultCause:R.cause}}),c?.(x,e,w),M(x,{origin:"result",resultCause:R.cause})}}if(E.ok){let T=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:T}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:T,result:E}),E.value}let y=E.error;if(r.on!==void 0&&r.on!==y){let T=performance.now()-m,_=H(y,{origin:"result",resultCause:E.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:T,error:_}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:T,result:E,meta:{origin:"result",resultCause:E.cause}}),c?.(_,e,w),M(_,{origin:"result",resultCause:E.cause})}let g;try{g=await r.fallback()}catch(T){if($(T))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:performance.now()-m}),T;let _;try{_=U(T)}catch(b){throw G(b)}let R=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:R,error:_}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:R,result:F(_,{cause:T}),meta:{origin:"throw",thrown:T}}),c?.(_,e,w),M(_,{origin:"throw",thrown:T})}if(g.ok){let T=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:T}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:T,result:g,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(y)}}),g.value}let S=performance.now()-m,O=H(g.error,{origin:"result",resultCause:g.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:n,name:e,ts:Date.now(),durationMs:S,error:O}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:e,ts:Date.now(),durationMs:S,result:g,meta:{origin:"result",resultCause:g.cause}}),c?.(O,e,w),M(O,{origin:"result",resultCause:g.cause})})()},p.withResource=(a,d)=>{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 r=a,n=a,e=V(r),i=k;return(async()=>{let l=i?performance.now():0;k&&u({type:"step_start",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now()});let m;try{m=await d.acquire()}catch(R){if($(R))throw u({type:"step_aborted",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:performance.now()-l}),R;let b;try{b=U(R)}catch(J){throw G(J)}let x=performance.now()-l;throw u({type:"step_error",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:x,error:b}),r&&u({type:"step_complete",workflowId:s,stepKey:r,name:n,ts:Date.now(),durationMs:x,result:F(b,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(b,n,w),M(b,{origin:"throw",thrown:R})}if(!m.ok){let R=performance.now()-l,b=H(m.error,{origin:"result",resultCause:m.cause});throw u({type:"step_error",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:R,error:b}),r&&u({type:"step_complete",workflowId:s,stepKey:r,name:n,ts:Date.now(),durationMs:R,result:m,meta:{origin:"result",resultCause:m.cause}}),c?.(b,n,w),M(b,{origin:"result",resultCause:m.cause})}let E=m.value,y,g,S=!1;try{y=await d.use(E)}catch(R){if($(R)){try{await d.release(E)}catch(b){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,b)}throw R}g=R,S=!0}try{await d.release(E)}catch(R){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,R)}if(S){let R;try{R=U(g)}catch(x){throw G(x)}let b=performance.now()-l;throw u({type:"step_error",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:b,error:R}),r&&u({type:"step_complete",workflowId:s,stepKey:r,name:n,ts:Date.now(),durationMs:b,result:F(R,{cause:g}),meta:{origin:"throw",thrown:g}}),c?.(R,n,w),M(R,{origin:"throw",thrown:g})}let O=y;if(O.ok){let R=performance.now()-l;return u({type:"step_success",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:R}),r&&u({type:"step_complete",workflowId:s,stepKey:r,name:n,ts:Date.now(),durationMs:R,result:O}),O.value}let T=performance.now()-l,_=H(O.error,{origin:"result",resultCause:O.cause});throw u({type:"step_error",workflowId:s,stepId:e,stepKey:r,name:n,ts:Date.now(),durationMs:T,error:_}),r&&u({type:"step_complete",workflowId:s,stepKey:r,name:n,ts:Date.now(),durationMs:T,result:O,meta:{origin:"result",resultCause:O.cause}}),c?.(_,n,w),M(_,{origin:"result",resultCause:O.cause})})()};let L=await o({step:p});if(process.env.NODE_ENV!=="production"&&L!==null&&typeof L=="object"&&"ok"in L&&typeof L.ok=="boolean"){let a=L;(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 B(L)}catch(p){if(Be(p))throw p.thrown;if($(p)){let q=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return F(p.error,{cause:q})}let j=U(p);return c?.(j,"unexpected",w),F(j,{cause:p})}}var Pe=de;de.strict=(o,t)=>de(o,t);async function be(o){return o.length===0?B([]):new Promise(t=>{let c=!1,k=o.length,D=new Array(o.length);for(let h=0;h<o.length;h++){let C=h;Promise.resolve(o[C]).catch(w=>F({type:"PROMISE_REJECTED",cause:w},{cause:{type:"PROMISE_REJECTION",reason:w}})).then(w=>{if(!c){if(!w.ok){c=!0,t(w);return}D[C]=w.value,k--,k===0&&t(B(D))}})}})}var We=o=>typeof o=="object"&&o!==null,He=o=>We(o)&&o.ok===!1&&!("error"in o);function qe(o,t,c){return Pe(async({step:k})=>{let D=k,h=k,C={};for(let A of Object.keys(o)){let s=o[A];if(typeof s=="function"){let U=s;C[A]=(...v)=>D(A,async()=>{let I=await Reflect.apply(U,o,v);if(He(I))throw new TypeError(`flow(${A}) expected Err to include an error field`);return I})}else C[A]=s}return t(C,{raw:o,key:((A,s)=>D(A,s)),all:((A,s)=>h.all(A,s))})},{catchUnexpected:c?.catchUnexpected,onEvent:c?.onEvent})}export{qe as flow};
|
|
7
|
-
//# sourceMappingURL=flow.js.map
|