ai-workflows 2.1.1 → 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 (211) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -1
  3. package/README.md +305 -184
  4. package/dist/barrier.d.ts +159 -0
  5. package/dist/barrier.d.ts.map +1 -0
  6. package/dist/barrier.js +377 -0
  7. package/dist/barrier.js.map +1 -0
  8. package/dist/cascade-context.d.ts +149 -0
  9. package/dist/cascade-context.d.ts.map +1 -0
  10. package/dist/cascade-context.js +324 -0
  11. package/dist/cascade-context.js.map +1 -0
  12. package/dist/cascade-executor.d.ts +196 -0
  13. package/dist/cascade-executor.d.ts.map +1 -0
  14. package/dist/cascade-executor.js +384 -0
  15. package/dist/cascade-executor.js.map +1 -0
  16. package/dist/context.d.ts.map +1 -1
  17. package/dist/context.js +27 -8
  18. package/dist/context.js.map +1 -1
  19. package/dist/cron-parser.d.ts +65 -0
  20. package/dist/cron-parser.d.ts.map +1 -0
  21. package/dist/cron-parser.js +294 -0
  22. package/dist/cron-parser.js.map +1 -0
  23. package/dist/cron-scheduler.d.ts +117 -0
  24. package/dist/cron-scheduler.d.ts.map +1 -0
  25. package/dist/cron-scheduler.js +176 -0
  26. package/dist/cron-scheduler.js.map +1 -0
  27. package/dist/database-context.d.ts +184 -0
  28. package/dist/database-context.d.ts.map +1 -0
  29. package/dist/database-context.js +428 -0
  30. package/dist/database-context.js.map +1 -0
  31. package/dist/dependency-graph.d.ts +157 -0
  32. package/dist/dependency-graph.d.ts.map +1 -0
  33. package/dist/dependency-graph.js +382 -0
  34. package/dist/dependency-graph.js.map +1 -0
  35. package/dist/digital-objects-adapter.d.ts +159 -0
  36. package/dist/digital-objects-adapter.d.ts.map +1 -0
  37. package/dist/digital-objects-adapter.js +229 -0
  38. package/dist/digital-objects-adapter.js.map +1 -0
  39. package/dist/durable-execution-cloudflare.d.ts +427 -0
  40. package/dist/durable-execution-cloudflare.d.ts.map +1 -0
  41. package/dist/durable-execution-cloudflare.js +510 -0
  42. package/dist/durable-execution-cloudflare.js.map +1 -0
  43. package/dist/durable-execution.d.ts +482 -0
  44. package/dist/durable-execution.d.ts.map +1 -0
  45. package/dist/durable-execution.js +594 -0
  46. package/dist/durable-execution.js.map +1 -0
  47. package/dist/durable-workflow.d.ts +176 -0
  48. package/dist/durable-workflow.d.ts.map +1 -0
  49. package/dist/durable-workflow.js +552 -0
  50. package/dist/durable-workflow.js.map +1 -0
  51. package/dist/every.d.ts +31 -2
  52. package/dist/every.d.ts.map +1 -1
  53. package/dist/every.js +63 -32
  54. package/dist/every.js.map +1 -1
  55. package/dist/graph/index.d.ts +8 -0
  56. package/dist/graph/index.d.ts.map +1 -0
  57. package/dist/graph/index.js +8 -0
  58. package/dist/graph/index.js.map +1 -0
  59. package/dist/graph/topological-sort.d.ts +121 -0
  60. package/dist/graph/topological-sort.d.ts.map +1 -0
  61. package/dist/graph/topological-sort.js +292 -0
  62. package/dist/graph/topological-sort.js.map +1 -0
  63. package/dist/index.d.ts +10 -1
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/logger.d.ts +101 -0
  68. package/dist/logger.d.ts.map +1 -0
  69. package/dist/logger.js +115 -0
  70. package/dist/logger.js.map +1 -0
  71. package/dist/on.d.ts +35 -10
  72. package/dist/on.d.ts.map +1 -1
  73. package/dist/on.js +53 -19
  74. package/dist/on.js.map +1 -1
  75. package/dist/runtime.d.ts +169 -0
  76. package/dist/runtime.d.ts.map +1 -0
  77. package/dist/runtime.js +275 -0
  78. package/dist/runtime.js.map +1 -0
  79. package/dist/send.d.ts.map +1 -1
  80. package/dist/send.js +4 -3
  81. package/dist/send.js.map +1 -1
  82. package/dist/telemetry.d.ts +150 -0
  83. package/dist/telemetry.d.ts.map +1 -0
  84. package/dist/telemetry.js +388 -0
  85. package/dist/telemetry.js.map +1 -0
  86. package/dist/timer-registry.d.ts +77 -0
  87. package/dist/timer-registry.d.ts.map +1 -0
  88. package/dist/timer-registry.js +154 -0
  89. package/dist/timer-registry.js.map +1 -0
  90. package/dist/types.d.ts +105 -6
  91. package/dist/types.d.ts.map +1 -1
  92. package/dist/types.js +17 -1
  93. package/dist/types.js.map +1 -1
  94. package/dist/worker/durable-step.d.ts +481 -0
  95. package/dist/worker/durable-step.d.ts.map +1 -0
  96. package/dist/worker/durable-step.js +606 -0
  97. package/dist/worker/durable-step.js.map +1 -0
  98. package/dist/worker/index.d.ts +106 -0
  99. package/dist/worker/index.d.ts.map +1 -0
  100. package/dist/worker/index.js +124 -0
  101. package/dist/worker/index.js.map +1 -0
  102. package/dist/worker/state-adapter.d.ts +230 -0
  103. package/dist/worker/state-adapter.d.ts.map +1 -0
  104. package/dist/worker/state-adapter.js +409 -0
  105. package/dist/worker/state-adapter.js.map +1 -0
  106. package/dist/worker/topological-executor.d.ts +282 -0
  107. package/dist/worker/topological-executor.d.ts.map +1 -0
  108. package/dist/worker/topological-executor.js +396 -0
  109. package/dist/worker/topological-executor.js.map +1 -0
  110. package/dist/worker/workflow-builder.d.ts +286 -0
  111. package/dist/worker/workflow-builder.d.ts.map +1 -0
  112. package/dist/worker/workflow-builder.js +565 -0
  113. package/dist/worker/workflow-builder.js.map +1 -0
  114. package/dist/worker.d.ts +800 -0
  115. package/dist/worker.d.ts.map +1 -0
  116. package/dist/worker.js +2428 -0
  117. package/dist/worker.js.map +1 -0
  118. package/dist/workflow-builder.d.ts +287 -0
  119. package/dist/workflow-builder.d.ts.map +1 -0
  120. package/dist/workflow-builder.js +762 -0
  121. package/dist/workflow-builder.js.map +1 -0
  122. package/dist/workflow.d.ts +14 -30
  123. package/dist/workflow.d.ts.map +1 -1
  124. package/dist/workflow.js +136 -292
  125. package/dist/workflow.js.map +1 -1
  126. package/examples/01-ecommerce-order-pipeline.ts +358 -0
  127. package/examples/02-content-moderation-cascade.ts +454 -0
  128. package/examples/03-scheduled-reporting-dependencies.ts +479 -0
  129. package/examples/04-database-persistence.ts +518 -0
  130. package/examples/README.md +173 -0
  131. package/package.json +21 -4
  132. package/src/__tests__/digital-objects-adapter.test.ts +274 -0
  133. package/src/__tests__/durable-workflow.test.ts +297 -0
  134. package/src/barrier.ts +507 -0
  135. package/src/cascade-context.ts +495 -0
  136. package/src/cascade-executor.ts +588 -0
  137. package/src/context.ts +51 -17
  138. package/src/cron-parser.ts +347 -0
  139. package/src/cron-scheduler.ts +239 -0
  140. package/src/database-context.ts +658 -0
  141. package/src/dependency-graph.ts +518 -0
  142. package/src/digital-objects-adapter.ts +351 -0
  143. package/src/durable-execution-cloudflare.ts +855 -0
  144. package/src/durable-execution.ts +1042 -0
  145. package/src/durable-workflow.ts +717 -0
  146. package/src/every.ts +104 -35
  147. package/src/graph/index.ts +19 -0
  148. package/src/graph/topological-sort.ts +412 -0
  149. package/src/index.ts +147 -0
  150. package/src/logger.ts +148 -0
  151. package/src/on.ts +81 -26
  152. package/src/runtime.ts +436 -0
  153. package/src/send.ts +4 -5
  154. package/src/telemetry.ts +577 -0
  155. package/src/timer-registry.ts +179 -0
  156. package/src/types.ts +146 -10
  157. package/src/worker/durable-step.ts +976 -0
  158. package/src/worker/index.ts +216 -0
  159. package/src/worker/state-adapter.ts +589 -0
  160. package/src/worker/topological-executor.ts +625 -0
  161. package/src/worker/workflow-builder.ts +871 -0
  162. package/src/worker.ts +2906 -0
  163. package/src/workflow-builder.ts +1068 -0
  164. package/src/workflow.ts +199 -355
  165. package/test/barrier-join.test.ts +442 -0
  166. package/test/barrier-unhandled-rejections.test.ts +359 -0
  167. package/test/cascade-context.test.ts +390 -0
  168. package/test/cascade-executor.test.ts +852 -0
  169. package/test/cron-parser.test.ts +314 -0
  170. package/test/cron-scheduler.test.ts +291 -0
  171. package/test/database-context.test.ts +770 -0
  172. package/test/db-provider-adapter.test.ts +862 -0
  173. package/test/dependency-graph.test.ts +512 -0
  174. package/test/durable-execution-cloudflare.test.ts +606 -0
  175. package/test/durable-execution-in-process.test.ts +286 -0
  176. package/test/durable-execution.test.ts +247 -0
  177. package/test/e2e/workflow-scenarios.e2e.test.ts +1039 -0
  178. package/test/graph/topological-sort.test.ts +586 -0
  179. package/test/integration.test.ts +442 -0
  180. package/test/rpc-surface.test.ts +946 -0
  181. package/test/runtime.test.ts +262 -0
  182. package/test/schedule-timer-cleanup.test.ts +353 -0
  183. package/test/send-race-conditions.test.ts +400 -0
  184. package/test/type-safety-every.test.ts +303 -0
  185. package/test/worker/durable-cascade.test.ts +1117 -0
  186. package/test/worker/durable-step.test.ts +723 -0
  187. package/test/worker/topological-executor.test.ts +1240 -0
  188. package/test/worker/workflow-builder.test.ts +1067 -0
  189. package/test/worker.test.ts +608 -0
  190. package/test/workflow-builder.test.ts +1670 -0
  191. package/test/workflow-cron.test.ts +256 -0
  192. package/test/workflow-state-adapter.test.ts +923 -0
  193. package/test/workflow.test.ts +25 -22
  194. package/tsconfig.json +3 -1
  195. package/vitest.config.ts +38 -1
  196. package/vitest.workers.config.ts +44 -0
  197. package/wrangler.jsonc +22 -0
  198. package/.turbo/turbo-test.log +0 -7
  199. package/src/context.js +0 -83
  200. package/src/every.js +0 -267
  201. package/src/index.js +0 -71
  202. package/src/on.js +0 -79
  203. package/src/send.js +0 -111
  204. package/src/types.js +0 -4
  205. package/src/workflow.js +0 -455
  206. package/test/context.test.js +0 -116
  207. package/test/every.test.js +0 -282
  208. package/test/on.test.js +0 -80
  209. package/test/send.test.js +0 -89
  210. package/test/workflow.test.js +0 -224
  211. package/vitest.config.js +0 -7
@@ -0,0 +1,594 @@
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 { recordStep } from './cascade-context.js';
123
+ import { getLogger } from './logger.js';
124
+ // =============================================================================
125
+ // Error types
126
+ // =============================================================================
127
+ /**
128
+ * Thrown when a step's body fails after all retries (or immediately, when
129
+ * retries are not configured).
130
+ *
131
+ * The {@link DurableStepError.retryable} flag reflects the adapter's
132
+ * judgement about the underlying failure: `true` means the adapter believed
133
+ * the failure was transient (network, rate-limit, server error) and would
134
+ * have retried again given more attempts; `false` means the adapter
135
+ * classified it as terminal (programmer error, invalid input). Callers can
136
+ * use this to decide whether to escalate or fall through to a different
137
+ * code path.
138
+ */
139
+ export class DurableStepError extends Error {
140
+ /** Step name that failed. */
141
+ stepName;
142
+ /** Number of attempts the adapter actually made (>= 1). */
143
+ attempts;
144
+ /** Whether the adapter considered the cause transient. */
145
+ retryable;
146
+ /** The error that ultimately caused the failure. */
147
+ cause;
148
+ constructor(message, options) {
149
+ super(message);
150
+ this.name = 'DurableStepError';
151
+ this.stepName = options.stepName;
152
+ this.attempts = options.attempts;
153
+ this.retryable = options.retryable;
154
+ this.cause = options.cause;
155
+ }
156
+ }
157
+ /**
158
+ * Thrown when {@link DurableExecutionAdapter.waitForEvent} elapses without
159
+ * the named event arriving.
160
+ */
161
+ export class WaitForEventTimeoutError extends Error {
162
+ eventName;
163
+ timeout;
164
+ constructor(eventName, timeout) {
165
+ super(`Timed out waiting for event "${eventName}" after ${String(timeout)}`);
166
+ this.name = 'WaitForEventTimeoutError';
167
+ this.eventName = eventName;
168
+ this.timeout = timeout;
169
+ }
170
+ }
171
+ /**
172
+ * Internal: parse human-readable durations like `'1 second'`, `'500ms'`,
173
+ * `'5 minutes'` into milliseconds. The supported grammar is small on
174
+ * purpose; real backends define their own. Numbers pass through.
175
+ */
176
+ function parseDuration(input) {
177
+ if (typeof input === 'number')
178
+ return input;
179
+ const trimmed = input.trim().toLowerCase();
180
+ const match = trimmed.match(/^(\d+(?:\.\d+)?)\s*(ms|millisecond|milliseconds|s|sec|second|seconds|m|min|minute|minutes|h|hr|hour|hours|d|day|days)$/);
181
+ if (!match) {
182
+ throw new Error(`Unrecognised duration: "${input}"`);
183
+ }
184
+ const value = parseFloat(match[1]);
185
+ const unit = match[2];
186
+ switch (unit) {
187
+ case 'ms':
188
+ case 'millisecond':
189
+ case 'milliseconds':
190
+ return value;
191
+ case 's':
192
+ case 'sec':
193
+ case 'second':
194
+ case 'seconds':
195
+ return value * 1000;
196
+ case 'm':
197
+ case 'min':
198
+ case 'minute':
199
+ case 'minutes':
200
+ return value * 60_000;
201
+ case 'h':
202
+ case 'hr':
203
+ case 'hour':
204
+ case 'hours':
205
+ return value * 3_600_000;
206
+ case 'd':
207
+ case 'day':
208
+ case 'days':
209
+ return value * 86_400_000;
210
+ /* istanbul ignore next */
211
+ default:
212
+ throw new Error(`Unrecognised duration unit: "${unit}"`);
213
+ }
214
+ }
215
+ /** Internal: compute backoff delay for retry attempt n (1-based). */
216
+ function computeBackoff(config, attempt) {
217
+ const baseMs = config.delay !== undefined ? parseDuration(config.delay) : 0;
218
+ const strategy = config.backoff ?? 'constant';
219
+ switch (strategy) {
220
+ case 'constant':
221
+ return baseMs;
222
+ case 'linear':
223
+ return baseMs * attempt;
224
+ case 'exponential':
225
+ return baseMs * Math.pow(2, attempt - 1);
226
+ }
227
+ }
228
+ /**
229
+ * @see InMemoryDurableExecution
230
+ */
231
+ export function createInMemoryDurableExecution(options = {}) {
232
+ const now = options.now ?? (() => Date.now());
233
+ const delay = options.delay ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
234
+ // Per-run memoization is keyed by the surrounding run's instanceId. Calls
235
+ // outside of a run get an `undefined` key (single shared bucket).
236
+ const runMemo = new Map();
237
+ // Active event waiters, FIFO per event name.
238
+ const waiters = new Map();
239
+ // Active scheduled intervals, by subscription id.
240
+ const schedules = new Map();
241
+ let scheduleSeq = 0;
242
+ let runSeq = 0;
243
+ const runStack = [];
244
+ const currentRun = () => runStack[runStack.length - 1];
245
+ async function executeStep(name, config, fn) {
246
+ const frame = currentRun();
247
+ const bucketKey = frame?.instanceId;
248
+ let bucket = runMemo.get(bucketKey);
249
+ if (!bucket) {
250
+ bucket = new Map();
251
+ runMemo.set(bucketKey, bucket);
252
+ }
253
+ if (bucket.has(name)) {
254
+ return bucket.get(name);
255
+ }
256
+ const retries = config?.retries;
257
+ const maxAttempts = retries?.limit ?? 1;
258
+ let lastErr;
259
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
260
+ try {
261
+ const result = await fn();
262
+ bucket.set(name, result);
263
+ return result;
264
+ }
265
+ catch (err) {
266
+ lastErr = err;
267
+ if (attempt < maxAttempts && retries) {
268
+ const wait = computeBackoff(retries, attempt);
269
+ if (wait > 0)
270
+ await delay(wait);
271
+ }
272
+ }
273
+ }
274
+ throw new DurableStepError(`Step "${name}" failed after ${maxAttempts} attempt(s)`, {
275
+ stepName: name,
276
+ attempts: maxAttempts,
277
+ retryable: true,
278
+ cause: lastErr,
279
+ });
280
+ }
281
+ async function sleep(duration) {
282
+ const ms = parseDuration(duration);
283
+ if (ms > 0)
284
+ await delay(ms);
285
+ }
286
+ async function sleepUntil(date) {
287
+ const ms = date.getTime() - now();
288
+ if (ms > 0)
289
+ await delay(ms);
290
+ }
291
+ function waitForEvent(name, timeout) {
292
+ return new Promise((resolve, reject) => {
293
+ const queue = waiters.get(name) ?? [];
294
+ const waiter = {
295
+ resolve: (v) => resolve(v),
296
+ reject,
297
+ };
298
+ queue.push(waiter);
299
+ waiters.set(name, queue);
300
+ if (timeout !== undefined) {
301
+ const ms = parseDuration(timeout);
302
+ const timer = setTimeout(() => {
303
+ const q = waiters.get(name);
304
+ if (!q)
305
+ return;
306
+ const idx = q.indexOf(waiter);
307
+ if (idx >= 0) {
308
+ q.splice(idx, 1);
309
+ if (q.length === 0)
310
+ waiters.delete(name);
311
+ reject(new WaitForEventTimeoutError(name, timeout));
312
+ }
313
+ }, ms);
314
+ // Don't keep the process alive solely for a wait timeout.
315
+ if (typeof timer.unref === 'function') {
316
+ ;
317
+ timer.unref();
318
+ }
319
+ }
320
+ });
321
+ }
322
+ function emit(name, value) {
323
+ const queue = waiters.get(name);
324
+ if (!queue || queue.length === 0)
325
+ return false;
326
+ const waiter = queue.shift();
327
+ if (queue.length === 0)
328
+ waiters.delete(name);
329
+ waiter.resolve(value);
330
+ return true;
331
+ }
332
+ function schedule(name, cron, fn) {
333
+ const id = `sched-${++scheduleSeq}`;
334
+ // The stub does not parse cron — it fires every second. Tests that
335
+ // need precise timing should drive runs manually rather than rely on
336
+ // the stub's scheduler. Real adapters honour the cron expression.
337
+ void cron;
338
+ void name;
339
+ const handle = setInterval(() => {
340
+ void adapter.run(name, fn, undefined).catch(() => {
341
+ // Schedule errors are swallowed; the stub has nowhere to surface
342
+ // them. Real adapters log/persist failures.
343
+ });
344
+ }, 1000);
345
+ if (typeof handle.unref === 'function') {
346
+ ;
347
+ handle.unref();
348
+ }
349
+ schedules.set(id, handle);
350
+ return {
351
+ id,
352
+ unsubscribe() {
353
+ const h = schedules.get(id);
354
+ if (h) {
355
+ clearInterval(h);
356
+ schedules.delete(id);
357
+ }
358
+ },
359
+ };
360
+ }
361
+ async function run(name, fn, input) {
362
+ const instanceId = `run-${++runSeq}`;
363
+ const frame = { instanceId };
364
+ runStack.push(frame);
365
+ const ctx = {
366
+ input,
367
+ instanceId,
368
+ name,
369
+ step: ((stepName, configOrFn, maybeFn) => {
370
+ if (typeof configOrFn === 'function') {
371
+ return executeStep(stepName, undefined, configOrFn);
372
+ }
373
+ return executeStep(stepName, configOrFn, maybeFn);
374
+ }),
375
+ sleep,
376
+ sleepUntil,
377
+ waitForEvent,
378
+ };
379
+ try {
380
+ return await fn(ctx);
381
+ }
382
+ finally {
383
+ runStack.pop();
384
+ runMemo.delete(instanceId);
385
+ }
386
+ }
387
+ const adapter = {
388
+ kind: 'in-process',
389
+ run,
390
+ step: ((name, configOrFn, maybeFn) => {
391
+ if (typeof configOrFn === 'function') {
392
+ return executeStep(name, undefined, configOrFn);
393
+ }
394
+ return executeStep(name, configOrFn, maybeFn);
395
+ }),
396
+ sleep,
397
+ sleepUntil,
398
+ waitForEvent,
399
+ schedule,
400
+ emit,
401
+ };
402
+ return adapter;
403
+ }
404
+ /**
405
+ * Construct the production in-process {@link DurableExecutionAdapter}.
406
+ *
407
+ * Differs from {@link createInMemoryDurableExecution} in three ways:
408
+ *
409
+ * 1. **Runtime integration.** When a {@link WorkflowRuntime} is supplied,
410
+ * each run/step is reflected in the runtime's cascade context, history,
411
+ * and (when `runtime.$.db` is wired) database adapter — making durable
412
+ * runs observable through the same surfaces as event-driven dispatch.
413
+ *
414
+ * 2. **Production-shape logging.** Schedule failures and step failures with
415
+ * a configured runtime are routed through the package logger
416
+ * ({@link getLogger}). The in-memory stub silently swallows these because
417
+ * tests do not want noise in the console.
418
+ *
419
+ * 3. **Workflow context exposes the runtime.** Bodies receive an
420
+ * {@link InProcessWorkflowContext} with `ctx.runtime` set, so durable
421
+ * workflows can dispatch events through the same `$.on`/`$.send`
422
+ * registry the rest of the app uses.
423
+ *
424
+ * The adapter is *not* durable across process restarts — that is the
425
+ * Cloudflare Workflows adapter's job (separate bead `aip-i456`). It exists
426
+ * for test environments, local development, and single-process callers that
427
+ * want the port semantics without a real backend.
428
+ *
429
+ * @example No runtime — equivalent to the in-memory stub but production-shape
430
+ * ```ts
431
+ * const dx = createInProcessDurableExecution()
432
+ * await dx.run('hello', async (ctx) => ctx.input.name, { name: 'world' })
433
+ * ```
434
+ *
435
+ * @example With runtime — durable runs participate in the `$` ecosystem
436
+ * ```ts
437
+ * const runtime = createWorkflowRuntime({ db: myDb })
438
+ * const dx = createInProcessDurableExecution({ runtime })
439
+ *
440
+ * await dx.run('cascade', async (ctx) => {
441
+ * const plan = await ctx.step('plan', async () => generatePlan(ctx.input))
442
+ * // The runtime's $.send delivers to handlers registered on the same runtime.
443
+ * ctx.runtime!.$.send('Plan.generated', plan)
444
+ * return plan
445
+ * }, { customerId: 'c-1' })
446
+ *
447
+ * // Cascade trace, history, and db actions all reflect the run.
448
+ * console.log(runtime.cascade.steps.length) // >= 1 (the 'plan' step)
449
+ * ```
450
+ */
451
+ export function createInProcessDurableExecution(options = {}) {
452
+ // The in-process adapter delegates step/sleep/wait/schedule mechanics to
453
+ // the in-memory factory and wraps run/step with runtime-integration hooks.
454
+ // This keeps the two factories from drifting in their core behaviour and
455
+ // lets the in-memory stub remain the canonical reference for the port's
456
+ // baseline semantics.
457
+ const inner = createInMemoryDurableExecution({
458
+ ...(options.now !== undefined && { now: options.now }),
459
+ ...(options.delay !== undefined && { delay: options.delay }),
460
+ });
461
+ const runtime = options.runtime;
462
+ function recordRunHistory(name, phase, data) {
463
+ if (!runtime)
464
+ return;
465
+ runtime.state.history.push({
466
+ timestamp: Date.now(),
467
+ type: 'event',
468
+ name: `durable-run:${phase}:${name}`,
469
+ ...(data !== undefined && { data }),
470
+ });
471
+ }
472
+ async function instrumentedStep(stepName, config, fn, innerStep) {
473
+ if (!runtime) {
474
+ // No runtime — defer to the inner mechanics unchanged.
475
+ return config !== undefined ? innerStep(stepName, config, fn) : innerStep(stepName, fn);
476
+ }
477
+ const cascadeStep = recordStep(runtime.cascade, stepName);
478
+ const db = runtime.$.db;
479
+ let actionRecorded = false;
480
+ if (db) {
481
+ try {
482
+ await db.createAction({
483
+ actor: 'workflow',
484
+ object: stepName,
485
+ action: 'step',
486
+ status: 'active',
487
+ });
488
+ actionRecorded = true;
489
+ }
490
+ catch (err) {
491
+ // Do not fail the step because action recording failed; surface the
492
+ // error through the package logger so it is observable.
493
+ getLogger().error(`[durable-execution] Failed to record action for step "${stepName}":`, err);
494
+ }
495
+ }
496
+ const wrapped = async () => fn();
497
+ try {
498
+ const result = await (config !== undefined
499
+ ? innerStep(stepName, config, wrapped)
500
+ : innerStep(stepName, wrapped));
501
+ cascadeStep.complete();
502
+ if (actionRecorded && db) {
503
+ try {
504
+ await db.completeAction(stepName, result);
505
+ }
506
+ catch (err) {
507
+ getLogger().error(`[durable-execution] Failed to complete action for step "${stepName}":`, err);
508
+ }
509
+ }
510
+ return result;
511
+ }
512
+ catch (err) {
513
+ cascadeStep.fail(err instanceof Error ? err : new Error(String(err)));
514
+ getLogger().error(`[durable-execution] Step "${stepName}" failed:`, err);
515
+ throw err;
516
+ }
517
+ }
518
+ async function run(name, fn, input) {
519
+ recordRunHistory(name, 'start', { input });
520
+ try {
521
+ const result = await inner.run(name, async (innerCtx) => {
522
+ const ctx = {
523
+ input: innerCtx.input,
524
+ instanceId: innerCtx.instanceId,
525
+ name: innerCtx.name,
526
+ sleep: innerCtx.sleep,
527
+ sleepUntil: innerCtx.sleepUntil,
528
+ waitForEvent: innerCtx.waitForEvent,
529
+ step: ((stepName, configOrFn, maybeFn) => {
530
+ if (typeof configOrFn === 'function') {
531
+ return instrumentedStep(stepName, undefined, configOrFn, innerCtx.step);
532
+ }
533
+ return instrumentedStep(stepName, configOrFn, maybeFn, innerCtx.step);
534
+ }),
535
+ ...(runtime !== undefined && { runtime }),
536
+ };
537
+ return fn(ctx);
538
+ }, input);
539
+ recordRunHistory(name, 'finish', { result });
540
+ return result;
541
+ }
542
+ catch (err) {
543
+ recordRunHistory(name, 'error', { error: err instanceof Error ? err.message : String(err) });
544
+ throw err;
545
+ }
546
+ }
547
+ function topLevelStep(name, configOrFn, maybeFn) {
548
+ if (typeof configOrFn === 'function') {
549
+ return instrumentedStep(name, undefined, configOrFn, inner.step);
550
+ }
551
+ return instrumentedStep(name, configOrFn, maybeFn, inner.step);
552
+ }
553
+ function instrumentedSchedule(name, cron, fn) {
554
+ if (!runtime) {
555
+ return inner.schedule(name, cron, fn);
556
+ }
557
+ // When a runtime is wired, surface schedule failures through the logger
558
+ // (the in-memory stub silently swallows them). We do this by wrapping the
559
+ // body to log; the inner schedule itself continues to swallow rejections
560
+ // so the interval keeps firing.
561
+ const wrapped = async (ctx) => {
562
+ try {
563
+ return await fn(ctx);
564
+ }
565
+ catch (err) {
566
+ getLogger().error(`[durable-execution] Scheduled run "${name}" failed:`, err);
567
+ throw err;
568
+ }
569
+ };
570
+ return inner.schedule(name, cron, wrapped);
571
+ }
572
+ const adapter = {
573
+ kind: 'in-process',
574
+ run: run,
575
+ step: topLevelStep,
576
+ sleep: inner.sleep,
577
+ sleepUntil: inner.sleepUntil,
578
+ waitForEvent: inner.waitForEvent,
579
+ schedule: instrumentedSchedule,
580
+ emit: inner.emit,
581
+ ...(runtime !== undefined && { runtime }),
582
+ };
583
+ return adapter;
584
+ }
585
+ // =============================================================================
586
+ // Cloudflare Workflows adapter (re-export)
587
+ // =============================================================================
588
+ // Re-export the Cloudflare Workflows adapter so callers using the
589
+ // `ai-workflows/durable-execution` subpath can reach both the port and its CF
590
+ // implementation through a single import. See `./durable-execution-cloudflare.ts`
591
+ // for the bridge logic and `docs/adr/0004-durable-execution-cf-workflows-default.md`
592
+ // for the rationale.
593
+ export { createCloudflareWorkflowsDurableExecution, createWorkflowEntrypoint, } from './durable-execution-cloudflare.js';
594
+ //# sourceMappingURL=durable-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-execution.js","sourceRoot":"","sources":["../src/durable-execution.ts"],"names":[],"mappings":"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"}