workflow 5.0.0-beta.5 → 5.0.0-beta.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -23
- package/dist/api-workflow.d.ts +1 -1
- package/dist/api-workflow.d.ts.map +1 -1
- package/dist/api-workflow.js +1 -1
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/internal/builtins.d.ts +20 -3
- package/dist/internal/builtins.d.ts.map +1 -1
- package/dist/internal/builtins.js +68 -4
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +2 -2
- package/dist/nest-builder.d.ts +2 -0
- package/dist/nest-builder.d.ts.map +1 -0
- package/dist/nest-builder.js +2 -0
- package/dist/nest-vercel-builder.d.ts +2 -0
- package/dist/nest-vercel-builder.d.ts.map +1 -0
- package/dist/nest-vercel-builder.js +2 -0
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +2 -2
- package/dist/runtime.d.ts +2 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -1
- package/docs/ai/chat-session-modeling.mdx +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 +71 -75
- 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 +9 -15
- package/docs/api-reference/workflow/create-hook.mdx +89 -10
- package/docs/api-reference/workflow/create-webhook.mdx +16 -15
- package/docs/api-reference/workflow/define-hook.mdx +35 -33
- package/docs/api-reference/workflow/fatal-error.mdx +30 -8
- package/docs/api-reference/workflow/fetch.mdx +14 -10
- package/docs/api-reference/workflow/get-step-metadata.mdx +2 -2
- package/docs/api-reference/workflow/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/workflow/get-writable.mdx +7 -7
- package/docs/api-reference/workflow/index.mdx +4 -1
- package/docs/api-reference/workflow/retryable-error.mdx +1 -1
- package/docs/api-reference/workflow/set-attributes.mdx +61 -0
- package/docs/api-reference/workflow/sleep.mdx +4 -4
- package/docs/api-reference/workflow-ai/durable-agent.mdx +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 +26 -12
- package/docs/api-reference/workflow-api/get-run.mdx +43 -8
- package/docs/api-reference/workflow-api/index.mdx +6 -10
- package/docs/api-reference/workflow-api/resume-hook.mdx +73 -12
- package/docs/api-reference/workflow-api/resume-webhook.mdx +11 -9
- package/docs/api-reference/workflow-api/start.mdx +60 -13
- package/docs/api-reference/workflow-astro/index.mdx +18 -0
- package/docs/api-reference/workflow-astro/meta.json +4 -0
- package/docs/api-reference/workflow-astro/workflow.mdx +45 -0
- package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/hook-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +8 -8
- package/docs/api-reference/workflow-errors/index.mdx +88 -0
- package/docs/api-reference/workflow-errors/meta.json +6 -0
- package/docs/api-reference/workflow-errors/precondition-failed-error.mdx +68 -0
- package/docs/api-reference/workflow-errors/run-expired-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/throttle-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/too-early-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
- package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +5 -6
- package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +6 -6
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-world-error.mdx +8 -8
- package/docs/api-reference/workflow-globals.mdx +14 -10
- package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +33 -0
- package/docs/api-reference/workflow-nest/index.mdx +31 -0
- package/docs/api-reference/workflow-nest/meta.json +9 -0
- package/docs/api-reference/workflow-nest/nest-local-builder.mdx +64 -0
- package/docs/api-reference/workflow-nest/workflow-controller.mdx +40 -0
- package/docs/api-reference/workflow-nest/workflow-module.mdx +74 -0
- package/docs/api-reference/workflow-next/with-workflow.mdx +39 -17
- package/docs/api-reference/workflow-nitro/index.mdx +60 -0
- package/docs/api-reference/workflow-nuxt/index.mdx +48 -0
- package/docs/api-reference/workflow-observability/hydrate-data.mdx +35 -0
- package/docs/api-reference/workflow-observability/hydrate-resource-io.mdx +62 -0
- package/docs/api-reference/workflow-observability/index.mdx +62 -0
- package/docs/api-reference/workflow-observability/meta.json +11 -0
- package/docs/api-reference/workflow-observability/observability-revivers.mdx +50 -0
- package/docs/api-reference/workflow-observability/parse-class-name.mdx +41 -0
- package/docs/api-reference/workflow-observability/parse-step-name.mdx +40 -0
- package/docs/api-reference/workflow-observability/parse-workflow-name.mdx +55 -0
- package/docs/api-reference/workflow-runtime/create-world.mdx +39 -0
- package/docs/api-reference/workflow-runtime/get-world-handlers.mdx +44 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/get-world.mdx +11 -14
- package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
- package/docs/api-reference/workflow-runtime/index.mdx +41 -0
- package/docs/api-reference/workflow-runtime/meta.json +12 -0
- package/docs/api-reference/workflow-runtime/set-world.mdx +51 -0
- package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +43 -0
- package/docs/api-reference/workflow-runtime/world/analytics.mdx +315 -0
- package/docs/api-reference/workflow-runtime/world/index.mdx +60 -0
- package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
- package/docs/api-reference/workflow-runtime/world/queue.mdx +88 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +98 -34
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +8 -8
- package/docs/api-reference/workflow-serde/index.mdx +1 -2
- package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +3 -4
- package/docs/api-reference/workflow-serde/workflow-serialize.mdx +8 -8
- package/docs/api-reference/workflow-sveltekit/index.mdx +18 -0
- package/docs/api-reference/workflow-sveltekit/meta.json +4 -0
- package/docs/api-reference/workflow-sveltekit/workflow-plugin.mdx +42 -0
- package/docs/api-reference/workflow-vite/index.mdx +18 -0
- package/docs/api-reference/workflow-vite/meta.json +4 -0
- package/docs/api-reference/workflow-vite/workflow.mdx +48 -0
- package/docs/changelog/attributes-mvp.mdx +380 -0
- package/docs/changelog/batched-event-writes.mdx +79 -0
- package/docs/changelog/eager-processing.mdx +110 -436
- package/docs/changelog/index.mdx +4 -2
- package/docs/changelog/lazy-event-creation.md +127 -0
- package/docs/changelog/lazy-hook-resume.mdx +78 -0
- package/docs/changelog/meta.json +11 -1
- package/docs/changelog/resilient-resume.mdx +32 -0
- package/docs/changelog/resilient-start.mdx +33 -285
- package/docs/changelog/step-message-ownership.mdx +360 -0
- package/docs/changelog/turbo-mode.md +87 -0
- package/docs/comparisons/index.mdx +66 -0
- package/docs/comparisons/meta.json +11 -0
- package/docs/comparisons/workflow-sdk-vs-aws-agentcore.mdx +55 -0
- package/docs/comparisons/workflow-sdk-vs-aws-step-functions.mdx +111 -0
- package/docs/comparisons/workflow-sdk-vs-cloudflare-workflows.mdx +71 -0
- package/docs/comparisons/workflow-sdk-vs-inngest.mdx +102 -0
- package/docs/comparisons/workflow-sdk-vs-temporal.mdx +123 -0
- package/docs/comparisons/workflow-sdk-vs-trigger-dev.mdx +104 -0
- package/docs/configuration/build-and-diagnostics.mdx +70 -0
- package/docs/configuration/cli-and-web-ui.mdx +241 -0
- package/docs/configuration/framework-options.mdx +165 -0
- package/docs/configuration/index.mdx +32 -0
- package/docs/configuration/meta.json +12 -0
- package/docs/configuration/runtime-tuning.mdx +381 -0
- package/docs/configuration/worlds.mdx +313 -0
- package/docs/cookbook/advanced/child-workflows.mdx +211 -264
- package/docs/cookbook/advanced/meta.json +6 -1
- package/docs/cookbook/advanced/publishing-libraries.mdx +65 -56
- package/docs/cookbook/advanced/serializable-steps.mdx +48 -68
- package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +78 -60
- package/docs/cookbook/agent-patterns/durable-agent.mdx +23 -131
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +180 -195
- package/docs/cookbook/common-patterns/batching.mdx +18 -14
- package/docs/cookbook/common-patterns/idempotency.mdx +41 -53
- package/docs/cookbook/common-patterns/rate-limiting.mdx +8 -4
- package/docs/cookbook/common-patterns/saga.mdx +23 -19
- package/docs/cookbook/common-patterns/scheduling.mdx +34 -22
- package/docs/cookbook/common-patterns/sequential-and-parallel.mdx +29 -25
- package/docs/cookbook/common-patterns/timeouts.mdx +26 -21
- package/docs/cookbook/common-patterns/webhooks.mdx +10 -6
- package/docs/cookbook/common-patterns/workflow-composition.mdx +30 -27
- package/docs/cookbook/index.mdx +22 -21
- package/docs/cookbook/integrations/ai-sdk.mdx +86 -48
- package/docs/cookbook/integrations/chat-sdk.mdx +50 -33
- package/docs/cookbook/integrations/sandbox.mdx +62 -45
- package/docs/deploying.mdx +95 -0
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +16 -12
- package/docs/errors/corrupted-event-log.mdx +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 +69 -13
- package/docs/errors/index.mdx +2 -36
- package/docs/errors/node-js-module-in-workflow.mdx +9 -5
- package/docs/errors/replay-divergence.mdx +27 -0
- package/docs/errors/run-expired.mdx +85 -0
- package/docs/errors/runtime-decryption-failed.mdx +77 -0
- package/docs/errors/serialization-failed.mdx +44 -12
- package/docs/errors/start-invalid-workflow-function.mdx +9 -5
- package/docs/errors/step-executed-multiple-times.mdx +23 -0
- package/docs/errors/step-not-registered.mdx +6 -6
- package/docs/errors/timeout-in-workflow.mdx +12 -8
- package/docs/errors/webhook-invalid-respond-with-value.mdx +18 -18
- package/docs/errors/webhook-response-not-sent.mdx +20 -16
- package/docs/errors/workflow-not-registered.mdx +5 -5
- package/docs/foundations/cancellation.mdx +31 -32
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +64 -35
- package/docs/foundations/idempotency.mdx +244 -12
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +2 -1
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +106 -30
- package/docs/foundations/streaming.mdx +108 -60
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/getting-started/astro.mdx +22 -18
- package/docs/getting-started/express.mdx +15 -11
- package/docs/getting-started/fastify.mdx +15 -11
- package/docs/getting-started/hono.mdx +15 -11
- package/docs/getting-started/index.mdx +10 -3
- package/docs/getting-started/meta.json +3 -1
- package/docs/getting-started/nestjs.mdx +87 -20
- package/docs/getting-started/next.mdx +22 -16
- package/docs/getting-started/nitro.mdx +22 -18
- package/docs/getting-started/nuxt.mdx +15 -11
- package/docs/getting-started/python.mdx +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 +83 -67
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +125 -34
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/understanding-directives.mdx +22 -22
- package/docs/internal/index.mdx +6 -4
- package/docs/internal/meta.json +6 -1
- package/docs/internal/nitro-native-build.mdx +38 -0
- package/docs/internal/nitro-web-ui.mdx +24 -0
- package/docs/internal/serializable-abort-controller.mdx +7 -7
- package/docs/meta.json +3 -2
- package/docs/observability/attributes.mdx +134 -0
- package/docs/observability/index.mdx +32 -10
- package/docs/observability/meta.json +1 -1
- package/docs/observability/retention.mdx +95 -0
- package/docs/observability/tracing.mdx +124 -0
- package/docs/testing/index.mdx +36 -36
- package/docs/testing/server-based.mdx +10 -10
- package/docs/whats-new.mdx +186 -0
- package/package.json +17 -14
- package/docs/api-reference/workflow-api/world/index.mdx +0 -58
- package/docs/api-reference/workflow-api/world/meta.json +0 -4
- package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
- package/docs/api-reference/workflow-api/world/queue.mdx +0 -86
- package/docs/deploying/building-a-world.mdx +0 -251
- package/docs/deploying/index.mdx +0 -95
- package/docs/deploying/meta.json +0 -4
- package/docs/deploying/world/local-world.mdx +0 -84
- package/docs/deploying/world/meta.json +0 -4
- package/docs/deploying/world/postgres-world.mdx +0 -224
- package/docs/deploying/world/vercel-world.mdx +0 -179
- package/docs/migration-guides/index.mdx +0 -34
- package/docs/migration-guides/meta.json +0 -9
- package/docs/migration-guides/migrating-from-aws-step-functions.mdx +0 -363
- package/docs/migration-guides/migrating-from-inngest.mdx +0 -314
- package/docs/migration-guides/migrating-from-temporal.mdx +0 -318
- package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -337
|
@@ -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` 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` or later with Nitro v3.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: SvelteKit
|
|
3
|
-
description:
|
|
3
|
+
description: Set up your first durable workflow in a SvelteKit app.
|
|
4
4
|
type: guide
|
|
5
5
|
summary: Set up Workflow SDK in a SvelteKit app.
|
|
6
6
|
prerequisites:
|
|
@@ -9,12 +9,16 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this SvelteKit app, run `npm i workflow`. In `vite.config.ts`, import `workflowPlugin` from `workflow/sveltekit` and add it to `plugins` with `sveltekit()`. Add the TypeScript plugin `{ "name": "workflow" }` to `tsconfig.json` if TypeScript is used. Create `workflows/user-signup.ts` exporting `handleUserSignup(email)` with `"use workflow"`, `sleep` from `workflow`, and `"use step"` helpers that create a user and send emails. Add `src/routes/api/signup/+server.ts` with a POST `RequestHandler` that reads `{ email }`, calls `start(handleUserSignup, [email])` from `workflow/api`, and returns `json({ message: "User signup workflow started" })`. Run `npm run dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:5173/api/signup`, then inspect with `npx workflow web` or `npx workflow inspect runs`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
12
16
|
<Steps>
|
|
13
17
|
|
|
14
18
|
<Step>
|
|
15
|
-
## Create
|
|
19
|
+
## Create your SvelteKit project
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
Create a minimal SvelteKit project in a new directory named `my-workflow-app`:
|
|
18
22
|
|
|
19
23
|
```bash
|
|
20
24
|
npx sv create my-workflow-app --template=minimal --types=ts --no-add-ons
|
|
@@ -50,16 +54,16 @@ export default defineConfig({
|
|
|
50
54
|
|
|
51
55
|
| Option | Type | Default | Description |
|
|
52
56
|
| --- | --- | --- | --- |
|
|
53
|
-
| `sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` | Controls source maps on generated workflow bundles. Accepts the same values as esbuild's `sourcemap` option.
|
|
57
|
+
| `sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` (dev) / `false` (prod) | Controls source maps on generated workflow bundles. Accepts the same values as esbuild's `sourcemap` option. Defaults to `'inline'` in development and `false` in production (smaller function bundles, which helps stay under the Vercel 250 MB function size limit). Set it explicitly, or use the `WORKFLOW_SOURCEMAP` environment variable, to override in either environment. |
|
|
54
58
|
|
|
55
59
|
<Accordion type="single" collapsible>
|
|
56
60
|
<AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
|
|
57
61
|
<AccordionTrigger className="text-sm">
|
|
58
|
-
###
|
|
62
|
+
### Set up IntelliSense for TypeScript (optional)
|
|
59
63
|
</AccordionTrigger>
|
|
60
64
|
<AccordionContent className="[&_p]:my-2">
|
|
61
65
|
|
|
62
|
-
To enable helpful hints in your IDE,
|
|
66
|
+
To enable helpful hints in your IDE, set up the workflow plugin in `tsconfig.json`:
|
|
63
67
|
|
|
64
68
|
```json title="tsconfig.json" lineNumbers
|
|
65
69
|
{
|
|
@@ -82,7 +86,7 @@ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json
|
|
|
82
86
|
|
|
83
87
|
<Step>
|
|
84
88
|
|
|
85
|
-
## Create
|
|
89
|
+
## Create your first workflow
|
|
86
90
|
|
|
87
91
|
Create a new file for our first workflow:
|
|
88
92
|
|
|
@@ -105,14 +109,14 @@ export async function handleUserSignup(email: string) {
|
|
|
105
109
|
|
|
106
110
|
```
|
|
107
111
|
|
|
108
|
-
We'll fill in those functions next, but
|
|
112
|
+
We'll fill in those functions next, but first review this code:
|
|
109
113
|
|
|
110
114
|
* We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
111
115
|
* The Workflow SDK's `sleep` function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long.
|
|
112
116
|
|
|
113
|
-
## Create
|
|
117
|
+
## Create your workflow steps
|
|
114
118
|
|
|
115
|
-
|
|
119
|
+
Define the missing functions.
|
|
116
120
|
|
|
117
121
|
```typescript title="workflows/user-signup.ts" lineNumbers
|
|
118
122
|
import { FatalError } from "workflow"
|
|
@@ -153,7 +157,7 @@ async function sendOnboardingEmail(user: { id: string; email: string}) {
|
|
|
153
157
|
|
|
154
158
|
Taking a look at this code:
|
|
155
159
|
|
|
156
|
-
* Business logic lives inside **steps**. When a
|
|
160
|
+
* Business logic lives inside **steps**. When a workflow invokes a step, the workflow suspends while the step runs with full Node.js access. The combined handler may execute it inline; queued retries and continuations return through the same flow route.
|
|
157
161
|
* If a step throws an error, like in `sendWelcomeEmail`, the step will automatically be retried until it succeeds (or hits the step's max retry count).
|
|
158
162
|
* Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
159
163
|
|
|
@@ -165,7 +169,7 @@ We'll dive deeper into workflows, steps, and other ways to suspend or handle eve
|
|
|
165
169
|
|
|
166
170
|
<Step>
|
|
167
171
|
|
|
168
|
-
## Create
|
|
172
|
+
## Create your route handler
|
|
169
173
|
|
|
170
174
|
To invoke your new workflow, we'll have to add your workflow to a `POST` API route handler, `src/routes/api/signup/+server.ts` with the following code:
|
|
171
175
|
|
|
@@ -228,7 +232,7 @@ npx workflow inspect runs
|
|
|
228
232
|
|
|
229
233
|
## Deploying to production
|
|
230
234
|
|
|
231
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
235
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
232
236
|
|
|
233
237
|
<FluidComputeCallout />
|
|
234
238
|
|
|
@@ -240,8 +244,8 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
240
244
|
|
|
241
245
|
If you see this error:
|
|
242
246
|
|
|
243
|
-
```
|
|
244
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
247
|
+
```text
|
|
248
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
245
249
|
```
|
|
246
250
|
|
|
247
251
|
Check both of these first:
|
|
@@ -251,7 +255,7 @@ Check both of these first:
|
|
|
251
255
|
|
|
252
256
|
See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
|
|
253
257
|
|
|
254
|
-
## Next
|
|
258
|
+
## Next steps
|
|
255
259
|
|
|
256
260
|
* Learn more about the [Foundations](/docs/foundations).
|
|
257
261
|
* Check [Errors](/docs/errors) if you encounter issues.
|
|
@@ -9,14 +9,18 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this TanStack Start app, run `npm i workflow`. In `vite.config.ts`, import `workflow` from `workflow/vite` and add `workflow()` first in the existing `plugins` array before `tanstackStart()`, `nitro()`, or other plugins. Add `{ "name": "workflow" }` to `compilerOptions.plugins` in `tsconfig.json` if TypeScript is used. Create `src/workflows/user-signup.ts` with `handleUserSignup(email)`, `"use workflow"`, `sleep`, and `"use step"` helpers. Add `src/routes/api/signup.ts` using `createFileRoute("/api/signup")`, a POST server handler, `start` from `workflow/api`, and `json` from `@tanstack/react-start`. Run `npm run dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup`, and inspect with `npx workflow web` or `npx workflow inspect runs`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
Set up your first durable workflow in a TanStack Start app and learn the core Workflow SDK concepts.
|
|
13
17
|
|
|
14
18
|
---
|
|
15
19
|
|
|
16
20
|
<Steps>
|
|
17
21
|
|
|
18
22
|
<Step>
|
|
19
|
-
## Create
|
|
23
|
+
## Create your TanStack Start project
|
|
20
24
|
|
|
21
25
|
Start by creating a new TanStack Start project:
|
|
22
26
|
|
|
@@ -38,7 +42,7 @@ npm i workflow
|
|
|
38
42
|
|
|
39
43
|
### Configure TanStack Start
|
|
40
44
|
|
|
41
|
-
TanStack Start runs on Vite, so the Workflow SDK is wired in via the same `workflow/vite` plugin. Add `workflow()` to the existing `plugins` array in your Vite config
|
|
45
|
+
TanStack Start runs on Vite, so the Workflow SDK is wired in via the same `workflow/vite` plugin. Add `workflow()` to the existing `plugins` array in your Vite config. List it first so the `"use workflow"` and `"use step"` transforms run before any other plugin processes the file.
|
|
42
46
|
|
|
43
47
|
```typescript title="vite.config.ts" lineNumbers
|
|
44
48
|
import { defineConfig } from "vite";
|
|
@@ -56,11 +60,11 @@ export default defineConfig({
|
|
|
56
60
|
<Accordion type="single" collapsible>
|
|
57
61
|
<AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
|
|
58
62
|
<AccordionTrigger className="text-sm">
|
|
59
|
-
###
|
|
63
|
+
### Set up IntelliSense for TypeScript (optional)
|
|
60
64
|
</AccordionTrigger>
|
|
61
65
|
<AccordionContent className="[&_p]:my-2">
|
|
62
66
|
|
|
63
|
-
To enable helpful hints in your IDE,
|
|
67
|
+
To enable helpful hints in your IDE, set up the workflow plugin in `tsconfig.json`:
|
|
64
68
|
|
|
65
69
|
```json title="tsconfig.json" lineNumbers
|
|
66
70
|
{
|
|
@@ -83,7 +87,7 @@ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json
|
|
|
83
87
|
|
|
84
88
|
<Step>
|
|
85
89
|
|
|
86
|
-
## Create
|
|
90
|
+
## Create your first workflow
|
|
87
91
|
|
|
88
92
|
Create a new file for our first workflow:
|
|
89
93
|
|
|
@@ -103,14 +107,14 @@ export async function handleUserSignup(email: string) {
|
|
|
103
107
|
}
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
We'll fill in those functions next, but
|
|
110
|
+
We'll fill in those functions next, but first review this code:
|
|
107
111
|
|
|
108
112
|
* We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
109
113
|
* The Workflow SDK's `sleep` function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long.
|
|
110
114
|
|
|
111
|
-
## Create
|
|
115
|
+
## Create your workflow steps
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
Define the missing functions.
|
|
114
118
|
|
|
115
119
|
```typescript title="src/workflows/user-signup.ts" lineNumbers
|
|
116
120
|
import { FatalError } from "workflow"
|
|
@@ -151,7 +155,7 @@ async function sendOnboardingEmail(user: { id: string; email: string}) {
|
|
|
151
155
|
|
|
152
156
|
Taking a look at this code:
|
|
153
157
|
|
|
154
|
-
* Business logic lives inside **steps**. When a
|
|
158
|
+
* Business logic lives inside **steps**. When a workflow invokes a step, the workflow suspends while the step runs with full Node.js access. The combined handler may execute it inline; queued retries and continuations return through the same flow route.
|
|
155
159
|
* If a step throws an error, like in `sendWelcomeEmail`, the step will automatically be retried until it succeeds (or hits the step's max retry count).
|
|
156
160
|
* Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
157
161
|
|
|
@@ -163,7 +167,7 @@ We'll dive deeper into workflows, steps, and other ways to suspend or handle eve
|
|
|
163
167
|
|
|
164
168
|
<Step>
|
|
165
169
|
|
|
166
|
-
## Create
|
|
170
|
+
## Create your route handler
|
|
167
171
|
|
|
168
172
|
To invoke your new workflow, add a server handler at `src/routes/api/signup.ts`:
|
|
169
173
|
|
|
@@ -228,13 +232,13 @@ npx workflow inspect runs
|
|
|
228
232
|
|
|
229
233
|
## Deploying to production
|
|
230
234
|
|
|
231
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
235
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
232
236
|
|
|
233
237
|
<FluidComputeCallout />
|
|
234
238
|
|
|
235
239
|
Check the [Deploying](/docs/deploying) section to learn how your workflows can be deployed elsewhere.
|
|
236
240
|
|
|
237
|
-
## Next
|
|
241
|
+
## Next steps
|
|
238
242
|
|
|
239
243
|
* Learn more about the [Foundations](/docs/foundations).
|
|
240
244
|
* Check [Errors](/docs/errors) if you encounter issues.
|