workflow 5.0.0-beta.4 → 5.0.0-beta.40
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 +63 -20
- 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 +5 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +12 -2
- 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 +17 -0
- package/dist/internal/builtins.d.ts.map +1 -1
- package/dist/internal/builtins.js +65 -1
- 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 +5 -2
- package/docs/ai/chat-session-modeling.mdx +7 -3
- package/docs/ai/defining-tools.mdx +2 -2
- package/docs/ai/index.mdx +30 -25
- package/docs/ai/message-queueing.mdx +10 -10
- package/docs/ai/resumable-streams.mdx +9 -1
- package/docs/api-reference/index.mdx +24 -0
- package/docs/api-reference/meta.json +8 -0
- package/docs/api-reference/vitest/index.mdx +28 -7
- package/docs/api-reference/workflow/create-hook.mdx +79 -0
- package/docs/api-reference/workflow/create-webhook.mdx +1 -0
- 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 +8 -4
- package/docs/api-reference/workflow/index.mdx +3 -0
- package/docs/api-reference/workflow/set-attributes.mdx +61 -0
- package/docs/api-reference/workflow/sleep.mdx +1 -1
- package/docs/api-reference/workflow-ai/durable-agent.mdx +7 -45
- package/docs/api-reference/workflow-ai/index.mdx +2 -2
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +44 -1
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +9 -0
- package/docs/api-reference/workflow-api/get-run.mdx +25 -0
- package/docs/api-reference/workflow-api/index.mdx +6 -8
- package/docs/api-reference/workflow-api/resume-hook.mdx +60 -1
- package/docs/api-reference/workflow-api/resume-webhook.mdx +6 -4
- package/docs/api-reference/workflow-api/start.mdx +39 -6
- 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 +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-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-failed-error.mdx +16 -6
- 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-globals.mdx +4 -1
- 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 +56 -2
- 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 +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-runtime/world/analytics.mdx +138 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/index.mdx +10 -10
- package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/queue.mdx +8 -6
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +18 -5
- 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 +2 -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 +380 -0
- package/docs/changelog/eager-processing.mdx +269 -0
- package/docs/changelog/index.mdx +3 -1
- package/docs/changelog/lazy-event-creation.md +127 -0
- package/docs/changelog/meta.json +9 -1
- package/docs/changelog/resilient-resume.mdx +22 -0
- package/docs/changelog/resilient-start.mdx +31 -283
- 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 +103 -0
- package/docs/configuration/build-and-diagnostics.mdx +70 -0
- package/docs/configuration/cli-and-web-ui.mdx +182 -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 +276 -0
- package/docs/configuration/worlds.mdx +275 -0
- package/docs/cookbook/advanced/child-workflows.mdx +203 -256
- package/docs/cookbook/advanced/meta.json +1 -1
- package/docs/cookbook/advanced/publishing-libraries.mdx +33 -24
- package/docs/cookbook/advanced/serializable-steps.mdx +12 -4
- package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +34 -75
- package/docs/cookbook/agent-patterns/durable-agent.mdx +14 -142
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +11 -3
- package/docs/cookbook/common-patterns/batching.mdx +4 -0
- package/docs/cookbook/common-patterns/idempotency.mdx +40 -52
- package/docs/cookbook/common-patterns/rate-limiting.mdx +5 -1
- package/docs/cookbook/common-patterns/saga.mdx +6 -2
- package/docs/cookbook/common-patterns/scheduling.mdx +12 -0
- package/docs/cookbook/common-patterns/sequential-and-parallel.mdx +4 -0
- package/docs/cookbook/common-patterns/timeouts.mdx +6 -1
- package/docs/cookbook/common-patterns/webhooks.mdx +4 -0
- package/docs/cookbook/common-patterns/workflow-composition.mdx +19 -16
- package/docs/cookbook/index.mdx +3 -3
- package/docs/cookbook/integrations/ai-sdk.mdx +64 -28
- package/docs/cookbook/integrations/chat-sdk.mdx +17 -0
- package/docs/cookbook/integrations/sandbox.mdx +17 -0
- package/docs/{deploying/index.mdx → deploying.mdx} +7 -7
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +84 -0
- package/docs/errors/corrupted-event-log.mdx +5 -5
- package/docs/errors/deployment-mismatch.mdx +71 -0
- package/docs/errors/fetch-in-workflow.mdx +4 -0
- package/docs/errors/hook-conflict.mdx +60 -4
- package/docs/errors/index.mdx +1 -35
- package/docs/errors/node-js-module-in-workflow.mdx +4 -0
- package/docs/errors/replay-divergence.mdx +27 -0
- package/docs/errors/runtime-decryption-failed.mdx +77 -0
- package/docs/errors/serialization-failed.mdx +4 -0
- package/docs/errors/start-invalid-workflow-function.mdx +4 -0
- package/docs/errors/step-executed-multiple-times.mdx +23 -0
- package/docs/errors/step-not-registered.mdx +1 -1
- package/docs/errors/timeout-in-workflow.mdx +4 -0
- package/docs/errors/webhook-response-not-sent.mdx +4 -0
- package/docs/foundations/cancellation.mdx +459 -0
- package/docs/foundations/errors-and-retries.mdx +7 -3
- package/docs/foundations/hooks.mdx +29 -0
- package/docs/foundations/idempotency.mdx +243 -11
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +3 -1
- package/docs/foundations/serialization.mdx +77 -41
- package/docs/foundations/starting-workflows.mdx +79 -2
- package/docs/foundations/streaming.mdx +14 -23
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/getting-started/astro.mdx +12 -2
- package/docs/getting-started/express.mdx +6 -2
- package/docs/getting-started/fastify.mdx +6 -2
- package/docs/getting-started/hono.mdx +6 -2
- package/docs/getting-started/index.mdx +16 -10
- package/docs/getting-started/meta.json +4 -1
- package/docs/getting-started/nestjs.mdx +77 -3
- package/docs/getting-started/next.mdx +12 -6
- package/docs/getting-started/nitro.mdx +28 -2
- package/docs/getting-started/nuxt.mdx +6 -2
- package/docs/getting-started/python.mdx +24 -18
- 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 +12 -2
- package/docs/getting-started/tanstack-start.mdx +245 -0
- package/docs/getting-started/vite.mdx +6 -2
- package/docs/how-it-works/cancellation.mdx +287 -0
- package/docs/how-it-works/code-transform.mdx +21 -17
- package/docs/how-it-works/encryption.mdx +5 -5
- package/docs/how-it-works/event-sourcing.mdx +6 -6
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/meta.json +2 -1
- package/docs/internal/index.mdx +21 -0
- package/docs/internal/meta.json +10 -0
- 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 +148 -0
- package/docs/meta.json +2 -2
- package/docs/observability/attributes.mdx +112 -0
- package/docs/observability/index.mdx +20 -1
- package/docs/observability/meta.json +1 -1
- package/docs/observability/tracing.mdx +124 -0
- package/docs/testing/index.mdx +2 -2
- package/package.json +17 -13
- package/docs/api-reference/workflow-api/world/meta.json +0 -4
- package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
- package/docs/cookbook/advanced/distributed-abort-controller.mdx +0 -318
- package/docs/deploying/building-a-world.mdx +0 -251
- 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 -222
- 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
|
@@ -9,10 +9,15 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this NestJS app, run `npm i workflow @workflow/nest` and `npm i -D @swc/cli @swc/core`. Configure `nest-cli.json` with `compilerOptions.builder: "swc"` and `deleteOutDir: true`. Run `npx @workflow/nest init`, add `.swcrc` to `.gitignore`, and set package scripts `prebuild: "npx @workflow/nest init --force"` and `start:dev: "npx @workflow/nest init --force && nest start --watch"`. Import `WorkflowModule.forRoot()` from `@workflow/nest` in `src/app.module.ts` (use `{ moduleType: "commonjs", distDir: "dist" }` if compiling CommonJS). Create `src/workflows/user-signup.ts` with `"use workflow"`, `sleep`, and `"use step"` helpers. Add a `POST /signup` controller method that reads `email`, calls `start(handleUserSignup, [email])` from `workflow/api`, and returns JSON. Run `npm run start:dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/signup`, and inspect with `npx workflow web` or `npx workflow inspect runs`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
12
16
|
This guide will walk through setting up your first workflow in a NestJS app. Along the way, you'll learn more about the concepts that are fundamental to using the Workflow SDK in your own projects.
|
|
13
17
|
|
|
14
18
|
<Callout>
|
|
15
|
-
NestJS integration is experimental
|
|
19
|
+
NestJS integration is experimental. Deployment to Vercel is supported via the
|
|
20
|
+
`workflow-nest build --vercel` command — see [Deploy to Vercel](#deploy-to-vercel) below.
|
|
16
21
|
</Callout>
|
|
17
22
|
|
|
18
23
|
---
|
|
@@ -284,7 +289,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
284
289
|
|
|
285
290
|
Taking a look at this code:
|
|
286
291
|
|
|
287
|
-
- Business logic lives inside **steps**. When a
|
|
292
|
+
- 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.
|
|
288
293
|
- 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).
|
|
289
294
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
290
295
|
|
|
@@ -357,6 +362,66 @@ npx workflow inspect runs
|
|
|
357
362
|
|
|
358
363
|
</Step>
|
|
359
364
|
|
|
365
|
+
<Step>
|
|
366
|
+
|
|
367
|
+
## Deploy to Vercel
|
|
368
|
+
|
|
369
|
+
Because NestJS is not a Vercel-native framework, the Workflow SDK produces a
|
|
370
|
+
[Build Output API](https://vercel.com/docs/build-output-api) directory for you. This emits the
|
|
371
|
+
workflow queue-consumer function (registered with `experimentalTriggers` so Vercel's queue can
|
|
372
|
+
discover it) alongside your NestJS app as a catch-all function. Without it, workflow runs stay
|
|
373
|
+
`pending` because nothing consumes the queue.
|
|
374
|
+
|
|
375
|
+
Add a Vercel-specific entry module that default-exports your Nest app's underlying Node handler:
|
|
376
|
+
|
|
377
|
+
```typescript title="_vercel/entry.ts" lineNumbers
|
|
378
|
+
import 'reflect-metadata';
|
|
379
|
+
import { NestFactory } from '@nestjs/core';
|
|
380
|
+
import type { NestExpressApplication } from '@nestjs/platform-express';
|
|
381
|
+
import express from 'express';
|
|
382
|
+
import { AppModule } from '../dist/app.module.js';
|
|
383
|
+
|
|
384
|
+
let ready: Promise<express.Express> | undefined;
|
|
385
|
+
|
|
386
|
+
async function createHandler() {
|
|
387
|
+
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
|
388
|
+
bodyParser: false,
|
|
389
|
+
});
|
|
390
|
+
app.use(express.json());
|
|
391
|
+
await app.init();
|
|
392
|
+
return app.getHttpAdapter().getInstance();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export default async function handler(req: express.Request, res: express.Response) {
|
|
396
|
+
ready ??= createHandler();
|
|
397
|
+
return (await ready)(req, res);
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Skip the in-process build on Vercel (the bundles are pre-built) by passing `skipBuild` when
|
|
402
|
+
`VERCEL` is set:
|
|
403
|
+
|
|
404
|
+
{/* @skip-typecheck - config snippet, WorkflowModule imported above */}
|
|
405
|
+
```typescript title="src/app.module.ts"
|
|
406
|
+
WorkflowModule.forRoot({ skipBuild: Boolean(process.env.VERCEL) });
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Then set your build command so the Build Output is produced after `nest build`:
|
|
410
|
+
|
|
411
|
+
```json title="package.json" lineNumbers
|
|
412
|
+
{
|
|
413
|
+
"scripts": {
|
|
414
|
+
"vercel-build": "workflow-nest init --force && nest build && workflow-nest build --vercel --dirs src/workflows --entry _vercel/entry.ts"
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Deploy as usual. `workflow-nest build --vercel` runs automatically on Vercel (it also detects the
|
|
420
|
+
`VERCEL` environment variable), writing `.vercel/output` with the consumer function so your runs
|
|
421
|
+
execute instead of staying `pending`.
|
|
422
|
+
|
|
423
|
+
</Step>
|
|
424
|
+
|
|
360
425
|
</Steps>
|
|
361
426
|
|
|
362
427
|
---
|
|
@@ -386,6 +451,15 @@ WorkflowModule.forRoot({
|
|
|
386
451
|
// Only used when moduleType is 'commonjs'
|
|
387
452
|
// Should match the outDir in your tsconfig.json
|
|
388
453
|
distDir: 'dist',
|
|
454
|
+
|
|
455
|
+
// Source maps on generated workflow bundles (default: 'inline' in
|
|
456
|
+
// development, false in production).
|
|
457
|
+
// Accepts the same values as esbuild's sourcemap option: true, false,
|
|
458
|
+
// 'inline', 'linked', 'external', 'both'. Set to false for smaller
|
|
459
|
+
// function bundles (useful for staying under the Vercel 250MB function
|
|
460
|
+
// size limit) at the cost of stack traces pointing at generated code.
|
|
461
|
+
// Can also be set via the WORKFLOW_SOURCEMAP environment variable.
|
|
462
|
+
sourcemap: 'inline',
|
|
389
463
|
});
|
|
390
464
|
```
|
|
391
465
|
|
|
@@ -396,7 +470,7 @@ WorkflowModule.forRoot({
|
|
|
396
470
|
If you see this error:
|
|
397
471
|
|
|
398
472
|
```
|
|
399
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
473
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
400
474
|
```
|
|
401
475
|
|
|
402
476
|
Check both of these first:
|
|
@@ -7,9 +7,13 @@ prerequisites:
|
|
|
7
7
|
- /docs/getting-started
|
|
8
8
|
related:
|
|
9
9
|
- /docs/api-reference/workflow-next
|
|
10
|
-
- /
|
|
10
|
+
- /worlds/vercel
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
<CopyPrompt
|
|
14
|
+
text="In this Next.js app, run `npm i workflow`. Wrap `next.config.ts` with `withWorkflow` from `workflow/next`. If the app has `proxy.ts` or middleware, exclude `.well-known/workflow/` from its matcher. Add `workflows/user-signup.ts` exporting `handleUserSignup(email)` with `"use workflow"`, `sleep` from `workflow`, and `"use step"` helper functions that create a user, send a welcome email, and send an onboarding email. Add `app/api/signup/route.ts` with a POST handler that reads `{ email }`, calls `start(handleUserSignup, [email])` from `workflow/api`, and returns JSON. Run `npm run dev`, trigger `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup`, and inspect with `npx workflow web` or `npx workflow inspect runs`."
|
|
15
|
+
/>
|
|
16
|
+
|
|
13
17
|
<Steps>
|
|
14
18
|
|
|
15
19
|
<Step>
|
|
@@ -75,9 +79,9 @@ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json
|
|
|
75
79
|
</Accordion>
|
|
76
80
|
|
|
77
81
|
<Accordion type="single" collapsible>
|
|
78
|
-
<AccordionItem value="
|
|
82
|
+
<AccordionItem value="configure-proxy-handler" className="[&_h3]:my-0">
|
|
79
83
|
<AccordionTrigger className="text-sm">
|
|
80
|
-
|
|
84
|
+
<h3 id="configure-proxy-handler">Configure Proxy Handler (if applicable)</h3>
|
|
81
85
|
</AccordionTrigger>
|
|
82
86
|
<AccordionContent className="[&_p]:my-2">
|
|
83
87
|
|
|
@@ -85,7 +89,9 @@ If your Next.js app has a [proxy handler](https://nextjs.org/docs/app/api-refere
|
|
|
85
89
|
(formerly known as "middleware"), you'll need to update the matcher pattern to exclude Workflow's
|
|
86
90
|
internal paths to prevent the proxy handler from running on them.
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
If you see `[local world] Queue operation failed` with `Cannot perform ArrayBuffer.prototype.slice on a detached ArrayBuffer`, your proxy matcher is still intercepting Workflow's internal `POST /.well-known/workflow/v1/flow` request. This is especially easy to miss in Next.js 16, where `proxy.ts` replaced `middleware.ts`.
|
|
93
|
+
|
|
94
|
+
Add `.well-known/workflow/*` to your matcher exclusion list:
|
|
89
95
|
|
|
90
96
|
```typescript title="proxy.ts" lineNumbers
|
|
91
97
|
import { NextResponse } from "next/server";
|
|
@@ -186,7 +192,7 @@ async function sendOnboardingEmail(user: { id: string; email: string}) {
|
|
|
186
192
|
|
|
187
193
|
Taking a look at this code:
|
|
188
194
|
|
|
189
|
-
* Business logic lives inside **steps**. When a
|
|
195
|
+
* 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.
|
|
190
196
|
* 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).
|
|
191
197
|
* Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
192
198
|
|
|
@@ -310,7 +316,7 @@ Without this configuration, you may experience intermittent issues where workflo
|
|
|
310
316
|
If you see this error:
|
|
311
317
|
|
|
312
318
|
```
|
|
313
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
319
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
314
320
|
```
|
|
315
321
|
|
|
316
322
|
Check both of these first:
|
|
@@ -9,6 +9,10 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Nitro app, run `npm i workflow`. In `nitro.config.ts`, use `defineConfig` from `nitro`, set `serverDir: "./server"`, and add `modules: ["workflow/nitro"]`. Add the TypeScript plugin `{ "name": "workflow" }` to `tsconfig.json` if TypeScript is used. Create `workflows/user-signup.ts` with `handleUserSignup(email)`, `"use workflow"`, `sleep` from `workflow`, and `"use step"` helpers. Add `server/api/signup.post.ts` using `defineEventHandler` from `nitro/h3` and `start` from `workflow/api` to start the workflow from `{ email }`. Run `npm run dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup`, then inspect with `npx workflow web` or `npx workflow inspect runs`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
12
16
|
<Steps>
|
|
13
17
|
|
|
14
18
|
<Step>
|
|
@@ -46,6 +50,28 @@ export default defineConfig({
|
|
|
46
50
|
|
|
47
51
|
```
|
|
48
52
|
|
|
53
|
+
### Module options
|
|
54
|
+
|
|
55
|
+
The `workflow/nitro` module reads its options from `workflow` on your Nitro config.
|
|
56
|
+
|
|
57
|
+
```typescript title="nitro.config.ts" lineNumbers
|
|
58
|
+
import { defineConfig } from "nitro";
|
|
59
|
+
|
|
60
|
+
export default defineConfig({
|
|
61
|
+
modules: ["workflow/nitro"],
|
|
62
|
+
workflow: {
|
|
63
|
+
runtime: "nodejs22.x",
|
|
64
|
+
sourcemap: "inline",
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Option | Type | Default | Description |
|
|
70
|
+
| --- | --- | --- | --- |
|
|
71
|
+
| `dirs` | `string[]` | — | Directories to scan for workflows and steps. By default, `workflows/` is scanned from the project root and all layer source directories. |
|
|
72
|
+
| `runtime` | `string` | `'nodejs22.x'` | Node.js runtime version for Vercel Functions (e.g. `'nodejs22.x'`, `'nodejs24.x'`). |
|
|
73
|
+
| `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 — helps stay under the Vercel 250MB function size limit). Set it explicitly, or use the `WORKFLOW_SOURCEMAP` environment variable, to override in either environment. |
|
|
74
|
+
|
|
49
75
|
<Accordion type="single" collapsible>
|
|
50
76
|
<AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
|
|
51
77
|
<AccordionTrigger className="[&_p]:my-0 text-lg [&_p]:text-foreground">
|
|
@@ -146,7 +172,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
146
172
|
|
|
147
173
|
Taking a look at this code:
|
|
148
174
|
|
|
149
|
-
- Business logic lives inside **steps**. When a
|
|
175
|
+
- 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.
|
|
150
176
|
- 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).
|
|
151
177
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
152
178
|
|
|
@@ -235,7 +261,7 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
235
261
|
If you see this error:
|
|
236
262
|
|
|
237
263
|
```
|
|
238
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
264
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
239
265
|
```
|
|
240
266
|
|
|
241
267
|
Check both of these first:
|
|
@@ -9,6 +9,10 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Nuxt app, run `npm i workflow`. In `nuxt.config.ts`, add `modules: ["workflow/nuxt"]` and keep `compatibilityDate: "latest"`. 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 `server/api/signup.post.ts` using `defineEventHandler` from `h3` or `nitro/h3` and `start` from `workflow/api` to read `{ email }` and start the workflow. 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
|
+
|
|
12
16
|
<Steps>
|
|
13
17
|
|
|
14
18
|
<Step>
|
|
@@ -145,7 +149,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
145
149
|
|
|
146
150
|
Taking a look at this code:
|
|
147
151
|
|
|
148
|
-
- Business logic lives inside **steps**. When a
|
|
152
|
+
- 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.
|
|
149
153
|
- 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).
|
|
150
154
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
151
155
|
|
|
@@ -236,7 +240,7 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
236
240
|
If you see this error:
|
|
237
241
|
|
|
238
242
|
```
|
|
239
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
243
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
240
244
|
```
|
|
241
245
|
|
|
242
246
|
Check both of these first:
|
|
@@ -10,34 +10,31 @@ related:
|
|
|
10
10
|
- /docs/foundations/workflows-and-steps
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
<CopyPrompt
|
|
14
|
+
text="In this Python project, add `requires-python = ">=3.12"` and `dependencies = ["vercel"]` under `[project]` in `pyproject.toml`. Add `[[tool.vercel.workflows]]` with `entrypoint = "app.workflows:wf"`. Create `app/workflow.py` with `from vercel import workflow` and `wf = workflow.Workflows()`. Create `app/workflows/ai_content_workflow.py` importing `wf`, define `@wf.workflow async def ai_content_workflow(*, topic: str)`, and call step functions such as `generate_draft` and `summarize_draft`. Export `wf` from `app/workflows/__init__.py` and import the workflow module so its definitions are registered. Mark step functions with `@wf.step`, use `await workflow.sleep("7 days")` for durable delays where needed, and use a `workflow.BaseHook` Pydantic model plus `.wait(token=...)` and `.resume(token)` for external approval events. Verify the workflow entrypoint uses the `module:object` format and points to the exported `Workflows` registry."
|
|
15
|
+
/>
|
|
16
|
+
|
|
13
17
|
<Callout type="warn">
|
|
14
|
-
The Python SDK is currently in **beta**. APIs and behavior may change. For the latest documentation and updates, see the [official Vercel Workflow Python documentation](https://vercel.com/docs/
|
|
18
|
+
The Python SDK is currently in **beta**. APIs and behavior may change. For the latest documentation and updates, see the [official Vercel Workflow Python documentation](https://vercel.com/docs/workflows/python).
|
|
15
19
|
</Callout>
|
|
16
20
|
|
|
17
21
|
You can build durable workflows in Python using the [`vercel` Python SDK](https://pypi.org/project/vercel/). Your workflow code can pause, resume, and maintain state, just like the JavaScript and TypeScript Workflow SDK.
|
|
18
22
|
|
|
19
23
|
## Getting Started
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```bash filename="Terminal"
|
|
24
|
-
pip install vercel
|
|
25
|
-
```
|
|
25
|
+
Add the `vercel` package and workflow entrypoint to `pyproject.toml`:
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
```toml filename="pyproject.toml"
|
|
28
|
+
[project]
|
|
29
|
+
requires-python = ">=3.12"
|
|
30
|
+
dependencies = ["vercel"]
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"experimentalServices": {
|
|
32
|
-
"ai_content_workflow": {
|
|
33
|
-
"type": "worker",
|
|
34
|
-
"entrypoint": "app/workflows/ai_content_workflow.py",
|
|
35
|
-
"topics": ["__wkf_*"]
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
32
|
+
[[tool.vercel.workflows]]
|
|
33
|
+
entrypoint = "app.workflows:wf"
|
|
39
34
|
```
|
|
40
35
|
|
|
36
|
+
The workflow `entrypoint` uses the `module:object` format and points to the exported `Workflows` registry.
|
|
37
|
+
|
|
41
38
|
## Workflows
|
|
42
39
|
|
|
43
40
|
A workflow is a stateful function that coordinates multi-step logic over time. Create a `Workflows` instance and use the `@wf.workflow` decorator to mark a function as durable:
|
|
@@ -62,6 +59,15 @@ async def ai_content_workflow(*, topic: str):
|
|
|
62
59
|
}
|
|
63
60
|
```
|
|
64
61
|
|
|
62
|
+
Export the registry from the workflow package and import the module containing your workflow so its definitions are registered:
|
|
63
|
+
|
|
64
|
+
```python filename="app/workflows/__init__.py"
|
|
65
|
+
from app.workflow import wf
|
|
66
|
+
from app.workflows import ai_content_workflow
|
|
67
|
+
|
|
68
|
+
__all__ = ["ai_content_workflow", "wf"]
|
|
69
|
+
```
|
|
70
|
+
|
|
65
71
|
Under the hood, the workflow compiles into a route that orchestrates execution. All inputs and outputs are recorded in an event log. If a deploy or crash happens, the system replays execution deterministically from where it stopped.
|
|
66
72
|
|
|
67
73
|
## Steps
|
|
@@ -156,7 +162,7 @@ When a hook receives data, the workflow resumes automatically. You don't ne
|
|
|
156
162
|
|
|
157
163
|
## Learn More
|
|
158
164
|
|
|
159
|
-
For comprehensive documentation, examples, and the latest updates, visit the [official Vercel Workflow Python documentation](https://vercel.com/docs/
|
|
165
|
+
For comprehensive documentation, examples, and the latest updates, visit the [official Vercel Workflow Python documentation](https://vercel.com/docs/workflows/python).
|
|
160
166
|
|
|
161
167
|
## Next Steps
|
|
162
168
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: React Router
|
|
3
|
+
description: Run durable workflows in a React Router framework-mode app using Nitro.
|
|
4
|
+
type: overview
|
|
5
|
+
summary: Choose your React Router version and connect React Router, Nitro, and Workflow SDK.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/getting-started/nitro
|
|
8
|
+
- /docs/getting-started/vite
|
|
9
|
+
- /docs/foundations/workflows-and-steps
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
React Router framework mode builds the browser application and its server-rendering code, but it still needs a server to receive requests. [Nitro](https://v3.nitro.build) provides that server. Workflow SDK integrates with Nitro to add the durable workflow routes and build artifacts.
|
|
13
|
+
|
|
14
|
+
The three pieces share one Vite build:
|
|
15
|
+
|
|
16
|
+
1. **React Router** builds your routes, loaders, actions, and browser assets.
|
|
17
|
+
2. **Nitro** runs the React Router request handler and any routes in `server/routes`.
|
|
18
|
+
3. **Workflow SDK** finds files with `"use workflow"` and `"use step"`, then adds its runtime routes to Nitro.
|
|
19
|
+
|
|
20
|
+
Choose the guide that matches your React Router major version:
|
|
21
|
+
|
|
22
|
+
<AutoCards />
|
|
23
|
+
|
|
24
|
+
<Callout>
|
|
25
|
+
These guides require **Nitro v3**. Nitro v2 does not provide the Vite
|
|
26
|
+
environment integration used by this setup.
|
|
27
|
+
</Callout>
|
|
28
|
+
|
|
29
|
+
## What the bridge does
|
|
30
|
+
|
|
31
|
+
The setup adds a small `server/ssr.ts` file. It turns React Router's generated server build into a standard Fetch API handler that Nitro can run. The Vite config then points Nitro's server and public output at the same `build` directory React Router uses.
|
|
32
|
+
|
|
33
|
+
This is configuration in your application, not a separate React Router adapter. Your React Router routes remain React Router routes, while Nitro owns the HTTP server and Workflow SDK uses Nitro's lifecycle and routing.
|
|
@@ -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.
|