@lunora/workflow 1.0.0-alpha.5 → 1.0.0-alpha.51
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/LICENSE.md +6 -0
- package/README.md +25 -2
- package/dist/do/index.d.mts +16 -16
- package/dist/do/index.d.ts +16 -16
- package/dist/do/index.mjs +1 -44
- package/dist/index.d.mts +187 -124
- package/dist/index.d.ts +187 -124
- package/dist/index.mjs +1 -9
- package/dist/packem_shared/MAX_BRANCHES-j59ZUUSu.mjs +1 -0
- package/dist/packem_shared/NonRetryableError-BPu01mU8.mjs +1 -0
- package/dist/packem_shared/WorkflowsRestError-Ccq1FUR1.mjs +1 -0
- package/dist/packem_shared/branch-marker-CCpWfS5k.mjs +1 -0
- package/dist/packem_shared/createRunStep-DnLETYtC.mjs +1 -0
- package/dist/packem_shared/createWaitForEvent-D5Ohn2Pz.mjs +1 -0
- package/dist/packem_shared/createWorkflowContext-zQR_9N-v.mjs +1 -0
- package/dist/packem_shared/createWorkflowRunContext-C03ogm48.mjs +1 -0
- package/dist/packem_shared/createWorkflows-LvAyUyKq.mjs +1 -0
- package/dist/packem_shared/defineStep-D1-9eOnA.mjs +1 -0
- package/dist/packem_shared/defineWorkflow-tKaIifbZ.mjs +1 -0
- package/dist/packem_shared/defineWorkflowEvent-suERPEEV.mjs +1 -0
- package/dist/packem_shared/isDuplicateInstanceError-CecnqNAa.mjs +1 -0
- package/dist/packem_shared/run-step-CFhxLFfp.mjs +1 -0
- package/dist/packem_shared/{types.d-C9W6rEWv.d.mts → types.d-C7jti0tm.d.mts} +221 -124
- package/dist/packem_shared/{types.d-C9W6rEWv.d.ts → types.d-C7jti0tm.d.ts} +221 -124
- package/package.json +3 -2
- package/dist/packem_shared/MAX_BRANCHES-D6cQabJ1.mjs +0 -132
- package/dist/packem_shared/NonRetryableError-Dn2dTyBS.mjs +0 -27
- package/dist/packem_shared/WorkflowsRestError-b06i7K5j.mjs +0 -118
- package/dist/packem_shared/createRunStep-8jOXxP2o.mjs +0 -54
- package/dist/packem_shared/createWorkflowContext-D6thzmlF.mjs +0 -14
- package/dist/packem_shared/createWorkflowRunContext-CYI9SeI9.mjs +0 -110
- package/dist/packem_shared/createWorkflows-BoSYVIXg.mjs +0 -23
- package/dist/packem_shared/defineStep-DJQtLw7g.mjs +0 -28
- package/dist/packem_shared/defineWorkflow-DbUC-oCN.mjs +0 -15
|
@@ -1,21 +1,46 @@
|
|
|
1
1
|
import { ValidatorMap, InferValidatorMap, Validator } from '@lunora/values';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
* The generated function-reference type, shared by every package that needs to
|
|
4
|
+
* infer a call's args or return from `api.<file>.<fn>`.
|
|
5
|
+
*
|
|
6
|
+
* This lives in `shared/` rather than in one package because the consumers span
|
|
7
|
+
* a dependency boundary they must not cross: `@lunora/scheduler` and
|
|
8
|
+
* `@lunora/workflow` accept a reference in `runAfter`/`runAt`/`step.run*` but
|
|
9
|
+
* cannot depend on `@lunora/client`, which is a browser package. Each of them
|
|
10
|
+
* previously hand-copied this declaration, and both copies silently rotted when
|
|
11
|
+
* the phantom carrier was renamed — the conditional matched an OPTIONAL property
|
|
12
|
+
* that no longer existed, so `ArgsOf<F>` quietly resolved to `unknown` and every
|
|
13
|
+
* `step.run(ref, args)` in the repo lost its arg checking without a single error.
|
|
14
|
+
*
|
|
15
|
+
* `shared/` is the repo's answer to exactly that shape: bundler-inlined,
|
|
16
|
+
* zero-dependency source imported by relative path, so it creates no runtime
|
|
17
|
+
* edge between the packages that inline it. Being ONE declaration, there is
|
|
18
|
+
* nothing to keep in lockstep and no drift test to write.
|
|
19
|
+
*/
|
|
20
|
+
/** The registered function kinds a {@link FunctionReference} can describe. `stream` is a query that yields multiple frames over the WS. */
|
|
21
|
+
type FunctionKind = "action" | "mutation" | "query" | "stream";
|
|
22
|
+
/**
|
|
23
|
+
* Opaque reference to a registered function emitted by `@lunora/codegen`.
|
|
24
|
+
*
|
|
25
|
+
* At runtime it carries the `<file>:<function>` identifier in `__lunoraRef`.
|
|
26
|
+
* Generated declarations decorate this with phantom type parameters so callers
|
|
27
|
+
* can infer args / return values per call site.
|
|
28
|
+
*/
|
|
29
|
+
interface FunctionReference<Kind extends FunctionKind = FunctionKind, Args = unknown, Return = unknown> {
|
|
30
|
+
/**
|
|
31
|
+
* Phantom marker carrying the `Kind`/`Args`/`Return` type parameters for
|
|
32
|
+
* inference. Never present at runtime; declared as a covariant (output)
|
|
33
|
+
* position so a concrete reference stays assignable to a widened one.
|
|
34
|
+
*/
|
|
35
|
+
readonly __lunoraPhantom?: {
|
|
36
|
+
args: Args;
|
|
37
|
+
kind: Kind;
|
|
38
|
+
returns: Return;
|
|
39
|
+
};
|
|
12
40
|
readonly __lunoraRef: string;
|
|
13
|
-
/** Marker phantom type — discriminates queries / mutations / actions. */
|
|
14
|
-
readonly _kind?: "query" | "mutation" | "action";
|
|
15
41
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} ? A : Record<string, unknown>;
|
|
42
|
+
/** Extract the args type from a {@link FunctionReference}. */
|
|
43
|
+
type ArgsOf<F> = F extends FunctionReference<infer _K, infer A, infer _R> ? A : never;
|
|
19
44
|
/** A workflow instance's lifecycle status. Mirrors `WorkflowInstanceStatus`. */
|
|
20
45
|
type WorkflowInstanceStatus = "complete" | "errored" | "paused" | "queued" | "running" | "terminated" | "unknown" | "waiting" | "waitingForPause";
|
|
21
46
|
/** Result of `WorkflowInstance.status()`. Mirrors Cloudflare's `InstanceStatus`. */
|
|
@@ -53,17 +78,17 @@ interface WorkflowInstanceLike {
|
|
|
53
78
|
terminate: () => Promise<void>;
|
|
54
79
|
}
|
|
55
80
|
/**
|
|
56
|
-
* The subset of the Cloudflare `Workflow` binding the package consumes.
|
|
57
|
-
* `createBatch` is a non-optional method on the real binding (Cloudflare's
|
|
58
|
-
* `Workflow` class declares it unconditionally), so it is required here too —
|
|
59
|
-
* the handle never has to guard for its absence.
|
|
60
|
-
*/
|
|
81
|
+
* The subset of the Cloudflare `Workflow` binding the package consumes.
|
|
82
|
+
* `createBatch` is a non-optional method on the real binding (Cloudflare's
|
|
83
|
+
* `Workflow` class declares it unconditionally), so it is required here too —
|
|
84
|
+
* the handle never has to guard for its absence.
|
|
85
|
+
*/
|
|
61
86
|
interface WorkflowBindingLike<Params = Record<string, unknown>> {
|
|
62
87
|
create: (options?: WorkflowCreateOptions<Params>) => Promise<WorkflowInstanceLike>;
|
|
63
88
|
createBatch: (batch: ReadonlyArray<WorkflowCreateOptions<Params>>) => Promise<WorkflowInstanceLike[]>;
|
|
64
89
|
get: (id: string) => Promise<WorkflowInstanceLike>;
|
|
65
90
|
}
|
|
66
|
-
/** The `event` argument a workflow `run` receives. Mirrors `WorkflowEvent
|
|
91
|
+
/** The `event` argument a workflow `run` receives. Mirrors `WorkflowEvent<T>`. */
|
|
67
92
|
interface WorkflowEventLike<Params = Record<string, unknown>> {
|
|
68
93
|
readonly instanceId: string;
|
|
69
94
|
readonly payload: Readonly<Params>;
|
|
@@ -80,10 +105,10 @@ interface WorkflowStepConfigLike {
|
|
|
80
105
|
timeout?: number | string;
|
|
81
106
|
}
|
|
82
107
|
/**
|
|
83
|
-
* The per-attempt info Cloudflare passes a `step.do` callback. Mirrors
|
|
84
|
-
* `WorkflowStepContext` — `attempt` is the 1-based retry counter (`> 1` on
|
|
85
|
-
* retries) and `step` carries the durable step's name + invocation count.
|
|
86
|
-
*/
|
|
108
|
+
* The per-attempt info Cloudflare passes a `step.do` callback. Mirrors
|
|
109
|
+
* `WorkflowStepContext` — `attempt` is the 1-based retry counter (`> 1` on
|
|
110
|
+
* retries) and `step` carries the durable step's name + invocation count.
|
|
111
|
+
*/
|
|
87
112
|
interface WorkflowStepContextLike {
|
|
88
113
|
/** 1-based attempt counter — `> 1` means this is a retry. */
|
|
89
114
|
attempt: number;
|
|
@@ -114,19 +139,19 @@ interface WorkflowStepRollbackOptionsLike<T = unknown> {
|
|
|
114
139
|
rollbackConfig?: WorkflowStepConfigLike;
|
|
115
140
|
}
|
|
116
141
|
/**
|
|
117
|
-
* The durable step API Cloudflare hands the workflow body. Mirrors
|
|
118
|
-
* `WorkflowStep` — `do` memoizes + retries its callback, `sleep`/`sleepUntil`
|
|
119
|
-
* are durable delays, and `waitForEvent` hibernates until an external event.
|
|
120
|
-
* `do`'s two overloads mirror Cloudflare's: an optional leading `config` and an
|
|
121
|
-
* optional trailing `rollback` (compensation run when a later step fails).
|
|
122
|
-
*
|
|
123
|
-
* Known mirror gap: Cloudflare constrains `do
|
|
124
|
-
* a non-serializable step result (a function, `Map`, class instance, …) is a
|
|
125
|
-
* compile error there. `Rpc.Serializable` lives in `@cloudflare/workers-types`
|
|
126
|
-
* and is not Node-importable, so this Node-safe mirror uses a bare
|
|
127
|
-
* cannot enforce that — a non-serializable result type-checks here but fails at
|
|
128
|
-
* runtime on the platform. Keep step results JSON-serialisable.
|
|
129
|
-
*/
|
|
142
|
+
* The durable step API Cloudflare hands the workflow body. Mirrors
|
|
143
|
+
* `WorkflowStep` — `do` memoizes + retries its callback, `sleep`/`sleepUntil`
|
|
144
|
+
* are durable delays, and `waitForEvent` hibernates until an external event.
|
|
145
|
+
* `do`'s two overloads mirror Cloudflare's: an optional leading `config` and an
|
|
146
|
+
* optional trailing `rollback` (compensation run when a later step fails).
|
|
147
|
+
*
|
|
148
|
+
* Known mirror gap: Cloudflare constrains `do<T extends Rpc.Serializable<T>>` so
|
|
149
|
+
* a non-serializable step result (a function, `Map`, class instance, …) is a
|
|
150
|
+
* compile error there. `Rpc.Serializable` lives in `@cloudflare/workers-types`
|
|
151
|
+
* and is not Node-importable, so this Node-safe mirror uses a bare `<T>` and
|
|
152
|
+
* cannot enforce that — a non-serializable result type-checks here but fails at
|
|
153
|
+
* runtime on the platform. Keep step results JSON-serialisable.
|
|
154
|
+
*/
|
|
130
155
|
interface WorkflowStepLike {
|
|
131
156
|
do: {
|
|
132
157
|
<T>(name: string, callback: (context: WorkflowStepContextLike) => Promise<T>, rollback?: WorkflowStepRollbackOptionsLike<T>): Promise<T>;
|
|
@@ -155,25 +180,25 @@ interface RunFunctionOptions {
|
|
|
155
180
|
shardKey?: string;
|
|
156
181
|
}
|
|
157
182
|
/**
|
|
158
|
-
* Calls a Lunora query / mutation / action from inside a workflow and resolves
|
|
159
|
-
* with its result. Wrap it in {@link WorkflowStepLike.do} to make the call a
|
|
160
|
-
* durable, memoized, retried step:
|
|
161
|
-
*
|
|
162
|
-
* ```ts
|
|
163
|
-
* const charge = await ctx.step.do("charge", () => ctx.run(api.payments.charge, { id }));
|
|
164
|
-
* ```
|
|
165
|
-
*/
|
|
183
|
+
* Calls a Lunora query / mutation / action from inside a workflow and resolves
|
|
184
|
+
* with its result. Wrap it in {@link WorkflowStepLike.do} to make the call a
|
|
185
|
+
* durable, memoized, retried step:
|
|
186
|
+
*
|
|
187
|
+
* ```ts
|
|
188
|
+
* const charge = await ctx.step.do("charge", () => ctx.run(api.payments.charge, { id }));
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
166
191
|
type WorkflowRunFunction = <F extends FunctionReference>(function_: F, args?: ArgsOf<F>, options?: RunFunctionOptions) => Promise<unknown>;
|
|
167
192
|
/** Map of validators describing a step's args record — the same shape a Lunora function's `args` uses. Alias of `@lunora/values`' shared {@link ValidatorMap}. */
|
|
168
193
|
type StepArgsValidator = ValidatorMap;
|
|
169
194
|
/** Infer the args object type from a {@link StepArgsValidator} (optional validators → optional keys). Alias of `@lunora/values`' shared {@link InferValidatorMap}. */
|
|
170
195
|
type InferStepArgs<A extends StepArgsValidator> = InferValidatorMap<A>;
|
|
171
196
|
/**
|
|
172
|
-
* The context a {@link StepDefinition} handler receives as its first argument
|
|
173
|
-
* (the validated args are the second). Bundles the native per-attempt info
|
|
174
|
-
* (`attempt`, `config`, `step`) with the Worker `env`, the Lunora runner, and a
|
|
175
|
-
* logger.
|
|
176
|
-
*/
|
|
197
|
+
* The context a {@link StepDefinition} handler receives as its first argument
|
|
198
|
+
* (the validated args are the second). Bundles the native per-attempt info
|
|
199
|
+
* (`attempt`, `config`, `step`) with the Worker `env`, the Lunora runner, and a
|
|
200
|
+
* logger.
|
|
201
|
+
*/
|
|
177
202
|
interface StepRunContext {
|
|
178
203
|
/** 1-based retry counter — `> 1` means Cloudflare is retrying the step. */
|
|
179
204
|
readonly attempt: number;
|
|
@@ -226,10 +251,10 @@ interface StepConfig<A extends StepArgsValidator, Result> {
|
|
|
226
251
|
rollbackConfig?: WorkflowStepConfigLike;
|
|
227
252
|
}
|
|
228
253
|
/**
|
|
229
|
-
* A `defineStep` result — a reusable, schema-validated durable step. Run it from
|
|
230
|
-
* a workflow body with `ctx.runStep(step, args)`. The phantom generics carry the
|
|
231
|
-
* inferred args + result types to the call site.
|
|
232
|
-
*/
|
|
254
|
+
* A `defineStep` result — a reusable, schema-validated durable step. Run it from
|
|
255
|
+
* a workflow body with `ctx.runStep(step, args)`. The phantom generics carry the
|
|
256
|
+
* inferred args + result types to the call site.
|
|
257
|
+
*/
|
|
233
258
|
interface StepDefinition<A extends StepArgsValidator = StepArgsValidator, Result = unknown> {
|
|
234
259
|
/** Validators for the step's args. */
|
|
235
260
|
readonly args: A;
|
|
@@ -252,35 +277,93 @@ interface StepDefinition<A extends StepArgsValidator = StepArgsValidator, Result
|
|
|
252
277
|
interface RunStepOptions {
|
|
253
278
|
/** Override the step's declared durability config for this call. */
|
|
254
279
|
config?: WorkflowStepConfigLike;
|
|
280
|
+
/**
|
|
281
|
+
* Override the durable step name for this call. Cloudflare keys a durable
|
|
282
|
+
* step by name **and occurrence** (`step.count` counts the calls made under
|
|
283
|
+
* one name in a run), so reusing a name in a loop is fine and each
|
|
284
|
+
* occurrence caches independently — this is for giving a call its own
|
|
285
|
+
* addressable name, e.g. to target it with `instance.restart({ from })`.
|
|
286
|
+
* Must be deterministic across replays, like any step name.
|
|
287
|
+
*/
|
|
288
|
+
name?: string;
|
|
255
289
|
}
|
|
256
290
|
/**
|
|
257
|
-
* Run a reusable {@link StepDefinition} as a durable, memoized, retried step:
|
|
258
|
-
* validates the args before the body runs and the result after (when the step
|
|
259
|
-
* declares `returns`), and forwards any rollback handler to Cloudflare.
|
|
260
|
-
*
|
|
261
|
-
* ```ts
|
|
262
|
-
* const data = await ctx.runStep(fetchImage, { imageKey });
|
|
263
|
-
* ```
|
|
264
|
-
*/
|
|
291
|
+
* Run a reusable {@link StepDefinition} as a durable, memoized, retried step:
|
|
292
|
+
* validates the args before the body runs and the result after (when the step
|
|
293
|
+
* declares `returns`), and forwards any rollback handler to Cloudflare.
|
|
294
|
+
*
|
|
295
|
+
* ```ts
|
|
296
|
+
* const data = await ctx.runStep(fetchImage, { imageKey });
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
265
299
|
type WorkflowRunStepFunction = <A extends StepArgsValidator, Result>(step: StepDefinition<A, Result>, args: InferStepArgs<A>, options?: RunStepOptions) => Promise<Result>;
|
|
266
300
|
/**
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
|
|
301
|
+
* A `defineWorkflowEvent` result — the single source of truth for one external
|
|
302
|
+
* event's wire `type` and payload shape. Both ends of the exchange import the same
|
|
303
|
+
* definition (`ctx.waitForEvent(orderApproved)` inside the workflow,
|
|
304
|
+
* `workflows.get(w).sendEvent(id, orderApproved, payload)` from the caller), so
|
|
305
|
+
* there is no string to typo and no second place to update on a rename, and the
|
|
306
|
+
* payload is parsed at both ends instead of crossing as `unknown`.
|
|
307
|
+
*
|
|
308
|
+
* It does NOT make every mismatch a compile error: two definitions with the same
|
|
309
|
+
* payload shape are mutually assignable, so sending `orderRejected` where the
|
|
310
|
+
* workflow awaits `orderApproved` still type-checks (and still hibernates until
|
|
311
|
+
* the timeout). What it removes is the hand-matched literal.
|
|
312
|
+
*/
|
|
313
|
+
interface WorkflowEventDefinition<Payload = unknown> {
|
|
314
|
+
/** Runtime brand check (see `isWorkflowEventDefinition`). */
|
|
315
|
+
readonly isLunoraWorkflowEvent: true;
|
|
316
|
+
/** Validator for the event payload — parsed on send and again on receive. */
|
|
317
|
+
readonly payload: Validator<Payload>;
|
|
318
|
+
/** The wire event type Cloudflare matches `sendEvent` against `waitForEvent`. */
|
|
319
|
+
readonly type: string;
|
|
320
|
+
}
|
|
321
|
+
/** Per-call options for {@link WorkflowWaitForEventFunction}. */
|
|
322
|
+
interface WaitForEventOptions {
|
|
323
|
+
/**
|
|
324
|
+
* The durable step label, defaulting to `event:<type>`.
|
|
325
|
+
*
|
|
326
|
+
* Cloudflare identifies a memoized step by this name, so the default couples
|
|
327
|
+
* step identity to the wire type: renaming the event type also renames the
|
|
328
|
+
* step, and an instance that already recorded the wait replays into a *fresh*
|
|
329
|
+
* one that nothing will ever satisfy. Pass a stable `name` on any wait that can
|
|
330
|
+
* outlive a deploy (an approval held for days), and to tell two waits on the
|
|
331
|
+
* same event type apart in the timeline.
|
|
332
|
+
*/
|
|
333
|
+
name?: string;
|
|
334
|
+
/** How long to wait before the wait rejects. Defaults to Cloudflare's 24h. */
|
|
335
|
+
timeout?: number | string;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Hibernate until a declared event is delivered to this instance, then resolve
|
|
339
|
+
* with its validated payload. The typed wrapper over
|
|
340
|
+
* {@link WorkflowStepLike.waitForEvent}: the event's `type` comes from the
|
|
341
|
+
* definition instead of a hand-written string, and the payload is parsed through
|
|
342
|
+
* the definition's validator before the workflow resumes on it.
|
|
343
|
+
*
|
|
344
|
+
* ```ts
|
|
345
|
+
* const { approvedBy } = await ctx.waitForEvent(orderApproved, { timeout: "1 hour" });
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
type WorkflowWaitForEventFunction = <Payload>(event: WorkflowEventDefinition<Payload>, options?: WaitForEventOptions) => Promise<Payload>;
|
|
349
|
+
/**
|
|
350
|
+
* One branch of a {@link WorkflowParallelFunction} fan-out — a declared child
|
|
351
|
+
* workflow (referenced by its `lunora/workflows.ts` export name) plus the params
|
|
352
|
+
* it is created with. The phantom `Output` carries the child's result type into
|
|
353
|
+
* the `ctx.parallel(...)` result tuple. Build one with the `branch(...)` helper.
|
|
354
|
+
*/
|
|
272
355
|
interface WorkflowBranch<Output = unknown> {
|
|
273
356
|
/** Phantom marker for the branch output type — never present at runtime. */
|
|
274
357
|
readonly __output?: Output;
|
|
275
358
|
/**
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
359
|
+
* Optional group-saga compensation (plan 075 Phase 3): the `lunora/workflows.ts`
|
|
360
|
+
* export name of a workflow to run if a **sibling** branch in the same
|
|
361
|
+
* `ctx.parallel(...)` group fails **after** this branch has already completed.
|
|
362
|
+
* It is spawned fire-and-forget (a durable, replay-safe idempotent create) with
|
|
363
|
+
* {@link BranchCompensationParams} as its `ctx.params`. Omit for no
|
|
364
|
+
* compensation — a group where no branch sets this behaves exactly as a plain
|
|
365
|
+
* fan-out (fail-fast, no rollback).
|
|
366
|
+
*/
|
|
284
367
|
readonly compensateWith?: string;
|
|
285
368
|
/** Optional explicit child instance id (defaults to a deterministic parent-derived id). */
|
|
286
369
|
readonly id?: string;
|
|
@@ -292,13 +375,13 @@ interface WorkflowBranch<Output = unknown> {
|
|
|
292
375
|
readonly workflow: string;
|
|
293
376
|
}
|
|
294
377
|
/**
|
|
295
|
-
* The `ctx.params` a group-saga compensation workflow (a branch's
|
|
296
|
-
* {@link WorkflowBranch.compensateWith}) receives when a sibling's failure rolls
|
|
297
|
-
* back the group. Everything is plain-serialisable — the compensation is an
|
|
298
|
-
* ordinary declared workflow, so it can `ctx.runStep(...)` its own undo logic.
|
|
299
|
-
*/
|
|
378
|
+
* The `ctx.params` a group-saga compensation workflow (a branch's
|
|
379
|
+
* {@link WorkflowBranch.compensateWith}) receives when a sibling's failure rolls
|
|
380
|
+
* back the group. Everything is plain-serialisable — the compensation is an
|
|
381
|
+
* ordinary declared workflow, so it can `ctx.runStep(...)` its own undo logic.
|
|
382
|
+
*/
|
|
300
383
|
interface BranchCompensationParams {
|
|
301
|
-
/** Index signature: this is a workflow `params` bag, so it is a valid `Record
|
|
384
|
+
/** Index signature: this is a workflow `params` bag, so it is a valid `Record<string, unknown>` payload. */
|
|
302
385
|
[key: string]: unknown;
|
|
303
386
|
/** The export name of the completed branch being compensated. */
|
|
304
387
|
branch: string;
|
|
@@ -313,20 +396,20 @@ interface BranchCompensationParams {
|
|
|
313
396
|
output?: unknown;
|
|
314
397
|
}
|
|
315
398
|
/** Map a tuple of {@link WorkflowBranch}es to the tuple of their output types, preserving order. */
|
|
316
|
-
type WorkflowBranchOutputs<B extends ReadonlyArray<WorkflowBranch>> = { -readonly [K in keyof B]: B[K] extends WorkflowBranch<infer Output> ? Output : never };
|
|
399
|
+
type WorkflowBranchOutputs<B extends ReadonlyArray<WorkflowBranch>> = { -readonly [K in keyof B]: B[K] extends WorkflowBranch<infer Output> ? Output : never; };
|
|
317
400
|
/**
|
|
318
|
-
* Run branches as isolated child workflow instances and resolve with their
|
|
319
|
-
* outputs in declaration order. Each branch gets its own Durable Object (own
|
|
320
|
-
* memory / CPU / retry budget); the parent hibernates while they execute. Rejects
|
|
321
|
-
* (non-retryable) on the first branch that fails.
|
|
322
|
-
*
|
|
323
|
-
* ```ts
|
|
324
|
-
* const [tags, thumb] = await ctx.parallel([
|
|
325
|
-
* branch("imageTag", { key }),
|
|
326
|
-
* branch("thumbnail", { key }),
|
|
327
|
-
* ]);
|
|
328
|
-
* ```
|
|
329
|
-
*/
|
|
401
|
+
* Run branches as isolated child workflow instances and resolve with their
|
|
402
|
+
* outputs in declaration order. Each branch gets its own Durable Object (own
|
|
403
|
+
* memory / CPU / retry budget); the parent hibernates while they execute. Rejects
|
|
404
|
+
* (non-retryable) on the first branch that fails.
|
|
405
|
+
*
|
|
406
|
+
* ```ts
|
|
407
|
+
* const [tags, thumb] = await ctx.parallel([
|
|
408
|
+
* branch("imageTag", { key }),
|
|
409
|
+
* branch("thumbnail", { key }),
|
|
410
|
+
* ]);
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
330
413
|
type WorkflowParallelFunction = <const B extends ReadonlyArray<WorkflowBranch>>(branches: B) => Promise<WorkflowBranchOutputs<B>>;
|
|
331
414
|
/** Per-call options for {@link WorkflowSpawnFunction}. */
|
|
332
415
|
interface WorkflowSpawnOptions {
|
|
@@ -334,17 +417,17 @@ interface WorkflowSpawnOptions {
|
|
|
334
417
|
id?: string;
|
|
335
418
|
}
|
|
336
419
|
/**
|
|
337
|
-
* Fire-and-forget start of a declared child workflow from inside a workflow body
|
|
338
|
-
* — replay-safe (idempotent create), returns a live handle to the child. Use
|
|
339
|
-
* {@link WorkflowParallelFunction} instead when you need to await results.
|
|
340
|
-
*/
|
|
420
|
+
* Fire-and-forget start of a declared child workflow from inside a workflow body
|
|
421
|
+
* — replay-safe (idempotent create), returns a live handle to the child. Use
|
|
422
|
+
* {@link WorkflowParallelFunction} instead when you need to await results.
|
|
423
|
+
*/
|
|
341
424
|
type WorkflowSpawnFunction = (workflow: string, params?: Record<string, unknown>, options?: WorkflowSpawnOptions) => Promise<WorkflowInstanceLike>;
|
|
342
425
|
/**
|
|
343
|
-
* The context object passed to a `defineWorkflow` handler. Bundles the native
|
|
344
|
-
* Cloudflare durability primitives (`step`, `event`) with the Lunora runner
|
|
345
|
-
* (`run`), the reusable-step runner (`runStep`), the fan-out primitives
|
|
346
|
-
* (`parallel` / `spawn`), the Worker `env`, and a logger.
|
|
347
|
-
*/
|
|
426
|
+
* The context object passed to a `defineWorkflow` handler. Bundles the native
|
|
427
|
+
* Cloudflare durability primitives (`step`, `event`) with the Lunora runner
|
|
428
|
+
* (`run`), the reusable-step runner (`runStep`), the fan-out primitives
|
|
429
|
+
* (`parallel` / `spawn`), the Worker `env`, and a logger.
|
|
430
|
+
*/
|
|
348
431
|
interface WorkflowRunContext<Params = Record<string, unknown>> {
|
|
349
432
|
/** The Worker environment bindings. */
|
|
350
433
|
readonly env: Record<string, unknown>;
|
|
@@ -364,6 +447,8 @@ interface WorkflowRunContext<Params = Record<string, unknown>> {
|
|
|
364
447
|
readonly spawn: WorkflowSpawnFunction;
|
|
365
448
|
/** The native Cloudflare Workflows durable-step API. */
|
|
366
449
|
readonly step: WorkflowStepLike;
|
|
450
|
+
/** Hibernate until a declared external event arrives; resolves with its validated payload. */
|
|
451
|
+
readonly waitForEvent: WorkflowWaitForEventFunction;
|
|
367
452
|
}
|
|
368
453
|
/** The workflow body. Receives a {@link WorkflowRunContext}, returns the output. */
|
|
369
454
|
type WorkflowHandler<Params = Record<string, unknown>, Output = unknown> = (context: WorkflowRunContext<Params>) => Output | Promise<Output>;
|
|
@@ -372,19 +457,19 @@ interface WorkflowConfig<Params = Record<string, unknown>, Output = unknown> {
|
|
|
372
457
|
/** The workflow body — the multi-step durable program. */
|
|
373
458
|
handler: WorkflowHandler<Params, Output>;
|
|
374
459
|
/**
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
460
|
+
* Optional override for the deployed workflow name — the `workflows[].name`
|
|
461
|
+
* written to `wrangler.jsonc`. Defaults to a kebab-cased form of the
|
|
462
|
+
* `lunora/workflows.ts` export name (`orderPipeline` → `order-pipeline`).
|
|
463
|
+
* This does NOT change the binding name, which is always derived from the
|
|
464
|
+
* export name (`orderPipeline` → `WORKFLOW_ORDER_PIPELINE`).
|
|
465
|
+
*/
|
|
381
466
|
name?: string;
|
|
382
467
|
}
|
|
383
468
|
/**
|
|
384
|
-
* A `defineWorkflow` result — the config plus the runtime brand codegen and the
|
|
385
|
-
* config layer use to discover it. The phantom `__params` / `__output` carry
|
|
386
|
-
* the inferred types to the generated `ctx.workflows` handle.
|
|
387
|
-
*/
|
|
469
|
+
* A `defineWorkflow` result — the config plus the runtime brand codegen and the
|
|
470
|
+
* config layer use to discover it. The phantom `__params` / `__output` carry
|
|
471
|
+
* the inferred types to the generated `ctx.workflows` handle.
|
|
472
|
+
*/
|
|
388
473
|
interface WorkflowDefinition<Params = Record<string, unknown>, Output = unknown> extends WorkflowConfig<Params, Output> {
|
|
389
474
|
/** Phantom marker for the output type — never present at runtime. */
|
|
390
475
|
readonly __output?: Output;
|
|
@@ -394,9 +479,10 @@ interface WorkflowDefinition<Params = Record<string, unknown>, Output = unknown>
|
|
|
394
479
|
readonly isLunoraWorkflow: true;
|
|
395
480
|
}
|
|
396
481
|
/**
|
|
397
|
-
* A typed handle to one declared workflow, addressable from `ctx.workflows`.
|
|
398
|
-
* Thin pass-through over the Cloudflare `Workflow` binding
|
|
399
|
-
|
|
482
|
+
* A typed handle to one declared workflow, addressable from `ctx.workflows`.
|
|
483
|
+
* Thin pass-through over the Cloudflare `Workflow` binding, plus the declared-event
|
|
484
|
+
* send (which the raw binding cannot type).
|
|
485
|
+
*/
|
|
400
486
|
interface WorkflowHandle<Params = Record<string, unknown>> {
|
|
401
487
|
/** Start a new instance (optionally with an id + params). */
|
|
402
488
|
create: (options?: WorkflowCreateOptions<Params>) => Promise<WorkflowInstanceLike>;
|
|
@@ -404,11 +490,22 @@ interface WorkflowHandle<Params = Record<string, unknown>> {
|
|
|
404
490
|
createBatch: (batch: ReadonlyArray<WorkflowCreateOptions<Params>>) => Promise<WorkflowInstanceLike[]>;
|
|
405
491
|
/** Get a handle to an existing instance by id. */
|
|
406
492
|
get: (id: string) => Promise<WorkflowInstanceLike>;
|
|
493
|
+
/**
|
|
494
|
+
* Deliver a declared event to one instance of this workflow — the typed
|
|
495
|
+
* counterpart of the workflow body's `ctx.waitForEvent`. The wire type comes
|
|
496
|
+
* from the definition (never a hand-written string) and the payload is parsed
|
|
497
|
+
* through the definition's validator **before** the send, so a bad value fails
|
|
498
|
+
* the caller's request instead of waking the workflow on garbage.
|
|
499
|
+
*
|
|
500
|
+
* Mirrors `ctx.agents.<name>.sendEvent(id, …)`: the instance is addressed by
|
|
501
|
+
* id rather than by holding an instance handle, so the common case is one call.
|
|
502
|
+
*/
|
|
503
|
+
sendEvent: <Payload>(instanceId: string, event: WorkflowEventDefinition<Payload>, payload: Payload) => Promise<void>;
|
|
407
504
|
}
|
|
408
505
|
/**
|
|
409
|
-
* The `ctx.workflows` surface available on `MutationCtx` and `ActionCtx`. Each
|
|
410
|
-
* declared workflow is reachable by its `lunora/workflows.ts` export name.
|
|
411
|
-
*/
|
|
506
|
+
* The `ctx.workflows` surface available on `MutationCtx` and `ActionCtx`. Each
|
|
507
|
+
* declared workflow is reachable by its `lunora/workflows.ts` export name.
|
|
508
|
+
*/
|
|
412
509
|
interface Workflows {
|
|
413
510
|
/** Resolve the handle for a declared workflow by export name. */
|
|
414
511
|
get: <Params = Record<string, unknown>>(name: string) => WorkflowHandle<Params>;
|
|
@@ -416,10 +513,10 @@ interface Workflows {
|
|
|
416
513
|
/** Options for `createWorkflows`. */
|
|
417
514
|
interface LunoraWorkflowsOptions {
|
|
418
515
|
/**
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
516
|
+
* Map of `lunora/workflows.ts` export name → its Cloudflare `Workflow`
|
|
517
|
+
* binding. Codegen builds this from `env` (`{ orderPipeline:
|
|
518
|
+
* env.WORKFLOW_ORDER_PIPELINE }`); for manual wiring construct it yourself.
|
|
519
|
+
*/
|
|
423
520
|
bindings: Record<string, WorkflowBindingLike>;
|
|
424
521
|
}
|
|
425
|
-
export { ArgsOf as A, BranchCompensationParams as B,
|
|
522
|
+
export { ArgsOf as A, BranchCompensationParams as B, WorkflowInstanceLike as C, WorkflowParallelFunction as D, WorkflowRollbackContextLike as E, FunctionKind as F, WorkflowRollbackHandlerLike as G, WorkflowSpawnFunction as H, InferStepArgs as I, WorkflowSpawnOptions as J, WorkflowStatusResult as K, LunoraWorkflowsOptions as L, WorkflowStepConfigLike as M, WorkflowStepContextLike as N, WorkflowStepRollbackOptionsLike as O, RunFunctionOptions as R, StepArgsValidator as S, WorkflowDefinition as W, Workflows as a, WorkflowEventDefinition as b, StepConfig as c, StepDefinition as d, WorkflowConfig as e, WorkflowBranch as f, WorkflowInstanceStatus as g, WorkflowEventLike as h, WorkflowStepLike as i, WorkflowRunContext as j, WorkflowLogger as k, WorkflowRunFunction as l, WorkflowRunStepFunction as m, WorkflowWaitForEventFunction as n, FunctionReference as o, RunStepOptions as p, StepHandler as q, StepRollbackContext as r, StepRollbackHandler as s, StepRunContext as t, WaitForEventOptions as u, WorkflowBindingLike as v, WorkflowBranchOutputs as w, WorkflowCreateOptions as x, WorkflowHandle as y, WorkflowHandler as z };
|