workflow 5.0.0-beta.5 → 5.0.0-beta.50
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 +29 -26
- package/docs/ai/defining-tools.mdx +6 -7
- package/docs/ai/human-in-the-loop.mdx +11 -11
- package/docs/ai/index.mdx +50 -45
- package/docs/ai/message-queueing.mdx +16 -16
- 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 +24 -0
- 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 +48 -86
- package/docs/api-reference/workflow-ai/index.mdx +3 -3
- 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 +376 -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 +28 -20
- package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +27 -19
- package/docs/cookbook/agent-patterns/durable-agent.mdx +14 -142
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +30 -22
- 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 +85 -47
- 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 +29 -18
- package/docs/errors/deployment-mismatch.mdx +71 -0
- package/docs/errors/fetch-in-workflow.mdx +11 -7
- 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 +107 -59
- 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 +135 -40
- 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 +98 -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 +93 -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
|
@@ -14,18 +14,18 @@ import { File, Folder, Files } from "fumadocs-ui/components/files";
|
|
|
14
14
|
|
|
15
15
|
Workflows (a.k.a. *durable functions*) are a programming model for building long-running, stateful application logic that can maintain its execution state across restarts, failures, or user events. Unlike traditional serverless functions that lose all state when they terminate, workflows persist their progress and can resume exactly where they left off.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Workflows let you model complex multi-step processes in code. To do this, we introduce two fundamental entities:
|
|
18
18
|
|
|
19
19
|
1. **Workflow Functions**: Functions that orchestrate/organize steps
|
|
20
20
|
2. **Step Functions**: Functions that carry out the actual work
|
|
21
21
|
|
|
22
|
-
## Workflow
|
|
22
|
+
## Workflow functions
|
|
23
23
|
|
|
24
24
|
*Directive: `"use workflow"`*
|
|
25
25
|
|
|
26
26
|
Workflow functions define the entrypoint of a workflow and organize how step functions are called. This type of function does not have access to the Node.js runtime, and usable `npm` packages are limited.
|
|
27
27
|
|
|
28
|
-
Although this may seem limiting initially, this feature is
|
|
28
|
+
Although this may seem limiting initially, this feature is required to suspend and accurately resume workflow execution.
|
|
29
29
|
|
|
30
30
|
It helps to think of the workflow function less like a full JavaScript runtime and more like "stitching together" various steps using conditionals, loops, try/catch handlers, `Promise.all`, and other language primitives.
|
|
31
31
|
|
|
@@ -51,7 +51,7 @@ Determinism in the workflow is required to resume the workflow from a suspension
|
|
|
51
51
|
|
|
52
52
|
The sandboxed environment that workflows run in already ensures determinism. For instance, `Math.random` and `Date` constructors are fixed in workflow runs, so you are safe to use them, and the framework ensures that the values don't change across replays.
|
|
53
53
|
|
|
54
|
-
## Step
|
|
54
|
+
## Step functions
|
|
55
55
|
|
|
56
56
|
*Directive: `"use step"`*
|
|
57
57
|
|
|
@@ -115,10 +115,10 @@ export async function POST() {
|
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
<Callout type="info">
|
|
118
|
-
|
|
118
|
+
Calling a step function outside a workflow function provides neither retry semantics nor observability. Additionally, certain workflow-specific functions like [`getStepMetadata()`](/docs/api-reference/workflow/get-step-metadata) will throw an error when used inside a step that's called outside a workflow.
|
|
119
119
|
</Callout>
|
|
120
120
|
|
|
121
|
-
### Suspension and
|
|
121
|
+
### Suspension and resumption
|
|
122
122
|
|
|
123
123
|
Workflow functions have the ability to automatically suspend while they wait on asynchronous work. While suspended, the workflow's state is stored via the [event log](/docs/how-it-works/event-sourcing) and no compute resources are used until the workflow resumes execution.
|
|
124
124
|
|
|
@@ -126,7 +126,7 @@ Workflow functions have the ability to automatically suspend while they wait on
|
|
|
126
126
|
|
|
127
127
|
There are multiple ways a workflow can suspend:
|
|
128
128
|
|
|
129
|
-
- Waiting on a step function: the workflow yields while the step runs in the step
|
|
129
|
+
- Waiting on a step function: the workflow yields while the step body runs. The step usually executes inline in the same invocation; when the invocation's inline budget is exhausted or its timeout approaches, the step is handed to the queue and the workflow resumes in a later invocation.
|
|
130
130
|
- Using `sleep()` to pause for some fixed duration.
|
|
131
131
|
- Awaiting on a promise returned by [`createWebhook()`](/docs/api-reference/workflow/create-webhook), which resumes the workflow when an external system passes data into the workflow.
|
|
132
132
|
|
|
@@ -150,9 +150,9 @@ export async function documentReviewProcess(userId: string) {
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
## Writing
|
|
153
|
+
## Writing workflows
|
|
154
154
|
|
|
155
|
-
### Basic
|
|
155
|
+
### Basic structure
|
|
156
156
|
|
|
157
157
|
The simplest workflow consists of a workflow function and one or more step functions.
|
|
158
158
|
|
|
@@ -9,16 +9,20 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Astro app, run `npm i workflow`. In `astro.config.mjs`, import `workflow` from `workflow/astro` and add `integrations: [workflow()]`. Add the TypeScript plugin `{ "name": "workflow" }` to `tsconfig.json` if TypeScript is used. Create `src/workflows/user-signup.ts` exporting `handleUserSignup(email)` with `"use workflow"`, `sleep` from `workflow`, and `"use step"` helpers. Add `src/pages/api/signup.ts` exporting `POST: APIRoute` that reads `{ email }`, calls `start(handleUserSignup, [email])` from `workflow/api`, returns `Response.json`, and sets `prerender = false`. Run `npm run dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:4321/api/signup`, and inspect with `npx workflow inspect runs`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
Set up your first durable workflow in an Astro 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 Astro project
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
Create an Astro project in a new directory named `my-workflow-app`:
|
|
22
26
|
|
|
23
27
|
```bash
|
|
24
28
|
npm create astro@latest my-workflow-app -- --template minimal --install --yes
|
|
@@ -55,16 +59,16 @@ export default defineConfig({
|
|
|
55
59
|
|
|
56
60
|
| Option | Type | Default | Description |
|
|
57
61
|
| --- | --- | --- | --- |
|
|
58
|
-
| `sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` | Controls source maps on generated workflow bundles. Accepts the same values as esbuild's `sourcemap` option.
|
|
62
|
+
| `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. |
|
|
59
63
|
|
|
60
64
|
<Accordion type="single" collapsible>
|
|
61
65
|
<AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
|
|
62
66
|
<AccordionTrigger className="text-sm">
|
|
63
|
-
###
|
|
67
|
+
### Set up IntelliSense for TypeScript (optional)
|
|
64
68
|
</AccordionTrigger>
|
|
65
69
|
<AccordionContent className="[&_p]:my-2">
|
|
66
70
|
|
|
67
|
-
To enable helpful hints in your IDE,
|
|
71
|
+
To enable helpful hints in your IDE, set up the workflow plugin in `tsconfig.json`:
|
|
68
72
|
|
|
69
73
|
```json title="tsconfig.json" lineNumbers
|
|
70
74
|
{
|
|
@@ -87,7 +91,7 @@ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json
|
|
|
87
91
|
|
|
88
92
|
<Step>
|
|
89
93
|
|
|
90
|
-
## Create
|
|
94
|
+
## Create your first workflow
|
|
91
95
|
|
|
92
96
|
Create a new file for our first workflow:
|
|
93
97
|
|
|
@@ -108,14 +112,14 @@ export async function handleUserSignup(email: string) {
|
|
|
108
112
|
|
|
109
113
|
```
|
|
110
114
|
|
|
111
|
-
We'll fill in those functions next, but
|
|
115
|
+
We'll fill in those functions next, but first review this code:
|
|
112
116
|
|
|
113
117
|
* We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
114
118
|
* 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.
|
|
115
119
|
|
|
116
|
-
## Create
|
|
120
|
+
## Create your workflow steps
|
|
117
121
|
|
|
118
|
-
|
|
122
|
+
Define the missing functions.
|
|
119
123
|
|
|
120
124
|
```typescript title="src/workflows/user-signup.ts" lineNumbers
|
|
121
125
|
import { FatalError } from "workflow"
|
|
@@ -156,7 +160,7 @@ async function sendOnboardingEmail(user: { id: string; email: string}) {
|
|
|
156
160
|
|
|
157
161
|
Taking a look at this code:
|
|
158
162
|
|
|
159
|
-
* Business logic lives inside **steps**. When a
|
|
163
|
+
* 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.
|
|
160
164
|
* 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).
|
|
161
165
|
* Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
162
166
|
|
|
@@ -168,7 +172,7 @@ We'll dive deeper into workflows, steps, and other ways to suspend or handle eve
|
|
|
168
172
|
|
|
169
173
|
<Step>
|
|
170
174
|
|
|
171
|
-
## Create
|
|
175
|
+
## Create your route handler
|
|
172
176
|
|
|
173
177
|
To invoke your new workflow, we'll have to add your workflow to a `POST` API route handler, `src/pages/api/signup.ts` with the following code:
|
|
174
178
|
|
|
@@ -200,7 +204,7 @@ Workflows can be triggered from API routes or any server-side code.
|
|
|
200
204
|
|
|
201
205
|
</Steps>
|
|
202
206
|
|
|
203
|
-
## Run in
|
|
207
|
+
## Run in development
|
|
204
208
|
|
|
205
209
|
To start your development server, run the following command in your terminal in the Vite root directory:
|
|
206
210
|
|
|
@@ -227,9 +231,9 @@ npx workflow inspect runs
|
|
|
227
231
|
|
|
228
232
|
---
|
|
229
233
|
|
|
230
|
-
## Deploying to
|
|
234
|
+
## Deploying to production
|
|
231
235
|
|
|
232
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
236
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
233
237
|
|
|
234
238
|
<FluidComputeCallout />
|
|
235
239
|
|
|
@@ -247,8 +251,8 @@ Additionally, check the [Deploying](/docs/deploying) section to learn how your w
|
|
|
247
251
|
|
|
248
252
|
If you see this error:
|
|
249
253
|
|
|
250
|
-
```
|
|
251
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
254
|
+
```text
|
|
255
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
252
256
|
```
|
|
253
257
|
|
|
254
258
|
Check both of these first:
|
|
@@ -258,7 +262,7 @@ Check both of these first:
|
|
|
258
262
|
|
|
259
263
|
See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
|
|
260
264
|
|
|
261
|
-
## Next
|
|
265
|
+
## Next steps
|
|
262
266
|
|
|
263
267
|
* Learn more about the [Foundations](/docs/foundations).
|
|
264
268
|
* Check [Errors](/docs/errors) if you encounter issues.
|
|
@@ -9,6 +9,10 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Express app, run `npm i workflow express nitro rollup` and, if using TypeScript, `npm i -D @types/express`. Create `nitro.config.ts` with `modules: ["workflow/nitro"]`, `vercel: { entryFormat: "node" }`, and `routes: { "/**": { handler: "./src/index.ts", format: "node" } }`. Add package scripts `dev: "nitro dev"` and `build: "nitro build"`. Create `workflows/user-signup.ts` with `"use workflow"`, `sleep`, and `"use step"` helpers. Add `src/index.ts` with Express JSON middleware, POST `/api/signup`, and `start(handleUserSignup, [email])` from `workflow/api`. 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
|
This guide will walk through setting up your first workflow in an Express 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
|
---
|
|
@@ -16,7 +20,7 @@ This guide will walk through setting up your first workflow in an Express app. A
|
|
|
16
20
|
<Steps>
|
|
17
21
|
|
|
18
22
|
<Step>
|
|
19
|
-
## Create
|
|
23
|
+
## Create your Express project
|
|
20
24
|
|
|
21
25
|
Start by creating a new Express project.
|
|
22
26
|
|
|
@@ -113,7 +117,7 @@ To use the Nitro builder, update your `package.json` to include the following sc
|
|
|
113
117
|
|
|
114
118
|
<Step>
|
|
115
119
|
|
|
116
|
-
## Create
|
|
120
|
+
## Create your first workflow
|
|
117
121
|
|
|
118
122
|
Create a new file for our first workflow:
|
|
119
123
|
|
|
@@ -133,14 +137,14 @@ export async function handleUserSignup(email: string) {
|
|
|
133
137
|
}
|
|
134
138
|
```
|
|
135
139
|
|
|
136
|
-
We'll fill in those functions next
|
|
140
|
+
We'll fill in those functions next. The current code does the following:
|
|
137
141
|
|
|
138
142
|
- We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
139
143
|
- 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.
|
|
140
144
|
|
|
141
|
-
## Create
|
|
145
|
+
## Create your workflow steps
|
|
142
146
|
|
|
143
|
-
|
|
147
|
+
Define the missing functions.
|
|
144
148
|
|
|
145
149
|
```typescript title="workflows/user-signup.ts" lineNumbers
|
|
146
150
|
import { FatalError } from "workflow";
|
|
@@ -181,7 +185,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
181
185
|
|
|
182
186
|
Taking a look at this code:
|
|
183
187
|
|
|
184
|
-
- Business logic lives inside **steps**. When a
|
|
188
|
+
- 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.
|
|
185
189
|
- 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).
|
|
186
190
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
187
191
|
|
|
@@ -194,7 +198,7 @@ Taking a look at this code:
|
|
|
194
198
|
|
|
195
199
|
<Step>
|
|
196
200
|
|
|
197
|
-
## Create
|
|
201
|
+
## Create your route handler
|
|
198
202
|
|
|
199
203
|
To invoke your new workflow, we'll create both the Express app and a new API route handler at `src/index.ts` with the following code:
|
|
200
204
|
|
|
@@ -256,7 +260,7 @@ npx workflow inspect runs
|
|
|
256
260
|
|
|
257
261
|
## Deploying to production
|
|
258
262
|
|
|
259
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
263
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
260
264
|
|
|
261
265
|
<FluidComputeCallout />
|
|
262
266
|
|
|
@@ -268,8 +272,8 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
268
272
|
|
|
269
273
|
If you see this error:
|
|
270
274
|
|
|
271
|
-
```
|
|
272
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
275
|
+
```text
|
|
276
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
273
277
|
```
|
|
274
278
|
|
|
275
279
|
Check both of these first:
|
|
@@ -279,7 +283,7 @@ Check both of these first:
|
|
|
279
283
|
|
|
280
284
|
See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
|
|
281
285
|
|
|
282
|
-
## Next
|
|
286
|
+
## Next steps
|
|
283
287
|
|
|
284
288
|
- Learn more about the [Foundations](/docs/foundations).
|
|
285
289
|
- Check [Errors](/docs/errors) if you encounter issues.
|
|
@@ -9,6 +9,10 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Fastify app, run `npm i workflow fastify nitro rollup` and, if using TypeScript, `npm i -D @types/node typescript`. Create `nitro.config.ts` with `modules: ["workflow/nitro"]`, `vercel: { entryFormat: "node" }`, and `routes: { "/**": { handler: "./src/index.ts", format: "node" } }`. Add package scripts `dev: "nitro dev"` and `build: "nitro build"`. Create `workflows/user-signup.ts` with `"use workflow"`, `sleep`, and `"use step"` helpers. Add `src/index.ts` with a Fastify app, POST `/api/signup`, `start(handleUserSignup, [email])`, `await app.ready()`, and an exported request handler. Run `npm run dev`, call `curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup`, and inspect with `npx workflow inspect runs --web`."
|
|
14
|
+
/>
|
|
15
|
+
|
|
12
16
|
This guide will walk through setting up your first workflow in a Fastify 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
|
---
|
|
@@ -16,7 +20,7 @@ This guide will walk through setting up your first workflow in a Fastify app. Al
|
|
|
16
20
|
<Steps>
|
|
17
21
|
|
|
18
22
|
<Step>
|
|
19
|
-
## Create
|
|
23
|
+
## Create your Fastify project
|
|
20
24
|
|
|
21
25
|
Start by creating a new Fastify project.
|
|
22
26
|
|
|
@@ -112,7 +116,7 @@ To use the Nitro builder, update your `package.json` to include the following sc
|
|
|
112
116
|
|
|
113
117
|
<Step>
|
|
114
118
|
|
|
115
|
-
## Create
|
|
119
|
+
## Create your first workflow
|
|
116
120
|
|
|
117
121
|
Create a new file for our first workflow:
|
|
118
122
|
|
|
@@ -132,13 +136,13 @@ export async function handleUserSignup(email: string) {
|
|
|
132
136
|
}
|
|
133
137
|
```
|
|
134
138
|
|
|
135
|
-
We'll fill in those functions next
|
|
139
|
+
We'll fill in those functions next. The current code does the following:
|
|
136
140
|
|
|
137
141
|
- We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
138
142
|
- 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.
|
|
139
|
-
## Create
|
|
143
|
+
## Create your workflow steps
|
|
140
144
|
|
|
141
|
-
|
|
145
|
+
Define the missing functions:
|
|
142
146
|
```typescript title="workflows/user-signup.ts" lineNumbers
|
|
143
147
|
import { FatalError } from "workflow";
|
|
144
148
|
|
|
@@ -170,7 +174,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
170
174
|
```
|
|
171
175
|
Taking a look at this code:
|
|
172
176
|
|
|
173
|
-
- Business logic lives inside **steps**. When a
|
|
177
|
+
- 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.
|
|
174
178
|
- 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).
|
|
175
179
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
176
180
|
|
|
@@ -182,7 +186,7 @@ Taking a look at this code:
|
|
|
182
186
|
|
|
183
187
|
<Step>
|
|
184
188
|
|
|
185
|
-
## Create
|
|
189
|
+
## Create your route handler
|
|
186
190
|
|
|
187
191
|
To invoke your new workflow, we'll create both the Fastify app and a new API route handler at `src/index.ts` with the following code:
|
|
188
192
|
|
|
@@ -243,7 +247,7 @@ npx workflow inspect runs # add '--web' for an interactive Web based UI
|
|
|
243
247
|
|
|
244
248
|
## Deploying to production
|
|
245
249
|
|
|
246
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
250
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
247
251
|
|
|
248
252
|
<FluidComputeCallout />
|
|
249
253
|
|
|
@@ -255,8 +259,8 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
255
259
|
|
|
256
260
|
If you see this error:
|
|
257
261
|
|
|
258
|
-
```
|
|
259
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
262
|
+
```text
|
|
263
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
260
264
|
```
|
|
261
265
|
|
|
262
266
|
Check both of these first:
|
|
@@ -266,7 +270,7 @@ Check both of these first:
|
|
|
266
270
|
|
|
267
271
|
See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
|
|
268
272
|
|
|
269
|
-
## Next
|
|
273
|
+
## Next steps
|
|
270
274
|
|
|
271
275
|
- Learn more about the [Foundations](/docs/foundations).
|
|
272
276
|
- Check [Errors](/docs/errors) if you encounter issues.
|
|
@@ -9,10 +9,14 @@ related:
|
|
|
9
9
|
- /docs/foundations/workflows-and-steps
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<CopyPrompt
|
|
13
|
+
text="In this Hono app, run `npm i workflow nitro rollup`. Create `nitro.config.ts` with `modules: ["workflow/nitro"]` and `routes: { "/**": "./src/index.ts" }`. Add package scripts `dev: "nitro dev"` and `build: "nitro build"`. 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 `src/index.ts` with a Hono app, POST `/api/signup`, `start(handleUserSignup, [email])` from `workflow/api`, and JSON response. 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>
|
|
15
|
-
## Create
|
|
19
|
+
## Create your Hono project
|
|
16
20
|
|
|
17
21
|
Start by creating a new Hono project. This command will create a new directory named `my-workflow-app` and set up a Hono project inside it.
|
|
18
22
|
|
|
@@ -96,7 +100,7 @@ To use the Nitro builder, update your `package.json` to include the following sc
|
|
|
96
100
|
|
|
97
101
|
<Step>
|
|
98
102
|
|
|
99
|
-
## Create
|
|
103
|
+
## Create your first workflow
|
|
100
104
|
|
|
101
105
|
Create a new file for our first workflow:
|
|
102
106
|
|
|
@@ -118,14 +122,14 @@ export async function handleUserSignup(email: string) {
|
|
|
118
122
|
}
|
|
119
123
|
```
|
|
120
124
|
|
|
121
|
-
We'll fill in those functions next
|
|
125
|
+
We'll fill in those functions next. The current code does the following:
|
|
122
126
|
|
|
123
127
|
- We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
|
|
124
128
|
- 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.
|
|
125
129
|
|
|
126
|
-
## Create
|
|
130
|
+
## Create your workflow steps
|
|
127
131
|
|
|
128
|
-
|
|
132
|
+
Define the missing functions.
|
|
129
133
|
|
|
130
134
|
```typescript title="workflows/user-signup.ts" lineNumbers
|
|
131
135
|
import { FatalError } from "workflow";
|
|
@@ -166,7 +170,7 @@ async function sendOnboardingEmail(user: { id: string; email: string }) {
|
|
|
166
170
|
|
|
167
171
|
Taking a look at this code:
|
|
168
172
|
|
|
169
|
-
- Business logic lives inside **steps**. When a
|
|
173
|
+
- 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.
|
|
170
174
|
- 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).
|
|
171
175
|
- Steps can throw a `FatalError` if an error is intentional and should not be retried.
|
|
172
176
|
|
|
@@ -179,7 +183,7 @@ Taking a look at this code:
|
|
|
179
183
|
|
|
180
184
|
<Step>
|
|
181
185
|
|
|
182
|
-
## Create
|
|
186
|
+
## Create your route handler
|
|
183
187
|
|
|
184
188
|
To invoke your new workflow, we'll create a new API route handler at `src/index.ts` with the following code:
|
|
185
189
|
|
|
@@ -238,7 +242,7 @@ npx workflow inspect runs
|
|
|
238
242
|
|
|
239
243
|
## Deploying to production
|
|
240
244
|
|
|
241
|
-
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and
|
|
245
|
+
Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
|
|
242
246
|
|
|
243
247
|
<FluidComputeCallout />
|
|
244
248
|
|
|
@@ -250,8 +254,8 @@ Check the [Deploying](/docs/deploying) section to learn how your workflows can b
|
|
|
250
254
|
|
|
251
255
|
If you see this error:
|
|
252
256
|
|
|
253
|
-
```
|
|
254
|
-
'start' received an invalid workflow function. Ensure the Workflow
|
|
257
|
+
```text
|
|
258
|
+
'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.
|
|
255
259
|
```
|
|
256
260
|
|
|
257
261
|
Check both of these first:
|
|
@@ -261,7 +265,7 @@ Check both of these first:
|
|
|
261
265
|
|
|
262
266
|
See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
|
|
263
267
|
|
|
264
|
-
## Next
|
|
268
|
+
## Next steps
|
|
265
269
|
|
|
266
270
|
- Learn more about the [Foundations](/docs/foundations).
|
|
267
271
|
- Check [Errors](/docs/errors) if you encounter issues.
|
|
@@ -9,6 +9,7 @@ related:
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStack, Vite, Express, Nest, Fastify, Python } from "@/app/[lang]/(home)/components/frameworks";
|
|
12
|
+
import { SiReactrouter } from "@icons-pack/react-simple-icons";
|
|
12
13
|
|
|
13
14
|
<Cards>
|
|
14
15
|
<Card href="/docs/getting-started/next">
|
|
@@ -20,6 +21,12 @@ import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStac
|
|
|
20
21
|
<span className="font-medium">Vite</span>
|
|
21
22
|
</div>
|
|
22
23
|
</Card>
|
|
24
|
+
<Card href="/docs/getting-started/react-router">
|
|
25
|
+
<div className="flex flex-col items-center justify-center gap-2">
|
|
26
|
+
<SiReactrouter className="size-16" />
|
|
27
|
+
<span className="font-medium">React Router</span>
|
|
28
|
+
</div>
|
|
29
|
+
</Card>
|
|
23
30
|
<Card href="/docs/getting-started/astro">
|
|
24
31
|
<div className="flex flex-col items-center justify-center gap-2">
|
|
25
32
|
<AstroLight className="size-16 dark:hidden" />
|
|
@@ -76,11 +83,11 @@ import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStac
|
|
|
76
83
|
<Badge variant="secondary">Beta</Badge>
|
|
77
84
|
</div>
|
|
78
85
|
</Card>
|
|
79
|
-
<Card
|
|
86
|
+
<Card href="/docs/getting-started/nestjs">
|
|
80
87
|
<div className="flex flex-col items-center justify-center gap-2">
|
|
81
|
-
<Nest className="size-16 dark:invert
|
|
88
|
+
<Nest className="size-16 dark:invert" />
|
|
82
89
|
<span className="font-medium">NestJS</span>
|
|
83
|
-
<Badge variant="secondary">
|
|
90
|
+
<Badge variant="secondary">Experimental</Badge>
|
|
84
91
|
</div>
|
|
85
92
|
</Card>
|
|
86
93
|
</Cards>
|