workflow 5.0.0-beta.14 → 5.0.0-beta.16
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/docs/api-reference/index.mdx +24 -0
- package/docs/api-reference/meta.json +8 -0
- package/docs/api-reference/vitest/index.mdx +1 -7
- package/docs/api-reference/workflow/create-hook.mdx +38 -0
- package/docs/api-reference/workflow/create-webhook.mdx +1 -0
- package/docs/api-reference/workflow/experimental-set-attributes.mdx +3 -1
- package/docs/api-reference/workflow/fetch.mdx +5 -0
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +7 -0
- package/docs/api-reference/workflow-api/get-run.mdx +6 -0
- package/docs/api-reference/workflow-api/index.mdx +6 -8
- package/docs/api-reference/workflow-api/resume-hook.mdx +57 -0
- package/docs/api-reference/workflow-api/start.mdx +6 -1
- 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/hook-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/index.mdx +85 -0
- package/docs/api-reference/workflow-errors/meta.json +5 -0
- package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
- 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-nitro/index.mdx +59 -0
- package/docs/api-reference/workflow-nuxt/index.mdx +47 -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 +64 -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 +7 -10
- package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
- package/docs/api-reference/workflow-runtime/index.mdx +43 -0
- package/docs/api-reference/workflow-runtime/meta.json +12 -0
- package/docs/api-reference/workflow-runtime/set-world.mdx +49 -0
- package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +42 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/index.mdx +5 -8
- package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/queue.mdx +2 -2
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +11 -4
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +2 -2
- package/docs/api-reference/workflow-serde/index.mdx +0 -1
- package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +1 -2
- package/docs/api-reference/workflow-serde/workflow-serialize.mdx +1 -2
- 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 +15 -3
- package/docs/changelog/eager-processing.mdx +26 -6
- package/docs/changelog/index.mdx +1 -1
- package/docs/cookbook/advanced/child-workflows.mdx +3 -1
- package/docs/cookbook/advanced/publishing-libraries.mdx +13 -12
- package/docs/cookbook/advanced/serializable-steps.mdx +3 -3
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +2 -2
- package/docs/cookbook/common-patterns/idempotency.mdx +36 -52
- package/docs/cookbook/common-patterns/rate-limiting.mdx +1 -1
- package/docs/cookbook/common-patterns/saga.mdx +2 -2
- package/docs/cookbook/common-patterns/scheduling.mdx +4 -0
- package/docs/cookbook/common-patterns/timeouts.mdx +2 -1
- package/docs/cookbook/common-patterns/workflow-composition.mdx +6 -0
- package/docs/cookbook/index.mdx +1 -1
- package/docs/cookbook/integrations/ai-sdk.mdx +10 -1
- package/docs/cookbook/integrations/chat-sdk.mdx +9 -0
- package/docs/cookbook/integrations/sandbox.mdx +9 -0
- package/docs/errors/step-not-registered.mdx +1 -1
- package/docs/foundations/cancellation.mdx +1 -2
- package/docs/foundations/hooks.mdx +29 -0
- package/docs/foundations/idempotency.mdx +236 -11
- package/docs/foundations/streaming.mdx +1 -1
- package/docs/foundations/versioning.mdx +1 -1
- package/docs/how-it-works/encryption.mdx +2 -2
- package/docs/how-it-works/event-sourcing.mdx +2 -2
- package/docs/migration-guides/migrating-from-temporal.mdx +1 -1
- package/docs/observability/attributes.mdx +26 -5
- package/docs/testing/index.mdx +2 -2
- package/package.json +10 -10
- package/docs/api-reference/workflow-api/world/meta.json +0 -4
- package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: workflowEntrypoint
|
|
3
|
+
description: Create the HTTP route handler that executes workflow runs from a workflow bundle.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Use workflowEntrypoint to wire a compiled workflow bundle into an HTTP route in custom server environments.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/how-it-works/code-transform
|
|
8
|
+
related:
|
|
9
|
+
- /docs/api-reference/workflow-runtime/health-check
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Creates the HTTP route handler that executes workflow runs. The handler receives queue messages, replays the workflow from its event log, executes steps inline where possible, and suspends when the workflow waits on sleeps or hooks.
|
|
13
|
+
|
|
14
|
+
Framework adapters (Next.js, Nitro, SvelteKit, etc.) call this for you and mount the result at `/.well-known/workflow/v1/flow` — you only need it when wiring workflow support into a custom server environment.
|
|
15
|
+
|
|
16
|
+
```typescript lineNumbers
|
|
17
|
+
import { workflowEntrypoint } from "workflow/runtime";
|
|
18
|
+
declare const workflowBundleCode: string; // @setup
|
|
19
|
+
|
|
20
|
+
const handler = workflowEntrypoint(workflowBundleCode); // [!code highlight]
|
|
21
|
+
|
|
22
|
+
// Mount on your server, e.g. a fetch-style route:
|
|
23
|
+
export const POST = (req: Request) => handler(req);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API Signature
|
|
27
|
+
|
|
28
|
+
### Parameters
|
|
29
|
+
|
|
30
|
+
| Parameter | Type | Description |
|
|
31
|
+
|-----------|------|-------------|
|
|
32
|
+
| `workflowCode` | `string` | The compiled workflow bundle code containing all workflow functions |
|
|
33
|
+
| `options` | `{ namespace?: string }` | Optional. `namespace` scopes the queue topics this handler consumes. |
|
|
34
|
+
|
|
35
|
+
### Returns
|
|
36
|
+
|
|
37
|
+
Returns a fetch-style request handler: `(req: Request) => Promise<Response>`.
|
|
38
|
+
|
|
39
|
+
## Related Functions
|
|
40
|
+
|
|
41
|
+
- [`getWorldHandlers()`](/docs/api-reference/workflow-runtime/get-world-handlers) - The build-time World access this handler is built on.
|
|
42
|
+
- [`healthCheck()`](/docs/api-reference/workflow-runtime/health-check) - Verify the entrypoint processes queue messages end-to-end.
|
|
@@ -4,7 +4,7 @@ description: Low-level API for inspecting and managing workflow runs, steps, eve
|
|
|
4
4
|
type: overview
|
|
5
5
|
summary: Access workflow infrastructure via await getWorld() for building observability dashboards, admin tools, and custom integrations.
|
|
6
6
|
prerequisites:
|
|
7
|
-
- /docs/api-reference/workflow-
|
|
7
|
+
- /docs/api-reference/workflow-runtime/get-world
|
|
8
8
|
keywords:
|
|
9
9
|
- getWorld
|
|
10
10
|
- World SDK
|
|
@@ -25,18 +25,15 @@ const world = await getWorld(); // [!code highlight]
|
|
|
25
25
|
## Interfaces
|
|
26
26
|
|
|
27
27
|
<Cards>
|
|
28
|
-
<Card href="/docs/api-reference/workflow-
|
|
28
|
+
<Card href="/docs/api-reference/workflow-runtime/world/storage" title="Storage">
|
|
29
29
|
Query runs, steps, hooks, and the underlying event log.
|
|
30
30
|
</Card>
|
|
31
|
-
<Card href="/docs/api-reference/workflow-
|
|
31
|
+
<Card href="/docs/api-reference/workflow-runtime/world/streams" title="Streams">
|
|
32
32
|
Read, write, and manage real-time data streams for workflow runs.
|
|
33
33
|
</Card>
|
|
34
|
-
<Card href="/docs/api-reference/workflow-
|
|
34
|
+
<Card href="/docs/api-reference/workflow-runtime/world/queue" title="Queue">
|
|
35
35
|
Low-level queue dispatch (internal SDK infrastructure).
|
|
36
36
|
</Card>
|
|
37
|
-
<Card href="/docs/api-reference/workflow-api/world/observability" title="Observability Utilities">
|
|
38
|
-
Hydrate step I/O, parse display names, and decrypt workflow data.
|
|
39
|
-
</Card>
|
|
40
37
|
</Cards>
|
|
41
38
|
|
|
42
39
|
<Callout type="info">
|
|
@@ -55,4 +52,4 @@ const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highl
|
|
|
55
52
|
console.log(hydrated.input, hydrated.output);
|
|
56
53
|
```
|
|
57
54
|
|
|
58
|
-
See [
|
|
55
|
+
See [`workflow/observability`](/docs/api-reference/workflow-observability) for the full API.
|
|
@@ -4,7 +4,7 @@ description: Low-level queue interface for dispatching workflow and step invocat
|
|
|
4
4
|
type: reference
|
|
5
5
|
summary: "Methods: getDeploymentId(), queue(), createQueueHandler(). Internal queue dispatch — normally handled by the SDK."
|
|
6
6
|
prerequisites:
|
|
7
|
-
- /docs/api-reference/workflow-
|
|
7
|
+
- /docs/api-reference/workflow-runtime/get-world
|
|
8
8
|
related:
|
|
9
9
|
- /docs/api-reference/workflow-api/start
|
|
10
10
|
- /docs/foundations/starting-workflows
|
|
@@ -83,4 +83,4 @@ const handler = world.createQueueHandler(prefix, callback); // [!code highlight]
|
|
|
83
83
|
|
|
84
84
|
- [start()](/docs/api-reference/workflow-api/start) — The standard way to start workflow runs
|
|
85
85
|
- [Starting Workflows](/docs/foundations/starting-workflows) — Core concepts for workflow invocation
|
|
86
|
-
- [Storage](/docs/api-reference/workflow-
|
|
86
|
+
- [Storage](/docs/api-reference/workflow-runtime/world/storage) — Create events that trigger queue dispatch
|
|
@@ -4,11 +4,11 @@ description: Query workflow runs, steps, hooks, and the underlying event log via
|
|
|
4
4
|
type: reference
|
|
5
5
|
summary: "Interfaces: world.events, world.runs, world.steps, world.hooks. Events are the source of truth; runs, steps, and hooks are materialized views."
|
|
6
6
|
prerequisites:
|
|
7
|
-
- /docs/api-reference/workflow-
|
|
7
|
+
- /docs/api-reference/workflow-runtime/get-world
|
|
8
8
|
related:
|
|
9
9
|
- /docs/api-reference/workflow-api/get-run
|
|
10
10
|
- /docs/how-it-works/event-sourcing
|
|
11
|
-
- /docs/api-reference/workflow-
|
|
11
|
+
- /docs/api-reference/workflow-observability
|
|
12
12
|
keywords:
|
|
13
13
|
- world.events
|
|
14
14
|
- world.runs
|
|
@@ -116,6 +116,7 @@ const result = await world.events.listByCorrelationId({ // [!code highlight]
|
|
|
116
116
|
| Category | Types |
|
|
117
117
|
|----------|-------|
|
|
118
118
|
| Run | `run_created`, `run_started`, `run_completed`, `run_failed`, `run_cancelled` |
|
|
119
|
+
| Attribute | `attr_set` |
|
|
119
120
|
| Step | `step_created`, `step_started`, `step_completed`, `step_failed`, `step_retrying` |
|
|
120
121
|
| Hook | `hook_created`, `hook_received`, `hook_disposed`, `hook_conflict` |
|
|
121
122
|
| Wait | `wait_created`, `wait_completed` |
|
|
@@ -229,7 +230,7 @@ const result = await world.steps.list({ // [!code highlight]
|
|
|
229
230
|
| `retryAfter` | `string \| null` | ISO timestamp for next retry attempt |
|
|
230
231
|
|
|
231
232
|
<Callout type="info">
|
|
232
|
-
Step I/O is serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Use `hydrateResourceIO()` from `workflow/observability` to deserialize it for display. See [
|
|
233
|
+
Step I/O is serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Use `hydrateResourceIO()` from `workflow/observability` to deserialize it for display. See [`hydrateResourceIO()`](/docs/api-reference/workflow-observability/hydrate-resource-io).
|
|
233
234
|
</Callout>
|
|
234
235
|
|
|
235
236
|
<Callout type="warn">
|
|
@@ -258,6 +259,12 @@ const hook = await world.hooks.get(hookId); // [!code highlight]
|
|
|
258
259
|
|
|
259
260
|
Look up a hook by its token. Useful in webhook resume flows where you receive a token in the callback URL.
|
|
260
261
|
|
|
262
|
+
<Callout type="info">
|
|
263
|
+
For runtime application code, prefer [`getHookByToken()`](/docs/api-reference/workflow-api/get-hook-by-token). Use `world.hooks.getByToken()` when you are working directly with the World storage interface for custom tooling, admin views, or low-level integrations.
|
|
264
|
+
|
|
265
|
+
Hook-token lookup is the low-level form of the recommended idempotency flow: if a hook is already registered for your business key, reuse the hook's `runId` or resume that hook instead of starting another run. If no hook exists yet, start a workflow that creates the deterministic hook near the beginning and checks `await hook.getConflict()` to detect whether another run claimed the token first — on a conflict it resolves with the run that owns the token. See [Run idempotency](/docs/foundations/idempotency#run-idempotency).
|
|
266
|
+
</Callout>
|
|
267
|
+
|
|
261
268
|
```typescript lineNumbers
|
|
262
269
|
const hook = await world.hooks.getByToken(token); // [!code highlight]
|
|
263
270
|
```
|
|
@@ -402,7 +409,7 @@ for (const event of events.data) {
|
|
|
402
409
|
|
|
403
410
|
- [Event Sourcing](/docs/how-it-works/event-sourcing) — How the event log powers workflow replay and state
|
|
404
411
|
- [getRun()](/docs/api-reference/workflow-api/get-run) — Higher-level API for working with individual runs
|
|
405
|
-
- [
|
|
412
|
+
- [`workflow/observability`](/docs/api-reference/workflow-observability) — Hydrate step I/O and parse display names
|
|
406
413
|
- [resumeHook()](/docs/api-reference/workflow-api/resume-hook) — Resume a workflow by sending a payload to a hook
|
|
407
414
|
- [Hooks](/docs/foundations/hooks) — Core concepts for hooks and pause points
|
|
408
415
|
- [Workflows and Steps](/docs/foundations/workflows-and-steps) — Core concepts for steps
|
|
@@ -4,7 +4,7 @@ description: Read, write, and manage real-time data streams for workflow runs.
|
|
|
4
4
|
type: reference
|
|
5
5
|
summary: "Methods: streams.write(), streams.writeMulti(), streams.get(), streams.close(), streams.list(), streams.getChunks(), streams.getInfo(). Stream methods live on world.streams."
|
|
6
6
|
prerequisites:
|
|
7
|
-
- /docs/api-reference/workflow-
|
|
7
|
+
- /docs/api-reference/workflow-runtime/get-world
|
|
8
8
|
related:
|
|
9
9
|
- /docs/foundations/streaming
|
|
10
10
|
- /docs/api-reference/workflow/get-writable
|
|
@@ -213,4 +213,4 @@ do {
|
|
|
213
213
|
|
|
214
214
|
- [Streaming](/docs/foundations/streaming) — Core concepts for streaming data from workflows
|
|
215
215
|
- [getWritable()](/docs/api-reference/workflow/get-writable) — The standard way to write to streams from within steps
|
|
216
|
-
- [Storage](/docs/api-reference/workflow-
|
|
216
|
+
- [Storage](/docs/api-reference/workflow-runtime/world/storage) — Query runs, steps, hooks, and events
|
|
@@ -6,7 +6,6 @@ A symbol used to define custom deserialization for user-defined class instances.
|
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
|
-
{/* @expect-error:2351 */}
|
|
10
9
|
|
|
11
10
|
```typescript lineNumbers
|
|
12
11
|
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde";
|
|
@@ -26,7 +25,7 @@ class Point {
|
|
|
26
25
|
|
|
27
26
|
## API Signature
|
|
28
27
|
|
|
29
|
-
{/* @skip-typecheck */}
|
|
28
|
+
{/* @skip-typecheck: type-only signature snippet, not compilable code */}
|
|
30
29
|
|
|
31
30
|
```typescript
|
|
32
31
|
static [WORKFLOW_DESERIALIZE](data: SerializableData): T
|
|
@@ -6,7 +6,6 @@ A symbol used to define custom serialization for user-defined class instances. T
|
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
|
-
{/* @expect-error:2351 */}
|
|
10
9
|
|
|
11
10
|
```typescript lineNumbers
|
|
12
11
|
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde";
|
|
@@ -26,7 +25,7 @@ class Point {
|
|
|
26
25
|
|
|
27
26
|
## API Signature
|
|
28
27
|
|
|
29
|
-
{/* @skip-typecheck */}
|
|
28
|
+
{/* @skip-typecheck: type-only signature snippet, not compilable code */}
|
|
30
29
|
|
|
31
30
|
```typescript
|
|
32
31
|
static [WORKFLOW_SERIALIZE](instance: T): SerializableData
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "workflow/sveltekit"
|
|
3
|
+
description: SvelteKit integration for automatic workflow bundling via Vite.
|
|
4
|
+
type: overview
|
|
5
|
+
summary: Explore the SvelteKit integration for automatic workflow bundling and runtime support.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/getting-started/sveltekit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
SvelteKit integration for Workflow SDK that configures Vite to transform workflow code and build the workflow bundles.
|
|
11
|
+
|
|
12
|
+
## Functions
|
|
13
|
+
|
|
14
|
+
<Cards>
|
|
15
|
+
<Card title="workflowPlugin()" href="/docs/api-reference/workflow-sveltekit/workflow-plugin">
|
|
16
|
+
Vite plugin that transforms workflow code (`"use step"`/`"use workflow"` directives) in SvelteKit apps
|
|
17
|
+
</Card>
|
|
18
|
+
</Cards>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: workflowPlugin
|
|
3
|
+
description: Configure Vite to transform workflow directives in SvelteKit.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Add workflowPlugin to your Vite config to enable workflow directive transformation in SvelteKit apps.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/getting-started/sveltekit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Returns the Vite plugins that transform workflow code (`"use step"`/`"use workflow"` directives) and build the workflow bundles in a SvelteKit app.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
To enable `"use step"` and `"use workflow"` directives while developing locally or deploying to production, add `workflowPlugin()` to the `plugins` array of your Vite config.
|
|
15
|
+
|
|
16
|
+
```typescript title="vite.config.ts" lineNumbers
|
|
17
|
+
import { sveltekit } from "@sveltejs/kit/vite";
|
|
18
|
+
import { defineConfig } from "vite";
|
|
19
|
+
import { workflowPlugin } from "workflow/sveltekit"; // [!code highlight]
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
plugins: [sveltekit(), workflowPlugin()], // [!code highlight]
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API Signature
|
|
27
|
+
|
|
28
|
+
### Parameters
|
|
29
|
+
|
|
30
|
+
| Parameter | Type | Description |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `options` | `WorkflowPluginOptions` | Optional. Configures the workflow build. |
|
|
33
|
+
|
|
34
|
+
#### WorkflowPluginOptions
|
|
35
|
+
|
|
36
|
+
| Option | Type | Default | Description |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| `sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` | Controls source maps on generated workflow bundles. Accepts the same values as esbuild's `sourcemap` option. Set to `false` for smaller function bundles (useful for staying under the Vercel 250MB function size limit) at the cost of stack traces pointing at generated code. Can also be set via the `WORKFLOW_SOURCEMAP` environment variable. |
|
|
39
|
+
|
|
40
|
+
### Returns
|
|
41
|
+
|
|
42
|
+
Returns an array of Vite `Plugin` objects. Spread or pass the array directly to the `plugins` option of your Vite config — Vite flattens nested plugin arrays automatically.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "workflow/vite"
|
|
3
|
+
description: Vite plugin for automatic workflow bundling in Vite + Nitro apps.
|
|
4
|
+
type: overview
|
|
5
|
+
summary: Explore the Vite plugin for automatic workflow bundling and runtime support.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/getting-started/vite
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Vite integration for Workflow SDK. It wraps the [`workflow/nitro`](/docs/api-reference/workflow-nitro) module as a Vite plugin, for apps using Nitro's Vite plugin (`nitro/vite`).
|
|
11
|
+
|
|
12
|
+
## Functions
|
|
13
|
+
|
|
14
|
+
<Cards>
|
|
15
|
+
<Card title="workflow()" href="/docs/api-reference/workflow-vite/workflow">
|
|
16
|
+
Vite plugin that transforms workflow code (`"use step"`/`"use workflow"` directives) and configures the Nitro server
|
|
17
|
+
</Card>
|
|
18
|
+
</Cards>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: workflow
|
|
3
|
+
description: Configure Vite and Nitro to transform workflow directives.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Add the workflow plugin to your Vite config to enable workflow directive transformation in Vite + Nitro apps.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/getting-started/vite
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Returns the Vite plugins that transform workflow code (`"use step"`/`"use workflow"` directives) and configure the [`workflow/nitro`](/docs/api-reference/workflow-nitro) module on the Nitro server. It is designed to be used alongside `nitro()` from `nitro/vite`, which provides the server framework for API routes and deployment.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
To enable `"use step"` and `"use workflow"` directives while developing locally or deploying to production, add `workflow()` to the `plugins` array of your Vite config, together with `nitro()`.
|
|
15
|
+
|
|
16
|
+
```typescript title="vite.config.ts" lineNumbers
|
|
17
|
+
import { nitro } from "nitro/vite";
|
|
18
|
+
import { defineConfig } from "vite";
|
|
19
|
+
import { workflow } from "workflow/vite"; // [!code highlight]
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
plugins: [nitro(), workflow()], // [!code highlight]
|
|
23
|
+
nitro: {
|
|
24
|
+
serverDir: "./",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API Signature
|
|
30
|
+
|
|
31
|
+
### Parameters
|
|
32
|
+
|
|
33
|
+
| Parameter | Type | Description |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `options` | `ModuleOptions` | Optional. Forwarded to the `workflow/nitro` module as its module options. |
|
|
36
|
+
|
|
37
|
+
#### ModuleOptions
|
|
38
|
+
|
|
39
|
+
| Option | Type | Default | Description |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| `dirs` | `string[]` | — | Directories to scan for workflows and steps. By default, the `workflows/` directory is scanned from the project root and all layer source directories. |
|
|
42
|
+
| `typescriptPlugin` | `boolean` | `false` | Adds the `workflow` TypeScript plugin to the generated `tsconfig.json` for IDE IntelliSense. |
|
|
43
|
+
| `runtime` | `string` | — | Node.js runtime version for Vercel Functions (e.g. `'nodejs22.x'`, `'nodejs24.x'`). Only applies when deploying to Vercel. |
|
|
44
|
+
| `sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` | Controls source maps on generated workflow bundles. Accepts the same values as esbuild's `sourcemap` option. Set to `false` for smaller function bundles (useful for staying under the Vercel 250MB function size limit) at the cost of stack traces pointing at generated code. Can also be set via the `WORKFLOW_SOURCEMAP` environment variable. |
|
|
45
|
+
|
|
46
|
+
### Returns
|
|
47
|
+
|
|
48
|
+
Returns an array of Vite `Plugin` objects. Spread or pass the array directly to the `plugins` option of your Vite config — Vite flattens nested plugin arrays automatically.
|
|
@@ -9,6 +9,18 @@ This is a minimal, **experimental** subset of the [planned Workflow Attributes f
|
|
|
9
9
|
|
|
10
10
|
The MVP lets workflow code attach plaintext `string → string` metadata to a run, viewable in any observability surface that reads the `WorkflowRun` entity. It is deliberately narrow: write-only, no reads from inside a run, no list/filter endpoints, no event-log representation. The wire format and SDK surface are chosen so the full 5.0.0 implementation replaces this without source-level breaking changes for end users.
|
|
11
11
|
|
|
12
|
+
## Native v4 follow-up
|
|
13
|
+
|
|
14
|
+
The v4 implementation now completes the planned dispatch migration while preserving the experimental SDK name:
|
|
15
|
+
|
|
16
|
+
- `experimental_setAttributes()` appends a native `attr_set` event from workflow and step bodies instead of mutating through the internal step bridge.
|
|
17
|
+
- Native events carry writer attribution and are materialized immediately onto `run.attributes`.
|
|
18
|
+
- `start(workflow, args, { attributes })` seeds attributes on the initial `run_created` event, including the resilient-start creation path.
|
|
19
|
+
- The World spec is bumped to v4; attributes are supported for v4 runs rather than being backported into older run specifications.
|
|
20
|
+
- The direct server attributes endpoint remains available only as a deprecated compatibility path for clients that shipped with the MVP.
|
|
21
|
+
|
|
22
|
+
The remainder of this page documents the original MVP motivation and implementation.
|
|
23
|
+
|
|
12
24
|
## What MVP supports
|
|
13
25
|
|
|
14
26
|
- `experimental_setAttributes(record)` callable from a **workflow body** (`"use workflow"` function), dispatched via an internal `__builtin_set_attributes` step bridge so the mutation gets a `step_created → step_completed` event pair
|
|
@@ -296,13 +308,13 @@ End-to-end in `workbench/nextjs-turbopack` (exercises the full SWC plugin + work
|
|
|
296
308
|
- `Promise.all` of disjoint-key writes — every key persists
|
|
297
309
|
- Workflow throws after an awaited `experimental_setAttributes` — the attribute persists on the now-`failed` run (the per-run file lock on `run_failed` re-reads inside the critical section so the attribute snapshot survives the lifecycle write)
|
|
298
310
|
|
|
299
|
-
## Migration to
|
|
311
|
+
## Migration to native v4
|
|
300
312
|
|
|
301
|
-
|
|
313
|
+
The native attributes follow-up applies this migration:
|
|
302
314
|
|
|
303
315
|
- `experimental_setAttributes` (SDK) — unchanged signature, new dispatch path
|
|
304
316
|
- `runs.experimentalSetAttributes` (world interface) — deprecated, then removed; replaced by `events.create(runId, { eventType: 'attr_set', eventData: { changes, writer } })`
|
|
305
|
-
- Wire endpoint — `POST /v2/runs/:runId/attributes`
|
|
317
|
+
- Wire endpoint — `POST /v2/runs/:runId/attributes` is deprecated but temporarily retained for older clients; new calls post the same `changes` shape to events as `attr_set`
|
|
306
318
|
- Pre-existing attribute values on MVP-era runs remain on the run entity but are not represented in the event log
|
|
307
319
|
|
|
308
320
|
Skew protection means workflows started under the MVP will continue to run with the MVP dispatch path on their original deployment. New deployments use the new path. No in-place data migration is needed.
|
|
@@ -157,15 +157,35 @@ To prevent deadlock when polling is executed inline by the step executor, `Run#p
|
|
|
157
157
|
|
|
158
158
|
### Mixed Suspensions
|
|
159
159
|
|
|
160
|
-
A suspension may contain steps, hooks, and waits simultaneously. The handler creates events for all, then
|
|
160
|
+
A suspension may contain steps, hooks, and waits simultaneously. The handler creates events for all, then dispatches everything we are not running inline as a single parallel batch of queue messages:
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
```
|
|
163
|
+
ownedPendingSteps = pendingSteps.filter(owned by this handler)
|
|
164
|
+
inlineStep = ownedPendingSteps[0] // optional
|
|
165
|
+
|
|
166
|
+
dispatches = [
|
|
167
|
+
...for each non-inline pendingStep: queue stepId message (idempotency=correlationId),
|
|
168
|
+
...if soonest pending wait: queue delayed continuation
|
|
169
|
+
(delaySeconds=min(remaining, maxDelay),
|
|
170
|
+
idempotency=waitCorrelationId[:hop|:secondBucket]),
|
|
171
|
+
]
|
|
172
|
+
await Promise.all(dispatches)
|
|
173
|
+
|
|
174
|
+
if (!inlineStep) return
|
|
175
|
+
await executeStep(inlineStep)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The wait timer is queued as its own continuation rather than encoded in the handler's return value (`{ timeoutSeconds }`). This is what makes `Promise.race(step, sleep)` behave correctly: even when the inline step blocks the handler for the full step duration, the wait continuation fires in a separate function invocation. If the sleep wins, that parallel invocation observes `wait_completed` via the "complete elapsed waits" pass and finishes the run; if the step wins, the wait continuation fires later and no-ops on the terminal run via the existing terminal-event check.
|
|
179
|
+
|
|
180
|
+
Step queueing remains unconditional (covers crash recovery: if a prior handler wrote `step_created` but crashed before queueing, a later handler will queue it; idempotency keys dedupe redundant queues across concurrent handlers).
|
|
181
|
+
|
|
182
|
+
Wait continuations are likewise deduplicated, keyed on the wait's correlation ID: while a wait is pending, every replay pass over the run re-observes it and would otherwise enqueue another delayed continuation. A key is attached in all cases, since some worlds serialize key-less workflow messages per run, which would park the continuation behind the handler's own inline step execution.
|
|
183
|
+
|
|
184
|
+
Two situations deliver a continuation while its wait is still pending, and each varies the key so the re-enqueue isn't dropped by a world's dedupe window (which outlives the first delivery): waits longer than the maximum queue delay (23h, bounded by VQS's 24h message retention) are clamped and chained across hops, with the hop index suffixed to the key so each hop dedupes within its window but the chain always advances; and near-elapsed waits (≤2s remaining) use a second-bucketed key suffix so a continuation delivered marginally early (clock skew) can enqueue a fresh short-delay retry. See `runtime/wait-continuation.ts` for the full selection logic.
|
|
165
185
|
|
|
166
|
-
The
|
|
186
|
+
The retry/throttle and hook-conflict paths still return `{ timeoutSeconds }` since their semantics are "redeliver THIS message after a delay" rather than "schedule a fresh wait timer." Those can be unified in a follow-up.
|
|
167
187
|
|
|
168
|
-
|
|
188
|
+
The unified dispatch requires `world-local` to honor `delaySeconds` on the queue (added in the same PR series). Without it, the wait continuation would fire instantly in dev and trigger a spurious replay before the wait elapsed (recoverable via redelivery, but inefficient and observable as duplicate `step_started` events under contention).
|
|
169
189
|
|
|
170
190
|
### VM Sandboxing
|
|
171
191
|
|
package/docs/changelog/index.mdx
CHANGED
|
@@ -13,4 +13,4 @@ Stay up to date with the latest changes to Workflow SDK.
|
|
|
13
13
|
## 2026
|
|
14
14
|
|
|
15
15
|
- [Eager processing of steps and incremental event replay](/docs/changelog/eager-processing) - March 2026
|
|
16
|
-
-
|
|
16
|
+
- Serializable AbortController and AbortSignal — March 12, 2026
|
|
@@ -3,6 +3,8 @@ title: Child Workflows
|
|
|
3
3
|
description: Spawn child workflows from a parent and wait for completion via hook resume.
|
|
4
4
|
type: guide
|
|
5
5
|
summary: Orchestrate independent child workflows from a parent using start(), defineHook(), and startAndWait() — the child resumes the parent's hook when done instead of polling getRun().status.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-api/start
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
Use child workflows when a single workflow needs to orchestrate many independent units of work. Each child runs as its own workflow with a separate event log, retry boundary, and failure scope -- if one child fails, it doesn't take down the parent or siblings.
|
|
@@ -145,7 +147,7 @@ Polling with `getRun().status` in a `sleep()` loop works, but hook resume is pre
|
|
|
145
147
|
- **Zero compute while waiting** — the parent suspends on the hook instead of waking every poll interval
|
|
146
148
|
- **Immediate wake-up** — the parent resumes as soon as the child finishes, not on the next poll tick
|
|
147
149
|
- **Typed payloads** — the child sends `{ status, value | error }` directly; no separate `returnValue` fetch step
|
|
148
|
-
- **No worker-pool pressure** — `Run#returnValue` polling inside steps can hold worker slots while waiting for children (see [Eager Processing](/changelog/eager-processing))
|
|
150
|
+
- **No worker-pool pressure** — `Run#returnValue` polling inside steps can hold worker slots while waiting for children (see [Eager Processing](/docs/changelog/eager-processing))
|
|
149
151
|
|
|
150
152
|
When a parent calls a child workflow inline with `await` (flattened into the same run), the same wrapper and hook handshake still works — pass the token and `await processDocumentWithCompletion(...)` inside `startAndWait()` instead of calling `start()`.
|
|
151
153
|
|
|
@@ -270,14 +270,14 @@ Declare `workflow` as an **optional** peer so consumers without the runtime aren
|
|
|
270
270
|
|
|
271
271
|
### Runtime detection
|
|
272
272
|
|
|
273
|
-
Wrap a dynamic `import("workflow")` in try/catch. If either the module isn't installed *or* `
|
|
273
|
+
Wrap a dynamic `import("workflow")` in try/catch. If either the module isn't installed *or* `getStepMetadata()` throws (call site isn't inside a workflow step), fall through to the standalone path.
|
|
274
274
|
|
|
275
275
|
```typescript lineNumbers
|
|
276
|
-
async function
|
|
276
|
+
async function getWorkflowStepId(): Promise<string | null> { // [!code highlight]
|
|
277
277
|
try {
|
|
278
278
|
const wf = await import("workflow");
|
|
279
|
-
const {
|
|
280
|
-
return
|
|
279
|
+
const { stepId } = wf.getStepMetadata();
|
|
280
|
+
return stepId;
|
|
281
281
|
} catch {
|
|
282
282
|
return null;
|
|
283
283
|
}
|
|
@@ -286,13 +286,14 @@ async function getWorkflowRunId(): Promise<string | null> { // [!code highlight]
|
|
|
286
286
|
|
|
287
287
|
### A concrete use case: replay-safe idempotency keys
|
|
288
288
|
|
|
289
|
-
A payments utility that uses the workflow
|
|
289
|
+
A payments utility that uses the current workflow step ID as a Stripe idempotency key when available, and a fresh UUID otherwise:
|
|
290
290
|
|
|
291
|
-
{/* @skip-typecheck - depends on getWorkflowRunId defined in the previous block */}
|
|
292
291
|
```typescript lineNumbers
|
|
292
|
+
declare function getWorkflowStepId(): Promise<string | null>; // @setup (defined in the previous block)
|
|
293
|
+
|
|
293
294
|
export async function processPayment(amount: number, currency: string) {
|
|
294
|
-
const
|
|
295
|
-
const idempotencyKey =
|
|
295
|
+
const stepId = await getWorkflowStepId();
|
|
296
|
+
const idempotencyKey = stepId ? `payment:${stepId}` : crypto.randomUUID(); // [!code highlight]
|
|
296
297
|
|
|
297
298
|
const res = await fetch("https://api.stripe.com/v1/charges", {
|
|
298
299
|
method: "POST",
|
|
@@ -306,7 +307,7 @@ export async function processPayment(amount: number, currency: string) {
|
|
|
306
307
|
}
|
|
307
308
|
```
|
|
308
309
|
|
|
309
|
-
When called from inside a workflow
|
|
310
|
+
When called from inside a workflow step, the utility gets a stable idempotency key for that step across retries — Stripe dedupes retries for free. When called from a plain Node.js process, it behaves like any other function and a fresh UUID is generated. For more patterns, see [Idempotency](/docs/foundations/idempotency).
|
|
310
311
|
|
|
311
312
|
### In production
|
|
312
313
|
|
|
@@ -330,7 +331,7 @@ Before publishing a workflow library:
|
|
|
330
331
|
|
|
331
332
|
## Key APIs
|
|
332
333
|
|
|
333
|
-
- [`"use workflow"`](/docs/
|
|
334
|
-
- [`"use step"`](/docs/
|
|
335
|
-
- [`start`](/docs/api-reference/workflow/start) — starts a workflow run
|
|
334
|
+
- [`"use workflow"`](/docs/foundations/workflows-and-steps#workflow-functions) — declares the orchestrator function
|
|
335
|
+
- [`"use step"`](/docs/foundations/workflows-and-steps#step-functions) — marks functions for durable execution
|
|
336
|
+
- [`start`](/docs/api-reference/workflow-api/start) — starts a workflow run
|
|
336
337
|
- [`getWorkflowMetadata`](/docs/api-reference/workflow/get-workflow-metadata) — runtime detection and run ID access
|
|
@@ -6,7 +6,7 @@ summary: Return a callback from a step to defer construction of a non-owned clas
|
|
|
6
6
|
related:
|
|
7
7
|
- /docs/foundations/serialization
|
|
8
8
|
- /docs/foundations/serialization#custom-class-serialization
|
|
9
|
-
- /docs/
|
|
9
|
+
- /docs/foundations/workflows-and-steps#step-functions
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
<Callout>
|
|
@@ -141,7 +141,7 @@ async function uploadFile(
|
|
|
141
141
|
|
|
142
142
|
## Key APIs
|
|
143
143
|
|
|
144
|
-
- [`"use step"`](/docs/
|
|
145
|
-
- [`"use workflow"`](/docs/
|
|
144
|
+
- [`"use step"`](/docs/foundations/workflows-and-steps#step-functions) — marks a function for extraction and serialization
|
|
145
|
+
- [`"use workflow"`](/docs/foundations/workflows-and-steps#workflow-functions) — declares the orchestrator function
|
|
146
146
|
- [`DurableAgent`](/docs/api-reference/workflow-ai/durable-agent) — accepts a model factory for durable AI agent streaming
|
|
147
147
|
- [Custom class serialization](/docs/foundations/serialization#custom-class-serialization) — the companion pattern for classes you own (`WORKFLOW_SERIALIZE` / `WORKFLOW_DESERIALIZE`)
|
|
@@ -247,8 +247,8 @@ const approvalResult = messages
|
|
|
247
247
|
|
|
248
248
|
## Key APIs
|
|
249
249
|
|
|
250
|
-
- [`"use workflow"`](/docs/
|
|
251
|
-
- [`"use step"`](/docs/
|
|
250
|
+
- [`"use workflow"`](/docs/foundations/workflows-and-steps#workflow-functions) — declares the orchestrator function
|
|
251
|
+
- [`"use step"`](/docs/foundations/workflows-and-steps#step-functions) — declares step functions with retries
|
|
252
252
|
- [`defineHook()`](/docs/api-reference/workflow/define-hook) — type-safe hook with schema validation
|
|
253
253
|
- [`sleep()`](/docs/api-reference/workflow/sleep) — durable timeout for approval expiry
|
|
254
254
|
- [`getWritable()`](/docs/api-reference/workflow/get-writable) — stream custom data parts from steps
|