@lunora/workflow 1.0.0-alpha.10 → 1.0.0-alpha.12

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.
@@ -1,13 +1,13 @@
1
1
  import { ValidatorMap, InferValidatorMap, Validator } from '@lunora/values';
2
2
  /**
3
- * Opaque reference to a Lunora function. Mirrors the `FunctionReference` shape
4
- * emitted by `@lunora/codegen` (and consumed by `@lunora/client`). We avoid a
5
- * direct dependency to keep this package usable from the codegen pipeline
6
- * itself — identical rationale to `@lunora/scheduler`'s copy.
7
- *
8
- * The runtime identifier lives in `__lunoraRef` — this MUST stay in lockstep
9
- * with the codegen emit + `@lunora/client`'s `FunctionReference`.
10
- */
3
+ * Opaque reference to a Lunora function. Mirrors the `FunctionReference` shape
4
+ * emitted by `@lunora/codegen` (and consumed by `@lunora/client`). We avoid a
5
+ * direct dependency to keep this package usable from the codegen pipeline
6
+ * itself — identical rationale to `@lunora/scheduler`'s copy.
7
+ *
8
+ * The runtime identifier lives in `__lunoraRef` — this MUST stay in lockstep
9
+ * with the codegen emit + `@lunora/client`'s `FunctionReference`.
10
+ */
11
11
  interface FunctionReference {
12
12
  readonly __lunoraRef: string;
13
13
  /** Marker phantom type — discriminates queries / mutations / actions. */
@@ -53,11 +53,11 @@ interface WorkflowInstanceLike {
53
53
  terminate: () => Promise<void>;
54
54
  }
55
55
  /**
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
- */
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
+ */
61
61
  interface WorkflowBindingLike<Params = Record<string, unknown>> {
62
62
  create: (options?: WorkflowCreateOptions<Params>) => Promise<WorkflowInstanceLike>;
63
63
  createBatch: (batch: ReadonlyArray<WorkflowCreateOptions<Params>>) => Promise<WorkflowInstanceLike[]>;
@@ -80,10 +80,10 @@ interface WorkflowStepConfigLike {
80
80
  timeout?: number | string;
81
81
  }
82
82
  /**
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
- */
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
+ */
87
87
  interface WorkflowStepContextLike {
88
88
  /** 1-based attempt counter — `> 1` means this is a retry. */
89
89
  attempt: number;
@@ -114,19 +114,19 @@ interface WorkflowStepRollbackOptionsLike<T = unknown> {
114
114
  rollbackConfig?: WorkflowStepConfigLike;
115
115
  }
116
116
  /**
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&lt;T extends Rpc.Serializable&lt;T>>` so
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 `&lt;T>` and
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
- */
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&lt;T extends Rpc.Serializable&lt;T>>` so
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 `&lt;T>` and
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
+ */
130
130
  interface WorkflowStepLike {
131
131
  do: {
132
132
  <T>(name: string, callback: (context: WorkflowStepContextLike) => Promise<T>, rollback?: WorkflowStepRollbackOptionsLike<T>): Promise<T>;
@@ -155,25 +155,25 @@ interface RunFunctionOptions {
155
155
  shardKey?: string;
156
156
  }
157
157
  /**
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
- */
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
+ */
166
166
  type WorkflowRunFunction = <F extends FunctionReference>(function_: F, args?: ArgsOf<F>, options?: RunFunctionOptions) => Promise<unknown>;
167
167
  /** 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
168
  type StepArgsValidator = ValidatorMap;
169
169
  /** Infer the args object type from a {@link StepArgsValidator} (optional validators → optional keys). Alias of `@lunora/values`' shared {@link InferValidatorMap}. */
170
170
  type InferStepArgs<A extends StepArgsValidator> = InferValidatorMap<A>;
171
171
  /**
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
- */
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
+ */
177
177
  interface StepRunContext {
178
178
  /** 1-based retry counter — `> 1` means Cloudflare is retrying the step. */
179
179
  readonly attempt: number;
@@ -226,10 +226,10 @@ interface StepConfig<A extends StepArgsValidator, Result> {
226
226
  rollbackConfig?: WorkflowStepConfigLike;
227
227
  }
228
228
  /**
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
- */
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
+ */
233
233
  interface StepDefinition<A extends StepArgsValidator = StepArgsValidator, Result = unknown> {
234
234
  /** Validators for the step's args. */
235
235
  readonly args: A;
@@ -254,33 +254,33 @@ interface RunStepOptions {
254
254
  config?: WorkflowStepConfigLike;
255
255
  }
256
256
  /**
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
- */
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
+ */
265
265
  type WorkflowRunStepFunction = <A extends StepArgsValidator, Result>(step: StepDefinition<A, Result>, args: InferStepArgs<A>, options?: RunStepOptions) => Promise<Result>;
266
266
  /**
267
- * One branch of a {@link WorkflowParallelFunction} fan-out — a declared child
268
- * workflow (referenced by its `lunora/workflows.ts` export name) plus the params
269
- * it is created with. The phantom `Output` carries the child's result type into
270
- * the `ctx.parallel(...)` result tuple. Build one with the `branch(...)` helper.
271
- */
267
+ * One branch of a {@link WorkflowParallelFunction} fan-out — a declared child
268
+ * workflow (referenced by its `lunora/workflows.ts` export name) plus the params
269
+ * it is created with. The phantom `Output` carries the child's result type into
270
+ * the `ctx.parallel(...)` result tuple. Build one with the `branch(...)` helper.
271
+ */
272
272
  interface WorkflowBranch<Output = unknown> {
273
273
  /** Phantom marker for the branch output type — never present at runtime. */
274
274
  readonly __output?: Output;
275
275
  /**
276
- * Optional group-saga compensation (plan 075 Phase 3): the `lunora/workflows.ts`
277
- * export name of a workflow to run if a **sibling** branch in the same
278
- * `ctx.parallel(...)` group fails **after** this branch has already completed.
279
- * It is spawned fire-and-forget (a durable, replay-safe idempotent create) with
280
- * {@link BranchCompensationParams} as its `ctx.params`. Omit for no
281
- * compensation — a group where no branch sets this behaves exactly as a plain
282
- * fan-out (fail-fast, no rollback).
283
- */
276
+ * Optional group-saga compensation (plan 075 Phase 3): the `lunora/workflows.ts`
277
+ * export name of a workflow to run if a **sibling** branch in the same
278
+ * `ctx.parallel(...)` group fails **after** this branch has already completed.
279
+ * It is spawned fire-and-forget (a durable, replay-safe idempotent create) with
280
+ * {@link BranchCompensationParams} as its `ctx.params`. Omit for no
281
+ * compensation — a group where no branch sets this behaves exactly as a plain
282
+ * fan-out (fail-fast, no rollback).
283
+ */
284
284
  readonly compensateWith?: string;
285
285
  /** Optional explicit child instance id (defaults to a deterministic parent-derived id). */
286
286
  readonly id?: string;
@@ -292,11 +292,11 @@ interface WorkflowBranch<Output = unknown> {
292
292
  readonly workflow: string;
293
293
  }
294
294
  /**
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
- */
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
+ */
300
300
  interface BranchCompensationParams {
301
301
  /** Index signature: this is a workflow `params` bag, so it is a valid `Record&lt;string, unknown>` payload. */
302
302
  [key: string]: unknown;
@@ -313,20 +313,20 @@ interface BranchCompensationParams {
313
313
  output?: unknown;
314
314
  }
315
315
  /** 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 };
316
+ type WorkflowBranchOutputs<B extends ReadonlyArray<WorkflowBranch>> = { -readonly [K in keyof B]: B[K] extends WorkflowBranch<infer Output> ? Output : never; };
317
317
  /**
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
- */
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
+ */
330
330
  type WorkflowParallelFunction = <const B extends ReadonlyArray<WorkflowBranch>>(branches: B) => Promise<WorkflowBranchOutputs<B>>;
331
331
  /** Per-call options for {@link WorkflowSpawnFunction}. */
332
332
  interface WorkflowSpawnOptions {
@@ -334,17 +334,17 @@ interface WorkflowSpawnOptions {
334
334
  id?: string;
335
335
  }
336
336
  /**
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
- */
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
+ */
341
341
  type WorkflowSpawnFunction = (workflow: string, params?: Record<string, unknown>, options?: WorkflowSpawnOptions) => Promise<WorkflowInstanceLike>;
342
342
  /**
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
- */
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
+ */
348
348
  interface WorkflowRunContext<Params = Record<string, unknown>> {
349
349
  /** The Worker environment bindings. */
350
350
  readonly env: Record<string, unknown>;
@@ -372,19 +372,19 @@ interface WorkflowConfig<Params = Record<string, unknown>, Output = unknown> {
372
372
  /** The workflow body — the multi-step durable program. */
373
373
  handler: WorkflowHandler<Params, Output>;
374
374
  /**
375
- * Optional override for the deployed workflow name — the `workflows[].name`
376
- * written to `wrangler.jsonc`. Defaults to a kebab-cased form of the
377
- * `lunora/workflows.ts` export name (`orderPipeline` → `order-pipeline`).
378
- * This does NOT change the binding name, which is always derived from the
379
- * export name (`orderPipeline` → `WORKFLOW_ORDER_PIPELINE`).
380
- */
375
+ * Optional override for the deployed workflow name — the `workflows[].name`
376
+ * written to `wrangler.jsonc`. Defaults to a kebab-cased form of the
377
+ * `lunora/workflows.ts` export name (`orderPipeline` → `order-pipeline`).
378
+ * This does NOT change the binding name, which is always derived from the
379
+ * export name (`orderPipeline` → `WORKFLOW_ORDER_PIPELINE`).
380
+ */
381
381
  name?: string;
382
382
  }
383
383
  /**
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
- */
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
+ */
388
388
  interface WorkflowDefinition<Params = Record<string, unknown>, Output = unknown> extends WorkflowConfig<Params, Output> {
389
389
  /** Phantom marker for the output type — never present at runtime. */
390
390
  readonly __output?: Output;
@@ -394,9 +394,9 @@ interface WorkflowDefinition<Params = Record<string, unknown>, Output = unknown>
394
394
  readonly isLunoraWorkflow: true;
395
395
  }
396
396
  /**
397
- * A typed handle to one declared workflow, addressable from `ctx.workflows`.
398
- * Thin pass-through over the Cloudflare `Workflow` binding.
399
- */
397
+ * A typed handle to one declared workflow, addressable from `ctx.workflows`.
398
+ * Thin pass-through over the Cloudflare `Workflow` binding.
399
+ */
400
400
  interface WorkflowHandle<Params = Record<string, unknown>> {
401
401
  /** Start a new instance (optionally with an id + params). */
402
402
  create: (options?: WorkflowCreateOptions<Params>) => Promise<WorkflowInstanceLike>;
@@ -406,9 +406,9 @@ interface WorkflowHandle<Params = Record<string, unknown>> {
406
406
  get: (id: string) => Promise<WorkflowInstanceLike>;
407
407
  }
408
408
  /**
409
- * The `ctx.workflows` surface available on `MutationCtx` and `ActionCtx`. Each
410
- * declared workflow is reachable by its `lunora/workflows.ts` export name.
411
- */
409
+ * The `ctx.workflows` surface available on `MutationCtx` and `ActionCtx`. Each
410
+ * declared workflow is reachable by its `lunora/workflows.ts` export name.
411
+ */
412
412
  interface Workflows {
413
413
  /** Resolve the handle for a declared workflow by export name. */
414
414
  get: <Params = Record<string, unknown>>(name: string) => WorkflowHandle<Params>;
@@ -416,10 +416,10 @@ interface Workflows {
416
416
  /** Options for `createWorkflows`. */
417
417
  interface LunoraWorkflowsOptions {
418
418
  /**
419
- * Map of `lunora/workflows.ts` export name → its Cloudflare `Workflow`
420
- * binding. Codegen builds this from `env` (`{ orderPipeline:
421
- * env.WORKFLOW_ORDER_PIPELINE }`); for manual wiring construct it yourself.
422
- */
419
+ * Map of `lunora/workflows.ts` export name → its Cloudflare `Workflow`
420
+ * binding. Codegen builds this from `env` (`{ orderPipeline:
421
+ * env.WORKFLOW_ORDER_PIPELINE }`); for manual wiring construct it yourself.
422
+ */
423
423
  bindings: Record<string, WorkflowBindingLike>;
424
424
  }
425
425
  export { ArgsOf as A, BranchCompensationParams as B, WorkflowSpawnFunction as C, WorkflowSpawnOptions as D, WorkflowStatusResult as E, FunctionReference as F, WorkflowStepConfigLike as G, WorkflowStepContextLike as H, InferStepArgs as I, WorkflowStepRollbackOptionsLike as J, LunoraWorkflowsOptions as L, RunFunctionOptions as R, StepArgsValidator as S, WorkflowDefinition as W, Workflows as a, StepConfig as b, StepDefinition as c, WorkflowConfig as d, WorkflowBranch as e, WorkflowInstanceStatus as f, WorkflowEventLike as g, WorkflowStepLike as h, WorkflowRunContext as i, WorkflowLogger as j, WorkflowRunFunction as k, WorkflowRunStepFunction as l, RunStepOptions as m, StepHandler as n, StepRollbackContext as o, StepRollbackHandler as p, StepRunContext as q, WorkflowBindingLike as r, WorkflowBranchOutputs as s, WorkflowCreateOptions as t, WorkflowHandle as u, WorkflowHandler as v, WorkflowInstanceLike as w, WorkflowParallelFunction as x, WorkflowRollbackContextLike as y, WorkflowRollbackHandlerLike as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/workflow",
3
- "version": "1.0.0-alpha.10",
3
+ "version": "1.0.0-alpha.12",
4
4
  "description": "Durable workflows for Lunora: defineWorkflow over Cloudflare Workflows, generated WorkflowEntrypoint classes, and the ctx.workflows surface",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -48,8 +48,8 @@
48
48
  "access": "public"
49
49
  },
50
50
  "dependencies": {
51
- "@lunora/errors": "1.0.0-alpha.5",
52
- "@lunora/values": "1.0.0-alpha.8"
51
+ "@lunora/errors": "1.0.0-alpha.7",
52
+ "@lunora/values": "1.0.0-alpha.10"
53
53
  },
54
54
  "engines": {
55
55
  "node": "^22.15.0 || >=24.11.0"