workflow 5.0.0-beta.34 → 5.0.0-beta.36
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/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/docs/api-reference/workflow/create-hook.mdx +43 -2
- package/docs/api-reference/workflow/define-hook.mdx +26 -24
- package/docs/api-reference/workflow/fatal-error.mdx +29 -7
- package/docs/api-reference/workflow/fetch.mdx +3 -4
- package/docs/api-reference/workflow/sleep.mdx +1 -1
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +2 -0
- package/docs/api-reference/workflow-api/resume-hook.mdx +2 -0
- package/docs/api-reference/workflow-api/resume-webhook.mdx +6 -4
- package/docs/api-reference/workflow-api/start.mdx +1 -1
- package/docs/api-reference/workflow-errors/index.mdx +3 -0
- package/docs/api-reference/workflow-errors/meta.json +1 -0
- package/docs/api-reference/workflow-errors/precondition-failed-error.mdx +62 -0
- package/docs/api-reference/workflow-nest/nest-local-builder.mdx +1 -1
- 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 +103 -0
- package/docs/configuration/runtime-tuning.mdx +26 -0
- package/docs/configuration/worlds.mdx +6 -7
- package/docs/cookbook/common-patterns/idempotency.mdx +1 -1
- package/docs/{deploying/index.mdx → deploying.mdx} +6 -8
- package/docs/foundations/hooks.mdx +1 -1
- package/docs/foundations/idempotency.mdx +16 -9
- package/docs/getting-started/astro.mdx +1 -1
- package/docs/getting-started/express.mdx +1 -1
- package/docs/getting-started/fastify.mdx +1 -1
- package/docs/getting-started/hono.mdx +1 -1
- package/docs/getting-started/index.mdx +10 -3
- package/docs/getting-started/meta.json +3 -1
- package/docs/getting-started/nestjs.mdx +63 -2
- package/docs/getting-started/next.mdx +2 -2
- package/docs/getting-started/nitro.mdx +1 -1
- package/docs/getting-started/nuxt.mdx +1 -1
- package/docs/getting-started/python.mdx +19 -17
- 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 +1 -1
- package/docs/getting-started/vite.mdx +1 -1
- package/docs/how-it-works/encryption.mdx +3 -3
- package/docs/how-it-works/event-sourcing.mdx +6 -6
- package/docs/how-it-works/framework-integrations.mdx +3 -3
- package/docs/meta.json +1 -1
- package/docs/observability/attributes.mdx +9 -0
- package/package.json +13 -11
- package/docs/deploying/building-a-world.mdx +0 -251
- package/docs/deploying/meta.json +0 -4
- package/docs/deploying/world/local-world.mdx +0 -101
- package/docs/deploying/world/meta.json +0 -4
- package/docs/deploying/world/postgres-world.mdx +0 -288
- package/docs/deploying/world/vercel-world.mdx +0 -275
- 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 -362
- package/docs/migration-guides/migrating-from-inngest.mdx +0 -308
- package/docs/migration-guides/migrating-from-temporal.mdx +0 -317
- package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -332
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: React Router v7
|
|
3
|
+
description: Add durable workflows to a React Router v7 framework-mode app using Nitro v3.
|
|
4
|
+
type: guide
|
|
5
|
+
summary: Enable the Vite Environment API and configure React Router v7, Nitro v3, and Workflow SDK.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/getting-started/react-router
|
|
8
|
+
related:
|
|
9
|
+
- /docs/getting-started/nitro
|
|
10
|
+
- /docs/foundations/workflows-and-steps
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
This guide starts with an existing React Router v7 framework-mode app. It is verified with v7.18.1; if your config does not recognize `v8_viteEnvironmentApi`, update to the latest v7 release.
|
|
14
|
+
|
|
15
|
+
<Steps>
|
|
16
|
+
|
|
17
|
+
<Step>
|
|
18
|
+
|
|
19
|
+
## Install Nitro and Workflow SDK
|
|
20
|
+
|
|
21
|
+
<Tabs items={["npm", "pnpm", "bun", "yarn"]} defaultValue="pnpm">
|
|
22
|
+
|
|
23
|
+
<Tab value="npm">
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install nitro workflow
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Tab>
|
|
30
|
+
|
|
31
|
+
<Tab value="pnpm">
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm add nitro workflow
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
</Tab>
|
|
38
|
+
|
|
39
|
+
<Tab value="bun">
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun add nitro workflow
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</Tab>
|
|
46
|
+
|
|
47
|
+
<Tab value="yarn">
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yarn add nitro workflow
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
</Tab>
|
|
54
|
+
|
|
55
|
+
</Tabs>
|
|
56
|
+
|
|
57
|
+
This integration requires Nitro v3.
|
|
58
|
+
|
|
59
|
+
</Step>
|
|
60
|
+
|
|
61
|
+
<Step>
|
|
62
|
+
|
|
63
|
+
## Enable the Vite Environment API
|
|
64
|
+
|
|
65
|
+
React Router v7 keeps the Vite Environment API behind a future flag. Enable the required flag and set an explicit build directory:
|
|
66
|
+
|
|
67
|
+
```typescript title="react-router.config.ts" lineNumbers
|
|
68
|
+
import type { Config } from "@react-router/dev/config";
|
|
69
|
+
|
|
70
|
+
export default {
|
|
71
|
+
ssr: true,
|
|
72
|
+
buildDirectory: "build", // [!code highlight]
|
|
73
|
+
future: {
|
|
74
|
+
v8_viteEnvironmentApi: true, // [!code highlight]
|
|
75
|
+
},
|
|
76
|
+
} satisfies Config;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
</Step>
|
|
80
|
+
|
|
81
|
+
<Step>
|
|
82
|
+
|
|
83
|
+
## Create the React Router server handler
|
|
84
|
+
|
|
85
|
+
Create `server/ssr.ts`:
|
|
86
|
+
|
|
87
|
+
```typescript title="server/ssr.ts" lineNumbers
|
|
88
|
+
import { createRequestHandler } from "react-router";
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
fetch: createRequestHandler(
|
|
92
|
+
() => import("virtual:react-router/server-build"),
|
|
93
|
+
import.meta.env.MODE,
|
|
94
|
+
),
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This adapts React Router's generated server build to the Fetch API handler Nitro expects.
|
|
99
|
+
|
|
100
|
+
</Step>
|
|
101
|
+
|
|
102
|
+
<Step>
|
|
103
|
+
|
|
104
|
+
## Configure Vite
|
|
105
|
+
|
|
106
|
+
Update `vite.config.ts`:
|
|
107
|
+
|
|
108
|
+
```typescript title="vite.config.ts" lineNumbers
|
|
109
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
110
|
+
import { nitro } from "nitro/vite";
|
|
111
|
+
import { defineConfig } from "vite";
|
|
112
|
+
import { workflow } from "workflow/vite";
|
|
113
|
+
import reactRouterConfig from "./react-router.config";
|
|
114
|
+
|
|
115
|
+
export default defineConfig({
|
|
116
|
+
plugins: [
|
|
117
|
+
reactRouter(),
|
|
118
|
+
nitro({
|
|
119
|
+
serverDir: "./server",
|
|
120
|
+
output: {
|
|
121
|
+
dir: reactRouterConfig.buildDirectory,
|
|
122
|
+
serverDir: `${reactRouterConfig.buildDirectory}/server`,
|
|
123
|
+
publicDir: `${reactRouterConfig.buildDirectory}/client`,
|
|
124
|
+
},
|
|
125
|
+
}),
|
|
126
|
+
workflow({ dirs: ["workflows"] }),
|
|
127
|
+
],
|
|
128
|
+
environments: {
|
|
129
|
+
ssr: {
|
|
130
|
+
build: {
|
|
131
|
+
rollupOptions: {
|
|
132
|
+
input: "./server/ssr.ts",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Keep `dirs: ["workflows"]` so subsequent builds do not scan generated files under `build`. Place `reactRouter()` before `nitro()` in the plugin array.
|
|
141
|
+
|
|
142
|
+
</Step>
|
|
143
|
+
|
|
144
|
+
<Step>
|
|
145
|
+
|
|
146
|
+
## Create a workflow
|
|
147
|
+
|
|
148
|
+
Create `workflows/greeting.ts`:
|
|
149
|
+
|
|
150
|
+
```typescript title="workflows/greeting.ts" lineNumbers
|
|
151
|
+
export async function greetingWorkflow(name: string) {
|
|
152
|
+
"use workflow";
|
|
153
|
+
|
|
154
|
+
return greet(name);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function greet(name: string) {
|
|
158
|
+
"use step";
|
|
159
|
+
|
|
160
|
+
return `Hello, ${name}!`;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
</Step>
|
|
165
|
+
|
|
166
|
+
<Step>
|
|
167
|
+
|
|
168
|
+
## Start the workflow from a Nitro route
|
|
169
|
+
|
|
170
|
+
Create `server/routes/api/greeting.post.ts`:
|
|
171
|
+
|
|
172
|
+
```typescript title="server/routes/api/greeting.post.ts" lineNumbers
|
|
173
|
+
import { defineHandler } from "nitro";
|
|
174
|
+
import { start } from "workflow/api";
|
|
175
|
+
import { greetingWorkflow } from "../../../workflows/greeting";
|
|
176
|
+
|
|
177
|
+
export default defineHandler(async (event) => {
|
|
178
|
+
const { name } = (await event.req.json()) as { name: string };
|
|
179
|
+
const run = await start(greetingWorkflow, [name]);
|
|
180
|
+
|
|
181
|
+
return { runId: run.runId };
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
React Router continues to handle your application routes. Nitro handles this server route at `POST /api/greeting`, as well as Workflow SDK's internal routes.
|
|
186
|
+
|
|
187
|
+
</Step>
|
|
188
|
+
|
|
189
|
+
<Step>
|
|
190
|
+
|
|
191
|
+
## Run the app
|
|
192
|
+
|
|
193
|
+
Start the development server:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
pnpm vite dev
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Then start a workflow:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
curl -X POST \
|
|
203
|
+
-H "content-type: application/json" \
|
|
204
|
+
-d '{"name":"Workflow"}' \
|
|
205
|
+
http://localhost:3000/api/greeting
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Build and start the production server:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
pnpm vite build
|
|
212
|
+
node ./build/server/index.mjs
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
You can inspect local runs with `pnpm workflow web`.
|
|
216
|
+
|
|
217
|
+
</Step>
|
|
218
|
+
|
|
219
|
+
</Steps>
|
|
220
|
+
|
|
221
|
+
## Troubleshooting
|
|
222
|
+
|
|
223
|
+
### Vite reports an invalid SSR input or `path.replace is not a function`
|
|
224
|
+
|
|
225
|
+
Set `future.v8_viteEnvironmentApi` to `true` in `react-router.config.ts`.
|
|
226
|
+
|
|
227
|
+
### React Router pages return 404
|
|
228
|
+
|
|
229
|
+
Check that the `ssr` environment input points to `./server/ssr.ts`.
|
|
230
|
+
|
|
231
|
+
### A second build tries to compile files under `build/server`
|
|
232
|
+
|
|
233
|
+
Use `workflow({ dirs: ["workflows"] })`, remove the existing `build` directory once, and rebuild.
|
|
234
|
+
|
|
235
|
+
### `vite build` finishes output but does not exit
|
|
236
|
+
|
|
237
|
+
Use `workflow@5.0.0-beta.33` or later with Nitro v3.
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: React Router v8
|
|
3
|
+
description: Add durable workflows to a React Router v8 framework-mode app using Nitro v3.
|
|
4
|
+
type: guide
|
|
5
|
+
summary: Configure React Router v8, Nitro v3, and Workflow SDK in one Vite build.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/getting-started/react-router
|
|
8
|
+
related:
|
|
9
|
+
- /docs/getting-started/nitro
|
|
10
|
+
- /docs/foundations/workflows-and-steps
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
This guide starts with an existing React Router v8 framework-mode app.
|
|
14
|
+
|
|
15
|
+
<Steps>
|
|
16
|
+
|
|
17
|
+
<Step>
|
|
18
|
+
|
|
19
|
+
## Install Nitro and Workflow SDK
|
|
20
|
+
|
|
21
|
+
<Tabs items={["npm", "pnpm", "bun", "yarn"]} defaultValue="pnpm">
|
|
22
|
+
|
|
23
|
+
<Tab value="npm">
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install nitro workflow
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Tab>
|
|
30
|
+
|
|
31
|
+
<Tab value="pnpm">
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm add nitro workflow
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
</Tab>
|
|
38
|
+
|
|
39
|
+
<Tab value="bun">
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun add nitro workflow
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</Tab>
|
|
46
|
+
|
|
47
|
+
<Tab value="yarn">
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yarn add nitro workflow
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
</Tab>
|
|
54
|
+
|
|
55
|
+
</Tabs>
|
|
56
|
+
|
|
57
|
+
This integration requires Nitro v3.
|
|
58
|
+
|
|
59
|
+
</Step>
|
|
60
|
+
|
|
61
|
+
<Step>
|
|
62
|
+
|
|
63
|
+
## Use a shared build directory
|
|
64
|
+
|
|
65
|
+
Set an explicit build directory in your React Router config:
|
|
66
|
+
|
|
67
|
+
```typescript title="react-router.config.ts" lineNumbers
|
|
68
|
+
import type { Config } from "@react-router/dev/config";
|
|
69
|
+
|
|
70
|
+
export default {
|
|
71
|
+
ssr: true,
|
|
72
|
+
buildDirectory: "build", // [!code highlight]
|
|
73
|
+
} satisfies Config;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
React Router will place browser assets in `build/client`. Nitro will place the runnable server in `build/server`.
|
|
77
|
+
|
|
78
|
+
</Step>
|
|
79
|
+
|
|
80
|
+
<Step>
|
|
81
|
+
|
|
82
|
+
## Create the React Router server handler
|
|
83
|
+
|
|
84
|
+
Create `server/ssr.ts`:
|
|
85
|
+
|
|
86
|
+
```typescript title="server/ssr.ts" lineNumbers
|
|
87
|
+
import { createRequestHandler } from "react-router";
|
|
88
|
+
|
|
89
|
+
export default {
|
|
90
|
+
fetch: createRequestHandler(
|
|
91
|
+
() => import("virtual:react-router/server-build"),
|
|
92
|
+
import.meta.env.MODE,
|
|
93
|
+
),
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This adapts React Router's generated server build to the Fetch API handler Nitro expects.
|
|
98
|
+
|
|
99
|
+
</Step>
|
|
100
|
+
|
|
101
|
+
<Step>
|
|
102
|
+
|
|
103
|
+
## Configure Vite
|
|
104
|
+
|
|
105
|
+
Update `vite.config.ts`:
|
|
106
|
+
|
|
107
|
+
```typescript title="vite.config.ts" lineNumbers
|
|
108
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
109
|
+
import { nitro } from "nitro/vite";
|
|
110
|
+
import { defineConfig } from "vite";
|
|
111
|
+
import { workflow } from "workflow/vite";
|
|
112
|
+
import reactRouterConfig from "./react-router.config";
|
|
113
|
+
|
|
114
|
+
export default defineConfig({
|
|
115
|
+
plugins: [
|
|
116
|
+
reactRouter(),
|
|
117
|
+
nitro({
|
|
118
|
+
serverDir: "./server",
|
|
119
|
+
output: {
|
|
120
|
+
dir: reactRouterConfig.buildDirectory,
|
|
121
|
+
serverDir: `${reactRouterConfig.buildDirectory}/server`,
|
|
122
|
+
publicDir: `${reactRouterConfig.buildDirectory}/client`,
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
workflow({ dirs: ["workflows"] }),
|
|
126
|
+
],
|
|
127
|
+
environments: {
|
|
128
|
+
ssr: {
|
|
129
|
+
build: {
|
|
130
|
+
rollupOptions: {
|
|
131
|
+
input: "./server/ssr.ts",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Keep `dirs: ["workflows"]` so subsequent builds do not scan generated files under `build`. Place `reactRouter()` before `nitro()` in the plugin array.
|
|
140
|
+
|
|
141
|
+
</Step>
|
|
142
|
+
|
|
143
|
+
<Step>
|
|
144
|
+
|
|
145
|
+
## Create a workflow
|
|
146
|
+
|
|
147
|
+
Create `workflows/greeting.ts`:
|
|
148
|
+
|
|
149
|
+
```typescript title="workflows/greeting.ts" lineNumbers
|
|
150
|
+
export async function greetingWorkflow(name: string) {
|
|
151
|
+
"use workflow";
|
|
152
|
+
|
|
153
|
+
return greet(name);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function greet(name: string) {
|
|
157
|
+
"use step";
|
|
158
|
+
|
|
159
|
+
return `Hello, ${name}!`;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
</Step>
|
|
164
|
+
|
|
165
|
+
<Step>
|
|
166
|
+
|
|
167
|
+
## Start the workflow from a Nitro route
|
|
168
|
+
|
|
169
|
+
Create `server/routes/api/greeting.post.ts`:
|
|
170
|
+
|
|
171
|
+
```typescript title="server/routes/api/greeting.post.ts" lineNumbers
|
|
172
|
+
import { defineHandler } from "nitro";
|
|
173
|
+
import { start } from "workflow/api";
|
|
174
|
+
import { greetingWorkflow } from "../../../workflows/greeting";
|
|
175
|
+
|
|
176
|
+
export default defineHandler(async (event) => {
|
|
177
|
+
const { name } = (await event.req.json()) as { name: string };
|
|
178
|
+
const run = await start(greetingWorkflow, [name]);
|
|
179
|
+
|
|
180
|
+
return { runId: run.runId };
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
React Router continues to handle your application routes. Nitro handles this server route at `POST /api/greeting`, as well as Workflow SDK's internal routes.
|
|
185
|
+
|
|
186
|
+
</Step>
|
|
187
|
+
|
|
188
|
+
<Step>
|
|
189
|
+
|
|
190
|
+
## Run the app
|
|
191
|
+
|
|
192
|
+
Start the development server:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pnpm vite dev
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Then start a workflow:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
curl -X POST \
|
|
202
|
+
-H "content-type: application/json" \
|
|
203
|
+
-d '{"name":"Workflow"}' \
|
|
204
|
+
http://localhost:3000/api/greeting
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Build and start the production server:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
pnpm vite build
|
|
211
|
+
node ./build/server/index.mjs
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
You can inspect local runs with `pnpm workflow web`.
|
|
215
|
+
|
|
216
|
+
</Step>
|
|
217
|
+
|
|
218
|
+
</Steps>
|
|
219
|
+
|
|
220
|
+
## Troubleshooting
|
|
221
|
+
|
|
222
|
+
### React Router pages return 404
|
|
223
|
+
|
|
224
|
+
Check that the `ssr` environment input points to `./server/ssr.ts`.
|
|
225
|
+
|
|
226
|
+
### A second build tries to compile files under `build/server`
|
|
227
|
+
|
|
228
|
+
Use `workflow({ dirs: ["workflows"] })`, remove the existing `build` directory once, and rebuild.
|
|
229
|
+
|
|
230
|
+
### `vite build` finishes output but does not exit
|
|
231
|
+
|
|
232
|
+
Use `workflow@5.0.0-beta.33` or later with Nitro v3.
|
|
@@ -245,7 +245,7 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
245
245
|
If you see this error:
|
|
246
246
|
|
|
247
247
|
```
|
|
248
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
248
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
249
249
|
```
|
|
250
250
|
|
|
251
251
|
Check both of these first:
|
|
@@ -245,7 +245,7 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
245
245
|
If you see this error:
|
|
246
246
|
|
|
247
247
|
```
|
|
248
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
248
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
249
249
|
```
|
|
250
250
|
|
|
251
251
|
Check both of these first:
|
|
@@ -7,7 +7,7 @@ prerequisites:
|
|
|
7
7
|
- /docs/how-it-works/event-sourcing
|
|
8
8
|
related:
|
|
9
9
|
- /docs/observability
|
|
10
|
-
- /
|
|
10
|
+
- /worlds/vercel
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
<Callout>
|
|
@@ -38,7 +38,7 @@ Metadata such as workflow names, step names, entity IDs, timestamps, and lifecyc
|
|
|
38
38
|
|
|
39
39
|
Each workflow run is encrypted with its own unique key, provided by the `World` implementation via `getEncryptionKeyForRun()`. How the key is generated and stored is up to the `World`.
|
|
40
40
|
|
|
41
|
-
For example, the [Vercel World](/
|
|
41
|
+
For example, the [Vercel World](/worlds/vercel) provides unique keys per run and execution environment, ensuring that a given run can only decrypt data from that run itself.
|
|
42
42
|
|
|
43
43
|
### Encryption Algorithm
|
|
44
44
|
|
|
@@ -127,4 +127,4 @@ async function lookupRunKey(
|
|
|
127
127
|
}
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
The [Vercel World](/
|
|
130
|
+
The [Vercel World](/worlds/vercel) implementation uses HKDF derivation from a deployment-scoped key, but any consistent key management scheme will work.
|
|
@@ -121,15 +121,15 @@ flowchart TD
|
|
|
121
121
|
|
|
122
122
|
**Hook states:**
|
|
123
123
|
|
|
124
|
-
- `active`: Ready to receive payloads
|
|
125
|
-
- `disposed`: No longer accepting payloads
|
|
124
|
+
- `active`: Ready to receive payloads
|
|
125
|
+
- `disposed`: No longer accepting payloads
|
|
126
126
|
- `conflicted`: Hook creation failed because the token is already in use by another workflow
|
|
127
127
|
|
|
128
|
-
Unlike other entities, hooks don't have a `status` field—the states above are conceptual.
|
|
128
|
+
Unlike other entities, hooks don't have a `status` field—the states above are conceptual. When a `hook_disposed` event is created, the hook record is removed rather than updated.
|
|
129
129
|
|
|
130
|
-
While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token
|
|
130
|
+
While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token reserved by another run — either by an active hook or by `experimental_minRetention` after its run ended — a `hook_conflict` event is recorded instead of `hook_created`. Current worlds include the token and the run ID that owns it, though older persisted events or world implementations may only include the token. This causes `hook.getConflict()` to resolve with the conflicting run and the hook's payload promise to reject with a `HookConflictError`, which you can detect with `HookConflictError.is(error)`. See the [hook-conflict error](/docs/errors/hook-conflict) documentation for more details.
|
|
131
131
|
|
|
132
|
-
When a
|
|
132
|
+
When a workflow ends, its Hooks can no longer be resumed. They are normally removed and their tokens become available again. With `experimental_minRetention`, a Hook remains readable and its token remains unavailable until retention ends. A `hook_disposed` event removes the Hook and makes its token available immediately.
|
|
133
133
|
|
|
134
134
|
See [Hooks & Webhooks](/docs/foundations/hooks) for more on how hooks and webhooks work.
|
|
135
135
|
|
|
@@ -188,7 +188,7 @@ Events are categorized by the entity type they affect. Each event contains metad
|
|
|
188
188
|
| Event | Description |
|
|
189
189
|
|-------|-------------|
|
|
190
190
|
| `hook_created` | Creates a new hook in `active` state. Contains the hook token and optional metadata. |
|
|
191
|
-
| `hook_conflict` | Records that hook creation failed because
|
|
191
|
+
| `hook_conflict` | Records that hook creation failed because another run owns the token. Contains the token and, for current worlds, the owner's run ID. The hook is not created: `hook.getConflict()` resolves with the conflicting run, and awaiting the hook payload rejects with a `HookConflictError`. |
|
|
192
192
|
| `hook_received` | Records that a payload was delivered to the hook. The hook remains `active` and can receive more payloads. |
|
|
193
193
|
| `hook_disposed` | Deletes the hook from storage (conceptually transitioning to `disposed` state). The token is released for reuse by future workflows. |
|
|
194
194
|
|
|
@@ -6,7 +6,7 @@ summary: Build a custom framework integration using the Workflow SDK compiler an
|
|
|
6
6
|
prerequisites:
|
|
7
7
|
- /docs/foundations/workflows-and-steps
|
|
8
8
|
related:
|
|
9
|
-
- /
|
|
9
|
+
- /worlds/building-a-world
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
<Callout>
|
|
@@ -414,7 +414,7 @@ const flowTriggers = [getWorkflowQueueTrigger()];
|
|
|
414
414
|
const stepTriggers = [STEP_QUEUE_TRIGGER];
|
|
415
415
|
```
|
|
416
416
|
|
|
417
|
-
If your integration constructs the flow trigger object itself instead of calling `getWorkflowQueueTrigger()`, it must add `maxConcurrency: 1` to that trigger when sequential replays are enabled at build time (`WORKFLOW_SEQUENTIAL_REPLAYS=1
|
|
417
|
+
If your integration constructs the flow trigger object itself instead of calling `getWorkflowQueueTrigger()`, it must add `maxConcurrency: 1` to that trigger when sequential replays are enabled at build time (`WORKFLOW_SEQUENTIAL_REPLAYS=1` — the exported `isSequentialReplaysEnabled()` helper implements this check). The runtime half of the feature (per-run queue topics) activates from the environment variable alone — without the trigger half, those per-run topics are not serialized and the setting only adds queue-topic cardinality.
|
|
418
418
|
|
|
419
419
|
|
|
420
420
|
### Custom implementations
|
|
@@ -425,7 +425,7 @@ For self-hosted or non-Vercel deployments, you are responsible for securing the
|
|
|
425
425
|
- **Network-level security** — Deploy handlers behind a VPC, private network, or firewall rules so only your queue infrastructure can reach them
|
|
426
426
|
- **Rate limiting** — Add request validation and rate limiting to prevent abuse
|
|
427
427
|
|
|
428
|
-
Learn more about [building custom Worlds](/
|
|
428
|
+
Learn more about [building custom Worlds](/worlds/building-a-world).
|
|
429
429
|
|
|
430
430
|
## Testing Your Integration
|
|
431
431
|
|
package/docs/meta.json
CHANGED
|
@@ -57,6 +57,15 @@ export async function cleanupAttributes() {
|
|
|
57
57
|
|
|
58
58
|
Attribute keys must be 1-256 characters, values must be strings up to 256 bytes, and each run can have up to 64 attributes. Keys that start with `$` are reserved for framework and library code.
|
|
59
59
|
|
|
60
|
+
## Reserved keys
|
|
61
|
+
|
|
62
|
+
When `start()` is called from inside a running workflow or step, the new run is automatically tagged with two reserved attributes:
|
|
63
|
+
|
|
64
|
+
- `$parentRunId`: the run that started it.
|
|
65
|
+
- `$rootRunId`: the root of the chain. It is inherited, so every run in a daisy chain or fan-out shares one root id.
|
|
66
|
+
|
|
67
|
+
Top-level runs (started outside any workflow or step) are not tagged.
|
|
68
|
+
|
|
60
69
|
## Viewing attributes
|
|
61
70
|
|
|
62
71
|
The run details panel in the observability UI shows the run's current attributes as key-value rows. Reserved `$`-prefixed keys are marked with a badge and sorted after user keys:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workflow",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.36",
|
|
4
4
|
"description": "Workflow SDK - Build durable, resilient, and observable workflows",
|
|
5
5
|
"main": "dist/typescript-plugin.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
"./astro": "./dist/astro.js",
|
|
50
50
|
"./vite": "./dist/vite.js",
|
|
51
51
|
"./nest": "./dist/nest.js",
|
|
52
|
+
"./nest/builder": "./dist/nest-builder.js",
|
|
53
|
+
"./nest/vercel-builder": "./dist/nest-vercel-builder.js",
|
|
52
54
|
"./runtime": "./dist/runtime.js",
|
|
53
55
|
"./observability": {
|
|
54
56
|
"types": "./dist/observability.d.ts",
|
|
@@ -57,18 +59,18 @@
|
|
|
57
59
|
},
|
|
58
60
|
"dependencies": {
|
|
59
61
|
"ms": "2.1.3",
|
|
60
|
-
"@workflow/astro": "5.0.0-beta.
|
|
61
|
-
"@workflow/cli": "5.0.0-beta.
|
|
62
|
-
"@workflow/core": "5.0.0-beta.
|
|
63
|
-
"@workflow/errors": "5.0.0-beta.10",
|
|
62
|
+
"@workflow/astro": "5.0.0-beta.36",
|
|
63
|
+
"@workflow/cli": "5.0.0-beta.36",
|
|
64
|
+
"@workflow/core": "5.0.0-beta.36",
|
|
64
65
|
"@workflow/typescript-plugin": "5.0.0-beta.5",
|
|
66
|
+
"@workflow/errors": "5.0.0-beta.12",
|
|
65
67
|
"@workflow/utils": "5.0.0-beta.6",
|
|
66
|
-
"@workflow/next": "5.0.0-beta.
|
|
67
|
-
"@workflow/nest": "5.0.0-beta.
|
|
68
|
-
"@workflow/nitro": "5.0.0-beta.
|
|
69
|
-
"@workflow/nuxt": "5.0.0-beta.
|
|
70
|
-
"@workflow/sveltekit": "5.0.0-beta.
|
|
71
|
-
"@workflow/rollup": "5.0.0-beta.
|
|
68
|
+
"@workflow/next": "5.0.0-beta.36",
|
|
69
|
+
"@workflow/nest": "5.0.0-beta.36",
|
|
70
|
+
"@workflow/nitro": "5.0.0-beta.36",
|
|
71
|
+
"@workflow/nuxt": "5.0.0-beta.36",
|
|
72
|
+
"@workflow/sveltekit": "5.0.0-beta.36",
|
|
73
|
+
"@workflow/rollup": "5.0.0-beta.36"
|
|
72
74
|
},
|
|
73
75
|
"devDependencies": {
|
|
74
76
|
"@types/ms": "2.1.0",
|