workflow 5.0.0-beta.9 → 5.0.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.
- package/README.md +68 -23
- package/dist/api-workflow.d.ts +3 -1
- package/dist/api-workflow.d.ts.map +1 -1
- package/dist/api-workflow.js +2 -1
- package/dist/api.d.ts +5 -4
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -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 +4 -4
- package/dist/internal/builtins.js +6 -6
- 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/runtime.d.ts +2 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -1
- package/docs/advanced/dynamic-workflows.mdx +224 -0
- package/docs/ai/chat-session-modeling.mdx +176 -422
- package/docs/ai/defining-tools.mdx +6 -7
- package/docs/ai/human-in-the-loop.mdx +11 -11
- package/docs/ai/index.mdx +67 -72
- package/docs/ai/message-queueing.mdx +71 -110
- 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 +25 -1
- package/docs/api-reference/meta.json +8 -0
- package/docs/api-reference/vitest/index.mdx +68 -15
- package/docs/api-reference/workflow/create-hook.mdx +166 -10
- package/docs/api-reference/workflow/create-webhook.mdx +16 -15
- package/docs/api-reference/workflow/define-hook.mdx +37 -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 +3 -3
- package/docs/api-reference/workflow/retryable-error.mdx +1 -1
- package/docs/api-reference/workflow/set-attributes.mdx +63 -0
- package/docs/api-reference/workflow/sleep.mdx +4 -4
- package/docs/api-reference/workflow-ai/durable-agent.mdx +63 -101
- package/docs/api-reference/workflow-ai/index.mdx +5 -5
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +67 -24
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +28 -12
- package/docs/api-reference/workflow-api/get-run.mdx +43 -8
- package/docs/api-reference/workflow-api/index.mdx +8 -9
- package/docs/api-reference/workflow-api/register-lifecycle-hooks.mdx +87 -0
- 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 +107 -12
- 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-force-claimed-error.mdx +70 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +8 -8
- package/docs/api-reference/workflow-errors/index.mdx +91 -0
- package/docs/api-reference/workflow-errors/meta.json +7 -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 +13 -6
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +12 -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 +15 -11
- package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +37 -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 +46 -0
- package/docs/api-reference/workflow-nest/workflow-module.mdx +134 -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 +51 -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 +104 -35
- 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 +53 -41
- 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 +79 -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 +399 -0
- package/docs/configuration/worlds.mdx +315 -0
- package/docs/cookbook/advanced/child-workflows.mdx +33 -25
- package/docs/cookbook/advanced/publishing-libraries.mdx +65 -56
- package/docs/cookbook/advanced/serializable-steps.mdx +48 -68
- package/docs/cookbook/advanced/upgrading-workflows.mdx +35 -31
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +78 -60
- package/docs/cookbook/agent-patterns/durable-agent.mdx +23 -135
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +180 -195
- package/docs/cookbook/common-patterns/batching.mdx +20 -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 +30 -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 +27 -17
- package/docs/cookbook/index.mdx +22 -22
- package/docs/cookbook/integrations/ai-sdk.mdx +63 -48
- package/docs/cookbook/integrations/chat-sdk.mdx +46 -33
- package/docs/cookbook/integrations/sandbox.mdx +58 -45
- package/docs/deploying.mdx +106 -0
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +16 -12
- package/docs/errors/corrupted-event-log.mdx +39 -18
- package/docs/errors/deployment-mismatch.mdx +71 -0
- package/docs/errors/fetch-in-workflow.mdx +15 -14
- package/docs/errors/hook-conflict.mdx +38 -11
- package/docs/errors/hook-force-claimed.mdx +96 -0
- package/docs/errors/index.mdx +24 -37
- 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 +54 -11
- package/docs/foundations/hooks.mdx +98 -35
- package/docs/foundations/idempotency.mdx +267 -12
- package/docs/foundations/index.mdx +1 -26
- package/docs/foundations/serialization.mdx +22 -22
- package/docs/foundations/starting-workflows.mdx +104 -30
- package/docs/foundations/streaming.mdx +108 -60
- package/docs/foundations/versioning.mdx +4 -4
- 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 +264 -21
- package/docs/getting-started/next.mdx +18 -14
- package/docs/getting-started/nitro.mdx +22 -18
- package/docs/getting-started/nuxt.mdx +15 -11
- package/docs/getting-started/python.mdx +190 -41
- 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 +82 -66
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +132 -35
- 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 +4 -2
- package/docs/observability/attributes.mdx +91 -21
- package/docs/observability/index.mdx +29 -15
- package/docs/observability/lifecycle-hooks.mdx +95 -0
- package/docs/observability/meta.json +1 -1
- package/docs/observability/retention.mdx +95 -0
- package/docs/observability/tracing.mdx +124 -0
- package/docs/testing/index.mdx +120 -38
- package/docs/testing/server-based.mdx +10 -10
- package/docs/whats-new.mdx +190 -0
- package/docs/worlds/building-a-world.mdx +538 -0
- package/docs/worlds/local.mdx +129 -0
- package/docs/worlds/meta.json +10 -0
- package/docs/worlds/postgres.mdx +424 -0
- package/docs/worlds/upgrading-to-v5.mdx +162 -0
- package/docs/worlds/vercel.mdx +345 -0
- package/package.json +17 -14
- package/docs/api-reference/workflow/experimental-set-attributes.mdx +0 -63
- 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 -181
- 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 -358
- package/docs/migration-guides/migrating-from-inngest.mdx +0 -304
- package/docs/migration-guides/migrating-from-temporal.mdx +0 -313
- package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -328
|
@@ -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,12 +28,13 @@ 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`
|
|
35
35
|
- `ArrayBuffer`
|
|
36
36
|
- `BigInt64Array`, `BigUint64Array`
|
|
37
|
+
- `DataView`
|
|
37
38
|
- `Date`
|
|
38
39
|
- `Float32Array`, `Float64Array`
|
|
39
40
|
- `Int8Array`, `Int16Array`, `Int32Array`
|
|
@@ -58,7 +59,7 @@ These types have special handling and are explained in detail in the sections be
|
|
|
58
59
|
- `AbortController`
|
|
59
60
|
- `AbortSignal`
|
|
60
61
|
|
|
61
|
-
## Pass-by-
|
|
62
|
+
## Pass-by-value semantics
|
|
62
63
|
|
|
63
64
|
**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
65
|
|
|
@@ -81,7 +82,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
81
82
|
}
|
|
82
83
|
```
|
|
83
84
|
|
|
84
|
-
**Correct
|
|
85
|
+
**Correct, return the modified data:**
|
|
85
86
|
|
|
86
87
|
```typescript title="workflows/correct-mutation.ts" lineNumbers
|
|
87
88
|
export async function updateUserWorkflow(userId: string) {
|
|
@@ -100,7 +101,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
100
101
|
}
|
|
101
102
|
```
|
|
102
103
|
|
|
103
|
-
**Custom
|
|
104
|
+
**Custom classes:**
|
|
104
105
|
|
|
105
106
|
- Class instances that implement [`WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE`](#custom-class-serialization)
|
|
106
107
|
|
|
@@ -110,7 +111,7 @@ async function updateUserStep(user: { id: string; name: string; email: string })
|
|
|
110
111
|
|
|
111
112
|
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
113
|
|
|
113
|
-
## Request &
|
|
114
|
+
## Request & response
|
|
114
115
|
|
|
115
116
|
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
117
|
and can be passed around between workflow and step functions similarly to other data types.
|
|
@@ -140,7 +141,7 @@ export async function handleWebhookWorkflow() {
|
|
|
140
141
|
}
|
|
141
142
|
```
|
|
142
143
|
|
|
143
|
-
### Using `fetch` in
|
|
144
|
+
### Using `fetch` in workflows
|
|
144
145
|
|
|
145
146
|
Because `Request` and `Response` are serializable, Workflow SDK provides a `fetch` function that can be used directly in workflow functions:
|
|
146
147
|
|
|
@@ -158,7 +159,7 @@ export async function apiWorkflow() {
|
|
|
158
159
|
}
|
|
159
160
|
```
|
|
160
161
|
|
|
161
|
-
The
|
|
162
|
+
The `fetch` implementation from `workflow` is a step function that wraps the standard `fetch`:
|
|
162
163
|
|
|
163
164
|
```typescript title="Implementation" lineNumbers
|
|
164
165
|
export async function fetch(...args: Parameters<typeof globalThis.fetch>) {
|
|
@@ -202,11 +203,11 @@ async function fetchData(signal: AbortSignal) {
|
|
|
202
203
|
|
|
203
204
|
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
205
|
|
|
205
|
-
## Custom
|
|
206
|
+
## Custom class serialization
|
|
206
207
|
|
|
207
208
|
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
209
|
|
|
209
|
-
### Basic
|
|
210
|
+
### Basic example
|
|
210
211
|
|
|
211
212
|
{/* @expect-error:2351 */}
|
|
212
213
|
|
|
@@ -256,13 +257,13 @@ async function doublePoint(point: Point) {
|
|
|
256
257
|
}
|
|
257
258
|
```
|
|
258
259
|
|
|
259
|
-
### How
|
|
260
|
+
### How it works
|
|
260
261
|
|
|
261
262
|
1. **`WORKFLOW_SERIALIZE`**: A static method that receives a class instance and returns serializable data (primitives, plain objects, arrays, etc.)
|
|
262
263
|
|
|
263
264
|
2. **`WORKFLOW_DESERIALIZE`**: A static method that receives the serialized data and returns a new class instance
|
|
264
265
|
|
|
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
|
|
266
|
+
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
267
|
|
|
267
268
|
### Requirements
|
|
268
269
|
|
|
@@ -279,12 +280,12 @@ The `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` methods run inside the workf
|
|
|
279
280
|
- No non-deterministic operations (like `Math.random()` or `Date.now()`)
|
|
280
281
|
- No external network calls
|
|
281
282
|
|
|
282
|
-
Keep these methods
|
|
283
|
+
Keep these methods focused on data transformation only.
|
|
283
284
|
</Callout>
|
|
284
285
|
|
|
285
|
-
### Instance
|
|
286
|
+
### Instance methods as steps
|
|
286
287
|
|
|
287
|
-
In practice, many classes have methods that need Node.js APIs, perform network calls, or interact with databases
|
|
288
|
+
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
289
|
|
|
289
290
|
This requires the class to implement `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE`, so that the instance can be passed to the step execution context.
|
|
290
291
|
|
|
@@ -301,7 +302,7 @@ class Order {
|
|
|
301
302
|
public createdAt: Date
|
|
302
303
|
) {}
|
|
303
304
|
|
|
304
|
-
// Custom serialization
|
|
305
|
+
// Custom serialization: data must be serializable types
|
|
305
306
|
static [WORKFLOW_SERIALIZE](instance: Order) { // [!code highlight]
|
|
306
307
|
return { // [!code highlight]
|
|
307
308
|
id: instance.id, // [!code highlight]
|
|
@@ -329,7 +330,7 @@ class Order {
|
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
// Instance methods with "use step" run as step functions
|
|
332
|
-
// with full Node.js access
|
|
333
|
+
// with full Node.js access; `this` is automatically serialized
|
|
333
334
|
async save(): Promise<void> {
|
|
334
335
|
"use step"; // [!code highlight]
|
|
335
336
|
await db.orders.insert({ // [!code highlight]
|
|
@@ -355,7 +356,7 @@ class Order {
|
|
|
355
356
|
}
|
|
356
357
|
```
|
|
357
358
|
|
|
358
|
-
The class can then be used naturally inside a workflow function. Instance methods marked with `"use step"` are each executed as a step
|
|
359
|
+
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
360
|
|
|
360
361
|
{/* @expect-error:2693 */}
|
|
361
362
|
|
|
@@ -369,7 +370,7 @@ export async function processOrderWorkflow(
|
|
|
369
370
|
|
|
370
371
|
const order = new Order(orderId, items, new Date()); // [!code highlight]
|
|
371
372
|
|
|
372
|
-
// Runs in the workflow context
|
|
373
|
+
// Runs in the workflow context; no "use step" needed
|
|
373
374
|
const itemCount = order.total(); // [!code highlight]
|
|
374
375
|
|
|
375
376
|
// Each "use step" instance method call runs as a separate step
|
|
@@ -380,7 +381,7 @@ export async function processOrderWorkflow(
|
|
|
380
381
|
}
|
|
381
382
|
```
|
|
382
383
|
|
|
383
|
-
|
|
384
|
+
[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
385
|
|
|
385
386
|
{/* @expect-error:2351 */}
|
|
386
387
|
|
|
@@ -408,4 +409,3 @@ export async function processOrderWorkflow() {
|
|
|
408
409
|
order = await order.addItem("Widget", 3); // [!code highlight]
|
|
409
410
|
}
|
|
410
411
|
```
|
|
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,20 +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">
|
|
45
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).
|
|
46
47
|
</Callout>
|
|
47
48
|
|
|
48
|
-
## The `Run`
|
|
49
|
+
## The `Run` object
|
|
49
50
|
|
|
50
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.
|
|
51
52
|
|
|
@@ -65,24 +66,55 @@ const status = await run.status; // "running" | "completed" | "failed"
|
|
|
65
66
|
const result = await run.returnValue;
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
**Key
|
|
69
|
+
**Key properties:**
|
|
69
70
|
|
|
70
|
-
- `runId
|
|
71
|
-
- `status
|
|
72
|
-
- `returnValue
|
|
73
|
-
- `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
|
|
74
75
|
|
|
75
76
|
<Callout type="info">
|
|
76
|
-
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.
|
|
77
78
|
</Callout>
|
|
78
79
|
|
|
79
|
-
**Learn more**: [`Run` API
|
|
80
|
+
**Learn more**: [`Run` API reference](/docs/api-reference/workflow-api/start#returns)
|
|
80
81
|
|
|
81
|
-
## Common
|
|
82
|
+
## Common patterns
|
|
82
83
|
|
|
83
|
-
###
|
|
84
|
+
### Starting workflows from workflow functions
|
|
84
85
|
|
|
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]
|
|
96
|
+
|
|
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
|
+
```
|
|
102
|
+
|
|
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.
|
|
104
|
+
|
|
105
|
+
If the child run fails or is canceled, `await childRun.returnValue` throws [`WorkflowRunFailedError`](/docs/api-reference/workflow-errors/workflow-run-failed-error) or [`WorkflowRunCancelledError`](/docs/api-reference/workflow-errors/workflow-run-cancelled-error) on the first attempt.
|
|
106
|
+
|
|
107
|
+
<Callout type="info">
|
|
108
|
+
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.
|
|
109
|
+
</Callout>
|
|
110
|
+
|
|
111
|
+
<Callout type="warn">
|
|
112
|
+
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).
|
|
113
|
+
</Callout>
|
|
114
|
+
|
|
115
|
+
### Fire and forget
|
|
116
|
+
|
|
117
|
+
Start a workflow and immediately return to let it execute in the background:
|
|
86
118
|
|
|
87
119
|
```typescript lineNumbers
|
|
88
120
|
import { start } from "workflow/api";
|
|
@@ -100,7 +132,7 @@ export async function POST(request: Request) {
|
|
|
100
132
|
}
|
|
101
133
|
```
|
|
102
134
|
|
|
103
|
-
### Wait for
|
|
135
|
+
### Wait for completion
|
|
104
136
|
|
|
105
137
|
If you need to wait for the workflow to complete before responding:
|
|
106
138
|
|
|
@@ -119,12 +151,12 @@ export async function POST(request: Request) {
|
|
|
119
151
|
```
|
|
120
152
|
|
|
121
153
|
<Callout type="warn">
|
|
122
|
-
|
|
154
|
+
Waiting for `returnValue` can cause your API route to time out if the workflow takes a long time.
|
|
123
155
|
</Callout>
|
|
124
156
|
|
|
125
|
-
### Stream
|
|
157
|
+
### Stream updates to client
|
|
126
158
|
|
|
127
|
-
Stream
|
|
159
|
+
Stream updates from your workflow as it executes without waiting for completion:
|
|
128
160
|
|
|
129
161
|
```typescript lineNumbers
|
|
130
162
|
import { start } from "workflow/api";
|
|
@@ -148,7 +180,7 @@ export async function POST(request: Request) {
|
|
|
148
180
|
}
|
|
149
181
|
```
|
|
150
182
|
|
|
151
|
-
Your workflow can
|
|
183
|
+
Your workflow can write to the stream using [`getWritable()`](/docs/api-reference/workflow/get-writable):
|
|
152
184
|
|
|
153
185
|
```typescript lineNumbers
|
|
154
186
|
import { getWritable } from "workflow";
|
|
@@ -182,12 +214,12 @@ async function streamContentToClient(
|
|
|
182
214
|
```
|
|
183
215
|
|
|
184
216
|
<Callout type="info">
|
|
185
|
-
|
|
217
|
+
Use streams to show users real-time progress from AI workflows or intermediate results from long-running processes.
|
|
186
218
|
</Callout>
|
|
187
219
|
|
|
188
|
-
**Learn more**: [Streaming in
|
|
220
|
+
**Learn more**: [Streaming in workflows](/docs/foundations/serialization#streaming)
|
|
189
221
|
|
|
190
|
-
### Check
|
|
222
|
+
### Check status later
|
|
191
223
|
|
|
192
224
|
You can retrieve a workflow run later using its `runId` with [`getRun()`](/docs/api-reference/workflow-api/get-run):
|
|
193
225
|
|
|
@@ -213,10 +245,52 @@ export async function GET(request: Request) {
|
|
|
213
245
|
}
|
|
214
246
|
```
|
|
215
247
|
|
|
216
|
-
|
|
248
|
+
### Recursive and repeating workflows
|
|
249
|
+
|
|
250
|
+
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.
|
|
251
|
+
|
|
252
|
+
```typescript lineNumbers
|
|
253
|
+
import { start } from "workflow/api";
|
|
254
|
+
declare function fetchBatch(cursor?: string): Promise<{ items: string[]; nextCursor?: string }>; // @setup
|
|
255
|
+
declare function processBatch(items: string[]): Promise<void>; // @setup
|
|
256
|
+
|
|
257
|
+
export async function processQueue(cursor?: string) {
|
|
258
|
+
"use workflow";
|
|
259
|
+
|
|
260
|
+
const { items, nextCursor } = await fetchBatch(cursor);
|
|
261
|
+
await processBatch(items);
|
|
262
|
+
|
|
263
|
+
if (nextCursor) {
|
|
264
|
+
// Continue processing in a new workflow run
|
|
265
|
+
await start(processQueue, [nextCursor]); // [!code highlight]
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
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:
|
|
271
|
+
|
|
272
|
+
```typescript lineNumbers
|
|
273
|
+
import { sleep } from "workflow";
|
|
274
|
+
import { start } from "workflow/api";
|
|
275
|
+
declare function refreshMetrics(): Promise<void>; // @setup
|
|
276
|
+
|
|
277
|
+
export async function syncDashboard() {
|
|
278
|
+
"use workflow";
|
|
279
|
+
|
|
280
|
+
await refreshMetrics();
|
|
281
|
+
await sleep("1h");
|
|
282
|
+
|
|
283
|
+
// Schedule the next run
|
|
284
|
+
await start(syncDashboard); // [!code highlight]
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### Starting against the latest deployment
|
|
289
|
+
|
|
290
|
+
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.
|
|
217
291
|
|
|
218
|
-
|
|
292
|
+
## Next steps
|
|
219
293
|
|
|
220
294
|
- Browse the [Cookbook](/cookbook) for copy-paste recipes covering composition, scheduling, timeouts, and more
|
|
221
|
-
- Explore [Errors
|
|
222
|
-
- Check the [`start()` API
|
|
295
|
+
- Explore [Errors and retrying](/docs/foundations/errors-and-retries) to handle failures
|
|
296
|
+
- Check the [`start()` API reference](/docs/api-reference/workflow-api/start) for complete details
|