workflow 5.0.0-beta.5 → 5.0.0-beta.50
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.
- package/README.md +68 -23
- package/dist/api-workflow.d.ts +1 -1
- package/dist/api-workflow.d.ts.map +1 -1
- package/dist/api-workflow.js +1 -1
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/internal/builtins.d.ts +20 -3
- package/dist/internal/builtins.d.ts.map +1 -1
- package/dist/internal/builtins.js +68 -4
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +2 -2
- package/dist/nest-builder.d.ts +2 -0
- package/dist/nest-builder.d.ts.map +1 -0
- package/dist/nest-builder.js +2 -0
- package/dist/nest-vercel-builder.d.ts +2 -0
- package/dist/nest-vercel-builder.d.ts.map +1 -0
- package/dist/nest-vercel-builder.js +2 -0
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +2 -2
- package/dist/runtime.d.ts +2 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -1
- package/docs/ai/chat-session-modeling.mdx +29 -26
- package/docs/ai/defining-tools.mdx +6 -7
- package/docs/ai/human-in-the-loop.mdx +11 -11
- package/docs/ai/index.mdx +50 -45
- package/docs/ai/message-queueing.mdx +16 -16
- package/docs/ai/meta.json +1 -0
- package/docs/ai/resumable-streams.mdx +40 -28
- package/docs/ai/sleep-and-delays.mdx +10 -10
- package/docs/ai/streaming-updates-from-tools.mdx +6 -6
- package/docs/api-reference/index.mdx +24 -0
- package/docs/api-reference/meta.json +8 -0
- package/docs/api-reference/vitest/index.mdx +9 -15
- package/docs/api-reference/workflow/create-hook.mdx +89 -10
- package/docs/api-reference/workflow/create-webhook.mdx +16 -15
- package/docs/api-reference/workflow/define-hook.mdx +35 -33
- package/docs/api-reference/workflow/fatal-error.mdx +30 -8
- package/docs/api-reference/workflow/fetch.mdx +14 -10
- package/docs/api-reference/workflow/get-step-metadata.mdx +2 -2
- package/docs/api-reference/workflow/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/workflow/get-writable.mdx +7 -7
- package/docs/api-reference/workflow/index.mdx +4 -1
- package/docs/api-reference/workflow/retryable-error.mdx +1 -1
- package/docs/api-reference/workflow/set-attributes.mdx +61 -0
- package/docs/api-reference/workflow/sleep.mdx +4 -4
- package/docs/api-reference/workflow-ai/durable-agent.mdx +48 -86
- package/docs/api-reference/workflow-ai/index.mdx +3 -3
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +67 -24
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +26 -12
- package/docs/api-reference/workflow-api/get-run.mdx +43 -8
- package/docs/api-reference/workflow-api/index.mdx +6 -10
- package/docs/api-reference/workflow-api/resume-hook.mdx +73 -12
- package/docs/api-reference/workflow-api/resume-webhook.mdx +11 -9
- package/docs/api-reference/workflow-api/start.mdx +60 -13
- package/docs/api-reference/workflow-astro/index.mdx +18 -0
- package/docs/api-reference/workflow-astro/meta.json +4 -0
- package/docs/api-reference/workflow-astro/workflow.mdx +45 -0
- package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/hook-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +8 -8
- package/docs/api-reference/workflow-errors/index.mdx +88 -0
- package/docs/api-reference/workflow-errors/meta.json +6 -0
- package/docs/api-reference/workflow-errors/precondition-failed-error.mdx +68 -0
- package/docs/api-reference/workflow-errors/run-expired-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/throttle-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/too-early-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
- package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +5 -6
- package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +6 -6
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-world-error.mdx +8 -8
- package/docs/api-reference/workflow-globals.mdx +14 -10
- package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +33 -0
- package/docs/api-reference/workflow-nest/index.mdx +31 -0
- package/docs/api-reference/workflow-nest/meta.json +9 -0
- package/docs/api-reference/workflow-nest/nest-local-builder.mdx +64 -0
- package/docs/api-reference/workflow-nest/workflow-controller.mdx +40 -0
- package/docs/api-reference/workflow-nest/workflow-module.mdx +74 -0
- package/docs/api-reference/workflow-next/with-workflow.mdx +39 -17
- package/docs/api-reference/workflow-nitro/index.mdx +60 -0
- package/docs/api-reference/workflow-nuxt/index.mdx +48 -0
- package/docs/api-reference/workflow-observability/hydrate-data.mdx +35 -0
- package/docs/api-reference/workflow-observability/hydrate-resource-io.mdx +62 -0
- package/docs/api-reference/workflow-observability/index.mdx +62 -0
- package/docs/api-reference/workflow-observability/meta.json +11 -0
- package/docs/api-reference/workflow-observability/observability-revivers.mdx +50 -0
- package/docs/api-reference/workflow-observability/parse-class-name.mdx +41 -0
- package/docs/api-reference/workflow-observability/parse-step-name.mdx +40 -0
- package/docs/api-reference/workflow-observability/parse-workflow-name.mdx +55 -0
- package/docs/api-reference/workflow-runtime/create-world.mdx +39 -0
- package/docs/api-reference/workflow-runtime/get-world-handlers.mdx +44 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/get-world.mdx +11 -14
- package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
- package/docs/api-reference/workflow-runtime/index.mdx +41 -0
- package/docs/api-reference/workflow-runtime/meta.json +12 -0
- package/docs/api-reference/workflow-runtime/set-world.mdx +51 -0
- package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +43 -0
- package/docs/api-reference/workflow-runtime/world/analytics.mdx +315 -0
- package/docs/api-reference/workflow-runtime/world/index.mdx +60 -0
- package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
- package/docs/api-reference/workflow-runtime/world/queue.mdx +88 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +98 -34
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +8 -8
- package/docs/api-reference/workflow-serde/index.mdx +1 -2
- package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +3 -4
- package/docs/api-reference/workflow-serde/workflow-serialize.mdx +8 -8
- package/docs/api-reference/workflow-sveltekit/index.mdx +18 -0
- package/docs/api-reference/workflow-sveltekit/meta.json +4 -0
- package/docs/api-reference/workflow-sveltekit/workflow-plugin.mdx +42 -0
- package/docs/api-reference/workflow-vite/index.mdx +18 -0
- package/docs/api-reference/workflow-vite/meta.json +4 -0
- package/docs/api-reference/workflow-vite/workflow.mdx +48 -0
- package/docs/changelog/attributes-mvp.mdx +380 -0
- package/docs/changelog/batched-event-writes.mdx +79 -0
- package/docs/changelog/eager-processing.mdx +110 -436
- package/docs/changelog/index.mdx +4 -2
- package/docs/changelog/lazy-event-creation.md +127 -0
- package/docs/changelog/lazy-hook-resume.mdx +78 -0
- package/docs/changelog/meta.json +11 -1
- package/docs/changelog/resilient-resume.mdx +32 -0
- package/docs/changelog/resilient-start.mdx +33 -285
- package/docs/changelog/step-message-ownership.mdx +360 -0
- package/docs/changelog/turbo-mode.md +87 -0
- package/docs/comparisons/index.mdx +66 -0
- package/docs/comparisons/meta.json +11 -0
- package/docs/comparisons/workflow-sdk-vs-aws-agentcore.mdx +55 -0
- package/docs/comparisons/workflow-sdk-vs-aws-step-functions.mdx +111 -0
- package/docs/comparisons/workflow-sdk-vs-cloudflare-workflows.mdx +71 -0
- package/docs/comparisons/workflow-sdk-vs-inngest.mdx +102 -0
- package/docs/comparisons/workflow-sdk-vs-temporal.mdx +123 -0
- package/docs/comparisons/workflow-sdk-vs-trigger-dev.mdx +104 -0
- package/docs/configuration/build-and-diagnostics.mdx +70 -0
- package/docs/configuration/cli-and-web-ui.mdx +241 -0
- package/docs/configuration/framework-options.mdx +165 -0
- package/docs/configuration/index.mdx +32 -0
- package/docs/configuration/meta.json +12 -0
- package/docs/configuration/runtime-tuning.mdx +376 -0
- package/docs/configuration/worlds.mdx +313 -0
- package/docs/cookbook/advanced/child-workflows.mdx +211 -264
- package/docs/cookbook/advanced/meta.json +6 -1
- package/docs/cookbook/advanced/publishing-libraries.mdx +65 -56
- package/docs/cookbook/advanced/serializable-steps.mdx +28 -20
- package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +27 -19
- package/docs/cookbook/agent-patterns/durable-agent.mdx +14 -142
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +30 -22
- package/docs/cookbook/common-patterns/batching.mdx +18 -14
- package/docs/cookbook/common-patterns/idempotency.mdx +41 -53
- package/docs/cookbook/common-patterns/rate-limiting.mdx +8 -4
- package/docs/cookbook/common-patterns/saga.mdx +23 -19
- package/docs/cookbook/common-patterns/scheduling.mdx +34 -22
- package/docs/cookbook/common-patterns/sequential-and-parallel.mdx +29 -25
- package/docs/cookbook/common-patterns/timeouts.mdx +26 -21
- package/docs/cookbook/common-patterns/webhooks.mdx +10 -6
- package/docs/cookbook/common-patterns/workflow-composition.mdx +30 -27
- package/docs/cookbook/index.mdx +22 -21
- package/docs/cookbook/integrations/ai-sdk.mdx +85 -47
- package/docs/cookbook/integrations/chat-sdk.mdx +50 -33
- package/docs/cookbook/integrations/sandbox.mdx +62 -45
- package/docs/deploying.mdx +95 -0
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +16 -12
- package/docs/errors/corrupted-event-log.mdx +29 -18
- package/docs/errors/deployment-mismatch.mdx +71 -0
- package/docs/errors/fetch-in-workflow.mdx +11 -7
- package/docs/errors/hook-conflict.mdx +69 -13
- package/docs/errors/index.mdx +2 -36
- package/docs/errors/node-js-module-in-workflow.mdx +9 -5
- package/docs/errors/replay-divergence.mdx +27 -0
- package/docs/errors/run-expired.mdx +85 -0
- package/docs/errors/runtime-decryption-failed.mdx +77 -0
- package/docs/errors/serialization-failed.mdx +44 -12
- package/docs/errors/start-invalid-workflow-function.mdx +9 -5
- package/docs/errors/step-executed-multiple-times.mdx +23 -0
- package/docs/errors/step-not-registered.mdx +6 -6
- package/docs/errors/timeout-in-workflow.mdx +12 -8
- package/docs/errors/webhook-invalid-respond-with-value.mdx +18 -18
- package/docs/errors/webhook-response-not-sent.mdx +20 -16
- package/docs/errors/workflow-not-registered.mdx +5 -5
- package/docs/foundations/cancellation.mdx +31 -32
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +64 -35
- package/docs/foundations/idempotency.mdx +244 -12
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +2 -1
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +106 -30
- package/docs/foundations/streaming.mdx +107 -59
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/getting-started/astro.mdx +22 -18
- package/docs/getting-started/express.mdx +15 -11
- package/docs/getting-started/fastify.mdx +15 -11
- package/docs/getting-started/hono.mdx +15 -11
- package/docs/getting-started/index.mdx +10 -3
- package/docs/getting-started/meta.json +3 -1
- package/docs/getting-started/nestjs.mdx +87 -20
- package/docs/getting-started/next.mdx +22 -16
- package/docs/getting-started/nitro.mdx +22 -18
- package/docs/getting-started/nuxt.mdx +15 -11
- package/docs/getting-started/python.mdx +135 -40
- package/docs/getting-started/react-router/index.mdx +33 -0
- package/docs/getting-started/react-router/meta.json +5 -0
- package/docs/getting-started/react-router/v7.mdx +237 -0
- package/docs/getting-started/react-router/v8.mdx +232 -0
- package/docs/getting-started/sveltekit.mdx +20 -16
- package/docs/getting-started/tanstack-start.mdx +17 -13
- package/docs/getting-started/vite.mdx +15 -11
- package/docs/how-it-works/cancellation.mdx +63 -63
- package/docs/how-it-works/code-transform.mdx +83 -67
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +98 -34
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/understanding-directives.mdx +22 -22
- package/docs/internal/index.mdx +6 -4
- package/docs/internal/meta.json +6 -1
- package/docs/internal/nitro-native-build.mdx +38 -0
- package/docs/internal/nitro-web-ui.mdx +24 -0
- package/docs/internal/serializable-abort-controller.mdx +7 -7
- package/docs/meta.json +3 -2
- package/docs/observability/attributes.mdx +134 -0
- package/docs/observability/index.mdx +32 -10
- package/docs/observability/meta.json +1 -1
- package/docs/observability/retention.mdx +93 -0
- package/docs/observability/tracing.mdx +124 -0
- package/docs/testing/index.mdx +36 -36
- package/docs/testing/server-based.mdx +10 -10
- package/docs/whats-new.mdx +186 -0
- package/package.json +17 -14
- package/docs/api-reference/workflow-api/world/index.mdx +0 -58
- package/docs/api-reference/workflow-api/world/meta.json +0 -4
- package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
- package/docs/api-reference/workflow-api/world/queue.mdx +0 -86
- package/docs/deploying/building-a-world.mdx +0 -251
- package/docs/deploying/index.mdx +0 -95
- package/docs/deploying/meta.json +0 -4
- package/docs/deploying/world/local-world.mdx +0 -84
- package/docs/deploying/world/meta.json +0 -4
- package/docs/deploying/world/postgres-world.mdx +0 -224
- package/docs/deploying/world/vercel-world.mdx +0 -179
- package/docs/migration-guides/index.mdx +0 -34
- package/docs/migration-guides/meta.json +0 -9
- package/docs/migration-guides/migrating-from-aws-step-functions.mdx +0 -363
- package/docs/migration-guides/migrating-from-inngest.mdx +0 -314
- package/docs/migration-guides/migrating-from-temporal.mdx +0 -318
- package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -337
|
@@ -15,11 +15,11 @@ All function arguments and return values passed between workflow and step functi
|
|
|
15
15
|
The serialization system ensures that all data persists correctly across workflow suspensions and resumptions, enabling durable execution.
|
|
16
16
|
</Callout>
|
|
17
17
|
|
|
18
|
-
## Supported
|
|
18
|
+
## Supported serializable types
|
|
19
19
|
|
|
20
20
|
The following types can be serialized and passed through workflow functions:
|
|
21
21
|
|
|
22
|
-
**Standard JSON
|
|
22
|
+
**Standard JSON types:**
|
|
23
23
|
|
|
24
24
|
- `string`
|
|
25
25
|
- `number`
|
|
@@ -28,7 +28,7 @@ The following types can be serialized and passed through workflow functions:
|
|
|
28
28
|
- Arrays of serializable values
|
|
29
29
|
- Objects with string keys and serializable values
|
|
30
30
|
|
|
31
|
-
**Extended
|
|
31
|
+
**Extended types:**
|
|
32
32
|
|
|
33
33
|
- `undefined`
|
|
34
34
|
- `bigint`
|
|
@@ -58,7 +58,7 @@ These types have special handling and are explained in detail in the sections be
|
|
|
58
58
|
- `AbortController`
|
|
59
59
|
- `AbortSignal`
|
|
60
60
|
|
|
61
|
-
## Pass-by-
|
|
61
|
+
## Pass-by-value semantics
|
|
62
62
|
|
|
63
63
|
**Parameters are passed by value, not by reference.** Steps receive deserialized copies of data. Mutations inside a step won't affect the original in the workflow.
|
|
64
64
|
|
|
@@ -81,7 +81,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
**Correct
|
|
84
|
+
**Correct, return the modified data:**
|
|
85
85
|
|
|
86
86
|
```typescript title="workflows/correct-mutation.ts" lineNumbers
|
|
87
87
|
export async function updateUserWorkflow(userId: string) {
|
|
@@ -100,7 +100,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
**Custom
|
|
103
|
+
**Custom classes:**
|
|
104
104
|
|
|
105
105
|
- Class instances that implement [`WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE`](#custom-class-serialization)
|
|
106
106
|
|
|
@@ -110,7 +110,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
110
110
|
|
|
111
111
|
For complete information about using streams in workflows, including patterns for AI streaming, file processing, and progress updates, see the [Streaming Guide](/docs/foundations/streaming).
|
|
112
112
|
|
|
113
|
-
## Request &
|
|
113
|
+
## Request & response
|
|
114
114
|
|
|
115
115
|
The Web API [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) APIs are supported by the serialization system,
|
|
116
116
|
and can be passed around between workflow and step functions similarly to other data types.
|
|
@@ -140,7 +140,7 @@ export async function handleWebhookWorkflow() {
|
|
|
140
140
|
}
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
### Using `fetch` in
|
|
143
|
+
### Using `fetch` in workflows
|
|
144
144
|
|
|
145
145
|
Because `Request` and `Response` are serializable, Workflow SDK provides a `fetch` function that can be used directly in workflow functions:
|
|
146
146
|
|
|
@@ -158,7 +158,7 @@ export async function apiWorkflow() {
|
|
|
158
158
|
}
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
The
|
|
161
|
+
The `fetch` implementation from `workflow` is a step function that wraps the standard `fetch`:
|
|
162
162
|
|
|
163
163
|
```typescript title="Implementation" lineNumbers
|
|
164
164
|
export async function fetch(...args: Parameters<typeof globalThis.fetch>) {
|
|
@@ -202,11 +202,11 @@ async function fetchData(signal: AbortSignal) {
|
|
|
202
202
|
|
|
203
203
|
For usage patterns including timeouts, parallel cancellation, user-triggered cancellation, and run cancellation, see the [Cancellation Guide](/docs/foundations/cancellation). For details on the hook and stream backing that makes this work, see [How Cancellation Works](/docs/how-it-works/cancellation).
|
|
204
204
|
|
|
205
|
-
## Custom
|
|
205
|
+
## Custom class serialization
|
|
206
206
|
|
|
207
207
|
By default, custom class instances cannot be serialized because the serialization system doesn't know how to reconstruct them. You can make your classes serializable by implementing two static methods using special symbols from the `@workflow/serde` package.
|
|
208
208
|
|
|
209
|
-
### Basic
|
|
209
|
+
### Basic example
|
|
210
210
|
|
|
211
211
|
{/* @expect-error:2351 */}
|
|
212
212
|
|
|
@@ -256,13 +256,13 @@ async function doublePoint(point: Point) {
|
|
|
256
256
|
}
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
### How
|
|
259
|
+
### How it works
|
|
260
260
|
|
|
261
261
|
1. **`WORKFLOW_SERIALIZE`**: A static method that receives a class instance and returns serializable data (primitives, plain objects, arrays, etc.)
|
|
262
262
|
|
|
263
263
|
2. **`WORKFLOW_DESERIALIZE`**: A static method that receives the serialized data and returns a new class instance
|
|
264
264
|
|
|
265
|
-
3. **Automatic Registration**: The SWC compiler plugin automatically detects classes that implement these symbols and registers them for serialization. Each class receives a deterministic `classId` derived from its file path and class name, and is registered into the global `Symbol.for("workflow-class-registry")` registry at build time
|
|
265
|
+
3. **Automatic Registration**: The SWC compiler plugin automatically detects classes that implement these symbols and registers them for serialization. Each class receives a deterministic `classId` derived from its file path and class name, and is registered into the global `Symbol.for("workflow-class-registry")` registry at build time. No manual registration step is required
|
|
266
266
|
|
|
267
267
|
### Requirements
|
|
268
268
|
|
|
@@ -279,12 +279,12 @@ The `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` methods run inside the workf
|
|
|
279
279
|
- No non-deterministic operations (like `Math.random()` or `Date.now()`)
|
|
280
280
|
- No external network calls
|
|
281
281
|
|
|
282
|
-
Keep these methods
|
|
282
|
+
Keep these methods focused on data transformation only.
|
|
283
283
|
</Callout>
|
|
284
284
|
|
|
285
|
-
### Instance
|
|
285
|
+
### Instance methods as steps
|
|
286
286
|
|
|
287
|
-
In practice, many classes have methods that need Node.js APIs, perform network calls, or interact with databases
|
|
287
|
+
In practice, many classes have methods that need Node.js APIs, perform network calls, or interact with databases, operations that are not allowed in the `"use workflow"` execution context. You can make these methods workflow-compatible by adding `"use step"` to them. The SWC compiler will strip the method bodies from the workflow bundle and replace them with proxy functions that invoke the method as a step, with full Node.js runtime access. The `this` context (the class instance) is automatically serialized and deserialized across the workflow/step boundary.
|
|
288
288
|
|
|
289
289
|
This requires the class to implement `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE`, so that the instance can be passed to the step execution context.
|
|
290
290
|
|
|
@@ -301,7 +301,7 @@ class Order {
|
|
|
301
301
|
public createdAt: Date
|
|
302
302
|
) {}
|
|
303
303
|
|
|
304
|
-
// Custom serialization
|
|
304
|
+
// Custom serialization: data must be serializable types
|
|
305
305
|
static [WORKFLOW_SERIALIZE](instance: Order) { // [!code highlight]
|
|
306
306
|
return { // [!code highlight]
|
|
307
307
|
id: instance.id, // [!code highlight]
|
|
@@ -329,7 +329,7 @@ class Order {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
// Instance methods with "use step" run as step functions
|
|
332
|
-
// with full Node.js access
|
|
332
|
+
// with full Node.js access; `this` is automatically serialized
|
|
333
333
|
async save(): Promise<void> {
|
|
334
334
|
"use step"; // [!code highlight]
|
|
335
335
|
await db.orders.insert({ // [!code highlight]
|
|
@@ -355,7 +355,7 @@ class Order {
|
|
|
355
355
|
}
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
The class can then be used naturally inside a workflow function. Instance methods marked with `"use step"` are each executed as a step
|
|
358
|
+
The class can then be used naturally inside a workflow function. Instance methods marked with `"use step"` are each executed as a step, with automatic caching, retry semantics, and full Node.js runtime access. Methods _without_ `"use step"` run directly in the workflow context, so they must follow the same constraints as workflow functions:
|
|
359
359
|
|
|
360
360
|
{/* @expect-error:2693 */}
|
|
361
361
|
|
|
@@ -369,7 +369,7 @@ export async function processOrderWorkflow(
|
|
|
369
369
|
|
|
370
370
|
const order = new Order(orderId, items, new Date()); // [!code highlight]
|
|
371
371
|
|
|
372
|
-
// Runs in the workflow context
|
|
372
|
+
// Runs in the workflow context; no "use step" needed
|
|
373
373
|
const itemCount = order.total(); // [!code highlight]
|
|
374
374
|
|
|
375
375
|
// Each "use step" instance method call runs as a separate step
|
|
@@ -380,7 +380,7 @@ export async function processOrderWorkflow(
|
|
|
380
380
|
}
|
|
381
381
|
```
|
|
382
382
|
|
|
383
|
-
|
|
383
|
+
[Pass-by-value semantics](#pass-by-value-semantics) also apply to the `this` context of `"use step"` instance methods. Modifying instance properties inside a step method will not affect the original instance in the workflow. If you need to update instance state, return `this` from the step method and re-assign the variable in the workflow:
|
|
384
384
|
|
|
385
385
|
{/* @expect-error:2351 */}
|
|
386
386
|
|
|
@@ -408,4 +408,3 @@ export async function processOrderWorkflow() {
|
|
|
408
408
|
order = await order.addItem("Widget", 3); // [!code highlight]
|
|
409
409
|
}
|
|
410
410
|
```
|
|
411
|
-
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Starting
|
|
2
|
+
title: Starting workflows
|
|
3
3
|
description: Trigger workflow execution with the start() function and track progress with Run objects.
|
|
4
4
|
type: guide
|
|
5
5
|
summary: Trigger workflows and track their execution using the start() function.
|
|
@@ -9,11 +9,11 @@ related:
|
|
|
9
9
|
- /docs/api-reference/workflow-api/start
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
After you define a workflow function, use the `start()` function from `workflow/api` to trigger it. The function enqueues a new workflow run and returns a `Run` object for tracking its progress.
|
|
13
13
|
|
|
14
|
-
## The `start()`
|
|
14
|
+
## The `start()` function
|
|
15
15
|
|
|
16
|
-
The [`start()`](/docs/api-reference/workflow-api/start) function
|
|
16
|
+
The [`start()`](/docs/api-reference/workflow-api/start) function programmatically triggers workflow executions from runtime contexts such as API routes, Server Actions, or other server-side code. In v5, you can also call `start()` inside a workflow function to spawn a child run or continue work in a new run.
|
|
17
17
|
|
|
18
18
|
```typescript lineNumbers
|
|
19
19
|
import { start } from "workflow/api";
|
|
@@ -32,16 +32,21 @@ export async function POST(request: Request) {
|
|
|
32
32
|
}
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
**Key
|
|
35
|
+
**Key points:**
|
|
36
36
|
|
|
37
|
-
- `start()` returns immediately after enqueuing the workflow
|
|
37
|
+
- `start()` returns immediately after enqueuing the workflow. It doesn't wait for completion
|
|
38
38
|
- The first argument is your workflow function
|
|
39
39
|
- The second argument is an array of arguments to pass to the workflow (optional if the workflow takes no arguments)
|
|
40
40
|
- All arguments must be [serializable](/docs/foundations/serialization)
|
|
41
|
+
- On Worlds with a regional dimension, the optional `region` option pins the new run's storage, queuing, and streams to a specific region. See [Multi-region on the Vercel World](/worlds/vercel#multi-region)
|
|
41
42
|
|
|
42
|
-
**Learn more**: [`start()` API
|
|
43
|
+
**Learn more**: [`start()` API reference](/docs/api-reference/workflow-api/start)
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
<Callout type="info">
|
|
46
|
+
For parent-child workflow patterns, see [Workflow Composition](/cookbook/common-patterns/workflow-composition). For long-lived workflows that intentionally hand off to newer deployments with `deploymentId: "latest"`, see [Versioning](/docs/foundations/versioning).
|
|
47
|
+
</Callout>
|
|
48
|
+
|
|
49
|
+
## The `Run` object
|
|
45
50
|
|
|
46
51
|
When you call `start()`, it returns a [`Run`](/docs/api-reference/workflow-api/start#returns) object that provides access to the workflow's status and results.
|
|
47
52
|
|
|
@@ -61,24 +66,53 @@ const status = await run.status; // "running" | "completed" | "failed"
|
|
|
61
66
|
const result = await run.returnValue;
|
|
62
67
|
```
|
|
63
68
|
|
|
64
|
-
**Key
|
|
69
|
+
**Key properties:**
|
|
65
70
|
|
|
66
|
-
- `runId
|
|
67
|
-
- `status
|
|
68
|
-
- `returnValue
|
|
69
|
-
- `readable`
|
|
71
|
+
- `runId`: Unique identifier for this workflow run
|
|
72
|
+
- `status`: Current status of the workflow (async)
|
|
73
|
+
- `returnValue`: The value returned by the workflow function (async, blocks until completion)
|
|
74
|
+
- `readable`: `ReadableStream` for streaming updates from the workflow
|
|
70
75
|
|
|
71
76
|
<Callout type="info">
|
|
72
|
-
Most `Run` properties are async getters that return promises.
|
|
77
|
+
Most `Run` properties are async getters that return promises. `await` them to get their values. For a complete list of properties and methods, see the API reference below.
|
|
73
78
|
</Callout>
|
|
74
79
|
|
|
75
|
-
**Learn more**: [`Run` API
|
|
80
|
+
**Learn more**: [`Run` API reference](/docs/api-reference/workflow-api/start#returns)
|
|
81
|
+
|
|
82
|
+
## Common patterns
|
|
83
|
+
|
|
84
|
+
### Starting workflows from workflow functions
|
|
85
|
+
|
|
86
|
+
You can also call `start()` directly inside workflow functions to spawn child workflows. For choosing between this and awaiting a workflow function directly, see [Workflow Composition](/cookbook/common-patterns/workflow-composition).
|
|
87
|
+
|
|
88
|
+
```typescript lineNumbers
|
|
89
|
+
import { start } from "workflow/api";
|
|
90
|
+
import { childWorkflow } from "./workflows/child";
|
|
91
|
+
|
|
92
|
+
export async function parentWorkflow(inputValue: number) {
|
|
93
|
+
"use workflow";
|
|
94
|
+
|
|
95
|
+
const childRun = await start(childWorkflow, [inputValue]); // [!code highlight]
|
|
76
96
|
|
|
77
|
-
|
|
97
|
+
// childRun is a full Run object. Use it like normal.
|
|
98
|
+
const childResult = await childRun.returnValue;
|
|
99
|
+
return { childRunId: childRun.runId, childResult };
|
|
100
|
+
}
|
|
101
|
+
```
|
|
78
102
|
|
|
79
|
-
|
|
103
|
+
When you call `start()` inside a workflow function, it automatically executes through an internal step to maintain deterministic replay. The returned `Run` object works as it does outside workflows. Properties such as `.runId`, `.status`, and `.returnValue`, and methods such as `.cancel()`, are all available. Each property access or method call executes as a separate step.
|
|
80
104
|
|
|
81
|
-
|
|
105
|
+
<Callout type="info">
|
|
106
|
+
Inside workflow functions, each `Run` property access (e.g., `run.status`, `run.returnValue`) triggers a workflow step. This means each access is recorded in the event log and replayed deterministically.
|
|
107
|
+
</Callout>
|
|
108
|
+
|
|
109
|
+
<Callout type="warn">
|
|
110
|
+
Awaiting `returnValue` polls the child run every second, and the polling step holds its worker slot open until the child finishes. Size worker-based Worlds to cover the peak number of these polls in flight. If the child workflow is long-running, spawn it without awaiting `returnValue` and have it resume a [hook](/docs/foundations/hooks) when it completes. See the [`startAndWait()` pattern](/cookbook/advanced/child-workflows).
|
|
111
|
+
</Callout>
|
|
112
|
+
|
|
113
|
+
### Fire and forget
|
|
114
|
+
|
|
115
|
+
Start a workflow and immediately return to let it execute in the background:
|
|
82
116
|
|
|
83
117
|
```typescript lineNumbers
|
|
84
118
|
import { start } from "workflow/api";
|
|
@@ -96,7 +130,7 @@ export async function POST(request: Request) {
|
|
|
96
130
|
}
|
|
97
131
|
```
|
|
98
132
|
|
|
99
|
-
### Wait for
|
|
133
|
+
### Wait for completion
|
|
100
134
|
|
|
101
135
|
If you need to wait for the workflow to complete before responding:
|
|
102
136
|
|
|
@@ -115,12 +149,12 @@ export async function POST(request: Request) {
|
|
|
115
149
|
```
|
|
116
150
|
|
|
117
151
|
<Callout type="warn">
|
|
118
|
-
|
|
152
|
+
Waiting for `returnValue` can cause your API route to time out if the workflow takes a long time.
|
|
119
153
|
</Callout>
|
|
120
154
|
|
|
121
|
-
### Stream
|
|
155
|
+
### Stream updates to client
|
|
122
156
|
|
|
123
|
-
Stream
|
|
157
|
+
Stream updates from your workflow as it executes without waiting for completion:
|
|
124
158
|
|
|
125
159
|
```typescript lineNumbers
|
|
126
160
|
import { start } from "workflow/api";
|
|
@@ -144,7 +178,7 @@ export async function POST(request: Request) {
|
|
|
144
178
|
}
|
|
145
179
|
```
|
|
146
180
|
|
|
147
|
-
Your workflow can
|
|
181
|
+
Your workflow can write to the stream using [`getWritable()`](/docs/api-reference/workflow/get-writable):
|
|
148
182
|
|
|
149
183
|
```typescript lineNumbers
|
|
150
184
|
import { getWritable } from "workflow";
|
|
@@ -178,12 +212,12 @@ async function streamContentToClient(
|
|
|
178
212
|
```
|
|
179
213
|
|
|
180
214
|
<Callout type="info">
|
|
181
|
-
|
|
215
|
+
Use streams to show users real-time progress from AI workflows or intermediate results from long-running processes.
|
|
182
216
|
</Callout>
|
|
183
217
|
|
|
184
|
-
**Learn more**: [Streaming in
|
|
218
|
+
**Learn more**: [Streaming in workflows](/docs/foundations/serialization#streaming)
|
|
185
219
|
|
|
186
|
-
### Check
|
|
220
|
+
### Check status later
|
|
187
221
|
|
|
188
222
|
You can retrieve a workflow run later using its `runId` with [`getRun()`](/docs/api-reference/workflow-api/get-run):
|
|
189
223
|
|
|
@@ -209,10 +243,52 @@ export async function GET(request: Request) {
|
|
|
209
243
|
}
|
|
210
244
|
```
|
|
211
245
|
|
|
212
|
-
|
|
246
|
+
### Recursive and repeating workflows
|
|
247
|
+
|
|
248
|
+
A workflow can start a new instance of itself. This pattern prevents a single long-running workflow from accumulating too many events. Large event logs are slower to replay, more expensive to store, and harder to inspect in the UI. Breaking work into smaller runs that chain together keeps each run lean.
|
|
249
|
+
|
|
250
|
+
```typescript lineNumbers
|
|
251
|
+
import { start } from "workflow/api";
|
|
252
|
+
declare function fetchBatch(cursor?: string): Promise<{ items: string[]; nextCursor?: string }>; // @setup
|
|
253
|
+
declare function processBatch(items: string[]): Promise<void>; // @setup
|
|
254
|
+
|
|
255
|
+
export async function processQueue(cursor?: string) {
|
|
256
|
+
"use workflow";
|
|
257
|
+
|
|
258
|
+
const { items, nextCursor } = await fetchBatch(cursor);
|
|
259
|
+
await processBatch(items);
|
|
260
|
+
|
|
261
|
+
if (nextCursor) {
|
|
262
|
+
// Continue processing in a new workflow run
|
|
263
|
+
await start(processQueue, [nextCursor]); // [!code highlight]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
This pattern also enables **repeating cron-like workflows**. A workflow can complete its work, sleep, and then schedule a new instance of itself. This creates an indefinite chain without allowing any single run to grow too large:
|
|
269
|
+
|
|
270
|
+
```typescript lineNumbers
|
|
271
|
+
import { sleep } from "workflow";
|
|
272
|
+
import { start } from "workflow/api";
|
|
273
|
+
declare function refreshMetrics(): Promise<void>; // @setup
|
|
274
|
+
|
|
275
|
+
export async function syncDashboard() {
|
|
276
|
+
"use workflow";
|
|
277
|
+
|
|
278
|
+
await refreshMetrics();
|
|
279
|
+
await sleep("1h");
|
|
280
|
+
|
|
281
|
+
// Schedule the next run
|
|
282
|
+
await start(syncDashboard); // [!code highlight]
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### Starting against the latest deployment
|
|
287
|
+
|
|
288
|
+
By default a chained run starts on the same deployment as its parent. For workflows that chain over long periods, pass [`deploymentId: "latest"`](/docs/api-reference/workflow-api/start#using-deploymentid-latest) so the next run picks up new code. [Versioning](/docs/foundations/versioning#self-upgrading-workflows) covers this pattern in full, including how the serialized state acts as the migration boundary between versions.
|
|
213
289
|
|
|
214
|
-
|
|
290
|
+
## Next steps
|
|
215
291
|
|
|
216
292
|
- Browse the [Cookbook](/cookbook) for copy-paste recipes covering composition, scheduling, timeouts, and more
|
|
217
|
-
- Explore [Errors
|
|
218
|
-
- Check the [`start()` API
|
|
293
|
+
- Explore [Errors and retrying](/docs/foundations/errors-and-retries) to handle failures
|
|
294
|
+
- Check the [`start()` API reference](/docs/api-reference/workflow-api/start) for complete details
|