workflow 5.0.0-beta.3 → 5.0.0-beta.30

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 (176) hide show
  1. package/dist/api-workflow.d.ts +1 -1
  2. package/dist/api-workflow.d.ts.map +1 -1
  3. package/dist/api-workflow.js +1 -1
  4. package/dist/api.d.ts +5 -1
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/api.js +12 -2
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +6 -1
  10. package/dist/internal/builtins.d.ts +17 -0
  11. package/dist/internal/builtins.d.ts.map +1 -1
  12. package/dist/internal/builtins.js +65 -1
  13. package/dist/observability.d.ts +1 -1
  14. package/dist/observability.js +2 -2
  15. package/dist/runtime.d.ts +2 -1
  16. package/dist/runtime.d.ts.map +1 -1
  17. package/dist/runtime.js +5 -2
  18. package/docs/ai/chat-session-modeling.mdx +7 -3
  19. package/docs/ai/defining-tools.mdx +2 -2
  20. package/docs/ai/index.mdx +28 -23
  21. package/docs/ai/message-queueing.mdx +10 -10
  22. package/docs/ai/resumable-streams.mdx +9 -1
  23. package/docs/api-reference/index.mdx +24 -0
  24. package/docs/api-reference/meta.json +8 -0
  25. package/docs/api-reference/vitest/index.mdx +28 -7
  26. package/docs/api-reference/workflow/create-hook.mdx +38 -0
  27. package/docs/api-reference/workflow/create-webhook.mdx +1 -0
  28. package/docs/api-reference/workflow/experimental-set-attributes.mdx +65 -0
  29. package/docs/api-reference/workflow/fetch.mdx +5 -0
  30. package/docs/api-reference/workflow/index.mdx +3 -0
  31. package/docs/api-reference/workflow-ai/durable-agent.mdx +7 -45
  32. package/docs/api-reference/workflow-ai/index.mdx +2 -2
  33. package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +44 -1
  34. package/docs/api-reference/workflow-api/get-hook-by-token.mdx +7 -0
  35. package/docs/api-reference/workflow-api/get-run.mdx +25 -0
  36. package/docs/api-reference/workflow-api/index.mdx +6 -8
  37. package/docs/api-reference/workflow-api/resume-hook.mdx +57 -0
  38. package/docs/api-reference/workflow-api/start.mdx +13 -5
  39. package/docs/api-reference/workflow-astro/index.mdx +18 -0
  40. package/docs/api-reference/workflow-astro/meta.json +4 -0
  41. package/docs/api-reference/workflow-astro/workflow.mdx +45 -0
  42. package/docs/api-reference/workflow-errors/hook-conflict-error.mdx +60 -0
  43. package/docs/api-reference/workflow-errors/index.mdx +85 -0
  44. package/docs/api-reference/workflow-errors/meta.json +5 -0
  45. package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
  46. package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
  47. package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +16 -6
  48. package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
  49. package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
  50. package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +33 -0
  51. package/docs/api-reference/workflow-nest/index.mdx +31 -0
  52. package/docs/api-reference/workflow-nest/meta.json +9 -0
  53. package/docs/api-reference/workflow-nest/nest-local-builder.mdx +64 -0
  54. package/docs/api-reference/workflow-nest/workflow-controller.mdx +40 -0
  55. package/docs/api-reference/workflow-nest/workflow-module.mdx +74 -0
  56. package/docs/api-reference/workflow-next/with-workflow.mdx +56 -2
  57. package/docs/api-reference/workflow-nitro/index.mdx +60 -0
  58. package/docs/api-reference/workflow-nuxt/index.mdx +48 -0
  59. package/docs/api-reference/workflow-observability/hydrate-data.mdx +35 -0
  60. package/docs/api-reference/workflow-observability/hydrate-resource-io.mdx +62 -0
  61. package/docs/api-reference/workflow-observability/index.mdx +64 -0
  62. package/docs/api-reference/workflow-observability/meta.json +11 -0
  63. package/docs/api-reference/workflow-observability/observability-revivers.mdx +50 -0
  64. package/docs/api-reference/workflow-observability/parse-class-name.mdx +41 -0
  65. package/docs/api-reference/workflow-observability/parse-step-name.mdx +40 -0
  66. package/docs/api-reference/workflow-observability/parse-workflow-name.mdx +55 -0
  67. package/docs/api-reference/workflow-runtime/create-world.mdx +39 -0
  68. package/docs/api-reference/workflow-runtime/get-world-handlers.mdx +44 -0
  69. package/docs/api-reference/{workflow-api → workflow-runtime}/get-world.mdx +7 -10
  70. package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
  71. package/docs/api-reference/workflow-runtime/index.mdx +43 -0
  72. package/docs/api-reference/workflow-runtime/meta.json +12 -0
  73. package/docs/api-reference/workflow-runtime/set-world.mdx +49 -0
  74. package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +42 -0
  75. package/docs/api-reference/{workflow-api → workflow-runtime}/world/index.mdx +5 -8
  76. package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
  77. package/docs/api-reference/{workflow-api → workflow-runtime}/world/queue.mdx +4 -2
  78. package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +11 -4
  79. package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +2 -2
  80. package/docs/api-reference/workflow-serde/index.mdx +0 -1
  81. package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +1 -2
  82. package/docs/api-reference/workflow-serde/workflow-serialize.mdx +1 -2
  83. package/docs/api-reference/workflow-sveltekit/index.mdx +18 -0
  84. package/docs/api-reference/workflow-sveltekit/meta.json +4 -0
  85. package/docs/api-reference/workflow-sveltekit/workflow-plugin.mdx +42 -0
  86. package/docs/api-reference/workflow-vite/index.mdx +18 -0
  87. package/docs/api-reference/workflow-vite/meta.json +4 -0
  88. package/docs/api-reference/workflow-vite/workflow.mdx +48 -0
  89. package/docs/changelog/attributes-mvp.mdx +380 -0
  90. package/docs/changelog/eager-processing.mdx +269 -0
  91. package/docs/changelog/index.mdx +2 -1
  92. package/docs/changelog/lazy-event-creation.md +127 -0
  93. package/docs/changelog/meta.json +8 -1
  94. package/docs/changelog/resilient-start.mdx +31 -283
  95. package/docs/changelog/step-message-ownership.mdx +360 -0
  96. package/docs/changelog/turbo-mode.md +87 -0
  97. package/docs/configuration/build-and-diagnostics.mdx +51 -0
  98. package/docs/configuration/cli-and-web-ui.mdx +154 -0
  99. package/docs/configuration/framework-options.mdx +165 -0
  100. package/docs/configuration/index.mdx +32 -0
  101. package/docs/configuration/meta.json +12 -0
  102. package/docs/configuration/runtime-tuning.mdx +156 -0
  103. package/docs/configuration/worlds.mdx +228 -0
  104. package/docs/cookbook/advanced/child-workflows.mdx +199 -256
  105. package/docs/cookbook/advanced/meta.json +1 -1
  106. package/docs/cookbook/advanced/publishing-libraries.mdx +13 -12
  107. package/docs/cookbook/advanced/serializable-steps.mdx +8 -4
  108. package/docs/cookbook/advanced/upgrading-workflows.mdx +195 -0
  109. package/docs/cookbook/agent-patterns/agent-cancellation.mdx +31 -76
  110. package/docs/cookbook/agent-patterns/durable-agent.mdx +11 -143
  111. package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +7 -3
  112. package/docs/cookbook/common-patterns/idempotency.mdx +36 -52
  113. package/docs/cookbook/common-patterns/rate-limiting.mdx +1 -1
  114. package/docs/cookbook/common-patterns/saga.mdx +2 -2
  115. package/docs/cookbook/common-patterns/scheduling.mdx +8 -0
  116. package/docs/cookbook/common-patterns/timeouts.mdx +2 -1
  117. package/docs/cookbook/common-patterns/workflow-composition.mdx +15 -16
  118. package/docs/cookbook/index.mdx +3 -3
  119. package/docs/cookbook/integrations/ai-sdk.mdx +60 -28
  120. package/docs/cookbook/integrations/chat-sdk.mdx +13 -0
  121. package/docs/cookbook/integrations/sandbox.mdx +13 -0
  122. package/docs/deploying/building-a-world.mdx +1 -1
  123. package/docs/deploying/index.mdx +1 -0
  124. package/docs/deploying/world/local-world.mdx +23 -6
  125. package/docs/deploying/world/postgres-world.mdx +79 -13
  126. package/docs/deploying/world/vercel-world.mdx +47 -12
  127. package/docs/errors/abort-signal-timeout-in-workflow.mdx +80 -0
  128. package/docs/errors/corrupted-event-log.mdx +5 -5
  129. package/docs/errors/hook-conflict.mdx +56 -4
  130. package/docs/errors/index.mdx +1 -35
  131. package/docs/errors/replay-divergence.mdx +27 -0
  132. package/docs/errors/runtime-decryption-failed.mdx +77 -0
  133. package/docs/errors/step-executed-multiple-times.mdx +23 -0
  134. package/docs/errors/step-not-registered.mdx +1 -1
  135. package/docs/foundations/cancellation.mdx +459 -0
  136. package/docs/foundations/errors-and-retries.mdx +7 -3
  137. package/docs/foundations/hooks.mdx +29 -0
  138. package/docs/foundations/idempotency.mdx +236 -11
  139. package/docs/foundations/index.mdx +1 -23
  140. package/docs/foundations/meta.json +3 -1
  141. package/docs/foundations/serialization.mdx +77 -41
  142. package/docs/foundations/starting-workflows.mdx +5 -1
  143. package/docs/foundations/streaming.mdx +14 -23
  144. package/docs/foundations/versioning.mdx +263 -0
  145. package/docs/getting-started/astro.mdx +6 -0
  146. package/docs/getting-started/index.mdx +6 -7
  147. package/docs/getting-started/meta.json +1 -0
  148. package/docs/getting-started/nestjs.mdx +9 -0
  149. package/docs/getting-started/next.mdx +5 -3
  150. package/docs/getting-started/nitro.mdx +22 -0
  151. package/docs/getting-started/sveltekit.mdx +6 -0
  152. package/docs/getting-started/tanstack-start.mdx +241 -0
  153. package/docs/how-it-works/cancellation.mdx +287 -0
  154. package/docs/how-it-works/code-transform.mdx +2 -2
  155. package/docs/how-it-works/encryption.mdx +2 -2
  156. package/docs/how-it-works/event-sourcing.mdx +2 -2
  157. package/docs/how-it-works/meta.json +2 -1
  158. package/docs/internal/index.mdx +21 -0
  159. package/docs/internal/meta.json +10 -0
  160. package/docs/internal/nitro-native-build.mdx +38 -0
  161. package/docs/internal/nitro-web-ui.mdx +24 -0
  162. package/docs/internal/serializable-abort-controller.mdx +148 -0
  163. package/docs/meta.json +1 -1
  164. package/docs/migration-guides/migrating-from-aws-step-functions.mdx +7 -12
  165. package/docs/migration-guides/migrating-from-inngest.mdx +7 -17
  166. package/docs/migration-guides/migrating-from-temporal.mdx +6 -11
  167. package/docs/migration-guides/migrating-from-trigger-dev.mdx +8 -17
  168. package/docs/observability/attributes.mdx +87 -0
  169. package/docs/observability/index.mdx +18 -1
  170. package/docs/observability/meta.json +1 -1
  171. package/docs/observability/tracing.mdx +119 -0
  172. package/docs/testing/index.mdx +2 -2
  173. package/package.json +14 -13
  174. package/docs/api-reference/workflow-api/world/meta.json +0 -4
  175. package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
  176. package/docs/cookbook/advanced/distributed-abort-controller.mdx +0 -318
@@ -54,11 +54,11 @@ The migration replaces declarative configuration with idiomatic TypeScript and c
54
54
  | Choice state | `if` / `else` / `switch` | Native TypeScript control flow. |
55
55
  | Wait state | `sleep()` | Import `sleep` from `workflow`. |
56
56
  | Parallel state | `Promise.all()` | Standard concurrency primitives. |
57
- | Map state | Inline sequential → `for` loop; bounded parallel (`MaxConcurrency: N`) → batched `Promise.all` or a concurrency limiter like `p-limit`; Distributed Map / large fan-out → step-wrapped `start()` per item, then step-wrapped `getRun()` to collect. | Match the concurrency mode of the original Map. |
57
+ | Map state | Inline sequential → `for` loop; bounded parallel (`MaxConcurrency: N`) → batched `Promise.all` or a concurrency limiter like `p-limit`; Distributed Map / large fan-out → `start()` per item, then step-wrapped `getRun()` to collect. | Match the concurrency mode of the original Map. |
58
58
  | Retry / Catch | Step retries, `RetryableError`, `FatalError` | Retry logic moves to step boundaries. |
59
59
  | `Catch` to a compensation state | `try`/`catch` in the workflow function, calling compensation steps in reverse order (push/pop a rollback stack) | See [`/docs/foundations/errors-and-retries`](/docs/foundations/errors-and-retries) for the SAGA pattern. |
60
60
  | `.waitForTaskToken` | `createHook()` or `createWebhook()` | Hooks for typed signals; webhooks for HTTP. |
61
- | Child state machine (`StartExecution`) | `"use step"` around `start()` / `getRun()` | Return the `Run` object, await its result from another step. |
61
+ | Child state machine (`StartExecution`) | `start()` plus a `"use step"` wrapper around `getRun()` | Return the `Run` object, await its result from another step. |
62
62
  | Execution event history | Workflow event log | Same durable replay model. |
63
63
  | Progress via DynamoDB / SNS for client polling | `getWritable()` + named streams | Stream durable updates; clients read from the stream. |
64
64
 
@@ -213,21 +213,16 @@ return { refundId, status: 'rejected' };
213
213
 
214
214
  ## Spawn a child workflow
215
215
 
216
- In ASL, a parent machine calls `StartExecution` (usually via `.sync` or `.waitForTaskToken`) to launch a child. In the Workflow SDK, `start()` and `getRun()` are runtime APIs, so wrap them in `"use step"` functions. Returning the `Run` object from the spawn step lets workflow observability deep-link to the child run.
216
+ In ASL, a parent machine calls `StartExecution` (usually via `.sync` or `.waitForTaskToken`) to launch a child. In v5, call `start()` directly from the workflow to launch a child. Wrap `getRun()` and `returnValue` access in a `"use step"` function when you need to await the child result.
217
217
 
218
218
  ### Parent starts a child
219
219
 
220
220
  ```typescript title="workflow/workflows/parent.ts"
221
221
  import { start } from 'workflow/api';
222
222
 
223
- async function spawnChild(item: string) {
224
- 'use step'; // [!code highlight]
225
- return await start(childWorkflow, [item]);
226
- }
227
-
228
223
  export async function parentWorkflow(item: string) {
229
224
  'use workflow';
230
- const run = await spawnChild(item);
225
+ const run = await start(childWorkflow, [item]); // [!code highlight]
231
226
  return { childRunId: run.runId };
232
227
  }
233
228
  ```
@@ -338,7 +333,7 @@ Delete the ASL JSON, per-task Lambda deployments, IAM roles, and callback queues
338
333
  ## Features without a 1:1 equivalent
339
334
 
340
335
  - **Express workflows.** At-least-once semantics and 5-minute duration make them a poor fit for the SDK's durable replay model. Consider keeping them on Step Functions or migrating to a queue consumer.
341
- - **Distributed Map state.** Up to 10,000 concurrent child executions with S3 item sources has no 1:1 analog; fan out with step-wrapped `start()` per item, then `Promise.all` with `p-limit` to bound concurrency.
336
+ - **Distributed Map state.** Up to 10,000 concurrent child executions with S3 item sources has no 1:1 analog; fan out with `start()` per item, then `Promise.all` with `p-limit` to bound concurrency.
342
337
  - **Optimized AWS service integrations (`arn:aws:states:::dynamodb:*`, `eventbridge:*`, `bedrock:*`, `ecs:runTask.sync`, etc.).** These become regular SDK calls inside `'use step'` functions — credentials, retries, and polling move into the step.
343
338
  - **Per-state IAM roles.** ASL lets each state run under its own IAM role. In the SDK, all steps share the deployment's credentials; scope secrets and roles at deployment time.
344
339
  - **CloudWatch alarms / X-Ray cross-service traces / CloudWatch Logs retention.** The SDK event log + observability UI replaces orchestrator state transitions, not AWS-wide observability. Keep alarms and traces for other resources.
@@ -351,8 +346,8 @@ Delete the ASL JSON, per-task Lambda deployments, IAM roles, and callback queues
351
346
  - Replace Choice states with `if`/`else`/`switch`.
352
347
  - Replace Wait states with `sleep()` from `workflow`.
353
348
  - Replace Parallel states with `Promise.all()`.
354
- - Replace Map states based on their concurrency mode: inline sequential → `for` loop; bounded parallel (`MaxConcurrency: N`) → batched `Promise.all` or a concurrency limiter like `p-limit`; Distributed Map / large fan-out → step-wrapped `start()` per item, then step-wrapped `getRun()` to collect.
355
- - Replace `StartExecution` child machines with `"use step"` wrappers around `start()` and `getRun()`.
349
+ - Replace Map states based on their concurrency mode: inline sequential → `for` loop; bounded parallel (`MaxConcurrency: N`) → batched `Promise.all` or a concurrency limiter like `p-limit`; Distributed Map / large fan-out → `start()` per item, then step-wrapped `getRun()` to collect.
350
+ - Replace `StartExecution` child machines with direct `start()` calls and a `"use step"` wrapper around `getRun()` when collecting results.
356
351
  - Replace `.waitForTaskToken` with `createHook()` (internal callers) or `createWebhook()` (HTTP callers).
357
352
  - Move Retry/Catch to step boundaries using `maxRetries`, `RetryableError`, and `FatalError`.
358
353
  - Use `getStepMetadata().stepId` as the idempotency key for external side effects.
@@ -51,10 +51,10 @@ Inngest's event-bus model is loosely coupled — publishers don't know consumers
51
51
  | `step.run()` | `"use step"` function | Standalone async function with Node.js access. |
52
52
  | `step.sleep()` / `step.sleepUntil()` | `sleep()` | `sleep('5m')` for a duration; `sleep(date)` for sleep-until. |
53
53
  | `step.waitForEvent()` | `createHook()` or `createWebhook()` | Hooks for typed signals, webhooks for HTTP. |
54
- | `step.invoke()` | `"use step"` wrappers around `start()` / `getRun()` | Spawn a child run, pass `runId` forward. |
54
+ | `step.invoke()` | `start()` plus a `"use step"` wrapper around `getRun()` | Spawn a child run, pass `runId` forward, and collect from a step when needed. |
55
55
  | `inngest.send()` / event triggers | `start()` from your app boundary | Start workflows directly. |
56
56
  | Retry configuration (`retries`) | `RetryableError`, `FatalError`, `maxRetries` | Retry logic lives at the step level. |
57
- | `step.sendEvent()` | `"use step"` wrapper around `start()` | Fan out via `start()`, not an event bus. |
57
+ | `step.sendEvent()` | `start()` from the workflow or app boundary | Fan out explicitly, not through an event bus. |
58
58
  | Realtime / `step.realtime.publish()` | `getWritable()` / `getWritable({ namespace })` | Named streams are the canonical way for clients to read workflow status. No database or `getRun()` polling required. |
59
59
 
60
60
  ## Translate your first workflow
@@ -169,20 +169,10 @@ Event matching disappears. A hook's token encodes the routing (for example, `ref
169
169
 
170
170
  ## Spawn a child workflow
171
171
 
172
- `step.invoke()` splits into two steps: spawn and collect. `start()` and `getRun()` are runtime APIs, so wrap them in `"use step"` functions. Return the `Run` object from the spawn step so observability can deep-link into the child run.
172
+ `step.invoke()` splits into spawn and collect. In v5, call `start()` directly from the workflow to spawn the child. Wrap `getRun()` and `returnValue` access in a `"use step"` function when you need to collect the result. Returning the `Run` object from `start()` lets observability deep-link into the child run.
173
173
 
174
174
  You can return either the full `Run` object (enables deep-linking) or just `run.runId` (simpler).
175
175
 
176
- {/* @skip-typecheck: snippet without imports */}
177
- ```typescript title="workflow/workflows/parent.ts"
178
- async function spawnChild(item: string) {
179
- 'use step';
180
- return start(childWorkflow, [item]); // [!code highlight]
181
- }
182
- ```
183
-
184
- Await the result in a second step, then orchestrate both from the parent:
185
-
186
176
  {/* @skip-typecheck: snippet without imports */}
187
177
  ```typescript title="workflow/workflows/parent.ts"
188
178
  async function collectResult(runId: string) {
@@ -193,7 +183,7 @@ async function collectResult(runId: string) {
193
183
 
194
184
  export async function parentWorkflow(item: string) {
195
185
  'use workflow';
196
- const child = await spawnChild(item);
186
+ const child = await start(childWorkflow, [item]); // [!code highlight]
197
187
  return await collectResult(child.runId);
198
188
  }
199
189
  ```
@@ -266,7 +256,7 @@ See [Errors and retries](/docs/foundations/errors-and-retries) for full retry do
266
256
 
267
257
  - `step.waitForEvent(...)` → `createHook({ token })` + `await hook`. Resume it from an API route with `resumeHook(token, payload)`.
268
258
  - `step.sleep(...)` → `sleep("5m")` from `workflow`.
269
- - `step.invoke(child, { data })` → wrap `start(child, [data])` in a `"use step"` function that returns the `Run`, and optionally read its return value with `getRun(run.runId).returnValue`.
259
+ - `step.invoke(child, { data })` → call `start(child, [data])` from the workflow, and optionally read its return value from a step with `getRun(run.runId).returnValue`.
270
260
 
271
261
  ### Step 5: Start runs from the app
272
262
 
@@ -301,8 +291,8 @@ Remove the `inngest` client, the `serve()` route, event schemas, and the Inngest
301
291
  - Swap `step.sleep()` / `step.sleepUntil()` for `sleep()` from `workflow`.
302
292
  - Swap `step.waitForEvent()` for `createHook()` (internal) or `createWebhook()` (HTTP).
303
293
  - Model `waitForEvent` timeouts as `Promise.race()` between the hook and `sleep()`.
304
- - Replace `step.invoke()` with `"use step"` wrappers around `start()` and `getRun()`.
305
- - Replace `step.sendEvent()` fan-out with `start()` called from a `"use step"` function.
294
+ - Replace `step.invoke()` with direct `start()` calls and a `"use step"` wrapper around `getRun()` when collecting results.
295
+ - Replace `step.sendEvent()` fan-out with explicit `start()` calls.
306
296
  - Remove the Inngest client, `serve()` handler, and event definitions.
307
297
  - Push retry configuration down to step boundaries via `maxRetries`, `RetryableError`, and `FatalError`.
308
298
  - Use `getStepMetadata().stepId` as the idempotency key for external side effects.
@@ -50,7 +50,7 @@ Migration removes infrastructure and collapses indirection. Business logic stays
50
50
  | Signal | `createHook()` or `createWebhook()` | Use hooks for typed resume signals; webhooks for HTTP callbacks. |
51
51
  | Query | `getWritable({ namespace: 'status' })` stream | Durably stream status updates from the workflow. Clients read from the stream instead of polling a database. |
52
52
  | Update | `createHook()` + `resumeHook()` (one-way) | Temporal Updates return a value to the caller; hooks do not. If the Update returns data, either write the result to a named stream via `getWritable()` and have the caller read from it, or keep an HTTP read route that fetches the workflow's current state. |
53
- | Child Workflow | `"use step"` wrappers around `start()` / `getRun()` | Spawn from a step and return the `Run` object so observability can deep-link into child runs. |
53
+ | Child Workflow | `start()` plus a `"use step"` wrapper around `getRun()` | Spawn a child run and return the `Run` object so observability can deep-link into child runs. |
54
54
  | Activity retry policy | Step retries, `RetryableError`, `FatalError`, `maxRetries` | Retries live at the step boundary. |
55
55
  | Event History | Workflow event log / run timeline | Same durable replay; built-in observability UI replaces Temporal Web. Search attributes and visibility APIs have no direct equivalent — filter by run status and timestamps instead. |
56
56
 
@@ -173,19 +173,14 @@ Temporal Queries expose in-memory workflow state on demand. In the Workflow SDK,
173
173
 
174
174
  ### Minimal translation
175
175
 
176
- `start()` and `getRun()` are runtime APIs, so wrap them in `"use step"` functions. Return the `Run` object (not a plain `runId` string) so workflow observability can deep-link into child runs.
176
+ In v5, call `start()` directly from the workflow to spawn a child run. Wrap `getRun()` and `returnValue` access in a `"use step"` function when you need to await the child result. Return the `Run` object (not a plain `runId` string) so workflow observability can deep-link into child runs.
177
177
 
178
178
  ```typescript title="workflow/workflows/parent.ts"
179
179
  import { start } from 'workflow/api';
180
180
 
181
- async function spawnChild(item: string) {
182
- 'use step'; // [!code highlight]
183
- return start(childWorkflow, [item]); // [!code highlight]
184
- }
185
-
186
181
  export async function parentWorkflow(item: string) {
187
182
  'use workflow';
188
- const child = await spawnChild(item); // [!code highlight]
183
+ const child = await start(childWorkflow, [item]); // [!code highlight]
189
184
  return { childRunId: child.runId };
190
185
  }
191
186
  ```
@@ -204,7 +199,7 @@ async function collectResult(runId: string) {
204
199
  }
205
200
  ```
206
201
 
207
- Call both steps from the parent in sequence: `const result = await collectResult(child.runId)`. To fan out, call `spawnChild` inside a loop, then `Promise.all` the `collectResult` calls.
202
+ Call `start()` and then `collectResult()` from the parent in sequence: `const result = await collectResult(child.runId)`. To fan out, call `start()` inside a loop, then `Promise.all` the `collectResult` calls.
208
203
 
209
204
  <Callout type="warn">
210
205
  Activity retry policy moves to the step boundary. Use `maxRetries`, `RetryableError`, and `FatalError` on each step instead of a single workflow-wide retry block.
@@ -300,7 +295,7 @@ Remove the Worker process, `@temporalio/*` dependencies, and the Temporal Server
300
295
  - **Event history archival.** Temporal archives histories to S3/GCS for long-term retention. Workflow SDK event logs are durable, but retention depends on the integration you are using. For example, see [Vercel Workflow Storage Retention](https://vercel.com/docs/workflows/pricing#storage-retention) for Vercel.
301
296
  - **Per-activity timeouts (`startToCloseTimeout`, `scheduleToCloseTimeout`, `heartbeatTimeout`).** Implement deadlines inside the step with `AbortSignal.timeout(ms)`, or wrap the call in `Promise.race(step(), sleep(...))` from the workflow.
302
297
  - **Rich retry policy (`initialInterval`, `backoffCoefficient`, `maximumInterval`, `nonRetryableErrorTypes`).** Only `maxRetries` is configurable. Classify retryability with `RetryableError`/`FatalError`; control delay between attempts via `new RetryableError(msg, { retryAfter: '5s' })`.
303
- - **Workers + task queues.** Managed deployments replace workers; self-hosted deployments still need a `World` implementation (see [/docs/deploying/world](/docs/deploying/world)).
298
+ - **Workers + task queues.** Managed deployments replace workers; self-hosted deployments still need a `World` implementation (see [/docs/deploying/building-a-world](/docs/deploying/building-a-world)).
304
299
 
305
300
  ## Quick-start checklist
306
301
 
@@ -308,7 +303,7 @@ Remove the Worker process, `@temporalio/*` dependencies, and the Temporal Server
308
303
  - Convert each Activity into a `"use step"` function.
309
304
  - Remove Worker and Task Queue code. Start workflows from the app with `start()`.
310
305
  - Replace Signals with `createHook()` or `createWebhook()` for HTTP callers.
311
- - Wrap `start()` and `getRun()` in `"use step"` functions for child workflows. Return the `Run` object from `start()` so observability can deep-link into child runs.
306
+ - Use `start()` directly for child workflows, and wrap `getRun()` in a `"use step"` function when collecting results. Return the `Run` object from `start()` so observability can deep-link into child runs.
312
307
  - Set retry policy per step with `maxRetries`, `RetryableError`, and `FatalError`.
313
308
  - Use `getStepMetadata().stepId` as the idempotency key for external side effects.
314
309
  - Stream status and progress from steps with `getWritable({ namespace: 'status' })`, and have clients read from the stream instead of polling.
@@ -48,7 +48,7 @@ Migration collapses the task abstraction into plain async functions. Business lo
48
48
  | `logger` / `metadata.set` | `console` + `getWritable({ namespace: 'status' })` | Logs flow through the run timeline. Status writes go on a named stream. |
49
49
  | `wait.for({ seconds \| minutes \| hours \| days })` / `wait.until({ date })` | `sleep()` | Import from `workflow`. |
50
50
  | `wait.forToken({ timeout })` | `createHook()` + `Promise.race` with `sleep()` | Hooks carry a typed token. |
51
- | `tasks.trigger()` / `triggerAndWait()` | `start()` and `getRun(runId).returnValue` | Wrap both in `"use step"` functions. |
51
+ | `tasks.trigger()` / `triggerAndWait()` | `start()` and `getRun(runId).returnValue` | Call `start()` directly; wrap `getRun()` collection in a `"use step"` function. |
52
52
  | `batch.triggerAndWait()` | `Promise.all(runIds.map(collectResult))` | Fan out via standard concurrency. |
53
53
  | `AbortTaskRunError` | `FatalError` | Stops retries immediately. |
54
54
  | `retry.onThrow` / `retry.fetch` | `RetryableError`, `FatalError`, `maxRetries` | Retry count lives on the step via `myStep.maxRetries = N` (default 3). Control delay between attempts by throwing `new RetryableError(msg, { retryAfter: '5s' })` — there is no built-in exponential helper; compute the delay yourself based on `getStepMetadata().attempt` if you need one. |
@@ -180,23 +180,14 @@ A hook is an inbound write channel. The caller that knows the token resumes the
180
180
 
181
181
  ## Spawn a child workflow
182
182
 
183
- `triggerAndWait()` splits into two steps: spawn and collect. `start()` and `getRun()` are runtime APIs, so wrap them in `"use step"` functions. Return the full `Run` object from `spawnChild` so observability tooling can deep-link to the child run.
183
+ `triggerAndWait()` splits into spawn and collect. In v5, call `start()` directly from the workflow to spawn the child. Wrap `getRun()` and `returnValue` access in a `"use step"` function when you need to collect the result.
184
184
 
185
185
  You can return either the full `Run` object (enables deep-linking) or just `run.runId` (simpler). The runtime serializes `Run` to its `runId` in the event log either way.
186
186
 
187
- ```typescript title="workflow/workflows/parent.ts"
188
- import { start } from 'workflow/api';
189
-
190
- async function spawnChild(item: string) {
191
- 'use step';
192
- return start(childWorkflow, [item]); // [!code highlight]
193
- }
194
- ```
195
-
196
- Await the result in a second step, then orchestrate both from the parent:
187
+ Await the result in a step, then orchestrate both from the parent:
197
188
 
198
189
  ```typescript title="workflow/workflows/parent.ts"
199
- import { getRun } from 'workflow/api';
190
+ import { getRun, start } from 'workflow/api';
200
191
 
201
192
  async function collectResult(runId: string) {
202
193
  'use step';
@@ -206,12 +197,12 @@ async function collectResult(runId: string) {
206
197
 
207
198
  export async function parentWorkflow(item: string) {
208
199
  'use workflow';
209
- const child = await spawnChild(item);
200
+ const child = await start(childWorkflow, [item]); // [!code highlight]
210
201
  return await collectResult(child.runId);
211
202
  }
212
203
  ```
213
204
 
214
- To fan out, call `spawnChild` inside a loop, then `Promise.all` the `collectResult` calls. That replaces `batch.triggerAndWait()`.
205
+ To fan out, call `start()` inside a loop, then `Promise.all` the `collectResult` calls. That replaces `batch.triggerAndWait()`.
215
206
 
216
207
  `Promise.all` rejects on first failure; use `Promise.allSettled` if you need batch-mode error tolerance similar to trigger.dev's `{ ok, output, error }` per-run result.
217
208
 
@@ -273,7 +264,7 @@ async function loadOrder(id: string) {
273
264
  - `wait.for({ seconds | minutes | hours | days })` / `wait.until({ date })` → `sleep('5m')` or `sleep(date)` from `workflow`.
274
265
  - `wait.forToken(token)` → `createHook({ token })` + `await`. Complete it with `resumeHook(token, payload)` from an API route.
275
266
  - `wait.forToken({ timeout })` → `Promise.race([hook, sleep(timeout)])`.
276
- - `triggerAndWait(payload)` → wrap `start(child, [payload])` in a `"use step"` function and return the `Run` object, then read the result with a second step that calls `getRun(runId).returnValue`.
267
+ - `triggerAndWait(payload)` → call `start(child, [payload])` from the workflow and return the `Run` object, then read the result with a step that calls `getRun(runId).returnValue`.
277
268
 
278
269
  ### Step 5: Start runs from the app
279
270
 
@@ -324,7 +315,7 @@ Throw `new RetryableError(msg, { retryAfter: '5s' })` to control delay between a
324
315
  - Swap `wait.for` / `wait.until` for `sleep()` from `workflow`.
325
316
  - Swap `wait.forToken` for `createHook()` (internal) or `createWebhook()` (HTTP).
326
317
  - Model `wait.forToken` timeouts as `Promise.race()` between the hook and `sleep()`.
327
- - Replace `triggerAndWait()` with `"use step"` wrappers around `start()` and `getRun()`.
318
+ - Replace `triggerAndWait()` with direct `start()` calls and a `"use step"` wrapper around `getRun()` when collecting results.
328
319
  - Replace `batch.triggerAndWait()` with `Promise.all` over the collected child `Run` handles.
329
320
  - Move `schemaTask` validation to the call site; pass typed arguments into the workflow.
330
321
  - Replace `AbortTaskRunError` with `FatalError`; model retries per step with `RetryableError` and `maxRetries`.
@@ -0,0 +1,87 @@
1
+ ---
2
+ title: Attributes
3
+ description: Attach experimental metadata to workflow runs for observability.
4
+ type: reference
5
+ summary: Add string attributes to a workflow run.
6
+ prerequisites:
7
+ - /docs/foundations/workflows-and-steps
8
+ related:
9
+ - /docs/observability
10
+ - /docs/api-reference/workflow/experimental-set-attributes
11
+ - /docs/api-reference/workflow-errors/workflow-world-error
12
+ ---
13
+
14
+ <Callout type="warn">
15
+ This feature is experimental and may change before the stable attributes API is released.
16
+ </Callout>
17
+
18
+ [`experimental_setAttributes`](/docs/api-reference/workflow/experimental-set-attributes) attaches plaintext string metadata to the current workflow run. These attributes are displayed in observability CLI/UI.
19
+ In the future, you'll be able to search and filter runs by attributes.
20
+
21
+ You can also seed any attributes directly when starting a run:
22
+
23
+ {/* @skip-typecheck: abbreviated usage; orderWorkflow is defined below */}
24
+ ```typescript lineNumbers
25
+ const run = await start(orderWorkflow, ["ord_123"], {
26
+ attributes: { source: "checkout" }, // [!code highlight]
27
+ })
28
+ ```
29
+
30
+ ```typescript lineNumbers
31
+ import { experimental_setAttributes } from "workflow"
32
+
33
+ export async function orderWorkflow(orderId: string) {
34
+ "use workflow"
35
+
36
+ await experimental_setAttributes({ // [!code highlight]
37
+ phase: "received", // [!code highlight]
38
+ orderId, // [!code highlight]
39
+ }) // [!code highlight]
40
+
41
+ // ...work...
42
+
43
+ await experimental_setAttributes({ phase: "complete" }) // [!code highlight]
44
+ }
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Call [`experimental_setAttributes`](/docs/api-reference/workflow/experimental-set-attributes) from a `"use workflow"` function or a `"use step"` function. Plain application code is not supported because there is no active workflow run to attach attributes to.
50
+
51
+ Values must be strings. Pass `undefined` to remove a key:
52
+
53
+ ```typescript lineNumbers
54
+ import { experimental_setAttributes } from "workflow"
55
+
56
+ export async function cleanupAttributes() {
57
+ "use workflow"
58
+
59
+ await experimental_setAttributes({ staleKey: undefined }) // [!code highlight]
60
+ }
61
+ ```
62
+
63
+ Attribute keys must be 1-256 characters, values must be strings up to 256 bytes, and each run can have up to 64 attributes. Keys that start with `$` are reserved for framework and library code.
64
+
65
+ ## Viewing attributes
66
+
67
+ The run details panel in the observability UI shows the run's current attributes as key-value rows. Reserved `$`-prefixed keys are marked with a badge and sorted after user keys:
68
+
69
+ ![Run details panel showing the Attributes card with reserved keys badged](/screenshots/attributes/run-details-attributes.png)
70
+
71
+ Each `experimental_setAttributes` call appears on the trace timeline as a diamond marker at the moment the attributes were written:
72
+
73
+ ![Trace timeline with attr_set diamond markers on the run row](/screenshots/attributes/trace-timeline.png)
74
+
75
+ Expanding an `attr_set` event — in the run sidebar or the Events tab — shows the changed keys, removed keys, and whether the write came from the workflow body or a step (with the attempt number):
76
+
77
+ ![Expanded attr_set events showing changes and the writer](/screenshots/attributes/run-details-attr-set-events.png)
78
+
79
+ ## Experimental Behavior
80
+
81
+ While attributes are experimental:
82
+
83
+ - Attributes require a World implementing spec version 4 or later.
84
+ - Writes from workflow and step bodies append native `attr_set` events and immediately materialize `run.attributes`.
85
+ - Storage errors surface rather than being silently ignored: transient errors on workflow-body writes are retried, and a write the World rejects as invalid (for example, exceeding the per-run attribute cap across multiple calls) fails the run with the validation error.
86
+ - Step-body storage errors throw from `experimental_setAttributes` like any other step-side network write. Catch the error inside the step if the attribute is best-effort.
87
+ - Reading and querying attributes is not available yet. A query API is planned.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Observability
3
3
  description: Inspect, monitor, and debug workflows through the CLI and Web UI with powerful observability tools.
4
- type: guide
4
+ type: overview
5
5
  summary: Inspect and debug workflow runs using the CLI and Web UI.
6
6
  prerequisites:
7
7
  - /docs/foundations
@@ -42,6 +42,19 @@ npx workflow inspect runs --web
42
42
 
43
43
  ![Workflow SDK Web UI](/o11y-ui.png)
44
44
 
45
+ To share a link to a specific run without opening a browser, use the `--url`
46
+ flag. It prints the dashboard deep link to stdout and exits (no browser, no
47
+ local server) — useful for scripts, PR comments, or automation. Add `--json` to
48
+ get `{ "url": "..." }`.
49
+
50
+ ```bash
51
+ # Print the deep-link URL for a run (no browser, no server)
52
+ npx workflow inspect run <run_id> --url
53
+
54
+ # Vercel runs: add the backend (and --env preview for preview deployments)
55
+ npx workflow inspect run <run_id> --backend vercel --url
56
+ ```
57
+
45
58
  ## Backends
46
59
 
47
60
  The Workflow SDK CLI can inspect data from any [World](/docs/deploying). By default, it inspects data in your local development environment. For example, if you are using Next.js to develop workflows locally, the
@@ -63,3 +76,7 @@ npx workflow inspect runs --backend vercel
63
76
  ```
64
77
 
65
78
  When deployed to Vercel, workflow data is [encrypted end-to-end](/docs/how-it-works/encryption). Encrypted fields display as locked placeholders until you choose to decrypt them using the **Decrypt** button in the web UI or the `--decrypt` flag in the CLI.
79
+
80
+ ## More Observability Features
81
+
82
+ <AutoCards />
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "title": "Observability",
3
- "pages": ["observability"]
3
+ "pages": ["tracing", "attributes"]
4
4
  }
@@ -0,0 +1,119 @@
1
+ ---
2
+ title: Tracing
3
+ description: Distributed tracing with OpenTelemetry for workflow runs, steps, and queue deliveries.
4
+ type: guide
5
+ summary: Trace workflow execution end to end with OpenTelemetry.
6
+ prerequisites:
7
+ - /docs/foundations/workflows-and-steps
8
+ related:
9
+ - /docs/observability
10
+ - /docs/observability/attributes
11
+ - /docs/how-it-works/event-sourcing
12
+ ---
13
+
14
+ The Workflow SDK is instrumented with [OpenTelemetry](https://opentelemetry.io) out of the box. It emits spans for workflow starts, every workflow and step invocation, and the HTTP calls it makes to the workflow backend — and it propagates trace context across queue deliveries so a run remains traceable end to end.
15
+
16
+ The SDK only depends on the OpenTelemetry **API**, never on an SDK or exporter. If your application does not register an OpenTelemetry SDK, all tracing code is a silent no-op with no overhead and no behavior change.
17
+
18
+ ## Enabling tracing
19
+
20
+ Register any OpenTelemetry Node SDK in your application. On Vercel with Next.js, the simplest setup is [`@vercel/otel`](https://vercel.com/docs/observability/otel-overview) in `instrumentation.ts`:
21
+
22
+ ```typescript title="instrumentation.ts" lineNumbers
23
+ import { registerOTel } from "@vercel/otel"
24
+
25
+ export function register() {
26
+ registerOTel({ serviceName: "my-app" })
27
+ }
28
+ ```
29
+
30
+ No workflow-specific configuration is required. As soon as a tracer provider and propagator are registered, the SDK's spans, context propagation, and span links activate automatically.
31
+
32
+ <Callout>
33
+ `@opentelemetry/api` is an **optional peer dependency**. An OpenTelemetry SDK such as `@vercel/otel` normally pulls it in transitively, but installing it directly (`npm i @opentelemetry/api`) guarantees it is present in your build — particularly for bundled or serverless targets where the SDK's tracing is inlined at build time. If it can't be resolved, tracing is a silent no-op.
34
+ </Callout>
35
+
36
+ ## Spans
37
+
38
+ | Span name | Kind | Emitted when |
39
+ | --- | --- | --- |
40
+ | `workflow.start <name>` | internal | `start()` is called in your application code |
41
+ | `workflow.execute <name>` | consumer (root) | a queue delivery invokes the workflow — replay, orchestration, and inline steps run under it |
42
+ | `step.execute <name>` | internal (inline) / consumer + root (queue-delivered) | a step function executes |
43
+ | `http <method>` | client | the SDK calls the workflow backend (event reads/writes) |
44
+ | `workflow.stream.write` | client | a stream chunk (or the stream close) is flushed to the backend |
45
+ | `workflow.stream.read.connect` | client | a live stream read opens; the span covers dispatch → response headers (network connect) |
46
+ | `workflow.stream.read` | client | a live stream read receives its first chunk; the span's duration is the end-to-end time-to-first-chunk (see `workflow.stream.read.ttfc_ms`) |
47
+
48
+ `<name>` is the short function name (for example `processOrder`); the full machine name, including the source module, is available in the `workflow.name` / `step.name` attributes.
49
+
50
+ Stream spans are emitted by the SDK's world backend on the client that writes or reads the stream, and (like all SDK spans) are no-ops when no OpenTelemetry SDK is registered. The `workflow.stream.read` span only appears once the first non-empty chunk arrives.
51
+
52
+ ## Key attributes
53
+
54
+ | Attribute | Description |
55
+ | --- | --- |
56
+ | `workflow.run.id` | The run ID (`wrun_...`). Present on every workflow and step span — the primary key for finding all spans of a run. |
57
+ | `workflow.name` | The workflow function name. |
58
+ | `workflow.trace.mode` | The active trace mode (`linked` or `continuous`). |
59
+ | `workflow.trace.propagated` | Whether the invocation received trace context from the queue message. |
60
+ | `workflow.queue.overhead_ms` | Time between the message being enqueued and the handler starting — queue dwell plus any cold start. |
61
+ | `workflow.stream.name` | The stream name, on stream write/read spans. |
62
+ | `workflow.stream.operation` | The stream operation: `write`, `write_multi`, `close`, or `read`. |
63
+ | `workflow.stream.write.chunk_rtt` | Time between emissions of a chunk to the wire, and receiving the `ack` message for that chunk. |
64
+ | `workflow.stream.read.ttfc_ms` | Time between opening a read connection and observing and receiving the first chunk back. |
65
+
66
+ ## Trace shape: one trace per invocation
67
+
68
+ A single workflow run can span hours or days across many separate function invocations: every step completion, `sleep()` wake-up, and retry is a new queue delivery. Stitching all of that into one trace produces giant, slow-loading traces that most tracing backends truncate.
69
+
70
+ Instead, the SDK creates **one bounded trace per invocation**. Each `workflow.execute` (or background `step.execute`) span starts a new trace root and attaches two **span links**:
71
+
72
+ - a link to the **enqueue site** — the span that queued the message which triggered this invocation, and
73
+ - a link to the **run origin** — the trace in which `start()` was originally called.
74
+
75
+ A span link is OpenTelemetry's relationship for "causally related, but in a different trace." It is the standard pattern for asynchronous messaging, where producing and consuming a message can be separated by arbitrary time.
76
+
77
+ ```mermaid
78
+ flowchart LR
79
+ O["start() request trace"]
80
+ A["invocation 1"]
81
+ B["invocation 2"]
82
+ C["invocation 3 ..."]
83
+ A -. "link" .-> O
84
+ B -. "link" .-> O
85
+ C -. "link" .-> O
86
+ B -. "link" .-> A
87
+ C -. "link" .-> B
88
+
89
+ style O fill:#a78bfa,stroke:#8b5cf6,color:#000
90
+ ```
91
+
92
+ Each invocation links back to the trace that enqueued it and to the run origin.
93
+
94
+ To see a whole run, query by attribute rather than by trace ID — for example `workflow.run.id = wrun_...` in your tracing backend — or follow the span links between invocation traces.
95
+
96
+ ## Trace modes
97
+
98
+ The `WORKFLOW_TRACE_MODE` environment variable controls the shape:
99
+
100
+ | Mode | Behavior |
101
+ | --- | --- |
102
+ | `linked` (default) | Each invocation is its own trace root with span links to the enqueue site and the run origin. Traces stay small; sampling is decided per invocation. |
103
+ | `continuous` | The run-origin context becomes the **parent** of every invocation, so the entire run shares one trace ID. |
104
+
105
+ <Callout type="warn">
106
+ This is a behavior change from v4, which always used `continuous`-style tracing. If you have dashboards or queries that assume one trace ID per run, either update them to use `workflow.run.id` and span links, or set `WORKFLOW_TRACE_MODE=continuous` to restore the previous shape. Note that in `linked` mode each invocation root makes its own sampling decision, and the number of root spans increases to one per invocation.
107
+ </Callout>
108
+
109
+ ## Context propagation
110
+
111
+ When tracing is enabled, the SDK propagates [W3C Trace Context](https://www.w3.org/TR/trace-context/) on its outbound calls:
112
+
113
+ - **Backend requests** carry `traceparent`, `tracestate`, and `baggage` headers, so backend spans can join your trace.
114
+ - **Queue messages** carry the run-origin trace context in the message payload, and the queue re-delivers the producer's context to the workflow handler, where it becomes the enqueue-site span link.
115
+ - **Baggage** carries `workflow.run_id` and `workflow.name` entries during workflow execution, allowing downstream services you call from steps to tag their own telemetry with the run ID.
116
+
117
+ <Callout>
118
+ Baggage entries set by your application are propagated as a `baggage` HTTP header on the SDK's backend requests, like any other OpenTelemetry-instrumented HTTP call. Avoid placing sensitive values in baggage.
119
+ </Callout>
@@ -109,7 +109,7 @@ That's it. The plugin automatically:
109
109
 
110
110
  1. Transforms `"use workflow"` and `"use step"` directives via SWC
111
111
  2. Builds workflow and step bundles before tests run
112
- 3. Sets up an in-process workflow runtime using a fresh [Local World](/docs/worlds/local) instance in each test worker — all workflow data is cleared automatically between test files for full isolation
112
+ 3. Sets up an in-process workflow runtime using a fresh [Local World](/worlds/local) instance in each test worker — all workflow data is cleared automatically between test files for full isolation
113
113
 
114
114
  <Callout type="info">
115
115
  Use a separate Vitest configuration and a distinct file naming convention (e.g. `*.integration.test.ts`) to keep unit tests and integration tests separate. Unit tests run with a standard Vitest config without the workflow plugin, while integration tests use the config above.
@@ -117,7 +117,7 @@ Use a separate Vitest configuration and a distinct file naming convention (e.g.
117
117
 
118
118
  ### Writing Integration Tests
119
119
 
120
- Use [`start()`](/docs/api-reference/workflow-api/start) to trigger a workflow and [`run.returnValue`](/docs/api-reference/workflow-api/start#returnvalue) to get the result. `returnValue` is a promise that blocks until the workflow completes (or throws if it fails):
120
+ Use [`start()`](/docs/api-reference/workflow-api/start) to trigger a workflow and [`run.returnValue`](/docs/api-reference/workflow-api/start#returns) to get the result. `returnValue` is a promise that blocks until the workflow completes (or throws if it fails):
121
121
 
122
122
  ```typescript title="workflows/calculate.integration.test.ts" lineNumbers
123
123
  import { describe, it, expect } from "vitest";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workflow",
3
- "version": "5.0.0-beta.3",
3
+ "version": "5.0.0-beta.30",
4
4
  "description": "Workflow SDK - Build durable, resilient, and observable workflows",
5
5
  "main": "dist/typescript-plugin.cjs",
6
6
  "type": "module",
@@ -29,6 +29,7 @@
29
29
  ".": {
30
30
  "types": "./dist/index.d.ts",
31
31
  "workflow": "./dist/workflow.js",
32
+ "node": "./dist/index.js",
32
33
  "require": "./dist/typescript-plugin.cjs",
33
34
  "default": "./dist/index.js"
34
35
  },
@@ -56,18 +57,18 @@
56
57
  },
57
58
  "dependencies": {
58
59
  "ms": "2.1.3",
59
- "@workflow/astro": "5.0.0-beta.3",
60
- "@workflow/cli": "5.0.0-beta.3",
61
- "@workflow/errors": "5.0.0-beta.1",
62
- "@workflow/typescript-plugin": "5.0.0-beta.3",
63
- "@workflow/core": "5.0.0-beta.3",
64
- "@workflow/next": "5.0.0-beta.3",
65
- "@workflow/utils": "5.0.0-beta.1",
66
- "@workflow/nest": "5.0.0-beta.3",
67
- "@workflow/nitro": "5.0.0-beta.3",
68
- "@workflow/nuxt": "5.0.0-beta.3",
69
- "@workflow/sveltekit": "5.0.0-beta.3",
70
- "@workflow/rollup": "5.0.0-beta.3"
60
+ "@workflow/astro": "5.0.0-beta.30",
61
+ "@workflow/cli": "5.0.0-beta.30",
62
+ "@workflow/core": "5.0.0-beta.30",
63
+ "@workflow/errors": "5.0.0-beta.10",
64
+ "@workflow/typescript-plugin": "5.0.0-beta.5",
65
+ "@workflow/utils": "5.0.0-beta.6",
66
+ "@workflow/next": "5.0.0-beta.30",
67
+ "@workflow/nest": "5.0.0-beta.30",
68
+ "@workflow/nitro": "5.0.0-beta.30",
69
+ "@workflow/nuxt": "5.0.0-beta.30",
70
+ "@workflow/sveltekit": "5.0.0-beta.30",
71
+ "@workflow/rollup": "5.0.0-beta.30"
71
72
  },
72
73
  "devDependencies": {
73
74
  "@types/ms": "2.1.0",
@@ -1,4 +0,0 @@
1
- {
2
- "title": "World SDK",
3
- "pages": ["storage", "streams", "queue", "observability"]
4
- }