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,510 @@
1
+ /**
2
+ * Cloudflare Workflows adapter for {@link DurableExecutionAdapter}.
3
+ *
4
+ * Bridges the backend-agnostic port defined in `./durable-execution.ts` to
5
+ * Cloudflare's class-based {@link https://developers.cloudflare.com/workflows/ Workflows runtime}.
6
+ * CF Workflows is the production default per
7
+ * {@link ../../docs/adr/0004-durable-execution-cf-workflows-default.md ADR-0004}:
8
+ * the recently expanded limits (25K steps default-configurable, 50K concurrent
9
+ * instances, 365-day max sleep, 1 GB persisted state) plus zero per-step
10
+ * billing make it the cost-optimal backend for cascade-heavy workloads.
11
+ *
12
+ * ## How the bridge works
13
+ *
14
+ * CF Workflows uses a class-based dispatch model — users author a
15
+ * {@link WorkflowEntrypointLike} subclass with `async run(event, step)`, and
16
+ * the runtime instantiates it for each invocation. Our port's
17
+ * `run(name, fn, input)` is callback-shaped. The adapter resolves the
18
+ * impedance mismatch with two complementary surfaces:
19
+ *
20
+ * 1. **Workflow-function registry.** Callers register named workflow bodies
21
+ * against the adapter via {@link CloudflareWorkflowsDurableExecution.register}
22
+ * (or implicitly the first time {@link CloudflareWorkflowsDurableExecution.run}
23
+ * is called with that name). The registry is a plain {@link Map}
24
+ * maintained on the adapter instance.
25
+ *
26
+ * 2. **`createWorkflowEntrypoint(adapter)`.** Returns a
27
+ * {@link WorkflowEntrypointLike} subclass whose `run(event, step)`
28
+ * reads the workflow name from `event.payload.__wfName`, looks the body
29
+ * up in the registry, and invokes it with a {@link WorkflowContext} that
30
+ * delegates each port primitive to the CF `step` argument. Users export
31
+ * this class from their worker module and wire it through `wrangler.jsonc`:
32
+ *
33
+ * ```jsonc
34
+ * "workflows": [{
35
+ * "name": "cascade",
36
+ * "binding": "WORKFLOW",
37
+ * "class_name": "MyWorkflowEntrypoint"
38
+ * }]
39
+ * ```
40
+ *
41
+ * The adapter's `run()` triggers a workflow by calling `binding.create({
42
+ * params: { __wfName, __wfInput } })` against the supplied
43
+ * {@link WorkflowsBindingLike}. By default it polls
44
+ * `instance.status()` until completion and returns the workflow output;
45
+ * callers that need fire-and-forget can opt out via
46
+ * {@link CloudflareWorkflowsDurableExecutionOptions.waitForCompletion}.
47
+ *
48
+ * ## Step / sleep / waitForEvent translation
49
+ *
50
+ * - `ctx.step(name, fn)` → `step.do(name, fn)`
51
+ * - `ctx.step(name, cfg, fn)` → `step.do(name, cfg, fn)`
52
+ * - `ctx.sleep(duration)` → `step.sleep(autoStepName, duration)`
53
+ * - `ctx.sleepUntil(date)` → `step.sleepUntil(autoStepName, date)`
54
+ * - `ctx.waitForEvent(name, t?)` → `step.waitForEvent(autoStepName, { type: name, timeout: t })`
55
+ *
56
+ * CF requires every primitive to receive a stable name; our port's `sleep` /
57
+ * `sleepUntil` / `waitForEvent` don't. The bridge synthesises a deterministic
58
+ * name from a per-context counter (`__sleep__1`, `__waitForEvent__Order.placed__1`)
59
+ * incremented in body order. Bodies that take the same control-flow path on
60
+ * replay therefore see identical names — the determinism rule applies.
61
+ *
62
+ * Callers who want full control over step naming for sleeps/waits should use
63
+ * {@link DurableExecutionAdapter.step} (or `ctx.step`) wrapping the desired
64
+ * primitive: e.g. `await ctx.step('payment-window', () => sleepUntil(deadline))`.
65
+ *
66
+ * ## Schedules
67
+ *
68
+ * CF Workflows do not support imperative cron registration through the binding;
69
+ * scheduled triggers are declared in `wrangler.jsonc` under `[triggers] crons`
70
+ * and routed to a Worker `scheduled()` handler. The adapter's
71
+ * {@link DurableExecutionAdapter.schedule} therefore registers the workflow
72
+ * body against the adapter and returns a {@link Subscription} whose `id` is
73
+ * the workflow name; the user's worker `scheduled()` handler must call
74
+ * {@link CloudflareWorkflowsDurableExecution.runSchedule} (or the adapter's
75
+ * `run()`) when the cron fires. {@link CloudflareWorkflowsDurableExecution.defineSchedule}
76
+ * is an alias for `schedule()` that emphasises the wrangler-coordinated nature
77
+ * of CF scheduling.
78
+ *
79
+ * ## Rules of Workflows (CF-imposed; universal)
80
+ *
81
+ * 1. **Steps must be idempotent.** CF re-executes step bodies on replay
82
+ * after a hibernation boundary or transient failure. Wrap external
83
+ * side-effects so a duplicate invocation is observably equivalent to a
84
+ * single one.
85
+ *
86
+ * 2. **Step names must be deterministic.** CF uses the step name as the
87
+ * memoization key. Random ids, timestamps, or run-specific values in
88
+ * step names break replay.
89
+ *
90
+ * 3. **State must flow through step returns.** Variables defined in the
91
+ * workflow body but outside a step DO NOT survive hibernation. Read
92
+ * inputs at the top of a step and return only what subsequent steps
93
+ * need.
94
+ *
95
+ * 4. **Workflow bodies must be deterministic.** Two replays of the same
96
+ * input must take the same control-flow path. Push non-determinism
97
+ * (clocks, randomness, network reads) into steps so CF can memoize the
98
+ * result.
99
+ *
100
+ * 5. **Use `step.sleep` / `step.sleepUntil` / `step.waitForEvent`.** Never
101
+ * `setTimeout` or polling — only the runtime knows how to suspend and
102
+ * resume the workflow.
103
+ *
104
+ * ## Limits
105
+ *
106
+ * Declared via {@link CloudflareWorkflowsDurableExecution.limits}:
107
+ *
108
+ * - **Steps per workflow:** 25,000 (default-configurable per Mar 2026
109
+ * change; see ADR-0004).
110
+ * - **Concurrent instances:** 50,000 per account (Apr 2026 change).
111
+ * - **Maximum sleep:** 365 days.
112
+ * - **Per-step / per-event payload:** 1 MiB (CF Workers RPC limit).
113
+ *
114
+ * @see {@link ../../docs/adr/0004-durable-execution-cf-workflows-default.md ADR-0004}
115
+ * @see {@link https://developers.cloudflare.com/workflows/build/workflows-api/ Workflows API}
116
+ * @see {@link https://developers.cloudflare.com/workflows/build/rules-of-workflows/ Rules of Workflows}
117
+ *
118
+ * @example Wiring an adapter
119
+ * ```ts
120
+ * // worker.ts
121
+ * import {
122
+ * createCloudflareWorkflowsDurableExecution,
123
+ * createWorkflowEntrypoint,
124
+ * } from 'ai-workflows/durable-execution'
125
+ *
126
+ * type Env = { WORKFLOW: import('cloudflare:workers').Workflow }
127
+ *
128
+ * const dx = createCloudflareWorkflowsDurableExecution({
129
+ * binding: () => env.WORKFLOW, // resolved per-request
130
+ * })
131
+ *
132
+ * dx.register('cascade', async (ctx) => {
133
+ * const plan = await ctx.step('plan', () => generatePlan(ctx.input))
134
+ * await ctx.sleep('1 minute')
135
+ * return ctx.step('write', () => writeAll(plan))
136
+ * })
137
+ *
138
+ * // The class wrangler binds; CF instantiates it on each run.
139
+ * export const MyWorkflow = createWorkflowEntrypoint(dx)
140
+ *
141
+ * export default {
142
+ * async fetch(req: Request, env: Env) {
143
+ * // Trigger from anywhere — adapter.run() goes through the binding.
144
+ * const result = await dx.run('cascade', undefined as never, { customerId: 'c-1' })
145
+ * return Response.json(result)
146
+ * },
147
+ * }
148
+ * ```
149
+ *
150
+ * @packageDocumentation
151
+ */
152
+ import { DurableStepError, WaitForEventTimeoutError, } from './durable-execution.js';
153
+ const CLOUDFLARE_WORKFLOWS_LIMITS = {
154
+ maxSteps: 25_000,
155
+ maxConcurrentInstances: 50_000,
156
+ maxSleepDays: 365,
157
+ maxPayloadBytes: 1_048_576,
158
+ };
159
+ function isEnvelope(payload) {
160
+ return (typeof payload === 'object' &&
161
+ payload !== null &&
162
+ '__wfName' in payload &&
163
+ typeof payload.__wfName === 'string' &&
164
+ '__wfInput' in payload);
165
+ }
166
+ /**
167
+ * Construct a Cloudflare Workflows {@link DurableExecutionAdapter}.
168
+ *
169
+ * The adapter satisfies the full port contract by translating each call into
170
+ * its CF equivalent (see module docs). Step bodies execute inside CF's
171
+ * runtime and inherit CF's idempotency, replay, and hibernation semantics.
172
+ *
173
+ * **The adapter does not run workflow bodies in-process.** Calling `run()`
174
+ * triggers a CF Workflow via the supplied binding; the body runs on CF's
175
+ * infrastructure and the adapter polls (or returns the instance handle).
176
+ * For tests that need to exercise the body directly without a CF runtime,
177
+ * use {@link createInProcessDurableExecution} or
178
+ * {@link createInMemoryDurableExecution} instead.
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * import { createCloudflareWorkflowsDurableExecution, createWorkflowEntrypoint } from 'ai-workflows/durable-execution'
183
+ *
184
+ * type Env = { WORKFLOW: Workflow }
185
+ *
186
+ * const dx = createCloudflareWorkflowsDurableExecution({ binding: () => env.WORKFLOW })
187
+ * dx.register('hello', async (ctx) => `hi, ${ctx.input}`)
188
+ *
189
+ * export const HelloWorkflow = createWorkflowEntrypoint(dx)
190
+ * ```
191
+ */
192
+ export function createCloudflareWorkflowsDurableExecution(options) {
193
+ const waitForCompletion = options.waitForCompletion ?? true;
194
+ const pollIntervalMs = options.pollIntervalMs ?? 250;
195
+ const pollTimeoutMs = options.pollTimeoutMs ?? 24 * 60 * 60 * 1000;
196
+ const delay = options.delay ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
197
+ const registry = new Map();
198
+ const schedules = new Map();
199
+ function resolveBinding() {
200
+ const b = options.binding;
201
+ return typeof b === 'function' ? b() : b;
202
+ }
203
+ // ---------------------------------------------------------------------------
204
+ // Workflow context bridge — invoked by the entrypoint handler with the CF
205
+ // `step` argument. Each port primitive translates to the matching CF call.
206
+ // ---------------------------------------------------------------------------
207
+ function buildContext(name, instanceId, input, step) {
208
+ // Auto-naming counter for sleep/waitForEvent (CF requires every primitive
209
+ // to receive a stable, deterministic name). The body's control flow is
210
+ // deterministic, so a strictly increasing counter yields stable names
211
+ // across replays.
212
+ let sleepCounter = 0;
213
+ let sleepUntilCounter = 0;
214
+ const waitCounters = new Map();
215
+ const ctx = {
216
+ input,
217
+ instanceId,
218
+ name,
219
+ step: ((stepName, configOrFn, maybeFn) => {
220
+ if (typeof configOrFn === 'function') {
221
+ return step.do(stepName, configOrFn);
222
+ }
223
+ return step.do(stepName, configOrFn, maybeFn);
224
+ }),
225
+ async sleep(duration) {
226
+ const stepName = `__sleep__${++sleepCounter}`;
227
+ await step.sleep(stepName, duration);
228
+ },
229
+ async sleepUntil(date) {
230
+ const stepName = `__sleepUntil__${++sleepUntilCounter}`;
231
+ await step.sleepUntil(stepName, date);
232
+ },
233
+ async waitForEvent(eventName, timeout) {
234
+ const seq = (waitCounters.get(eventName) ?? 0) + 1;
235
+ waitCounters.set(eventName, seq);
236
+ const stepName = `__waitForEvent__${eventName}__${seq}`;
237
+ try {
238
+ const opts = { type: eventName };
239
+ if (timeout !== undefined)
240
+ opts.timeout = timeout;
241
+ const result = await step.waitForEvent(stepName, opts);
242
+ // CF returns { payload, type, timestamp } — unwrap to the user-shaped
243
+ // value when the envelope is present; otherwise pass through.
244
+ if (result !== null &&
245
+ typeof result === 'object' &&
246
+ 'payload' in result) {
247
+ return result.payload;
248
+ }
249
+ return result;
250
+ }
251
+ catch (err) {
252
+ // CF surfaces wait timeouts as thrown errors; normalise to the
253
+ // port's WaitForEventTimeoutError when the message indicates a
254
+ // timeout. Otherwise rethrow.
255
+ const msg = err instanceof Error ? err.message : String(err);
256
+ if (/timeout|timed out/i.test(msg) && timeout !== undefined) {
257
+ throw new WaitForEventTimeoutError(eventName, timeout);
258
+ }
259
+ throw err;
260
+ }
261
+ },
262
+ };
263
+ return ctx;
264
+ }
265
+ // ---------------------------------------------------------------------------
266
+ // Entrypoint handler — invoked by the generated WorkflowEntrypoint class.
267
+ // ---------------------------------------------------------------------------
268
+ async function entrypointHandler(event, step) {
269
+ const payload = event.payload;
270
+ if (!isEnvelope(payload)) {
271
+ throw new Error('Cloudflare Workflows adapter: workflow event payload missing __wfName/__wfInput envelope. ' +
272
+ 'Workflows triggered through this adapter must be created via adapter.run() or adapter.runSchedule().');
273
+ }
274
+ const fn = registry.get(payload.__wfName);
275
+ if (!fn) {
276
+ throw new Error(`Cloudflare Workflows adapter: no workflow registered for name "${payload.__wfName}". ` +
277
+ 'Call adapter.register(name, fn) before triggering it.');
278
+ }
279
+ const instanceId = event.instanceId ?? `cf-${Date.now()}`;
280
+ const ctx = buildContext(payload.__wfName, instanceId, payload.__wfInput, step);
281
+ return fn(ctx);
282
+ }
283
+ // ---------------------------------------------------------------------------
284
+ // Polling — wait for an instance to terminate.
285
+ // ---------------------------------------------------------------------------
286
+ async function pollUntilDone(instance) {
287
+ const start = Date.now();
288
+ // First check is unconditional so quick-completing workflows return
289
+ // without an extra delay tick.
290
+ let last = await instance.status();
291
+ while (true) {
292
+ if (last.status === 'complete')
293
+ return last.output;
294
+ if (last.status === 'errored' || last.status === 'terminated') {
295
+ const message = last.error?.message ?? `Workflow instance ${instance.id} ended with status ${last.status}`;
296
+ throw new DurableStepError(message, {
297
+ stepName: `<workflow:${instance.id}>`,
298
+ attempts: 1,
299
+ retryable: false,
300
+ cause: last.error ?? new Error(message),
301
+ });
302
+ }
303
+ if (Date.now() - start > pollTimeoutMs) {
304
+ throw new DurableStepError(`Workflow instance ${instance.id} did not complete within ${pollTimeoutMs}ms`, {
305
+ stepName: `<workflow:${instance.id}>`,
306
+ attempts: 1,
307
+ retryable: false,
308
+ cause: new Error('poll timeout'),
309
+ });
310
+ }
311
+ await delay(pollIntervalMs);
312
+ last = await instance.status();
313
+ }
314
+ }
315
+ // ---------------------------------------------------------------------------
316
+ // Public surface
317
+ // ---------------------------------------------------------------------------
318
+ function register(name, fn) {
319
+ registry.set(name, fn);
320
+ }
321
+ async function run(name, fn, input) {
322
+ // Implicitly register if the caller supplied a body. Allows the
323
+ // canonical port shape `dx.run(name, fn, input)` without a separate
324
+ // register() step. If the same name is later run() with no body, the
325
+ // most recent registration wins — matching the in-process adapter.
326
+ if (typeof fn === 'function') {
327
+ registry.set(name, fn);
328
+ }
329
+ const binding = resolveBinding();
330
+ const envelope = { __wfName: name, __wfInput: input };
331
+ const instance = await binding.create({ params: envelope });
332
+ if (!waitForCompletion) {
333
+ // Caller manages the instance; return it cast through unknown.
334
+ return instance;
335
+ }
336
+ return (await pollUntilDone(instance));
337
+ }
338
+ async function step(name, configOrFn, maybeFn) {
339
+ // Outside a workflow body CF Workflows have no step concept — the binding
340
+ // can't run a single step in isolation. We mirror the in-memory stub's
341
+ // behaviour for callers using `dx.step()` outside a `run`: execute the
342
+ // function directly without memoization. Inside a body, the
343
+ // {@link WorkflowContext.step} delegate is used (which translates to
344
+ // `step.do`).
345
+ void name;
346
+ const fn = typeof configOrFn === 'function' ? configOrFn : maybeFn;
347
+ return fn();
348
+ }
349
+ async function sleep(duration) {
350
+ // Outside a body, sleep is just a delay — there's no CF step context to
351
+ // suspend. This matches the in-memory stub.
352
+ const ms = typeof duration === 'number' ? duration : parseDurationLoose(duration);
353
+ if (ms > 0)
354
+ await delay(ms);
355
+ }
356
+ async function sleepUntil(date) {
357
+ const ms = date.getTime() - Date.now();
358
+ if (ms > 0)
359
+ await delay(ms);
360
+ }
361
+ function waitForEvent(name, timeout) {
362
+ // Outside a body there is no CF step.waitForEvent surface. Reject so
363
+ // callers don't accidentally rely on hibernation-style waits without a
364
+ // running workflow.
365
+ return Promise.reject(new Error(`Cloudflare Workflows adapter: waitForEvent("${name}"${timeout !== undefined ? `, ${String(timeout)}` : ''}) ` +
366
+ 'is only supported inside a workflow body (ctx.waitForEvent). ' +
367
+ 'Trigger the workflow via adapter.run() and call waitForEvent on its ctx.'));
368
+ }
369
+ function schedule(name, cron, fn) {
370
+ schedules.set(name, { cron, fn: fn });
371
+ registry.set(name, fn);
372
+ return {
373
+ id: name,
374
+ unsubscribe() {
375
+ schedules.delete(name);
376
+ // Leave the body in registry so already-fired runs still resolve.
377
+ },
378
+ };
379
+ }
380
+ function defineSchedule(name, cron, fn) {
381
+ return schedule(name, cron, fn);
382
+ }
383
+ async function runSchedule(name) {
384
+ const entry = schedules.get(name);
385
+ if (!entry) {
386
+ throw new Error(`Cloudflare Workflows adapter: no schedule registered for "${name}". ` +
387
+ 'Call adapter.defineSchedule(name, cron, fn) before invoking runSchedule.');
388
+ }
389
+ return run(name, entry.fn, undefined);
390
+ }
391
+ const adapter = {
392
+ kind: 'cloudflare',
393
+ limits: CLOUDFLARE_WORKFLOWS_LIMITS,
394
+ register,
395
+ run: run,
396
+ step: step,
397
+ sleep,
398
+ sleepUntil,
399
+ waitForEvent,
400
+ schedule,
401
+ defineSchedule,
402
+ runSchedule,
403
+ entrypointHandler,
404
+ };
405
+ return adapter;
406
+ }
407
+ /**
408
+ * Generate a {@link WorkflowEntrypointLike} subclass bound to `adapter`.
409
+ *
410
+ * Users export the returned class from their worker module and reference it
411
+ * in `wrangler.jsonc` under `workflows[].class_name`. CF instantiates the
412
+ * class for each workflow run, calls its `run(event, step)`, and the adapter
413
+ * dispatches into the registered body.
414
+ *
415
+ * **Why a factory instead of a fixed export?** CF binds workflows by class
416
+ * name at deploy time — each binding needs its own class identity. The
417
+ * factory pattern lets users have multiple adapters/classes in one module
418
+ * (e.g. one per binding) without colliding.
419
+ *
420
+ * If `Base` is omitted, this module declares an internal abstract class with
421
+ * the signature CF expects. In production, callers SHOULD pass the real
422
+ * `WorkflowEntrypoint` from `cloudflare:workers` so CF's runtime magic (env
423
+ * injection, `[Rpc.__WORKFLOW_ENTRYPOINT_BRAND]`, etc.) is preserved:
424
+ *
425
+ * ```ts
426
+ * import { WorkflowEntrypoint } from 'cloudflare:workers'
427
+ * import { createCloudflareWorkflowsDurableExecution, createWorkflowEntrypoint } from 'ai-workflows/durable-execution'
428
+ *
429
+ * const dx = createCloudflareWorkflowsDurableExecution({ binding: () => env.WORKFLOW })
430
+ * export const MyWorkflow = createWorkflowEntrypoint(dx, WorkflowEntrypoint)
431
+ * ```
432
+ *
433
+ * In tests / Node environments where `cloudflare:workers` isn't available,
434
+ * call without `Base` and the adapter's dispatch logic is exercised against
435
+ * the structural fake.
436
+ */
437
+ export function createWorkflowEntrypoint(adapter, Base) {
438
+ if (Base) {
439
+ return class extends Base {
440
+ async run(event, step) {
441
+ return adapter.entrypointHandler(event, step);
442
+ }
443
+ };
444
+ }
445
+ // Pure-JS shim used when callers don't (or can't) supply the real CF base
446
+ // class. Sufficient for unit tests of the dispatch path; production callers
447
+ // should always pass `WorkflowEntrypoint` from `cloudflare:workers`.
448
+ return class WorkflowEntrypointShim {
449
+ constructor(_ctx, _env) {
450
+ // Match CF's two-arg constructor shape; we don't need the values.
451
+ void _ctx;
452
+ void _env;
453
+ }
454
+ async run(event, step) {
455
+ return adapter.entrypointHandler(event, step);
456
+ }
457
+ };
458
+ }
459
+ // =============================================================================
460
+ // Internal: minimal duration parser (top-level sleep outside a body)
461
+ // =============================================================================
462
+ /**
463
+ * Tolerant duration parser used only by the top-level `sleep()` outside a
464
+ * body. Inside a body, durations are passed verbatim to CF's `step.sleep`,
465
+ * which has its own grammar. We do not constrain string forms here as
466
+ * tightly as the in-memory stub since CF accepts a richer grammar
467
+ * (`'10 seconds'`, `'1 day'`, etc.).
468
+ */
469
+ function parseDurationLoose(input) {
470
+ const trimmed = input.trim().toLowerCase();
471
+ 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|w|week|weeks)$/);
472
+ if (!match) {
473
+ throw new Error(`Cloudflare Workflows adapter: unrecognised duration "${input}"`);
474
+ }
475
+ const value = parseFloat(match[1]);
476
+ const unit = match[2];
477
+ switch (unit) {
478
+ case 'ms':
479
+ case 'millisecond':
480
+ case 'milliseconds':
481
+ return value;
482
+ case 's':
483
+ case 'sec':
484
+ case 'second':
485
+ case 'seconds':
486
+ return value * 1000;
487
+ case 'm':
488
+ case 'min':
489
+ case 'minute':
490
+ case 'minutes':
491
+ return value * 60_000;
492
+ case 'h':
493
+ case 'hr':
494
+ case 'hour':
495
+ case 'hours':
496
+ return value * 3_600_000;
497
+ case 'd':
498
+ case 'day':
499
+ case 'days':
500
+ return value * 86_400_000;
501
+ case 'w':
502
+ case 'week':
503
+ case 'weeks':
504
+ return value * 604_800_000;
505
+ /* istanbul ignore next */
506
+ default:
507
+ throw new Error(`Cloudflare Workflows adapter: unrecognised duration unit "${unit}"`);
508
+ }
509
+ }
510
+ //# sourceMappingURL=durable-execution-cloudflare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-execution-cloudflare.js","sourceRoot":"","sources":["../src/durable-execution-cloudflare.ts"],"names":[],"mappings":"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"}