Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
a031e41
remove suppressUndefinedRejections from base builder
adriandlam Nov 21, 2025
cf55563
Normalize Workbenches
pranaygp Nov 10, 2025
22838db
fix: normalize workbench tests (#292)
adriandlam Nov 12, 2025
f820ae1
fix: cleanup builder directories (#319)
adriandlam Nov 13, 2025
559a29c
refactor(nitro): use suppressUndefinedRejections
adriandlam Nov 13, 2025
fb80857
feat(astro): add @workflow/astro
adriandlam Nov 14, 2025
70a8040
add astro workbench
adriandlam Nov 14, 2025
4885fa7
test: add astro test
adriandlam Nov 14, 2025
9e21854
feat(astro): add prefixer to non-api routes in builder
adriandlam Nov 14, 2025
c2c7aa8
revert sveltekit builder change
adriandlam Nov 14, 2025
bfedace
chore: cleanup astro stuff
adriandlam Nov 14, 2025
69d8f13
test: add astro
adriandlam Nov 14, 2025
e0429ef
fix: add astro deps
adriandlam Nov 14, 2025
4220272
fix(astro): add vercel.json to ensure pnpm version detection
adriandlam Nov 14, 2025
46f1efc
update project id on astro
adriandlam Nov 14, 2025
5bdb657
fix(astro): add .npmrc with engine-strict to enforce pnpm version
adriandlam Nov 14, 2025
e5de41f
cleanup
adriandlam Nov 14, 2025
d1edbcb
remove package lock
adriandlam Nov 14, 2025
d4be48a
fix: disable cross site origin check
adriandlam Nov 14, 2025
d7d482a
.
adriandlam Nov 14, 2025
33403eb
add astro start command
adriandlam Nov 14, 2025
ddaba65
update symlink
adriandlam Nov 14, 2025
b8c6355
fix astro test config
adriandlam Nov 14, 2025
671ad64
fix: override path-to-regexp to patched version 6.3.0 to resolve CVE
adriandlam Nov 14, 2025
b902021
fix: missing vercel functions on astro builder
adriandlam Nov 14, 2025
db060ce
test
adriandlam Nov 14, 2025
db3777a
test
adriandlam Nov 14, 2025
33f4e89
fix: dev tests
adriandlam Nov 14, 2025
2cbb493
add astro to local build
adriandlam Nov 14, 2025
1c50a05
fix: add prefixes to debug files in local builder
adriandlam Nov 14, 2025
35ea400
add index to astro workbench for demoing
adriandlam Nov 14, 2025
ec23071
add output to astro config
adriandlam Nov 14, 2025
d4205c7
fix: astro vercel adapter overwriting vercel workflow config
adriandlam Nov 14, 2025
3e965bf
testing astro bundling
adriandlam Nov 15, 2025
89302a2
update vercel workflow output route ordering
adriandlam Nov 15, 2025
7745954
fix: check vercel env var for astro vercel builder
adriandlam Nov 15, 2025
7f50e44
fix: not building workflows locally
adriandlam Nov 15, 2025
fd257c1
chore: remove generated _workflow.ts
adriandlam Nov 15, 2025
04c34b6
chore: cleanup
adriandlam Nov 15, 2025
2548842
chore(deps): lock deps
adriandlam Nov 15, 2025
86a2c0f
changeset stuff
adriandlam Nov 15, 2025
b19cb54
Apply suggestion from @vercel[bot]
adriandlam Nov 15, 2025
012a504
changeset
adriandlam Nov 15, 2025
bee5046
Apply suggestions from code review
adriandlam Nov 21, 2025
515802f
format
adriandlam Nov 21, 2025
5594f70
refactor: cleanup astro plugin name and add comment on csrf protectiopn
adriandlam Nov 21, 2025
a97a9ba
chore(deps): cleanup astro deps
adriandlam Nov 21, 2025
d0748c8
revert docs frameworks page
adriandlam Nov 21, 2025
09ac372
format
adriandlam Nov 21, 2025
6e75c80
docs: update supported frameworks and index
adriandlam Nov 21, 2025
6747006
docs: add astro getting started
adriandlam Nov 21, 2025
14a0da7
Update packages/astro/src/builder.ts
adriandlam Nov 21, 2025
6b3bfe5
test: add astro dev test workflowsDir
adriandlam Nov 21, 2025
9d49861
fix: update base builder to accept debug prefix
adriandlam Nov 21, 2025
c233221
lockfile
adriandlam Nov 21, 2025
70f0d4b
Update packages/astro/src/plugin.ts
adriandlam Nov 21, 2025
c5658f7
test: add astro to cross file test
adriandlam Nov 21, 2025
54b4be4
fix astro symlink
adriandlam Nov 21, 2025
514ca35
remove example worklfow hack
adriandlam Nov 21, 2025
85ce395
fix symlink
adriandlam Nov 21, 2025
cdfbe27
fix index astrofile
adriandlam Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@workflow/example-nitro-v2",
"@workflow/example-nuxt",
"@workflow/example-vite",
"@workflow/example-sveltekit"
"@workflow/example-sveltekit",
"@workflow/example-astro"
]
}
7 changes: 7 additions & 0 deletions .changeset/grumpy-ties-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@workflow/builders": patch
"workflow": patch
"@workflow/astro": patch
---

Add @workflow/astro package
1 change: 1 addition & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@workflow/example-nuxt": "0.0.0",
"@workflow/example-vite": "0.0.0",
"@workflow/example-sveltekit": "0.0.0",
"@workflow/example-astro": "0.0.0",
"@workflow/builders": "4.0.1-beta.3",
"@workflow/sveltekit": "4.0.0-beta.1",
"@workflow/nuxt": "4.0.1-beta.6"
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ jobs:
project-id: "prj_p0GIEsfl53L7IwVbosPvi9rPSOYW"
- name: "express"
project-id: "prj_cCZjpBy92VRbKHHbarDMhOHtkuIr"
- name: "astro"
project-id: "prj_YDAXj3K8LM0hgejuIMhioz2yLgTI"
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
Expand Down Expand Up @@ -191,7 +193,7 @@ jobs:
run: cd workbench/${{ matrix.app.name }} && pnpm dev & echo "starting tests in 10 seconds" && sleep 10 && pnpm vitest run packages/core/e2e/dev.test.ts && pnpm run test:e2e
env:
APP_NAME: ${{ matrix.app.name }}
DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '5173' || '3000' }}"
DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '5173' || (matrix.app.name == 'astro' && '4321' || '3000') }}"
DEV_TEST_CONFIG: ${{ toJSON(matrix.app) }}

e2e-local-prod:
Expand Down Expand Up @@ -243,7 +245,7 @@ jobs:
run: cd workbench/${{ matrix.app.name }} && pnpm start & echo "starting tests in 10 seconds" && sleep 10 && pnpm run test:e2e
env:
APP_NAME: ${{ matrix.app.name }}
DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '4173' || '3000' }}"
DEPLOYMENT_URL: "http://localhost:${{ matrix.app.name == 'sveltekit' && '4173' || (matrix.app.name == 'astro' && '4321' || '3000') }}"

e2e-local-postgres:
name: E2E Local Postgres Tests (${{ matrix.app.name }} - ${{ matrix.app.canary && 'canary' || 'stable' }})
Expand Down
235 changes: 130 additions & 105 deletions docs/app/(home)/components/frameworks.tsx

Large diffs are not rendered by default.

233 changes: 233 additions & 0 deletions docs/content/docs/getting-started/astro.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
---
title: Astro
---

This guide will walk through setting up your first workflow in an Astro app. Along the way, you'll learn more about the concepts that are fundamental to using the development kit in your own projects.

---

<Steps>

<Step>
## Create Your Astro Project

Start by creating a new Astro project. This command will create a new directory named `my-workflow-app` and setup a minimal Astro project inside it.

```bash
npm create astro@latest my-workflow-app -- --template minimal --install --yes
```

Enter the newly made directory:

```bash
cd my-workflow-app
```

### Install `workflow`

```package-install
npm i workflow
```

### Configure Astro

Add `workflow()` to your Astro config. This enables usage of the `"use workflow"` and `"use step"` directives.

```typescript title="astro.config.mjs" lineNumbers
// @ts-check
import { defineConfig } from "astro/config";
import { workflow } from "workflow/astro";

// https://astro.build/config
export default defineConfig({
integrations: [workflow()],
});
```

<Accordion type="single" collapsible>
<AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
<AccordionTrigger className="text-sm">
### Setup IntelliSense for TypeScript (Optional)
</AccordionTrigger>
<AccordionContent className="[&_p]:my-2">

To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json`:

```json title="tsconfig.json" lineNumbers
{
"compilerOptions": {
// ... rest of your TypeScript config
"plugins": [
{
"name": "workflow" // [!code highlight]
}
]
}
}
```

</AccordionContent>
</AccordionItem>
</Accordion>

</Step>

<Step>

## Create Your First Workflow

Create a new file for our first workflow:

```typescript title="src/workflows/user-signup.ts" lineNumbers
import { sleep } from "workflow";

export async function handleUserSignup(email: string) {
"use workflow"; // [!code highlight]

const user = await createUser(email);
await sendWelcomeEmail(user);

await sleep("5s"); // Pause for 5s - doesn't consume any resources
await sendOnboardingEmail(user);

return { userId: user.id, status: "onboarded" };
}

```

We'll fill in those functions next, but let's take a look at this code:

* We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
* The Workflow DevKit'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.

## Create Your Workflow Steps

Let's now define those missing functions.

```typescript title="src/workflows/user-signup.ts" lineNumbers
import { FatalError } from "workflow"

// Our workflow function defined earlier

async function createUser(email: string) {
"use step"; // [!code highlight]

console.log(`Creating user with email: ${email}`);

// Full Node.js access - database calls, APIs, etc.
return { id: crypto.randomUUID(), email };
}

async function sendWelcomeEmail(user: { id: string; email: string; }) {
"use step"; // [!code highlight]

console.log(`Sending welcome email to user: ${user.id}`);

if (Math.random() < 0.3) {
// By default, steps will be retried for unhandled errors
throw new Error("Retryable!");
}
}

async function sendOnboardingEmail(user: { id: string; email: string}) {
"use step"; // [!code highlight]

if (!user.email.includes("@")) {
// To skip retrying, throw a FatalError instead
throw new FatalError("Invalid Email");
}

console.log(`Sending onboarding email to user: ${user.id}`);
}
```

Taking a look at this code:

* Business logic lives inside **steps**. When a step is invoked inside a **workflow**, it gets enqueued to run on a separate request while the workflow is suspended, just like `sleep`.
* 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).
* Steps can throw a `FatalError` if an error is intentional and should not be retried.

<Callout>
We'll dive deeper into workflows, steps, and other ways to suspend or handle events in [Foundations](/docs/foundations).
</Callout>

</Step>

<Step>

## Create Your Route Handler

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:

```typescript title="src/pages/api/signup.ts"
import type { APIRoute } from "astro";
import { start } from "workflow/api";
import { handleUserSignup } from "../../workflows/user-signup";

export const POST: APIRoute = async ({ request }: { request: Request }) => {
const { email } = await request.json();

// Executes asynchronously and doesn't block your app
await start(handleUserSignup, [email]);
return Response.json({
message: "User signup workflow started",
});
};

export const prerender = false; // Don't prerender this page since it's an API route
```

This route handler creates a `POST` request endpoint at `/api/signup` that will trigger your workflow.

<Callout>
Workflows can be triggered from API routes or any server-side code.
</Callout>

</Step>

</Steps>

## Run in Development

To start your development server, run the following command in your terminal in the Vite root directory:

```bash
npm run dev
```

Once your development server is running, you can trigger your workflow by running this command in the terminal:

```bash
curl -X POST --json '{"email":"[email protected]"}' http://localhost:5173/api/signup
```

Check the Astro development server logs to see your workflow execute as well as the steps that are being processed.

Additionally, you can use the [Workflow DevKit CLI or Web UI](/docs/observability) to inspect your workflow runs and steps in detail.

```bash
npx workflow inspect runs
# or add '--web' for an interactive Web based UI
```

<img src="/o11y-ui.png" alt="Workflow DevKit Web UI" />

---

## Deploying to Production

Workflow DevKit apps currently work best when deployed to [Vercel](https://vercel.com/home) and needs no special configuration.

To deploy your Astro project to Vercel, ensure that the [Astro Vercel adapter](https://docs.astro.build/en/guides/integrations-guide/vercel) is configured:

```bash
npx astro add vercel
```

Additionally, check the [Deploying](/docs/deploying) section to learn how your workflows can be deployed elsewhere.

## Next Steps

* Learn more about the [Foundations](/docs/foundations).
* Check [Errors](/docs/errors) if you encounter issues.
* Explore the [API Reference](/docs/api-reference).
31 changes: 17 additions & 14 deletions docs/content/docs/getting-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,59 @@ title: Getting Started
description: Start by choosing your framework. Each guide will walk you through the steps to install the dependencies and start running your first workflow.
---

import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStack, Vite, Express } from '@/app/(home)/components/frameworks';
import { Next, Nitro, SvelteKit, Nuxt, Hono, Bun, AstroDark, AstroLight, TanStack, Vite, Express, Nest } from '@/app/(home)/components/frameworks';

<Cards>
<Card href="/docs/getting-started/next">
<div className="flex flex-col items-center justify-center text-center gap-2">
<Next className="size-16" />
<span className="font-medium">Next.js</span>
</div>
<div className="flex flex-col items-center justify-center gap-2"> <Next className="size-16" /> <span className="font-medium">Next.js</span> </div>
</Card>
<Card href="/docs/getting-started/vite">
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<Vite className="size-16" />
<span className="font-medium">Vite</span>
</div>
</Card>
<Card href="/docs/getting-started/astro">
<div className="flex flex-col items-center justify-center gap-2">
<AstroLight className="size-16 dark:hidden" />
<AstroDark className="size-16 hidden dark:block" />
<span className="font-medium">Astro</span>
</div>
</Card>
<Card href="/docs/getting-started/express" >
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<Express className="size-16 dark:invert" />
<span className="font-medium">Express</span>
</div>
</Card>
<Card href="/docs/getting-started/hono">
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<Hono className="size-16" />
<span className="font-medium">Hono</span>
</div>
</Card>
<Card href="/docs/getting-started/nitro" >
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<Nitro className="size-16" />
<span className="font-medium">Nitro</span>
</div>
</Card>
<Card href="/docs/getting-started/nuxt" >
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<Nuxt className="size-16" />
<span className="font-medium">Nuxt</span>
</div>
</Card>
<Card href="/docs/getting-started/sveltekit" >
<div className="flex flex-col items-center justify-center text-center gap-2">
<div className="flex flex-col items-center justify-center gap-2">
<SvelteKit className="size-16" />
<span className="font-medium">SvelteKit</span>
</div>
</Card>
<Card className="opacity-50">
<div className="flex flex-col items-center justify-center gap-2">
<AstroLight className="size-16 dark:hidden grayscale" />
<AstroDark className="size-16 hidden dark:block grayscale" />
<span className="font-medium">Astro</span>
<Nest className="size-16 dark:invert grayscale" />
<span className="font-medium">NestJS</span>
<Badge variant="secondary">Coming soon</Badge>
</div>
</Card>
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"packageManager": "[email protected]+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd",
"pnpm": {
"overrides": {
"rfc6902": "5.1.2"
"rfc6902": "5.1.2",
"path-to-regexp": "6.3.0"
},
"onlyBuiltDependencies": [
"bun"
Expand Down
Loading
Loading