ai-workflows 2.1.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +8 -1
  3. package/README.md +2 -0
  4. package/dist/barrier.d.ts +6 -0
  5. package/dist/barrier.d.ts.map +1 -1
  6. package/dist/barrier.js +45 -7
  7. package/dist/barrier.js.map +1 -1
  8. package/dist/cascade-context.d.ts.map +1 -1
  9. package/dist/cascade-context.js +25 -25
  10. package/dist/cascade-context.js.map +1 -1
  11. package/dist/cascade-executor.d.ts.map +1 -1
  12. package/dist/cascade-executor.js +1 -1
  13. package/dist/cascade-executor.js.map +1 -1
  14. package/dist/context.d.ts.map +1 -1
  15. package/dist/context.js +23 -7
  16. package/dist/context.js.map +1 -1
  17. package/dist/cron-parser.d.ts +65 -0
  18. package/dist/cron-parser.d.ts.map +1 -0
  19. package/dist/cron-parser.js +294 -0
  20. package/dist/cron-parser.js.map +1 -0
  21. package/dist/cron-scheduler.d.ts +117 -0
  22. package/dist/cron-scheduler.d.ts.map +1 -0
  23. package/dist/cron-scheduler.js +176 -0
  24. package/dist/cron-scheduler.js.map +1 -0
  25. package/dist/database-context.d.ts +184 -0
  26. package/dist/database-context.d.ts.map +1 -0
  27. package/dist/database-context.js +428 -0
  28. package/dist/database-context.js.map +1 -0
  29. package/dist/digital-objects-adapter.d.ts +159 -0
  30. package/dist/digital-objects-adapter.d.ts.map +1 -0
  31. package/dist/digital-objects-adapter.js +229 -0
  32. package/dist/digital-objects-adapter.js.map +1 -0
  33. package/dist/durable-execution-cloudflare.d.ts +427 -0
  34. package/dist/durable-execution-cloudflare.d.ts.map +1 -0
  35. package/dist/durable-execution-cloudflare.js +510 -0
  36. package/dist/durable-execution-cloudflare.js.map +1 -0
  37. package/dist/durable-execution.d.ts +482 -0
  38. package/dist/durable-execution.d.ts.map +1 -0
  39. package/dist/durable-execution.js +594 -0
  40. package/dist/durable-execution.js.map +1 -0
  41. package/dist/durable-workflow.d.ts +176 -0
  42. package/dist/durable-workflow.d.ts.map +1 -0
  43. package/dist/durable-workflow.js +552 -0
  44. package/dist/durable-workflow.js.map +1 -0
  45. package/dist/graph/topological-sort.d.ts.map +1 -1
  46. package/dist/graph/topological-sort.js +5 -5
  47. package/dist/graph/topological-sort.js.map +1 -1
  48. package/dist/index.d.ts +4 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +15 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/logger.d.ts +101 -0
  53. package/dist/logger.d.ts.map +1 -0
  54. package/dist/logger.js +115 -0
  55. package/dist/logger.js.map +1 -0
  56. package/dist/on.d.ts.map +1 -1
  57. package/dist/on.js +3 -3
  58. package/dist/on.js.map +1 -1
  59. package/dist/runtime.d.ts +169 -0
  60. package/dist/runtime.d.ts.map +1 -0
  61. package/dist/runtime.js +275 -0
  62. package/dist/runtime.js.map +1 -0
  63. package/dist/send.d.ts.map +1 -1
  64. package/dist/send.js +4 -3
  65. package/dist/send.js.map +1 -1
  66. package/dist/telemetry.d.ts +150 -0
  67. package/dist/telemetry.d.ts.map +1 -0
  68. package/dist/telemetry.js +388 -0
  69. package/dist/telemetry.js.map +1 -0
  70. package/dist/timer-registry.d.ts +25 -0
  71. package/dist/timer-registry.d.ts.map +1 -1
  72. package/dist/timer-registry.js +42 -8
  73. package/dist/timer-registry.js.map +1 -1
  74. package/dist/types.d.ts +17 -6
  75. package/dist/types.d.ts.map +1 -1
  76. package/dist/types.js +1 -1
  77. package/dist/types.js.map +1 -1
  78. package/dist/worker/durable-step.d.ts +481 -0
  79. package/dist/worker/durable-step.d.ts.map +1 -0
  80. package/dist/worker/durable-step.js +606 -0
  81. package/dist/worker/durable-step.js.map +1 -0
  82. package/dist/worker/index.d.ts +106 -0
  83. package/dist/worker/index.d.ts.map +1 -0
  84. package/dist/worker/index.js +124 -0
  85. package/dist/worker/index.js.map +1 -0
  86. package/dist/worker/state-adapter.d.ts +230 -0
  87. package/dist/worker/state-adapter.d.ts.map +1 -0
  88. package/dist/worker/state-adapter.js +409 -0
  89. package/dist/worker/state-adapter.js.map +1 -0
  90. package/dist/worker/topological-executor.d.ts +282 -0
  91. package/dist/worker/topological-executor.d.ts.map +1 -0
  92. package/dist/worker/topological-executor.js +396 -0
  93. package/dist/worker/topological-executor.js.map +1 -0
  94. package/dist/worker/workflow-builder.d.ts +286 -0
  95. package/dist/worker/workflow-builder.d.ts.map +1 -0
  96. package/dist/worker/workflow-builder.js +565 -0
  97. package/dist/worker/workflow-builder.js.map +1 -0
  98. package/dist/worker.d.ts +800 -0
  99. package/dist/worker.d.ts.map +1 -0
  100. package/dist/worker.js +2428 -0
  101. package/dist/worker.js.map +1 -0
  102. package/dist/workflow-builder.d.ts +287 -0
  103. package/dist/workflow-builder.d.ts.map +1 -0
  104. package/dist/workflow-builder.js +762 -0
  105. package/dist/workflow-builder.js.map +1 -0
  106. package/dist/workflow.d.ts +14 -30
  107. package/dist/workflow.d.ts.map +1 -1
  108. package/dist/workflow.js +132 -292
  109. package/dist/workflow.js.map +1 -1
  110. package/examples/01-ecommerce-order-pipeline.ts +358 -0
  111. package/examples/02-content-moderation-cascade.ts +454 -0
  112. package/examples/03-scheduled-reporting-dependencies.ts +479 -0
  113. package/examples/04-database-persistence.ts +518 -0
  114. package/examples/README.md +173 -0
  115. package/package.json +30 -13
  116. package/src/__tests__/digital-objects-adapter.test.ts +274 -0
  117. package/src/__tests__/durable-workflow.test.ts +297 -0
  118. package/src/barrier.ts +48 -7
  119. package/src/cascade-context.ts +36 -29
  120. package/src/cascade-executor.ts +3 -2
  121. package/src/context.ts +41 -12
  122. package/src/cron-parser.ts +347 -0
  123. package/src/cron-scheduler.ts +239 -0
  124. package/src/database-context.ts +658 -0
  125. package/src/digital-objects-adapter.ts +351 -0
  126. package/src/durable-execution-cloudflare.ts +855 -0
  127. package/src/durable-execution.ts +1042 -0
  128. package/src/durable-workflow.ts +717 -0
  129. package/src/graph/topological-sort.ts +6 -8
  130. package/src/index.ts +69 -0
  131. package/src/logger.ts +148 -0
  132. package/src/on.ts +8 -9
  133. package/src/runtime.ts +436 -0
  134. package/src/send.ts +4 -5
  135. package/src/telemetry.ts +577 -0
  136. package/src/timer-registry.ts +44 -10
  137. package/src/types.ts +32 -17
  138. package/src/worker/durable-step.ts +976 -0
  139. package/src/worker/index.ts +216 -0
  140. package/src/worker/state-adapter.ts +589 -0
  141. package/src/worker/topological-executor.ts +625 -0
  142. package/src/worker/workflow-builder.ts +871 -0
  143. package/src/worker.ts +2906 -0
  144. package/src/workflow-builder.ts +1068 -0
  145. package/src/workflow.ts +188 -351
  146. package/test/barrier-join.test.ts +32 -24
  147. package/test/cascade-executor.test.ts +9 -16
  148. package/test/cron-parser.test.ts +314 -0
  149. package/test/cron-scheduler.test.ts +291 -0
  150. package/test/database-context.test.ts +770 -0
  151. package/test/db-provider-adapter.test.ts +862 -0
  152. package/test/durable-execution-cloudflare.test.ts +606 -0
  153. package/test/durable-execution-in-process.test.ts +286 -0
  154. package/test/durable-execution.test.ts +247 -0
  155. package/test/e2e/workflow-scenarios.e2e.test.ts +1039 -0
  156. package/test/integration.test.ts +442 -0
  157. package/test/rpc-surface.test.ts +946 -0
  158. package/test/runtime.test.ts +262 -0
  159. package/test/schedule-timer-cleanup.test.ts +30 -21
  160. package/test/send-race-conditions.test.ts +30 -40
  161. package/test/worker/durable-cascade.test.ts +1117 -0
  162. package/test/worker/durable-step.test.ts +723 -0
  163. package/test/worker/topological-executor.test.ts +1240 -0
  164. package/test/worker/workflow-builder.test.ts +1067 -0
  165. package/test/worker.test.ts +608 -0
  166. package/test/workflow-builder.test.ts +1670 -0
  167. package/test/workflow-cron.test.ts +256 -0
  168. package/test/workflow-state-adapter.test.ts +923 -0
  169. package/test/workflow.test.ts +25 -22
  170. package/tsconfig.json +3 -1
  171. package/vitest.config.ts +38 -1
  172. package/vitest.workers.config.ts +44 -0
  173. package/wrangler.jsonc +22 -0
  174. package/.turbo/turbo-test.log +0 -169
  175. package/LICENSE +0 -21
  176. package/src/context.js +0 -83
  177. package/src/every.js +0 -267
  178. package/src/index.js +0 -71
  179. package/src/on.js +0 -79
  180. package/src/send.js +0 -111
  181. package/src/types.js +0 -4
  182. package/src/workflow.js +0 -455
  183. package/test/context.test.js +0 -116
  184. package/test/every.test.js +0 -282
  185. package/test/on.test.js +0 -80
  186. package/test/send.test.js +0 -89
  187. package/test/workflow.test.js +0 -224
  188. package/vitest.config.js +0 -7
@@ -0,0 +1,482 @@
1
+ /**
2
+ * DurableExecutionAdapter - Port for durable workflow execution backends.
3
+ *
4
+ * Defines a small, backend-agnostic interface that callers (notably
5
+ * `ai-database`'s cascade orchestration in ADR-0003) can program against
6
+ * without knowing which durable execution backend is wired underneath.
7
+ *
8
+ * ## Why this port exists
9
+ *
10
+ * `ai-workflows`'s {@link createWorkflowRuntime} owns the `$` runtime
11
+ * contract — handlers, dispatch, cascade-context, database-context. It runs
12
+ * in-process and lives only as long as the host process. For long-running
13
+ * cascades, scheduled jobs, and orchestration spanning hours-to-days, an
14
+ * external durable execution backend is required.
15
+ *
16
+ * Two production candidates (per ADR-0004):
17
+ *
18
+ * - **Cloudflare Workflows** (default backend; Workers-only). Hibernation
19
+ * while waiting; no per-step billing; 25K steps default; 365-day max
20
+ * sleep. State must flow through step returns — in-memory variables do
21
+ * not survive hibernation.
22
+ *
23
+ * - **Vercel Workflow Development Kit (WDK)** (alternate backend; Vercel
24
+ * or self-hosted). Apache-2.0; pluggable "Worlds"; per-step billing;
25
+ * event-sourced replay; unlimited sleep.
26
+ *
27
+ * Plus an in-process stub (this file's {@link createInMemoryDurableExecution})
28
+ * for tests and local development that does not need durability across
29
+ * process restarts. Phase 1 (bead `aip-fgq5`) will land a richer in-process
30
+ * adapter that bridges this port to the existing
31
+ * {@link createWorkflowRuntime}.
32
+ *
33
+ * The port is modeled after WDK's "Worlds" abstraction — the prior art for
34
+ * exactly this pattern: a small, backend-portable surface for `step`,
35
+ * `sleep`, `waitForEvent`, and scheduling, with each adapter translating to
36
+ * its native primitive (CF's hibernation, WDK's event-sourced replay,
37
+ * in-process's plain async).
38
+ *
39
+ * ## Programming model: Rules of Workflows
40
+ *
41
+ * These rules are universal to durable execution and are not specific to
42
+ * any one backend. They originate in CF's "Rules of Workflows" guidance and
43
+ * apply equally to WDK's deterministic replay model.
44
+ *
45
+ * 1. **Steps must be idempotent.** A step body may be re-executed across
46
+ * a hibernation/restart boundary or after a transient failure. Wrap
47
+ * external side-effects (writes, payments, emails) so a duplicate
48
+ * invocation is observably equivalent to a single invocation.
49
+ *
50
+ * 2. **Step names must be deterministic.** Adapters use the step name as
51
+ * a stable identity for memoization and event-sourced replay. Do not
52
+ * include random ids, timestamps, or run-specific values in the name.
53
+ *
54
+ * 3. **State flows through step returns.** Variables defined inside a
55
+ * workflow body but outside a step are not guaranteed to survive a
56
+ * hibernation boundary. Read inputs at the top of a step; return only
57
+ * what you need; pass results forward through subsequent steps.
58
+ *
59
+ * 4. **Workflow bodies must be deterministic.** Two replays of the same
60
+ * input must take the same control-flow path. Push non-determinism
61
+ * (clocks, randomness, network reads) into steps so the adapter can
62
+ * memoize the result.
63
+ *
64
+ * 5. **Sleeps and waits are first-class.** Use
65
+ * {@link DurableExecutionAdapter.sleep},
66
+ * {@link DurableExecutionAdapter.sleepUntil}, and
67
+ * {@link DurableExecutionAdapter.waitForEvent} rather than `setTimeout`
68
+ * or polling — only the adapter knows how to suspend and resume the
69
+ * workflow correctly.
70
+ *
71
+ * ## Error semantics
72
+ *
73
+ * - {@link DurableStepError} (and its subclasses) are thrown by step
74
+ * execution failures. The {@link DurableStepError.retryable} flag tells
75
+ * the caller whether the adapter considered the failure transient. Real
76
+ * adapters surface their backend's retry decisions through this flag.
77
+ *
78
+ * - {@link WaitForEventTimeoutError} is thrown by
79
+ * {@link DurableExecutionAdapter.waitForEvent} when a timeout elapses
80
+ * without the named event arriving. Callers should catch this explicitly
81
+ * to model "happens within N" branches.
82
+ *
83
+ * - All other thrown errors propagate as-is. Callers must classify
84
+ * non-retryable business errors themselves; adapters do not introspect
85
+ * user errors.
86
+ *
87
+ * ## Subpath export
88
+ *
89
+ * This module ships at the `ai-workflows/durable-execution` subpath so the
90
+ * cascade orchestrator (in `ai-database`) can depend on the port without
91
+ * pulling in the full `ai-workflows` runtime — keeping the static dependency
92
+ * graph one-way (`ai-database` → `ai-workflows/durable-execution`).
93
+ *
94
+ * @example In-memory test usage
95
+ * ```ts
96
+ * import { createInMemoryDurableExecution } from 'ai-workflows/durable-execution'
97
+ *
98
+ * const dx = createInMemoryDurableExecution()
99
+ * const result = await dx.run('charge-customer', async (ctx) => {
100
+ * const charged = await ctx.step('charge-card', async () => {
101
+ * return chargeStripe(ctx.input)
102
+ * })
103
+ * await ctx.sleep('1 second')
104
+ * return { id: charged.id }
105
+ * }, { customerId: 'c-1', amount: 1000 })
106
+ * ```
107
+ *
108
+ * @example Wiring a real adapter (future Phase 1; bead aip-fgq5/aip-i456)
109
+ * ```ts
110
+ * import type { DurableExecutionAdapter } from 'ai-workflows/durable-execution'
111
+ *
112
+ * function makeCascadeRunner(dx: DurableExecutionAdapter) {
113
+ * return (input: CascadeInput) => dx.run('cascade', async (ctx) => {
114
+ * const plan = await ctx.step('plan', () => generatePlan(ctx.input))
115
+ * return ctx.step('write', () => writeAll(plan))
116
+ * }, input)
117
+ * }
118
+ * ```
119
+ *
120
+ * @packageDocumentation
121
+ */
122
+ import type { WorkflowRuntime } from './runtime.js';
123
+ /**
124
+ * Context passed to a {@link WorkflowFn}. Provides the same step / sleep /
125
+ * wait primitives as the top-level {@link DurableExecutionAdapter}, plus the
126
+ * input the workflow was invoked with.
127
+ *
128
+ * The context is bound to one workflow run; calls on it are routed to the
129
+ * adapter that started the run.
130
+ */
131
+ export interface WorkflowContext<TInput = unknown> {
132
+ /** The input value the workflow was invoked with. */
133
+ readonly input: TInput;
134
+ /** Stable instance id assigned by the adapter at run start. */
135
+ readonly instanceId: string;
136
+ /** Logical workflow name supplied at {@link DurableExecutionAdapter.run}. */
137
+ readonly name: string;
138
+ /**
139
+ * Execute a named, durable step. See
140
+ * {@link DurableExecutionAdapter.step} for semantics.
141
+ */
142
+ step<T>(name: string, fn: () => Promise<T>): Promise<T>;
143
+ /**
144
+ * Execute a named, durable step with explicit configuration. See
145
+ * {@link DurableExecutionAdapter.step}.
146
+ */
147
+ step<T>(name: string, config: StepConfig, fn: () => Promise<T>): Promise<T>;
148
+ /** Suspend the workflow for {@link DurableExecutionAdapter.sleep}. */
149
+ sleep(duration: string | number): Promise<void>;
150
+ /** Suspend until {@link DurableExecutionAdapter.sleepUntil}. */
151
+ sleepUntil(date: Date): Promise<void>;
152
+ /** Wait for a named event. See {@link DurableExecutionAdapter.waitForEvent}. */
153
+ waitForEvent<T = unknown>(name: string, timeout?: number | string): Promise<T>;
154
+ }
155
+ /**
156
+ * A user-authored workflow body.
157
+ *
158
+ * The body must be deterministic across replays — see the "Rules of
159
+ * Workflows" in the module-level docs. The function is invoked once per
160
+ * run-or-replay; the adapter memoizes step results by step name so repeated
161
+ * executions converge on the same outcome.
162
+ */
163
+ export type WorkflowFn<TResult = unknown, TInput = unknown> = (ctx: WorkflowContext<TInput>) => Promise<TResult>;
164
+ /**
165
+ * Per-step configuration. Adapters that do not support a given option treat
166
+ * it as advisory. CF Workflows and WDK both support timeout and retries;
167
+ * the in-memory stub honours retries and ignores timeout (since steps are
168
+ * synchronous from the adapter's perspective).
169
+ */
170
+ export interface StepConfig {
171
+ /** Maximum total attempts including the first. Default: adapter-specific (typically 1). */
172
+ retries?: {
173
+ /** Total attempts (>= 1). */
174
+ limit: number;
175
+ /** Delay between attempts. String forms: '1 second', '500ms'. */
176
+ delay?: string | number;
177
+ /** Backoff curve. Default: 'constant'. */
178
+ backoff?: 'constant' | 'linear' | 'exponential';
179
+ };
180
+ /** Per-attempt timeout. String or ms. */
181
+ timeout?: string | number;
182
+ }
183
+ /**
184
+ * Returned by {@link DurableExecutionAdapter.schedule}. Calling
185
+ * {@link Subscription.unsubscribe} cancels the schedule; idempotent.
186
+ */
187
+ export interface Subscription {
188
+ /** Stable id for the schedule (adapter-defined format). */
189
+ readonly id: string;
190
+ /** Cancel the schedule. Safe to call more than once. */
191
+ unsubscribe(): void;
192
+ }
193
+ /**
194
+ * Thrown when a step's body fails after all retries (or immediately, when
195
+ * retries are not configured).
196
+ *
197
+ * The {@link DurableStepError.retryable} flag reflects the adapter's
198
+ * judgement about the underlying failure: `true` means the adapter believed
199
+ * the failure was transient (network, rate-limit, server error) and would
200
+ * have retried again given more attempts; `false` means the adapter
201
+ * classified it as terminal (programmer error, invalid input). Callers can
202
+ * use this to decide whether to escalate or fall through to a different
203
+ * code path.
204
+ */
205
+ export declare class DurableStepError extends Error {
206
+ /** Step name that failed. */
207
+ readonly stepName: string;
208
+ /** Number of attempts the adapter actually made (>= 1). */
209
+ readonly attempts: number;
210
+ /** Whether the adapter considered the cause transient. */
211
+ readonly retryable: boolean;
212
+ /** The error that ultimately caused the failure. */
213
+ readonly cause: unknown;
214
+ constructor(message: string, options: {
215
+ stepName: string;
216
+ attempts: number;
217
+ retryable: boolean;
218
+ cause: unknown;
219
+ });
220
+ }
221
+ /**
222
+ * Thrown when {@link DurableExecutionAdapter.waitForEvent} elapses without
223
+ * the named event arriving.
224
+ */
225
+ export declare class WaitForEventTimeoutError extends Error {
226
+ readonly eventName: string;
227
+ readonly timeout: number | string;
228
+ constructor(eventName: string, timeout: number | string);
229
+ }
230
+ /**
231
+ * Concrete adapter kind. Used only as a discriminant for callers that want
232
+ * to log or branch on the active backend; should never be relied on for
233
+ * correctness.
234
+ */
235
+ export type DurableExecutionKind = 'in-process' | 'cloudflare' | 'vercel-wdk';
236
+ /**
237
+ * The port. A small, backend-agnostic interface over `run`, `step`, `sleep`,
238
+ * `waitForEvent`, and `schedule`.
239
+ *
240
+ * Real adapters live alongside this file but ship behind feature flags or
241
+ * separate subpath modules so importing the port itself does not pull in
242
+ * any backend dependencies.
243
+ */
244
+ export interface DurableExecutionAdapter {
245
+ /** Discriminant tag for the active backend. */
246
+ readonly kind: DurableExecutionKind;
247
+ /**
248
+ * Run a workflow body to completion. The adapter assigns the run a
249
+ * stable `instanceId`, persists it (where applicable), and invokes `fn`
250
+ * with a {@link WorkflowContext}.
251
+ *
252
+ * Resolves with the workflow's return value. Rejects with whatever the
253
+ * body or its steps reject with — callers must handle both
254
+ * {@link DurableStepError} and arbitrary user errors.
255
+ *
256
+ * @param name Logical name of the workflow (used for telemetry and, in
257
+ * some backends, for routing). Should be stable across deployments.
258
+ * @param fn The deterministic workflow body. See module docs for rules.
259
+ * @param input Arbitrary input value passed through to `ctx.input`. Must
260
+ * be JSON-serializable for adapters that persist state (CF, WDK).
261
+ */
262
+ run<TResult = unknown, TInput = unknown>(name: string, fn: WorkflowFn<TResult, TInput>, input: TInput): Promise<TResult>;
263
+ /**
264
+ * Execute a named, idempotent step.
265
+ *
266
+ * Step names must be stable across replays — the adapter uses the name
267
+ * as the memoization key. On replay, a step that has already succeeded
268
+ * returns its memoized result without re-invoking `fn`. On a transient
269
+ * failure, the adapter retries per {@link StepConfig.retries} (or its
270
+ * default policy).
271
+ *
272
+ * Outside of `run()` (e.g. when the adapter is called directly without a
273
+ * surrounding workflow body) implementations may either: (a) treat
274
+ * `step` as a thin wrapper that calls `fn` once with no replay, or (b)
275
+ * throw. The in-memory stub picks (a) because it is convenient for tests.
276
+ *
277
+ * Step bodies must be idempotent — see the Rules of Workflows.
278
+ */
279
+ step<T>(name: string, fn: () => Promise<T>): Promise<T>;
280
+ step<T>(name: string, config: StepConfig, fn: () => Promise<T>): Promise<T>;
281
+ /**
282
+ * Suspend execution for a duration. The adapter's backend may hibernate
283
+ * the workflow during the sleep window; in-memory the stub merely awaits.
284
+ *
285
+ * @param duration Number of milliseconds, or a human string accepted by
286
+ * the backend (e.g. `'1 second'`, `'5 minutes'`, `'1 day'`). Adapters
287
+ * that do not understand a string form must throw.
288
+ */
289
+ sleep(duration: string | number): Promise<void>;
290
+ /** Suspend execution until the given absolute timestamp. */
291
+ sleepUntil(date: Date): Promise<void>;
292
+ /**
293
+ * Wait for an externally-signalled event by name.
294
+ *
295
+ * @param name Event name. Convention: `Noun.event` (matching
296
+ * `ai-workflows`'s dispatch shape) but adapters do not enforce this.
297
+ * @param timeout Optional max wait. Number = milliseconds. String = a
298
+ * backend-recognised duration. When `undefined` the adapter waits
299
+ * forever (or until its hard backend limit, e.g. 365 days for CF).
300
+ *
301
+ * Rejects with {@link WaitForEventTimeoutError} if the timeout elapses.
302
+ */
303
+ waitForEvent<T = unknown>(name: string, timeout?: number | string): Promise<T>;
304
+ /**
305
+ * Register a workflow body to run on a cron schedule.
306
+ *
307
+ * The schedule itself is durable — the adapter is responsible for firing
308
+ * at the given cron expression even across process restarts. The
309
+ * returned {@link Subscription} cancels the schedule when unsubscribed.
310
+ *
311
+ * Fired runs receive an empty input (`undefined`). To pass per-run data,
312
+ * read it from external state inside the workflow body.
313
+ */
314
+ schedule<TResult = unknown>(name: string, cron: string, fn: WorkflowFn<TResult, undefined>): Subscription;
315
+ }
316
+ /**
317
+ * Options for {@link createInMemoryDurableExecution}.
318
+ */
319
+ export interface InMemoryDurableExecutionOptions {
320
+ /**
321
+ * Override the clock. Used by tests to control sleep without waiting in
322
+ * real time. When provided, `sleep`/`sleepUntil` resolve as soon as the
323
+ * clock returns a value `>= deadline`.
324
+ */
325
+ now?: () => number;
326
+ /**
327
+ * Override the sleep primitive. Defaults to a real `setTimeout`. Tests
328
+ * that want to fast-forward time can replace this with a no-op.
329
+ */
330
+ delay?: (ms: number) => Promise<void>;
331
+ }
332
+ /**
333
+ * Construct an in-memory {@link DurableExecutionAdapter} suitable for tests
334
+ * and validating the port shape. **Not durable** — state lives only in
335
+ * closure for the lifetime of the process.
336
+ *
337
+ * Behaviour:
338
+ *
339
+ * - `run`: invokes the body once with a fresh context. No replay.
340
+ * - `step`: memoizes the result by step name within a single `run`
341
+ * invocation; outside a `run` it executes once and returns. Honours
342
+ * retries (constant/linear/exponential backoff).
343
+ * - `sleep` / `sleepUntil`: awaits real time by default, overridable via
344
+ * {@link InMemoryDurableExecutionOptions.delay}.
345
+ * - `waitForEvent`: pairs with {@link InMemoryDurableExecution.emit} on the
346
+ * returned object. If `timeout` elapses first, rejects with
347
+ * {@link WaitForEventTimeoutError}.
348
+ * - `schedule`: installs a `setInterval` that fires the workflow body each
349
+ * `cron` tick. The cron expression itself is **not** parsed in the stub —
350
+ * it is treated as opaque metadata. Tests that want time-driven schedules
351
+ * should drive emissions manually via the returned helpers.
352
+ *
353
+ * The stub satisfies the full {@link DurableExecutionAdapter} surface so
354
+ * tests can validate the port shape without writing a real adapter.
355
+ */
356
+ export interface InMemoryDurableExecution extends DurableExecutionAdapter {
357
+ /**
358
+ * Manually deliver an event to the next pending {@link waitForEvent}
359
+ * call with the matching name. Returns `true` if a waiter was resolved,
360
+ * `false` otherwise.
361
+ */
362
+ emit<T = unknown>(name: string, value: T): boolean;
363
+ }
364
+ /**
365
+ * @see InMemoryDurableExecution
366
+ */
367
+ export declare function createInMemoryDurableExecution(options?: InMemoryDurableExecutionOptions): InMemoryDurableExecution;
368
+ /**
369
+ * Options for {@link createInProcessDurableExecution}.
370
+ *
371
+ * When a `runtime` is supplied the adapter records each durable run/step into
372
+ * the runtime's cascade context, history, and (when configured) database. When
373
+ * no runtime is supplied the adapter behaves identically to
374
+ * {@link createInMemoryDurableExecution} but uses production logging instead of
375
+ * silently swallowing schedule errors — making it suitable for local dev and
376
+ * single-process callers that want durable-execution semantics without
377
+ * crash-recovery.
378
+ *
379
+ * `now` and `delay` are forwarded to the underlying machinery for tests that
380
+ * need to fast-forward time. Real callers should leave them at the defaults.
381
+ */
382
+ export interface InProcessDurableExecutionOptions extends InMemoryDurableExecutionOptions {
383
+ /**
384
+ * Optional {@link WorkflowRuntime} to integrate with. When supplied:
385
+ *
386
+ * - Each durable `run` pushes an `event`-typed history entry on start and
387
+ * completion through `runtime.state.history`.
388
+ * - Each durable `step` records a {@link CascadeStep} on
389
+ * `runtime.cascade` via {@link recordStep}; the step is marked
390
+ * completed/failed when the body resolves/rejects.
391
+ * - When `runtime.$.db` is present, each durable step creates an action
392
+ * via `db.createAction({ actor: 'workflow', object: name, action: 'step' })`
393
+ * before invoking the body, and completes (or records failure) on resolution.
394
+ * - The workflow context handed to the body exposes the runtime's `$` as
395
+ * {@link InProcessWorkflowContext.runtime} so handlers can dispatch
396
+ * events through the same registry the rest of the app uses.
397
+ *
398
+ * Pass `null`/omitted to opt out — the adapter still satisfies the port and
399
+ * runs durably in-process, just without the runtime integration.
400
+ */
401
+ runtime?: WorkflowRuntime;
402
+ }
403
+ /**
404
+ * Workflow context handed to bodies invoked through
405
+ * {@link createInProcessDurableExecution}. Identical to {@link WorkflowContext}
406
+ * but with an optional `runtime` reference exposing the wrapping
407
+ * {@link WorkflowRuntime} (when one was supplied at construction time).
408
+ *
409
+ * `runtime` is `undefined` when the adapter was constructed without a runtime.
410
+ */
411
+ export interface InProcessWorkflowContext<TInput = unknown> extends WorkflowContext<TInput> {
412
+ /** The `WorkflowRuntime` wrapped by the adapter, if any. */
413
+ readonly runtime?: WorkflowRuntime;
414
+ }
415
+ /**
416
+ * The adapter returned by {@link createInProcessDurableExecution}.
417
+ *
418
+ * Extends {@link DurableExecutionAdapter} with `emit` (for paired
419
+ * `waitForEvent` testing) and exposes the wrapped runtime when one was
420
+ * supplied. The `runtime` reference is the same object passed in at
421
+ * construction; callers can use it to register handlers, inspect history, or
422
+ * read cascade traces emitted during durable runs.
423
+ */
424
+ export interface InProcessDurableExecution extends DurableExecutionAdapter {
425
+ /**
426
+ * Manually deliver an event to the next pending {@link waitForEvent} call
427
+ * with the matching name. Mirrors {@link InMemoryDurableExecution.emit}.
428
+ */
429
+ emit<T = unknown>(name: string, value: T): boolean;
430
+ /** The runtime wrapped by the adapter, if one was supplied. */
431
+ readonly runtime?: WorkflowRuntime;
432
+ }
433
+ /**
434
+ * Construct the production in-process {@link DurableExecutionAdapter}.
435
+ *
436
+ * Differs from {@link createInMemoryDurableExecution} in three ways:
437
+ *
438
+ * 1. **Runtime integration.** When a {@link WorkflowRuntime} is supplied,
439
+ * each run/step is reflected in the runtime's cascade context, history,
440
+ * and (when `runtime.$.db` is wired) database adapter — making durable
441
+ * runs observable through the same surfaces as event-driven dispatch.
442
+ *
443
+ * 2. **Production-shape logging.** Schedule failures and step failures with
444
+ * a configured runtime are routed through the package logger
445
+ * ({@link getLogger}). The in-memory stub silently swallows these because
446
+ * tests do not want noise in the console.
447
+ *
448
+ * 3. **Workflow context exposes the runtime.** Bodies receive an
449
+ * {@link InProcessWorkflowContext} with `ctx.runtime` set, so durable
450
+ * workflows can dispatch events through the same `$.on`/`$.send`
451
+ * registry the rest of the app uses.
452
+ *
453
+ * The adapter is *not* durable across process restarts — that is the
454
+ * Cloudflare Workflows adapter's job (separate bead `aip-i456`). It exists
455
+ * for test environments, local development, and single-process callers that
456
+ * want the port semantics without a real backend.
457
+ *
458
+ * @example No runtime — equivalent to the in-memory stub but production-shape
459
+ * ```ts
460
+ * const dx = createInProcessDurableExecution()
461
+ * await dx.run('hello', async (ctx) => ctx.input.name, { name: 'world' })
462
+ * ```
463
+ *
464
+ * @example With runtime — durable runs participate in the `$` ecosystem
465
+ * ```ts
466
+ * const runtime = createWorkflowRuntime({ db: myDb })
467
+ * const dx = createInProcessDurableExecution({ runtime })
468
+ *
469
+ * await dx.run('cascade', async (ctx) => {
470
+ * const plan = await ctx.step('plan', async () => generatePlan(ctx.input))
471
+ * // The runtime's $.send delivers to handlers registered on the same runtime.
472
+ * ctx.runtime!.$.send('Plan.generated', plan)
473
+ * return plan
474
+ * }, { customerId: 'c-1' })
475
+ *
476
+ * // Cascade trace, history, and db actions all reflect the run.
477
+ * console.log(runtime.cascade.steps.length) // >= 1 (the 'plan' step)
478
+ * ```
479
+ */
480
+ export declare function createInProcessDurableExecution(options?: InProcessDurableExecutionOptions): InProcessDurableExecution;
481
+ export { createCloudflareWorkflowsDurableExecution, createWorkflowEntrypoint, type CloudflareWorkflowsDurableExecution, type CloudflareWorkflowsDurableExecutionOptions, type CloudflareWorkflowsLimits, type WorkflowEnvelope, type WorkflowEntrypointConstructor, type WorkflowEntrypointLike, type WorkflowEventLike, type WorkflowInstanceLike, type WorkflowsBindingLike, type WorkflowStepConfigLike, type WorkflowStepLike, } from './durable-execution-cloudflare.js';
482
+ //# sourceMappingURL=durable-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-execution.d.ts","sourceRoot":"","sources":["../src/durable-execution.ts"],"names":[],"mappings":"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"}