From 4153e42511ae1355f79dff2754886f6c985d9ba0 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Tue, 28 Oct 2025 17:27:39 -0700 Subject: [PATCH 01/63] add workbench sveltekit --- workbench/sveltekit/.gitignore | 23 +++++++++ workbench/sveltekit/.npmrc | 1 + workbench/sveltekit/README.md | 38 +++++++++++++++ workbench/sveltekit/package.json | 28 +++++++++++ workbench/sveltekit/src/app.d.ts | 13 +++++ workbench/sveltekit/src/app.html | 11 +++++ .../sveltekit/src/lib/assets/favicon.svg | 1 + workbench/sveltekit/src/lib/index.ts | 1 + workbench/sveltekit/src/routes/+layout.svelte | 11 +++++ workbench/sveltekit/src/routes/+page.svelte | 2 + .../sveltekit/src/routes/test/+server.ts | 8 ++++ workbench/sveltekit/static/robots.txt | 3 ++ workbench/sveltekit/svelte.config.js | 12 +++++ workbench/sveltekit/tsconfig.json | 19 ++++++++ workbench/sveltekit/vite.config.ts | 14 ++++++ workbench/sveltekit/workflows/user-signup.ts | 48 +++++++++++++++++++ 16 files changed, 233 insertions(+) create mode 100644 workbench/sveltekit/.gitignore create mode 100644 workbench/sveltekit/.npmrc create mode 100644 workbench/sveltekit/README.md create mode 100644 workbench/sveltekit/package.json create mode 100644 workbench/sveltekit/src/app.d.ts create mode 100644 workbench/sveltekit/src/app.html create mode 100644 workbench/sveltekit/src/lib/assets/favicon.svg create mode 100644 workbench/sveltekit/src/lib/index.ts create mode 100644 workbench/sveltekit/src/routes/+layout.svelte create mode 100644 workbench/sveltekit/src/routes/+page.svelte create mode 100644 workbench/sveltekit/src/routes/test/+server.ts create mode 100644 workbench/sveltekit/static/robots.txt create mode 100644 workbench/sveltekit/svelte.config.js create mode 100644 workbench/sveltekit/tsconfig.json create mode 100644 workbench/sveltekit/vite.config.ts create mode 100644 workbench/sveltekit/workflows/user-signup.ts diff --git a/workbench/sveltekit/.gitignore b/workbench/sveltekit/.gitignore new file mode 100644 index 000000000..3b462cb0c --- /dev/null +++ b/workbench/sveltekit/.gitignore @@ -0,0 +1,23 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/workbench/sveltekit/.npmrc b/workbench/sveltekit/.npmrc new file mode 100644 index 000000000..b6f27f135 --- /dev/null +++ b/workbench/sveltekit/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/workbench/sveltekit/README.md b/workbench/sveltekit/README.md new file mode 100644 index 000000000..75842c404 --- /dev/null +++ b/workbench/sveltekit/README.md @@ -0,0 +1,38 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json new file mode 100644 index 000000000..2b58ea7d3 --- /dev/null +++ b/workbench/sveltekit/package.json @@ -0,0 +1,28 @@ +{ + "name": "sveltekit", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@sveltejs/adapter-node": "^5.3.2", + "@sveltejs/kit": "^2.43.2", + "@sveltejs/vite-plugin-svelte": "^6.2.0", + "@workflow/sveltekit": "workspace:*", + "svelte": "^5.39.5", + "svelte-check": "^4.3.2", + "typescript": "^5.9.2", + "vite": "^7.1.7", + "vite-plugin-devtools-json": "^1.0.0" + }, + "dependencies": { + "workflow": "workspace:*" + } +} diff --git a/workbench/sveltekit/src/app.d.ts b/workbench/sveltekit/src/app.d.ts new file mode 100644 index 000000000..520c4217a --- /dev/null +++ b/workbench/sveltekit/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/workbench/sveltekit/src/app.html b/workbench/sveltekit/src/app.html new file mode 100644 index 000000000..f273cc58f --- /dev/null +++ b/workbench/sveltekit/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/workbench/sveltekit/src/lib/assets/favicon.svg b/workbench/sveltekit/src/lib/assets/favicon.svg new file mode 100644 index 000000000..cc5dc66a3 --- /dev/null +++ b/workbench/sveltekit/src/lib/assets/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/workbench/sveltekit/src/lib/index.ts b/workbench/sveltekit/src/lib/index.ts new file mode 100644 index 000000000..856f2b6c3 --- /dev/null +++ b/workbench/sveltekit/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/workbench/sveltekit/src/routes/+layout.svelte b/workbench/sveltekit/src/routes/+layout.svelte new file mode 100644 index 000000000..20f8d044f --- /dev/null +++ b/workbench/sveltekit/src/routes/+layout.svelte @@ -0,0 +1,11 @@ + + + + + + +{@render children?.()} diff --git a/workbench/sveltekit/src/routes/+page.svelte b/workbench/sveltekit/src/routes/+page.svelte new file mode 100644 index 000000000..cc88df0ea --- /dev/null +++ b/workbench/sveltekit/src/routes/+page.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit svelte.dev/docs/kit to read the documentation

diff --git a/workbench/sveltekit/src/routes/test/+server.ts b/workbench/sveltekit/src/routes/test/+server.ts new file mode 100644 index 000000000..a1764dcfd --- /dev/null +++ b/workbench/sveltekit/src/routes/test/+server.ts @@ -0,0 +1,8 @@ +import { start } from 'workflow/api'; +import { handleUserSignup } from '../../../workflows/user-signup.js'; + +export const GET = async () => { + const run = await start(handleUserSignup, ['test@example.com']); + + return new Response(String(run.runId)); +}; diff --git a/workbench/sveltekit/static/robots.txt b/workbench/sveltekit/static/robots.txt new file mode 100644 index 000000000..b6dd6670c --- /dev/null +++ b/workbench/sveltekit/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js new file mode 100644 index 000000000..c1c25feca --- /dev/null +++ b/workbench/sveltekit/svelte.config.js @@ -0,0 +1,12 @@ +import adapter from '@sveltejs/adapter-node'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://svelte.dev/docs/kit/integrations + // for more information about preprocessors + preprocess: vitePreprocess(), + kit: { adapter: adapter() }, +}; + +export default config; diff --git a/workbench/sveltekit/tsconfig.json b/workbench/sveltekit/tsconfig.json new file mode 100644 index 000000000..e3898cb22 --- /dev/null +++ b/workbench/sveltekit/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/workbench/sveltekit/vite.config.ts b/workbench/sveltekit/vite.config.ts new file mode 100644 index 000000000..a9bd91352 --- /dev/null +++ b/workbench/sveltekit/vite.config.ts @@ -0,0 +1,14 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { workflowBuilderPlugin } from '@workflow/sveltekit'; +import { defineConfig } from 'vite'; +import devtoolsJson from 'vite-plugin-devtools-json'; +import { workflowRollupPlugin } from 'workflow/rollup-plugin'; + +export default defineConfig({ + plugins: [ + sveltekit(), + devtoolsJson(), + workflowBuilderPlugin(), + workflowRollupPlugin(), + ], +}); diff --git a/workbench/sveltekit/workflows/user-signup.ts b/workbench/sveltekit/workflows/user-signup.ts new file mode 100644 index 000000000..c3a445735 --- /dev/null +++ b/workbench/sveltekit/workflows/user-signup.ts @@ -0,0 +1,48 @@ +import { sleep } from 'workflow'; + +export async function handleUserSignup(email: string) { + 'use workflow'; + + 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' }; +} + +import { FatalError } from 'workflow'; + +// Our workflow function defined earlier + +async function createUser(email: string) { + 'use step'; + + 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'; + + 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'; + + 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}`); +} From ff11f596591b17029edf1900aa6401d9904b7254 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Tue, 28 Oct 2025 17:27:52 -0700 Subject: [PATCH 02/63] add sveltekit package --- packages/sveltekit/LICENSE.md | 1 + packages/sveltekit/README.md | 3 + packages/sveltekit/package.json | 41 ++++ packages/sveltekit/src/builders.ts | 149 +++++++++++++++ packages/sveltekit/src/index.ts | 10 + packages/sveltekit/tsconfig.json | 12 ++ pnpm-lock.yaml | 294 ++++++++++++++++++++++++++++- pnpm-workspace.yaml | 2 + 8 files changed, 510 insertions(+), 2 deletions(-) create mode 120000 packages/sveltekit/LICENSE.md create mode 100644 packages/sveltekit/README.md create mode 100644 packages/sveltekit/package.json create mode 100644 packages/sveltekit/src/builders.ts create mode 100644 packages/sveltekit/src/index.ts create mode 100644 packages/sveltekit/tsconfig.json diff --git a/packages/sveltekit/LICENSE.md b/packages/sveltekit/LICENSE.md new file mode 120000 index 000000000..f0608a63a --- /dev/null +++ b/packages/sveltekit/LICENSE.md @@ -0,0 +1 @@ +../../LICENSE.md \ No newline at end of file diff --git a/packages/sveltekit/README.md b/packages/sveltekit/README.md new file mode 100644 index 000000000..88571598b --- /dev/null +++ b/packages/sveltekit/README.md @@ -0,0 +1,3 @@ +# workflow/sveltekit + +The docs have moved! Refer to them [here](https://useworkflow.dev/) diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json new file mode 100644 index 000000000..da478fc65 --- /dev/null +++ b/packages/sveltekit/package.json @@ -0,0 +1,41 @@ +{ + "name": "@workflow/sveltekit", + "version": "4.0.0-beta.1", + "description": "SvelteKit integration for Workflow DevKit", + "type": "module", + "main": "dist/index.js", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/vercel/workflow.git", + "directory": "packages/sveltekit" + }, + "exports": { + ".": "./dist/index.js" + }, + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "clean": "tsc --build --clean && rm -rf dist" + }, + "dependencies": { + "@sveltejs/kit": "^2.48.2", + "@swc/core": "1.11.24", + "@workflow/cli": "workspace:*", + "@workflow/core": "workspace:*", + "@workflow/swc-plugin": "workspace:*", + "exsolve": "^1.0.7", + "workflow": "workspace:*" + }, + "devDependencies": { + "@types/node": "catalog:", + "@workflow/tsconfig": "workspace:*", + "vite": "^7.1.11" + } +} diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts new file mode 100644 index 000000000..d538ffec9 --- /dev/null +++ b/packages/sveltekit/src/builders.ts @@ -0,0 +1,149 @@ +import { constants } from 'node:fs'; +import { access, mkdir, stat, writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import { BaseBuilder } from '@workflow/cli/dist/lib/builders/base-builder.js'; +import type { WorkflowConfig } from '@workflow/cli/dist/lib/config/types.js'; + +const CommonBuildOptions = { + dirs: ['workflows', 'src/workflows'], + buildTarget: 'next' as const, // unused in base + stepsBundlePath: '', // unused in base + workflowsBundlePath: '', // unused in base + webhookBundlePath: '', // unused in base +}; + +export class LocalBuilder extends BaseBuilder { + constructor(config: Partial) { + super({ + ...CommonBuildOptions, + ...config, + workingDir: config.workingDir || process.cwd(), + }); + } + + override async build(): Promise { + // Find SvelteKit routes directory (src/routes or routes) + const routesDir = await this.findRoutesDirectory(); + const workflowGeneratedDir = join(routesDir, '.well-known/workflow/v1'); + + // Ensure output directories exist + await mkdir(workflowGeneratedDir, { recursive: true }); + + // Add .gitignore to exclude generated files from version control + await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); + + // Get workflow and step files to bundle + const inputFiles = await this.getInputFiles(); + const tsConfig = await this.getTsConfigOptions(); + + const options = { + inputFiles, + workflowGeneratedDir, + tsBaseUrl: tsConfig.baseUrl, + tsPaths: tsConfig.paths, + }; + + // Generate the three SvelteKit route handlers + await this.buildStepsRoute(options); + await this.buildWorkflowsRoute(options); + await this.buildWebhookRoute({ workflowGeneratedDir }); + } + + private async buildStepsRoute({ + inputFiles, + workflowGeneratedDir, + tsPaths, + tsBaseUrl, + }: { + inputFiles: string[]; + workflowGeneratedDir: string; + tsBaseUrl?: string; + tsPaths?: Record; + }) { + // Create steps route: .well-known/workflow/v1/step/+server.ts + const stepsRouteDir = join(workflowGeneratedDir, 'step'); + await mkdir(stepsRouteDir, { recursive: true }); + + return await this.createStepsBundle({ + format: 'esm', + inputFiles, + outfile: join(stepsRouteDir, '+server.ts'), + externalizeNonSteps: true, + tsBaseUrl, + tsPaths, + }); + } + + private async buildWorkflowsRoute({ + inputFiles, + workflowGeneratedDir, + tsPaths, + tsBaseUrl, + }: { + inputFiles: string[]; + workflowGeneratedDir: string; + tsBaseUrl?: string; + tsPaths?: Record; + }) { + // Create workflows route: .well-known/workflow/v1/flow/+server.ts + const workflowsRouteDir = join(workflowGeneratedDir, 'flow'); + await mkdir(workflowsRouteDir, { recursive: true }); + + return await this.createWorkflowsBundle({ + format: 'esm', + outfile: join(workflowsRouteDir, '+server.ts'), + bundleFinalOutput: false, + inputFiles, + tsBaseUrl, + tsPaths, + }); + } + + private async buildWebhookRoute({ + workflowGeneratedDir, + }: { + workflowGeneratedDir: string; + }) { + // Create webhook route: .well-known/workflow/v1/webhook/[token]/+server.ts + const webhookRouteFile = join( + workflowGeneratedDir, + 'webhook/[token]/+server.ts' + ); + + return await this.createWebhookBundle({ + outfile: webhookRouteFile, + bundle: false, // SvelteKit will handle bundling + }); + } + + private async findRoutesDirectory(): Promise { + const routesDir = resolve(this.config.workingDir, 'src/routes'); + const rootRoutesDir = resolve(this.config.workingDir, 'routes'); + + // Try src/routes first (standard SvelteKit convention) + try { + await access(routesDir, constants.F_OK); + const routesStats = await stat(routesDir); + if (!routesStats.isDirectory()) { + throw new Error(`Path exists but is not a directory: ${routesDir}`); + } + return routesDir; + } catch { + // Try routes as fallback + try { + await access(rootRoutesDir, constants.F_OK); + const rootRoutesStats = await stat(rootRoutesDir); + if (!rootRoutesStats.isDirectory()) { + throw new Error( + `Path exists but is not a directory: ${rootRoutesDir}` + ); + } + return rootRoutesDir; + } catch { + throw new Error( + 'Could not find SvelteKit routes directory. Expected either "src/routes" or "routes" to exist.' + ); + } + } + } +} diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts new file mode 100644 index 000000000..9b9b524d6 --- /dev/null +++ b/packages/sveltekit/src/index.ts @@ -0,0 +1,10 @@ +import { LocalBuilder } from './builders.js'; + +export function workflowBuilderPlugin() { + return { + name: 'workflow-sveltekit-plugin', + async buildStart() { + await new LocalBuilder({}).build(); + }, + }; +} diff --git a/packages/sveltekit/tsconfig.json b/packages/sveltekit/tsconfig.json new file mode 100644 index 000000000..ba5d9aec0 --- /dev/null +++ b/packages/sveltekit/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@workflow/tsconfig/base.json", + "compilerOptions": { + "outDir": "dist", + "target": "es2022", + "module": "preserve", + "baseUrl": ".", + "moduleResolution": "bundler" + }, + "include": ["src"], + "exclude": ["node_modules", "**/*.test.ts"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3177f9c95..958ac15d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,7 @@ importers: version: 19.1.9(@types/react@19.1.13) '@vercel/analytics': specifier: ^1.5.0 - version: 1.5.0(next@15.6.0-canary.13(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + version: 1.5.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(next@15.6.0-canary.13(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.43.0)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@vercel/edge-config': specifier: ^1.4.0 version: 1.4.0(@opentelemetry/api@1.9.0) @@ -508,6 +508,40 @@ importers: specifier: latest version: 3.0.1-alpha.0(@vercel/functions@3.1.4(@aws-sdk/credential-provider-web-identity@3.844.0))(better-sqlite3@11.10.0)(chokidar@4.0.3)(drizzle-orm@0.31.4(@opentelemetry/api@1.9.0)(@types/react@19.1.13)(better-sqlite3@11.10.0)(pg@8.16.3)(postgres@3.4.7)(react@19.2.0))(ioredis@5.8.2)(lru-cache@11.2.2)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + packages/sveltekit: + dependencies: + '@sveltejs/kit': + specifier: ^2.48.2 + version: 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@swc/core': + specifier: 1.11.24 + version: 1.11.24 + '@workflow/cli': + specifier: workspace:* + version: link:../cli + '@workflow/core': + specifier: workspace:* + version: link:../core + '@workflow/swc-plugin': + specifier: workspace:* + version: link:../swc-plugin-workflow + exsolve: + specifier: ^1.0.7 + version: 1.0.7 + workflow: + specifier: workspace:* + version: link:../workflow + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 24.6.2 + '@workflow/tsconfig': + specifier: workspace:* + version: link:../tsconfig + vite: + specifier: ^7.1.11 + version: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + packages/swc-plugin-workflow: dependencies: '@swc/core': @@ -1175,6 +1209,40 @@ importers: specifier: 'catalog:' version: 4.1.11 + workbench/sveltekit: + dependencies: + workflow: + specifier: workspace:* + version: link:../../packages/workflow + devDependencies: + '@sveltejs/adapter-node': + specifier: ^5.3.2 + version: 5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) + '@sveltejs/kit': + specifier: ^2.43.2 + version: 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': + specifier: ^6.2.0 + version: 6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@workflow/sveltekit': + specifier: workspace:* + version: link:../../packages/sveltekit + svelte: + specifier: ^5.39.5 + version: 5.43.0 + svelte-check: + specifier: ^4.3.2 + version: 4.3.3(picomatch@4.0.3)(svelte@5.43.0)(typescript@5.9.3) + typescript: + specifier: ^5.9.2 + version: 5.9.3 + vite: + specifier: ^7.1.7 + version: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + vite-plugin-devtools-json: + specifier: ^1.0.0 + version: 1.0.0(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + packages: '@ai-sdk/gateway@2.0.0': @@ -4269,6 +4337,44 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@sveltejs/acorn-typescript@1.0.6': + resolution: {integrity: sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/adapter-node@5.4.0': + resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} + peerDependencies: + '@sveltejs/kit': ^2.4.0 + + '@sveltejs/kit@2.48.2': + resolution: {integrity: sha512-WIgVMGt+b9OxPDtu0Txow28RsBrLoV3wr2QoUxEHd4CHbpxbqKQf2SIEzd+SE+bqrUL2D5MxBeQBdY+t7o6n1A==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1': + resolution: {integrity: sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@sveltejs/vite-plugin-svelte@6.2.1': + resolution: {integrity: sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + '@swc/core-darwin-arm64@1.11.24': resolution: {integrity: sha512-dhtVj0PC1APOF4fl5qT2neGjRLgHAAYfiVP8poJelhzhB/318bO+QCFWAiimcDoyMgpCXOhTp757gnoJJrheWA==} engines: {node: '>=10'} @@ -4447,6 +4553,9 @@ packages: '@types/chai@5.2.2': resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} @@ -4965,6 +5074,10 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + array-timsort@1.0.3: resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} @@ -5010,6 +5123,10 @@ packages: peerDependencies: postcss: ^8.1.0 + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + b4a@1.7.3: resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} peerDependencies: @@ -5376,6 +5493,10 @@ packages: cookie-es@2.0.0: resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} @@ -6049,6 +6170,9 @@ packages: jiti: optional: true + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -6062,6 +6186,9 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} + esrap@2.1.1: + resolution: {integrity: sha512-ebTT9B6lOtZGMgJ3o5r12wBacHctG7oEWazIda8UlPfA3HD/Wrv8FdXoVo73vzdpwCxNyXjPauyN2bbJzMkB9A==} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -6733,6 +6860,9 @@ packages: is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-ssh@1.4.1: resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} @@ -7002,6 +7132,9 @@ packages: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -8521,6 +8654,10 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -8584,6 +8721,9 @@ packages: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -8849,6 +8989,18 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte-check@4.3.3: + resolution: {integrity: sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte@5.43.0: + resolution: {integrity: sha512-1sRxVbgJAB+UGzwkc3GUoiBSzEOf0jqzccMaVoI2+pI+kASUe9qubslxace8+Mzhqw19k4syTA5niCIJwfXpOA==} + engines: {node: '>=18'} + svgo@4.0.0: resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} engines: {node: '>=16'} @@ -9423,6 +9575,11 @@ packages: vue-tsc: optional: true + vite-plugin-devtools-json@1.0.0: + resolution: {integrity: sha512-MobvwqX76Vqt/O4AbnNMNWoXWGrKUqZbphCUle/J2KXH82yKQiunOeKnz/nqEPosPsoWWPP9FtNuPBSYpiiwkw==} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite-plugin-inspect@11.3.3: resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} engines: {node: '>=14'} @@ -9479,6 +9636,14 @@ packages: yaml: optional: true + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -9680,6 +9845,9 @@ packages: youch@4.1.0-beta.11: resolution: {integrity: sha512-sQi6PERyO/mT8w564ojOVeAlYTtVQmC2GaktQAf+IdI75/GKIggosBuvyVXvEV+FATAT6RbLdIjFoiIId4ozoQ==} + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} @@ -13344,6 +13512,60 @@ snapshots: '@standard-schema/utils@0.3.0': {} + '@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + + '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': + dependencies: + '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) + '@rollup/plugin-json': 6.1.0(rollup@4.52.5) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.52.5) + '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + rollup: 4.52.5 + + '@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': + dependencies: + '@standard-schema/spec': 1.0.0 + '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@types/cookie': 0.6.0 + acorn: 8.15.0 + cookie: 0.6.0 + devalue: 5.4.1 + esm-env: 1.2.2 + kleur: 4.1.5 + magic-string: 0.30.19 + mrmime: 2.0.1 + sade: 1.8.1 + set-cookie-parser: 2.7.2 + sirv: 3.0.2 + svelte: 5.43.0 + vite: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + optionalDependencies: + '@opentelemetry/api': 1.9.0 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + debug: 4.4.3(supports-color@8.1.1) + svelte: 5.43.0 + vite: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + debug: 4.4.3(supports-color@8.1.1) + deepmerge: 4.3.1 + magic-string: 0.30.19 + svelte: 5.43.0 + vite: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + vitefu: 1.1.1(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + transitivePeerDependencies: + - supports-color + '@swc/core-darwin-arm64@1.11.24': optional: true @@ -13496,6 +13718,8 @@ snapshots: dependencies: '@types/deep-eql': 4.0.2 + '@types/cookie@0.6.0': {} + '@types/d3-array@3.2.2': {} '@types/d3-axis@3.0.6': @@ -13732,10 +13956,12 @@ snapshots: unhead: 2.0.19 vue: 3.5.22(typescript@5.9.3) - '@vercel/analytics@1.5.0(next@15.6.0-canary.13(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + '@vercel/analytics@1.5.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(next@15.6.0-canary.13(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.43.0)(vue-router@4.6.3(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': optionalDependencies: + '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) next: 15.6.0-canary.13(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 + svelte: 5.43.0 vue: 3.5.22(typescript@5.9.3) vue-router: 4.6.3(vue@3.5.22(typescript@5.9.3)) @@ -14119,6 +14345,8 @@ snapshots: dependencies: tslib: 2.8.1 + aria-query@5.3.2: {} + array-timsort@1.0.3: {} array-union@2.1.0: {} @@ -14163,6 +14391,8 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 + axobject-query@4.1.0: {} + b4a@1.7.3: {} bail@2.0.2: {} @@ -14528,6 +14758,8 @@ snapshots: cookie-es@2.0.0: {} + cookie@0.6.0: {} + cookie@1.0.2: {} copy-anything@4.0.5: @@ -15232,6 +15464,8 @@ snapshots: - supports-color optional: true + esm-env@1.2.2: {} + espree@10.4.0: dependencies: acorn: 8.15.0 @@ -15246,6 +15480,10 @@ snapshots: estraverse: 5.3.0 optional: true + esrap@2.1.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -15974,6 +16212,10 @@ snapshots: dependencies: '@types/estree': 1.0.8 + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + is-ssh@1.4.1: dependencies: protocols: 2.0.2 @@ -16234,6 +16476,8 @@ snapshots: pkg-types: 2.3.0 quansync: 0.2.11 + locate-character@3.0.0: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -18486,6 +18730,10 @@ snapshots: rw@1.3.3: {} + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -18554,6 +18802,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@2.7.2: {} + setprototypeof@1.2.0: {} sharp@0.34.4: @@ -18842,6 +19092,35 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svelte-check@4.3.3(picomatch@4.0.3)(svelte@5.43.0)(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.3) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.43.0 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte@5.43.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + esm-env: 1.2.2 + esrap: 2.1.1 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.19 + zimmerframe: 1.1.4 + svgo@4.0.0: dependencies: commander: 11.1.0 @@ -19411,6 +19690,11 @@ snapshots: optionator: 0.9.4 typescript: 5.9.3 + vite-plugin-devtools-json@1.0.0(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)): + dependencies: + uuid: 11.1.0 + vite: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + vite-plugin-inspect@11.3.3(@nuxt/kit@3.19.3(magicast@0.3.5))(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)): dependencies: ansis: 4.2.0 @@ -19455,6 +19739,10 @@ snapshots: tsx: 4.20.6 yaml: 2.8.0 + vitefu@1.1.1(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)): + optionalDependencies: + vite: 7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0) + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 @@ -19659,6 +19947,8 @@ snapshots: cookie: 1.0.2 youch-core: 0.3.3 + zimmerframe@1.1.4: {} + zip-stream@6.0.1: dependencies: archiver-utils: 5.0.2 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f6fe1858c..99e018529 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,3 +14,5 @@ catalog: typescript: ^5.9.3 vitest: ^3.2.4 zod: 4.1.11 +onlyBuiltDependencies: + - esbuild From 49d696cba972bdada7a722be66bbaa948be3b282 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Tue, 28 Oct 2025 17:45:00 -0700 Subject: [PATCH 03/63] fix: use js for generated server routes in svelte --- packages/sveltekit/src/builders.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index d538ffec9..e89d67487 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -60,14 +60,14 @@ export class LocalBuilder extends BaseBuilder { tsBaseUrl?: string; tsPaths?: Record; }) { - // Create steps route: .well-known/workflow/v1/step/+server.ts + // Create steps route: .well-known/workflow/v1/step/+server.js const stepsRouteDir = join(workflowGeneratedDir, 'step'); await mkdir(stepsRouteDir, { recursive: true }); return await this.createStepsBundle({ format: 'esm', inputFiles, - outfile: join(stepsRouteDir, '+server.ts'), + outfile: join(stepsRouteDir, '+server.js'), externalizeNonSteps: true, tsBaseUrl, tsPaths, @@ -85,13 +85,13 @@ export class LocalBuilder extends BaseBuilder { tsBaseUrl?: string; tsPaths?: Record; }) { - // Create workflows route: .well-known/workflow/v1/flow/+server.ts + // Create workflows route: .well-known/workflow/v1/flow/+server.js const workflowsRouteDir = join(workflowGeneratedDir, 'flow'); await mkdir(workflowsRouteDir, { recursive: true }); return await this.createWorkflowsBundle({ format: 'esm', - outfile: join(workflowsRouteDir, '+server.ts'), + outfile: join(workflowsRouteDir, '+server.js'), bundleFinalOutput: false, inputFiles, tsBaseUrl, @@ -104,10 +104,10 @@ export class LocalBuilder extends BaseBuilder { }: { workflowGeneratedDir: string; }) { - // Create webhook route: .well-known/workflow/v1/webhook/[token]/+server.ts + // Create webhook route: .well-known/workflow/v1/webhook/[token]/+server.js const webhookRouteFile = join( workflowGeneratedDir, - 'webhook/[token]/+server.ts' + 'webhook/[token]/+server.js' ); return await this.createWebhookBundle({ From d90e965e465c18f258a0d13ea6613a5bae3e94dc Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Tue, 28 Oct 2025 22:57:30 -0700 Subject: [PATCH 04/63] add test routes for sveltekit workbench --- .../sveltekit/src/routes/api/signup/+server.ts | 14 ++++++++++++++ workbench/sveltekit/src/routes/test/+server.ts | 8 -------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 workbench/sveltekit/src/routes/api/signup/+server.ts delete mode 100644 workbench/sveltekit/src/routes/test/+server.ts diff --git a/workbench/sveltekit/src/routes/api/signup/+server.ts b/workbench/sveltekit/src/routes/api/signup/+server.ts new file mode 100644 index 000000000..0303765e1 --- /dev/null +++ b/workbench/sveltekit/src/routes/api/signup/+server.ts @@ -0,0 +1,14 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import { start } from 'workflow/api'; +import { handleUserSignup } from '../../../../workflows/user-signup.js'; + +export const POST: RequestHandler = async ({ request }) => { + const { email } = await request.json(); + // Executes asynchronously and doesn't block your app + await start(handleUserSignup, [email]); + return new Response( + JSON.stringify({ + message: 'User signup workflow started', + }) + ); +}; diff --git a/workbench/sveltekit/src/routes/test/+server.ts b/workbench/sveltekit/src/routes/test/+server.ts deleted file mode 100644 index a1764dcfd..000000000 --- a/workbench/sveltekit/src/routes/test/+server.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { start } from 'workflow/api'; -import { handleUserSignup } from '../../../workflows/user-signup.js'; - -export const GET = async () => { - const run = await start(handleUserSignup, ['test@example.com']); - - return new Response(String(run.runId)); -}; From 777db329a9dab7b603925caa633d11ccb0de0bc2 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 29 Oct 2025 13:18:56 -0700 Subject: [PATCH 05/63] updates from debugging --- packages/cli/src/lib/builders/base-builder.ts | 26 +++++++++++++++++-- packages/sveltekit/src/index.ts | 2 +- packages/world-local/src/queue.ts | 7 ++++- workbench/sveltekit/vite.config.ts | 4 +-- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/lib/builders/base-builder.ts b/packages/cli/src/lib/builders/base-builder.ts index 9ac184ca3..f8b3aae6f 100644 --- a/packages/cli/src/lib/builders/base-builder.ts +++ b/packages/cli/src/lib/builders/base-builder.ts @@ -260,7 +260,19 @@ export abstract class BaseBuilder { // User steps ${imports} // API entrypoint - export { stepEntrypoint as POST } from 'workflow/runtime';`; + import { stepEntrypoint } from 'workflow/runtime'; + export const POST = async ({request}) => { + const body = await request.arrayBuffer() + const normalRequest = new Request(request.url, { + method: request.method, + headers: new Headers(request.headers), + ...(request.method !== 'GET' && request.method !== 'HEAD') ? { + body + } : {} + }) + return stepEntrypoint(normalRequest); + } + `; // Bundle with esbuild and our custom SWC plugin const esbuildCtx = await esbuild.context({ @@ -462,7 +474,17 @@ import { workflowEntrypoint } from 'workflow/runtime'; const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; -export const POST = workflowEntrypoint(workflowCode);`; +export const POST = async ({ request }) => { + const body = await request.arrayBuffer() + const normalRequest = new Request(request.url, { + method: request.method, + headers: new Headers(request.headers), + ...(request.method !== 'GET' && request.method !== 'HEAD') ? { + body + } : {} + }) + return workflowEntrypoint(workflowCode)(normalRequest); +}`; // we skip the final bundling step for Next.js so it can bundle itself if (!bundleFinalOutput) { diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 9b9b524d6..2b7a6342b 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -3,7 +3,7 @@ import { LocalBuilder } from './builders.js'; export function workflowBuilderPlugin() { return { name: 'workflow-sveltekit-plugin', - async buildStart() { + async configResolved() { await new LocalBuilder({}).build(); }, }; diff --git a/packages/world-local/src/queue.ts b/packages/world-local/src/queue.ts index 93ce627dd..2b02973cf 100644 --- a/packages/world-local/src/queue.ts +++ b/packages/world-local/src/queue.ts @@ -59,6 +59,7 @@ export function createQueue(port?: number): Queue { method: 'POST', duplex: 'half', headers: { + 'content-type': 'application/json', 'x-vqs-queue-name': queueName, 'x-vqs-message-id': messageId, 'x-vqs-message-attempt': String(attempt + 1), @@ -115,7 +116,11 @@ export function createQueue(port?: number): Queue { if (!headers.success || !req.body) { return Response.json( - { error: 'Missing required headers' }, + { + error: !req.body + ? 'Missing request body' + : 'Missing required headers', + }, { status: 400 } ); } diff --git a/workbench/sveltekit/vite.config.ts b/workbench/sveltekit/vite.config.ts index a9bd91352..ab0548691 100644 --- a/workbench/sveltekit/vite.config.ts +++ b/workbench/sveltekit/vite.config.ts @@ -6,9 +6,9 @@ import { workflowRollupPlugin } from 'workflow/rollup-plugin'; export default defineConfig({ plugins: [ - sveltekit(), - devtoolsJson(), workflowBuilderPlugin(), workflowRollupPlugin(), + devtoolsJson(), + sveltekit(), ], }); From aa535729675ce43cdbad9085a3818421fe1d5722 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 17:04:09 -0700 Subject: [PATCH 06/63] feat: add sveltekit build target --- packages/cli/src/lib/builders/base-builder.ts | 30 +++++++++++++++++-- packages/cli/src/lib/config/types.ts | 1 + packages/sveltekit/src/builders.ts | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/lib/builders/base-builder.ts b/packages/cli/src/lib/builders/base-builder.ts index f8b3aae6f..90863badb 100644 --- a/packages/cli/src/lib/builders/base-builder.ts +++ b/packages/cli/src/lib/builders/base-builder.ts @@ -254,7 +254,19 @@ export abstract class BaseBuilder { // Create a virtual entry that imports all files. All step definitions // will get registered thanks to the swc transform. const imports = stepFiles.map((file) => `import '${file}';`).join('\n'); - const entryContent = ` + + let entryContent = ''; + if (this.config.buildTarget === 'next') { + entryContent = ` + // Built in steps + import '${builtInSteps}'; + // User steps + ${imports} + // API entrypoint + export { stepEntrypoint as POST } from 'workflow/runtime'; + `; + } else if (this.config.buildTarget === 'sveltekit') { + entryContent = ` // Built in steps import '${builtInSteps}'; // User steps @@ -273,6 +285,7 @@ export abstract class BaseBuilder { return stepEntrypoint(normalRequest); } `; + } // Bundle with esbuild and our custom SWC plugin const esbuildCtx = await esbuild.context({ @@ -467,8 +480,18 @@ export abstract class BaseBuilder { const bundleFinal = async (interimBundle: string) => { const workflowBundleCode = interimBundle; - // Create the workflow function handler with proper linter suppressions - const workflowFunctionCode = `// biome-ignore-all lint: generated file + let workflowFunctionCode = ''; + if (this.config.buildTarget === 'next') { + workflowFunctionCode = `// biome-ignore-all lint: generated file +/* eslint-disable */ +import { workflowEntrypoint } from 'workflow/runtime'; + +const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; + +export const POST = workflowEntrypoint(workflowCode);`; + } else if (this.config.buildTarget === 'sveltekit') { + // Create the workflow function handler with proper linter suppressions + workflowFunctionCode = `// biome-ignore-all lint: generated file /* eslint-disable */ import { workflowEntrypoint } from 'workflow/runtime'; @@ -485,6 +508,7 @@ export const POST = async ({ request }) => { }) return workflowEntrypoint(workflowCode)(normalRequest); }`; + } // we skip the final bundling step for Next.js so it can bundle itself if (!bundleFinalOutput) { diff --git a/packages/cli/src/lib/config/types.ts b/packages/cli/src/lib/config/types.ts index 9bdeb712d..b4d729c74 100644 --- a/packages/cli/src/lib/config/types.ts +++ b/packages/cli/src/lib/config/types.ts @@ -2,6 +2,7 @@ export const validBuildTargets = [ 'standalone', 'vercel-build-output-api', 'next', + 'sveltekit', ] as const; export type BuildTarget = (typeof validBuildTargets)[number]; diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index e89d67487..0a0d9d355 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -6,7 +6,7 @@ import type { WorkflowConfig } from '@workflow/cli/dist/lib/config/types.js'; const CommonBuildOptions = { dirs: ['workflows', 'src/workflows'], - buildTarget: 'next' as const, // unused in base + buildTarget: 'sveltekit' as const, // unused in base stepsBundlePath: '', // unused in base workflowsBundlePath: '', // unused in base webhookBundlePath: '', // unused in base From 99a03c36ff5ad377c2d991455e990efaa188765c Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 17:11:57 -0700 Subject: [PATCH 07/63] update user sign up workflow workbench sveltekit --- workbench/sveltekit/workflows/user-signup.ts | 35 +++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/workbench/sveltekit/workflows/user-signup.ts b/workbench/sveltekit/workflows/user-signup.ts index c3a445735..173c7196e 100644 --- a/workbench/sveltekit/workflows/user-signup.ts +++ b/workbench/sveltekit/workflows/user-signup.ts @@ -1,4 +1,4 @@ -import { sleep } from 'workflow'; +import { createWebhook, sleep } from 'workflow'; export async function handleUserSignup(email: string) { 'use workflow'; @@ -6,22 +6,22 @@ export async function handleUserSignup(email: string) { const user = await createUser(email); await sendWelcomeEmail(user); - await sleep('5s'); // Pause for 5s - doesn't consume any resources - await sendOnboardingEmail(user); + await sleep('5s'); - return { userId: user.id, status: 'onboarded' }; -} + const webhook = createWebhook(); + await sendOnboardingEmail(user, webhook.url); -import { FatalError } from 'workflow'; + await webhook; + console.log('Webhook Resolved'); -// Our workflow function defined earlier + return { userId: user.id, status: 'onboarded' }; +} async function createUser(email: string) { 'use step'; - console.log(`Creating user with email: ${email}`); + console.log(`Creating a new user with email: ${email}`); - // Full Node.js access - database calls, APIs, etc. return { id: crypto.randomUUID(), email }; } @@ -29,20 +29,15 @@ async function sendWelcomeEmail(user: { id: string; email: string }) { 'use step'; 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 }) { +async function sendOnboardingEmail( + user: { id: string; email: string }, + callback: string +) { 'use step'; - 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}`); + + console.log(`Click this link to resolve the webhook: ${callback}`); } From f436c923a22f1643a6f285ce9e408ec424b3ad0d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 17:16:04 -0700 Subject: [PATCH 08/63] fix: base builder missing GET route handler for sveltekit --- packages/cli/src/lib/builders/base-builder.ts | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/packages/cli/src/lib/builders/base-builder.ts b/packages/cli/src/lib/builders/base-builder.ts index 90863badb..8404a45b1 100644 --- a/packages/cli/src/lib/builders/base-builder.ts +++ b/packages/cli/src/lib/builders/base-builder.ts @@ -255,22 +255,18 @@ export abstract class BaseBuilder { // will get registered thanks to the swc transform. const imports = stepFiles.map((file) => `import '${file}';`).join('\n'); - let entryContent = ''; - if (this.config.buildTarget === 'next') { - entryContent = ` + let entryContent = ` // Built in steps import '${builtInSteps}'; // User steps - ${imports} + ${imports}`; + if (this.config.buildTarget === 'next') { + entryContent += ` // API entrypoint export { stepEntrypoint as POST } from 'workflow/runtime'; `; } else if (this.config.buildTarget === 'sveltekit') { - entryContent = ` - // Built in steps - import '${builtInSteps}'; - // User steps - ${imports} + entryContent += ` // API entrypoint import { stepEntrypoint } from 'workflow/runtime'; export const POST = async ({request}) => { @@ -278,9 +274,9 @@ export abstract class BaseBuilder { const normalRequest = new Request(request.url, { method: request.method, headers: new Headers(request.headers), - ...(request.method !== 'GET' && request.method !== 'HEAD') ? { + ...(['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) ? {} : { body - } : {} + } }) return stepEntrypoint(normalRequest); } @@ -480,31 +476,25 @@ export abstract class BaseBuilder { const bundleFinal = async (interimBundle: string) => { const workflowBundleCode = interimBundle; - let workflowFunctionCode = ''; - if (this.config.buildTarget === 'next') { - workflowFunctionCode = `// biome-ignore-all lint: generated file + let workflowFunctionCode = `// biome-ignore-all lint: generated file /* eslint-disable */ import { workflowEntrypoint } from 'workflow/runtime'; const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; - +`; + if (this.config.buildTarget === 'next') { + workflowFunctionCode += ` export const POST = workflowEntrypoint(workflowCode);`; } else if (this.config.buildTarget === 'sveltekit') { - // Create the workflow function handler with proper linter suppressions - workflowFunctionCode = `// biome-ignore-all lint: generated file -/* eslint-disable */ -import { workflowEntrypoint } from 'workflow/runtime'; - -const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; - + workflowFunctionCode += ` export const POST = async ({ request }) => { const body = await request.arrayBuffer() const normalRequest = new Request(request.url, { method: request.method, headers: new Headers(request.headers), - ...(request.method !== 'GET' && request.method !== 'HEAD') ? { + ...(['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) ? {} : { body - } : {} + } }) return workflowEntrypoint(workflowCode)(normalRequest); }`; @@ -631,7 +621,7 @@ export const POST = async ({ request }) => { // Create a static route that calls resumeWebhook // This route works for both Next.js and Vercel Build Output API - const routeContent = `import { resumeWebhook } from 'workflow/api'; + let routeContent = `import { resumeWebhook } from 'workflow/api'; async function handler(request) { const url = new URL(request.url); @@ -651,8 +641,9 @@ async function handler(request) { console.error('Error during resumeWebhook', error); return new Response(null, { status: 404 }); } -} - +}`; + if (this.config.buildTarget === 'next') { + routeContent += ` export const GET = handler; export const POST = handler; export const PUT = handler; @@ -661,7 +652,29 @@ export const DELETE = handler; export const HEAD = handler; export const OPTIONS = handler; `; - + } else if (this.config.buildTarget === 'sveltekit') { + routeContent += ` +const createSvelteKitHandler = (method) => async ({ request }) => { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + const normalRequest = new Request(request.url, options); + return handler(normalRequest); +}; + +export const GET = createSvelteKitHandler('GET'); +export const POST = createSvelteKitHandler('POST'); +export const PUT = createSvelteKitHandler('PUT'); +export const PATCH = createSvelteKitHandler('PATCH'); +export const DELETE = createSvelteKitHandler('DELETE'); +export const HEAD = createSvelteKitHandler('HEAD'); +export const OPTIONS = createSvelteKitHandler('OPTIONS'); +`; + } if (!bundle) { // For Next.js, just write the unbundled file await writeFile(outfile, routeContent); From 5d844a67db9c002324a3d2d53c686cffdb05bb95 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 19:12:15 -0700 Subject: [PATCH 09/63] feat: add vercel builder and check for vercel env --- packages/sveltekit/src/builders.ts | 24 +++++++++++++++++++++++- packages/sveltekit/src/index.ts | 12 +++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 0a0d9d355..3c68d9ccf 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -1,7 +1,8 @@ import { constants } from 'node:fs'; -import { access, mkdir, stat, writeFile } from 'node:fs/promises'; +import { access, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder } from '@workflow/cli/dist/lib/builders/base-builder.js'; +import { VercelBuildOutputAPIBuilder } from '@workflow/cli/dist/lib/builders/vercel-build-output-api.js'; import type { WorkflowConfig } from '@workflow/cli/dist/lib/config/types.js'; const CommonBuildOptions = { @@ -12,6 +13,27 @@ const CommonBuildOptions = { webhookBundlePath: '', // unused in base }; +export class VercelBuilder extends VercelBuildOutputAPIBuilder { + constructor(config: Partial) { + super({ + ...CommonBuildOptions, + ...config, + workingDir: config.workingDir || process.cwd(), + }); + } + override async build(): Promise { + const configPath = join( + this.config.workingDir, + '.vercel/output/config.json' + ); + const originalConfig = JSON.parse(await readFile(configPath, 'utf-8')); + await super.build(); + const newConfig = JSON.parse(await readFile(configPath, 'utf-8')); + originalConfig.routes.unshift(...newConfig.routes); + await writeFile(configPath, JSON.stringify(originalConfig, null, 2)); + } +} + export class LocalBuilder extends BaseBuilder { constructor(config: Partial) { super({ diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 2b7a6342b..191b2e56f 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,10 +1,16 @@ -import { LocalBuilder } from './builders.js'; +import { LocalBuilder, VercelBuilder } from './builders.js'; -export function workflowBuilderPlugin() { +export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', async configResolved() { - await new LocalBuilder({}).build(); + if (process.env.VERCEL === '1') { + await new VercelBuilder({}).build(); + } else { + await new LocalBuilder({}).build(); + } }, }; } + +export { workflowRollupPlugin } from 'workflow/rollup-plugin'; From 1438ac6235931cf7889b234e4d6e77ff329aad1a Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 19:12:32 -0700 Subject: [PATCH 10/63] refactor: workflowPlugin for sveltekit --- workbench/sveltekit/vite.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workbench/sveltekit/vite.config.ts b/workbench/sveltekit/vite.config.ts index ab0548691..462ea2b81 100644 --- a/workbench/sveltekit/vite.config.ts +++ b/workbench/sveltekit/vite.config.ts @@ -1,12 +1,12 @@ import { sveltekit } from '@sveltejs/kit/vite'; -import { workflowBuilderPlugin } from '@workflow/sveltekit'; +import { workflowPlugin } from '@workflow/sveltekit'; import { defineConfig } from 'vite'; import devtoolsJson from 'vite-plugin-devtools-json'; import { workflowRollupPlugin } from 'workflow/rollup-plugin'; export default defineConfig({ plugins: [ - workflowBuilderPlugin(), + workflowPlugin(), workflowRollupPlugin(), devtoolsJson(), sveltekit(), From cd161c60e30e5f3ba71b1758c6d04379f8a4ad07 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 21:22:07 -0700 Subject: [PATCH 11/63] ci: add tests to workbench sveltekit --- .changeset/config.json | 3 +- .changeset/pre.json | 3 +- .github/workflows/tests.yml | 10 +- packages/core/e2e/local-build.test.ts | 2 +- pnpm-lock.yaml | 47 ++++++ scripts/create-test-matrix.mjs | 5 + workbench/sveltekit/package.json | 11 +- .../sveltekit/src/routes/api/hook/+server.ts | 29 ++++ .../src/routes/api/signup/+server.ts | 14 -- .../src/routes/api/trigger/+server.ts | 135 ++++++++++++++++++ workbench/sveltekit/workflows/6_batching.ts | 1 + .../sveltekit/workflows/98_duplicate_case.ts | 1 + workbench/sveltekit/workflows/99_e2e.ts | 1 + workbench/sveltekit/workflows/user-signup.ts | 43 ------ 14 files changed, 243 insertions(+), 62 deletions(-) create mode 100644 workbench/sveltekit/src/routes/api/hook/+server.ts delete mode 100644 workbench/sveltekit/src/routes/api/signup/+server.ts create mode 100644 workbench/sveltekit/src/routes/api/trigger/+server.ts create mode 120000 workbench/sveltekit/workflows/6_batching.ts create mode 120000 workbench/sveltekit/workflows/98_duplicate_case.ts create mode 120000 workbench/sveltekit/workflows/99_e2e.ts delete mode 100644 workbench/sveltekit/workflows/user-signup.ts diff --git a/.changeset/config.json b/.changeset/config.json index 4b700162e..ff0a3ea14 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -15,6 +15,7 @@ "@workflow/example-hono", "@workflow/example-nitro-v3", "@workflow/example-nitro-v2", - "@workflow/example-nuxt" + "@workflow/example-nuxt", + "@workflow/example-sveltekit" ] } diff --git a/.changeset/pre.json b/.changeset/pre.json index 4507a2e09..01854a64a 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -26,7 +26,8 @@ "nextjs-webpack": "0.0.2-alpha.5", "@workflow/example-nitro-v3": "0.0.0", "@workflow/example-nitro-v2": "0.0.0", - "@workflow/example-nuxt": "0.0.0" + "@workflow/example-nuxt": "0.0.0", + "@workflow/example-sveltekit": "0.0.0" }, "changesets": [ "angry-owls-beg", diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f23442bd9..5a1f1ac0b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -56,6 +56,8 @@ jobs: project-id: "prj_avRPBF3eWjh6iDNQgmhH4VOg27h0" - name: "nitro" project-id: "prj_e7DZirYdLrQKXNrlxg7KmA6ABx8r" + - name: "sveltekit" + project-id: "prj_MqnBLm71ceXGSnm3Fs8i8gBnI23G" env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }} @@ -170,7 +172,7 @@ jobs: run: cd workbench/${{ matrix.app.name }} && ./resolve-symlinks.sh - name: Run E2E Tests (Next.js) - if: matrix.app.name != 'nitro' + if: matrix.app.name != 'nitro' && matrix.app.name != 'sveltekit' run: cd workbench/${{ matrix.app.name }} && pnpm dev & echo "starting tests in 10 seconds" && sleep 10 && pnpm vitest run packages/core/e2e/next-dev.test.ts && pnpm run test:e2e env: APP_NAME: ${{ matrix.app.name }} @@ -182,6 +184,12 @@ jobs: env: APP_NAME: ${{ matrix.app.name }} DEPLOYMENT_URL: "http://localhost:3000" + - name: Run E2E Tests (SvelteKit) + if: matrix.app.name == 'sveltekit' + run: cd workbench/${{ matrix.app.name }} && pnpm dev & echo "starting tests in 10 seconds" && sleep 10 && pnpm vitest run packages/core/e2e/e2e.test.ts + env: + APP_NAME: ${{ matrix.app.name }} + DEPLOYMENT_URL: "http://localhost:3000" e2e-local-prod: name: E2E Local Prod Tests (${{ matrix.app.name }} - ${{ matrix.app.canary && 'canary' || 'stable' }}) diff --git a/packages/core/e2e/local-build.test.ts b/packages/core/e2e/local-build.test.ts index c32a3690c..237d6628c 100644 --- a/packages/core/e2e/local-build.test.ts +++ b/packages/core/e2e/local-build.test.ts @@ -5,7 +5,7 @@ import { getWorkbenchAppPath } from './utils'; const exec = promisify(execOriginal); -describe.each(['nextjs-webpack', 'nextjs-turbopack', 'nitro'])( +describe.each(['nextjs-webpack', 'nextjs-turbopack', 'nitro', 'sveltekit'])( 'e2e', (project) => { test('builds without errors', { timeout: 180_000 }, async () => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 958ac15d9..a2ab3cdd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1211,9 +1211,33 @@ importers: workbench/sveltekit: dependencies: + '@ai-sdk/react': + specifier: 2.0.76 + version: 2.0.76(react@19.2.0)(zod@4.1.11) + '@node-rs/xxhash': + specifier: 1.7.6 + version: 1.7.6 + '@opentelemetry/api': + specifier: ^1.9.0 + version: 1.9.0 + '@vercel/otel': + specifier: ^1.13.0 + version: 1.13.0(@opentelemetry/api-logs@0.57.2)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) + '@workflow/ai': + specifier: workspace:* + version: link:../../packages/ai + ai: + specifier: 'catalog:' + version: 5.0.76(zod@4.1.11) + lodash.chunk: + specifier: ^4.2.0 + version: 4.2.0 workflow: specifier: workspace:* version: link:../../packages/workflow + zod: + specifier: 'catalog:' + version: 4.1.11 devDependencies: '@sveltejs/adapter-node': specifier: ^5.3.2 @@ -1224,6 +1248,9 @@ importers: '@sveltejs/vite-plugin-svelte': specifier: ^6.2.0 version: 6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@types/lodash.chunk': + specifier: ^4.2.9 + version: 4.2.9 '@workflow/sveltekit': specifier: workspace:* version: link:../../packages/sveltekit @@ -9891,6 +9918,16 @@ snapshots: optionalDependencies: zod: 4.1.11 + '@ai-sdk/react@2.0.76(react@19.2.0)(zod@4.1.11)': + dependencies: + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.11) + ai: 5.0.76(zod@4.1.11) + react: 19.2.0 + swr: 2.3.6(react@19.2.0) + throttleit: 2.1.0 + optionalDependencies: + zod: 4.1.11 + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -19143,6 +19180,12 @@ snapshots: react: 19.1.1 use-sync-external-store: 1.5.0(react@19.1.1) + swr@2.3.6(react@19.2.0): + dependencies: + dequal: 2.0.3 + react: 19.2.0 + use-sync-external-store: 1.5.0(react@19.2.0) + system-architecture@0.1.0: {} tagged-tag@1.0.0: {} @@ -19600,6 +19643,10 @@ snapshots: dependencies: react: 19.1.1 + use-sync-external-store@1.5.0(react@19.2.0): + dependencies: + react: 19.2.0 + util-deprecate@1.0.2: {} uuid@10.0.0: {} diff --git a/scripts/create-test-matrix.mjs b/scripts/create-test-matrix.mjs index bb5731fd8..007fd7598 100644 --- a/scripts/create-test-matrix.mjs +++ b/scripts/create-test-matrix.mjs @@ -26,4 +26,9 @@ matrix.app.push({ project: 'workbench-nitro-workflow', }); +matrix.app.push({ + name: 'sveltekit', + project: 'workbench-sveltekit-workflow', +}); + console.log(JSON.stringify(matrix)); diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 2b58ea7d3..8de4f34e9 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -12,6 +12,7 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { + "@types/lodash.chunk": "^4.2.9", "@sveltejs/adapter-node": "^5.3.2", "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", @@ -23,6 +24,14 @@ "vite-plugin-devtools-json": "^1.0.0" }, "dependencies": { - "workflow": "workspace:*" + "@ai-sdk/react": "2.0.76", + "@node-rs/xxhash": "1.7.6", + "@opentelemetry/api": "^1.9.0", + "@vercel/otel": "^1.13.0", + "workflow": "workspace:*", + "@workflow/ai": "workspace:*", + "ai": "catalog:", + "lodash.chunk": "^4.2.0", + "zod": "catalog:" } } diff --git a/workbench/sveltekit/src/routes/api/hook/+server.ts b/workbench/sveltekit/src/routes/api/hook/+server.ts new file mode 100644 index 000000000..a0254e560 --- /dev/null +++ b/workbench/sveltekit/src/routes/api/hook/+server.ts @@ -0,0 +1,29 @@ +import { json, type RequestHandler } from '@sveltejs/kit'; +import { getHookByToken, resumeHook } from 'workflow/api'; + +export const POST: RequestHandler = async ({ + request, +}: { + request: Request; +}) => { + const { token, data } = await request.json(); + + let hook: Awaited>; + try { + hook = await getHookByToken(token); + console.log('hook', hook); + } catch (error) { + console.log('error during getHookByToken', error); + // TODO: `WorkflowAPIError` is not exported, so for now + // we'll return 404 assuming it's the "invalid" token test case + return json(null, { status: 404 }); + } + + await resumeHook(hook.token, { + ...data, + // @ts-expect-error metadata is not typed + customData: hook.metadata?.customData, + }); + + return json(hook); +}; diff --git a/workbench/sveltekit/src/routes/api/signup/+server.ts b/workbench/sveltekit/src/routes/api/signup/+server.ts deleted file mode 100644 index 0303765e1..000000000 --- a/workbench/sveltekit/src/routes/api/signup/+server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { RequestHandler } from '@sveltejs/kit'; -import { start } from 'workflow/api'; -import { handleUserSignup } from '../../../../workflows/user-signup.js'; - -export const POST: RequestHandler = async ({ request }) => { - const { email } = await request.json(); - // Executes asynchronously and doesn't block your app - await start(handleUserSignup, [email]); - return new Response( - JSON.stringify({ - message: 'User signup workflow started', - }) - ); -}; diff --git a/workbench/sveltekit/src/routes/api/trigger/+server.ts b/workbench/sveltekit/src/routes/api/trigger/+server.ts new file mode 100644 index 000000000..24ad1d682 --- /dev/null +++ b/workbench/sveltekit/src/routes/api/trigger/+server.ts @@ -0,0 +1,135 @@ +import { json, type RequestHandler } from '@sveltejs/kit'; +import { getRun, start } from 'workflow/api'; +import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import * as batchingWorkflow from '../../../../workflows/6_batching'; +import * as duplicateE2e from '../../../../workflows/98_duplicate_case'; +import * as e2eWorkflows from '../../../../workflows/99_e2e'; + +export const POST: RequestHandler = async ({ request }) => { + const url = new URL(request.url); + const workflowFile = + url.searchParams.get('workflowFile') || 'workflows/99_e2e.ts'; + const workflowFn = url.searchParams.get('workflowFn') || 'simple'; + + console.log('calling workflow', { workflowFile, workflowFn }); + + let args: any[] = []; + + // Args from query string + const argsParam = url.searchParams.get('args'); + if (argsParam) { + args = argsParam.split(',').map((arg) => { + const num = parseFloat(arg); + return Number.isNaN(num) ? arg.trim() : num; + }); + } else { + // Args from body + const body = await request.text(); + if (body) { + args = hydrateWorkflowArguments(JSON.parse(body), globalThis); + } else { + args = [42]; + } + } + console.log( + `Starting "${workflowFile}/${workflowFn}" workflow with args: ${args}` + ); + + try { + let workflows: any; + if (workflowFile === 'workflows/99_e2e.ts') { + workflows = e2eWorkflows; + } else if (workflowFile === 'workflows/6_batching.ts') { + workflows = batchingWorkflow; + } else { + workflows = duplicateE2e; + } + + const run = await start((workflows as any)[workflowFn], args); + console.log('Run:', run); + return json(run); + } catch (err) { + console.error(`Failed to start!!`, err); + throw err; + } +}; + +export const GET: RequestHandler = async ({ request }) => { + const url = new URL(request.url); + const runId = url.searchParams.get('runId'); + if (!runId) { + return new Response('No runId provided', { status: 400 }); + } + + const outputStreamParam = url.searchParams.get('output-stream'); + if (outputStreamParam) { + const namespace = outputStreamParam === '1' ? undefined : outputStreamParam; + const run = getRun(runId); + const stream = run.getReadable({ + namespace, + }); + // Add JSON framing to the stream, wrapping binary data in base64 + const streamWithFraming = new TransformStream({ + transform(chunk, controller) { + const data = + chunk instanceof Uint8Array + ? { data: Buffer.from(chunk).toString('base64') } + : chunk; + controller.enqueue(`${JSON.stringify(data)}\n`); + }, + }); + return new Response(stream.pipeThrough(streamWithFraming), { + headers: { + 'Content-Type': 'application/octet-stream', + }, + }); + } + + try { + const run = getRun(runId); + const returnValue = await run.returnValue; + console.log('Return value:', returnValue); + return returnValue instanceof ReadableStream + ? new Response(returnValue, { + headers: { + 'Content-Type': 'application/octet-stream', + }, + }) + : json(returnValue); + } catch (error) { + if (error instanceof Error) { + if (error.name === 'WorkflowRunNotCompletedError') { + return json( + { + ...error, + name: error.name, + message: error.message, + }, + { status: 202 } + ); + } + + if (error.name === 'WorkflowRunFailedError') { + return json( + { + ...error, + name: error.name, + message: error.message, + }, + { status: 400 } + ); + } + } + + console.error( + 'Unexpected error while getting workflow return value:', + error + ); + return json( + { + error: 'Internal server error', + }, + { status: 500 } + ); + } +}; diff --git a/workbench/sveltekit/workflows/6_batching.ts b/workbench/sveltekit/workflows/6_batching.ts new file mode 120000 index 000000000..75feb6fee --- /dev/null +++ b/workbench/sveltekit/workflows/6_batching.ts @@ -0,0 +1 @@ +../../example/workflows/6_batching.ts \ No newline at end of file diff --git a/workbench/sveltekit/workflows/98_duplicate_case.ts b/workbench/sveltekit/workflows/98_duplicate_case.ts new file mode 120000 index 000000000..49404a981 --- /dev/null +++ b/workbench/sveltekit/workflows/98_duplicate_case.ts @@ -0,0 +1 @@ +../../example/workflows/98_duplicate_case.ts \ No newline at end of file diff --git a/workbench/sveltekit/workflows/99_e2e.ts b/workbench/sveltekit/workflows/99_e2e.ts new file mode 120000 index 000000000..a7eb151e6 --- /dev/null +++ b/workbench/sveltekit/workflows/99_e2e.ts @@ -0,0 +1 @@ +../../example/workflows/99_e2e.ts \ No newline at end of file diff --git a/workbench/sveltekit/workflows/user-signup.ts b/workbench/sveltekit/workflows/user-signup.ts deleted file mode 100644 index 173c7196e..000000000 --- a/workbench/sveltekit/workflows/user-signup.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createWebhook, sleep } from 'workflow'; - -export async function handleUserSignup(email: string) { - 'use workflow'; - - const user = await createUser(email); - await sendWelcomeEmail(user); - - await sleep('5s'); - - const webhook = createWebhook(); - await sendOnboardingEmail(user, webhook.url); - - await webhook; - console.log('Webhook Resolved'); - - return { userId: user.id, status: 'onboarded' }; -} - -async function createUser(email: string) { - 'use step'; - - console.log(`Creating a new user with email: ${email}`); - - return { id: crypto.randomUUID(), email }; -} - -async function sendWelcomeEmail(user: { id: string; email: string }) { - 'use step'; - - console.log(`Sending welcome email to user: ${user.id}`); -} - -async function sendOnboardingEmail( - user: { id: string; email: string }, - callback: string -) { - 'use step'; - - console.log(`Sending onboarding email to user: ${user.id}`); - - console.log(`Click this link to resolve the webhook: ${callback}`); -} From 919ce3b8c10fc089b220c762507d663b620785da Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 21:39:12 -0700 Subject: [PATCH 12/63] fix: no start command and vercel builder outputs --- packages/sveltekit/src/builders.ts | 22 +++++++++++++++++----- workbench/sveltekit/package.json | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 3c68d9ccf..13ad9a509 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -7,7 +7,7 @@ import type { WorkflowConfig } from '@workflow/cli/dist/lib/config/types.js'; const CommonBuildOptions = { dirs: ['workflows', 'src/workflows'], - buildTarget: 'sveltekit' as const, // unused in base + buildTarget: 'sveltekit' as const, stepsBundlePath: '', // unused in base workflowsBundlePath: '', // unused in base webhookBundlePath: '', // unused in base @@ -26,11 +26,23 @@ export class VercelBuilder extends VercelBuildOutputAPIBuilder { this.config.workingDir, '.vercel/output/config.json' ); - const originalConfig = JSON.parse(await readFile(configPath, 'utf-8')); + + let existingConfig: { version?: number; routes?: any[] } | null = null; + try { + const existingConfigContent = await readFile(configPath, 'utf-8'); + existingConfig = JSON.parse(existingConfigContent); + } catch {} + await super.build(); - const newConfig = JSON.parse(await readFile(configPath, 'utf-8')); - originalConfig.routes.unshift(...newConfig.routes); - await writeFile(configPath, JSON.stringify(originalConfig, null, 2)); + + if (existingConfig?.routes) { + const workflowConfig = JSON.parse(await readFile(configPath, 'utf-8')); + const mergedConfig = { + ...workflowConfig, + routes: [...workflowConfig.routes, ...existingConfig.routes], + }; + await writeFile(configPath, JSON.stringify(mergedConfig, null, 2)); + } } } diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 8de4f34e9..0d88d56b8 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -7,6 +7,7 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", + "start": "node build/index.js", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" From 3f6b249a8f9dfb3bff12baacc8b01f9bba9b9a24 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 21:51:21 -0700 Subject: [PATCH 13/63] fix: base builder conditions --- packages/cli/src/lib/builders/base-builder.ts | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/cli/src/lib/builders/base-builder.ts b/packages/cli/src/lib/builders/base-builder.ts index 8404a45b1..f12298ea5 100644 --- a/packages/cli/src/lib/builders/base-builder.ts +++ b/packages/cli/src/lib/builders/base-builder.ts @@ -260,12 +260,7 @@ export abstract class BaseBuilder { import '${builtInSteps}'; // User steps ${imports}`; - if (this.config.buildTarget === 'next') { - entryContent += ` - // API entrypoint - export { stepEntrypoint as POST } from 'workflow/runtime'; - `; - } else if (this.config.buildTarget === 'sveltekit') { + if (this.config.buildTarget === 'sveltekit') { entryContent += ` // API entrypoint import { stepEntrypoint } from 'workflow/runtime'; @@ -281,6 +276,11 @@ export abstract class BaseBuilder { return stepEntrypoint(normalRequest); } `; + } else { + entryContent += ` + // API entrypoint + export { stepEntrypoint as POST } from 'workflow/runtime'; + `; } // Bundle with esbuild and our custom SWC plugin @@ -482,10 +482,7 @@ import { workflowEntrypoint } from 'workflow/runtime'; const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; `; - if (this.config.buildTarget === 'next') { - workflowFunctionCode += ` -export const POST = workflowEntrypoint(workflowCode);`; - } else if (this.config.buildTarget === 'sveltekit') { + if (this.config.buildTarget === 'sveltekit') { workflowFunctionCode += ` export const POST = async ({ request }) => { const body = await request.arrayBuffer() @@ -498,6 +495,9 @@ export const POST = async ({ request }) => { }) return workflowEntrypoint(workflowCode)(normalRequest); }`; + } else { + workflowFunctionCode += ` +export const POST = workflowEntrypoint(workflowCode);`; } // we skip the final bundling step for Next.js so it can bundle itself @@ -642,17 +642,7 @@ async function handler(request) { return new Response(null, { status: 404 }); } }`; - if (this.config.buildTarget === 'next') { - routeContent += ` -export const GET = handler; -export const POST = handler; -export const PUT = handler; -export const PATCH = handler; -export const DELETE = handler; -export const HEAD = handler; -export const OPTIONS = handler; -`; - } else if (this.config.buildTarget === 'sveltekit') { + if (this.config.buildTarget === 'sveltekit') { routeContent += ` const createSvelteKitHandler = (method) => async ({ request }) => { const options = { @@ -673,6 +663,16 @@ export const PATCH = createSvelteKitHandler('PATCH'); export const DELETE = createSvelteKitHandler('DELETE'); export const HEAD = createSvelteKitHandler('HEAD'); export const OPTIONS = createSvelteKitHandler('OPTIONS'); +`; + } else { + routeContent += ` +export const GET = handler; +export const POST = handler; +export const PUT = handler; +export const PATCH = handler; +export const DELETE = handler; +export const HEAD = handler; +export const OPTIONS = handler; `; } if (!bundle) { From d4ca09ffe8b45ead522d64307c7073bfc7d6e1f1 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 22:02:01 -0700 Subject: [PATCH 14/63] . --- workbench/sveltekit/package.json | 2 +- workbench/sveltekit/svelte.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 0d88d56b8..76a1b7a09 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -4,7 +4,7 @@ "version": "0.0.1", "type": "module", "scripts": { - "dev": "vite dev", + "dev": "vite dev --port 3000", "build": "vite build", "preview": "vite preview", "start": "node build/index.js", diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index c1c25feca..8f0f9dacc 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-node'; +import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ From 8c0cad101ece46350fe4913a2b4152eb570b3207 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 22:04:25 -0700 Subject: [PATCH 15/63] add auto adapter sveltekit --- pnpm-lock.yaml | 12 ++++++++++++ workbench/sveltekit/package.json | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2ab3cdd5..53340161f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1220,6 +1220,9 @@ importers: '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 + '@sveltejs/adapter-auto': + specifier: ^7.0.0 + version: 7.0.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) '@vercel/otel': specifier: ^1.13.0 version: 1.13.0(@opentelemetry/api-logs@0.57.2)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) @@ -4369,6 +4372,11 @@ packages: peerDependencies: acorn: ^8.9.0 + '@sveltejs/adapter-auto@7.0.0': + resolution: {integrity: sha512-ImDWaErTOCkRS4Gt+5gZuymKFBobnhChXUZ9lhUZLahUgvA4OOvRzi3sahzYgbxGj5nkA6OV0GAW378+dl/gyw==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + '@sveltejs/adapter-node@5.4.0': resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} peerDependencies: @@ -13553,6 +13561,10 @@ snapshots: dependencies: acorn: 8.15.0 + '@sveltejs/adapter-auto@7.0.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': + dependencies: + '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': dependencies: '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 76a1b7a09..ba3b3de0f 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -13,10 +13,10 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@types/lodash.chunk": "^4.2.9", "@sveltejs/adapter-node": "^5.3.2", "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", + "@types/lodash.chunk": "^4.2.9", "@workflow/sveltekit": "workspace:*", "svelte": "^5.39.5", "svelte-check": "^4.3.2", @@ -28,11 +28,12 @@ "@ai-sdk/react": "2.0.76", "@node-rs/xxhash": "1.7.6", "@opentelemetry/api": "^1.9.0", + "@sveltejs/adapter-auto": "^7.0.0", "@vercel/otel": "^1.13.0", - "workflow": "workspace:*", "@workflow/ai": "workspace:*", "ai": "catalog:", "lodash.chunk": "^4.2.0", + "workflow": "workspace:*", "zod": "catalog:" } } From 3da001e78352c6fa2c09c3d507308945e7339a01 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 22:09:18 -0700 Subject: [PATCH 16/63] fix: disable checking origin for cross site ci stuff --- workbench/sveltekit/svelte.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index 8f0f9dacc..f5c2a6cae 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -6,7 +6,7 @@ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: adapter() }, + kit: { adapter: adapter(), csrf: { checkOrigin: false } }, }; export default config; From 3ac85f21a66c1f7fda165a3e819d93b4fe37c55b Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 22:48:11 -0700 Subject: [PATCH 17/63] allow all trusted origins in svelte config --- pnpm-lock.yaml | 16 ---------------- workbench/sveltekit/package.json | 1 - workbench/sveltekit/svelte.config.js | 2 +- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53340161f..9b97d1dfe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1242,9 +1242,6 @@ importers: specifier: 'catalog:' version: 4.1.11 devDependencies: - '@sveltejs/adapter-node': - specifier: ^5.3.2 - version: 5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) '@sveltejs/kit': specifier: ^2.43.2 version: 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) @@ -4377,11 +4374,6 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/adapter-node@5.4.0': - resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} - peerDependencies: - '@sveltejs/kit': ^2.4.0 - '@sveltejs/kit@2.48.2': resolution: {integrity: sha512-WIgVMGt+b9OxPDtu0Txow28RsBrLoV3wr2QoUxEHd4CHbpxbqKQf2SIEzd+SE+bqrUL2D5MxBeQBdY+t7o6n1A==} engines: {node: '>=18.13'} @@ -13565,14 +13557,6 @@ snapshots: dependencies: '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) - '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': - dependencies: - '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) - '@rollup/plugin-json': 6.1.0(rollup@4.52.5) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.52.5) - '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) - rollup: 4.52.5 - '@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': dependencies: '@standard-schema/spec': 1.0.0 diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index ba3b3de0f..4c86cb8c9 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -13,7 +13,6 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@sveltejs/adapter-node": "^5.3.2", "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", "@types/lodash.chunk": "^4.2.9", diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index f5c2a6cae..b714fca28 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -6,7 +6,7 @@ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: adapter(), csrf: { checkOrigin: false } }, + kit: { adapter: adapter(), csrf: { trustedOrigins: ['*'] } }, }; export default config; From 03997dd3a2f2f73c91a4ab8f61bd9e9f9ad1e7c6 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 22:57:03 -0700 Subject: [PATCH 18/63] fix: add catch for error thrown when waiting for ops --- packages/core/src/runtime.ts | 12 ++++++++++-- packages/core/src/runtime/resume-hook.ts | 6 +++++- packages/core/src/runtime/start.ts | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts index 9fa31c92d..01bce4bc1 100644 --- a/packages/core/src/runtime.ts +++ b/packages/core/src/runtime.ts @@ -401,7 +401,11 @@ export function workflowEntrypoint(workflowCode: string) { input: dehydratedArgs as Serializable[], }); - waitUntil(Promise.all(ops)); + waitUntil( + Promise.all(ops).catch((err) => { + console.error('Error waiting for ops', err); + }) + ); await world.queue( `__wkf_step_${queueItem.stepName}`, @@ -680,7 +684,11 @@ export const stepEntrypoint = result = dehydrateStepReturnValue(result, ops); - waitUntil(Promise.all(ops)); + waitUntil( + Promise.all(ops).catch((err) => { + console.error('Error waiting for ops', err); + }) + ); // Update the event log with the step result await world.events.create(workflowRunId, { diff --git a/packages/core/src/runtime/resume-hook.ts b/packages/core/src/runtime/resume-hook.ts index aa6401aa8..119ed71c5 100644 --- a/packages/core/src/runtime/resume-hook.ts +++ b/packages/core/src/runtime/resume-hook.ts @@ -78,7 +78,11 @@ export async function resumeHook( ops, globalThis ); - waitUntil(Promise.all(ops)); + waitUntil( + Promise.all(ops).catch((err) => { + console.error('Error waiting for ops', err); + }) + ); // Create a hook_received event with the payload await world.events.create(hook.runId, { diff --git a/packages/core/src/runtime/start.ts b/packages/core/src/runtime/start.ts index ee61093df..56e379cbc 100644 --- a/packages/core/src/runtime/start.ts +++ b/packages/core/src/runtime/start.ts @@ -91,7 +91,11 @@ export async function start( input: workflowArguments, executionContext: { traceCarrier }, }); - waitUntil(Promise.all(ops)); + waitUntil( + Promise.all(ops).catch((err) => { + console.error('Error waiting for ops', err); + }) + ); span?.setAttributes({ ...Attribute.WorkflowRunId(runResponse.runId), From 00d487d3b6033c7a884b4d5d953a213f63d20e8c Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 23:10:31 -0700 Subject: [PATCH 19/63] fix: sveltekit workbench adapter --- pnpm-lock.yaml | 16 ++++++++++++++++ workbench/sveltekit/package.json | 3 ++- workbench/sveltekit/svelte.config.js | 7 +++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b97d1dfe..f2b89db35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1223,6 +1223,9 @@ importers: '@sveltejs/adapter-auto': specifier: ^7.0.0 version: 7.0.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) + '@sveltejs/adapter-node': + specifier: ^5.4.0 + version: 5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) '@vercel/otel': specifier: ^1.13.0 version: 1.13.0(@opentelemetry/api-logs@0.57.2)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) @@ -4374,6 +4377,11 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 + '@sveltejs/adapter-node@5.4.0': + resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} + peerDependencies: + '@sveltejs/kit': ^2.4.0 + '@sveltejs/kit@2.48.2': resolution: {integrity: sha512-WIgVMGt+b9OxPDtu0Txow28RsBrLoV3wr2QoUxEHd4CHbpxbqKQf2SIEzd+SE+bqrUL2D5MxBeQBdY+t7o6n1A==} engines: {node: '>=18.13'} @@ -13557,6 +13565,14 @@ snapshots: dependencies: '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': + dependencies: + '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) + '@rollup/plugin-json': 6.1.0(rollup@4.52.5) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.52.5) + '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + rollup: 4.52.5 + '@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': dependencies: '@standard-schema/spec': 1.0.0 diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 4c86cb8c9..1791e007a 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -7,7 +7,7 @@ "dev": "vite dev --port 3000", "build": "vite build", "preview": "vite preview", - "start": "node build/index.js", + "start": "node build/index.js --port 3000", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" @@ -28,6 +28,7 @@ "@node-rs/xxhash": "1.7.6", "@opentelemetry/api": "^1.9.0", "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/adapter-node": "^5.4.0", "@vercel/otel": "^1.13.0", "@workflow/ai": "workspace:*", "ai": "catalog:", diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index b714fca28..cda376e6a 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -1,12 +1,15 @@ -import adapter from '@sveltejs/adapter-auto'; +import autoAdapter from '@sveltejs/adapter-auto'; +import nodeAdapter from '@sveltejs/adapter-node'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +const adapter = process.env.VERCEL === '1' ? autoAdapter() : nodeAdapter(); + /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: adapter(), csrf: { trustedOrigins: ['*'] } }, + kit: { adapter: adapter, csrf: { trustedOrigins: ['*'] } }, }; export default config; From 92787ef7ab41ce31c1f58e2f8072d5495e918ab5 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 23:40:38 -0700 Subject: [PATCH 20/63] test --- packages/sveltekit/src/index.ts | 7 +++++-- pnpm-lock.yaml | 19 +++++++++++++++++++ workbench/sveltekit/package.json | 1 + workbench/sveltekit/svelte.config.js | 8 ++++---- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 191b2e56f..f20408945 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -4,10 +4,13 @@ export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', async configResolved() { + if (process.env.NODE_ENV === 'development') { + await new LocalBuilder({}).build(); + } + }, + async closeBundle() { if (process.env.VERCEL === '1') { await new VercelBuilder({}).build(); - } else { - await new LocalBuilder({}).build(); } }, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2b89db35..89b33c73e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1226,6 +1226,9 @@ importers: '@sveltejs/adapter-node': specifier: ^5.4.0 version: 5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) + '@sveltejs/adapter-vercel': + specifier: ^6.1.1 + version: 6.1.1(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(rollup@4.52.5) '@vercel/otel': specifier: ^1.13.0 version: 1.13.0(@opentelemetry/api-logs@0.57.2)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)) @@ -4382,6 +4385,12 @@ packages: peerDependencies: '@sveltejs/kit': ^2.4.0 + '@sveltejs/adapter-vercel@6.1.1': + resolution: {integrity: sha512-rnuREIO/dBYZn825aXTmdCU7sBr4nQqxNVkqYLUHoUnuv3vaas6O/SxAI1TiYBDEetgeQ5m51I5dTVJvhVzASA==} + engines: {node: '>=20.0'} + peerDependencies: + '@sveltejs/kit': ^2.4.0 + '@sveltejs/kit@2.48.2': resolution: {integrity: sha512-WIgVMGt+b9OxPDtu0Txow28RsBrLoV3wr2QoUxEHd4CHbpxbqKQf2SIEzd+SE+bqrUL2D5MxBeQBdY+t7o6n1A==} engines: {node: '>=18.13'} @@ -13573,6 +13582,16 @@ snapshots: '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) rollup: 4.52.5 + '@sveltejs/adapter-vercel@6.1.1(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(rollup@4.52.5)': + dependencies: + '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) + '@vercel/nft': 0.30.3(rollup@4.52.5) + esbuild: 0.25.11 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + '@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))': dependencies: '@standard-schema/spec': 1.0.0 diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 1791e007a..322432cda 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -29,6 +29,7 @@ "@opentelemetry/api": "^1.9.0", "@sveltejs/adapter-auto": "^7.0.0", "@sveltejs/adapter-node": "^5.4.0", + "@sveltejs/adapter-vercel": "^6.1.1", "@vercel/otel": "^1.13.0", "@workflow/ai": "workspace:*", "ai": "catalog:", diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index cda376e6a..fec420ed0 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -1,15 +1,15 @@ -import autoAdapter from '@sveltejs/adapter-auto'; -import nodeAdapter from '@sveltejs/adapter-node'; +import node from '@sveltejs/adapter-node'; +import vercel from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; -const adapter = process.env.VERCEL === '1' ? autoAdapter() : nodeAdapter(); +const adapter = process.env.VERCEL === '1' ? vercel() : node(); /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: adapter, csrf: { trustedOrigins: ['*'] } }, + kit: { adapter: node(), csrf: { trustedOrigins: ['*'] } }, }; export default config; From 7febb8c2b259b809018746ae749ef433d6724c74 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Wed, 29 Oct 2025 23:47:21 -0700 Subject: [PATCH 21/63] test --- workbench/sveltekit/svelte.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index fec420ed0..29881d03e 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -9,7 +9,7 @@ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: node(), csrf: { trustedOrigins: ['*'] } }, + kit: { adapter: adapter, csrf: { trustedOrigins: ['*'] } }, }; export default config; From 2243e0c982d936a986ed9771a0c5706858cf030e Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 12:43:38 -0700 Subject: [PATCH 22/63] refactor: move vercel builder on config resolved --- packages/sveltekit/src/index.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index f20408945..191b2e56f 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -4,13 +4,10 @@ export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', async configResolved() { - if (process.env.NODE_ENV === 'development') { - await new LocalBuilder({}).build(); - } - }, - async closeBundle() { if (process.env.VERCEL === '1') { await new VercelBuilder({}).build(); + } else { + await new LocalBuilder({}).build(); } }, }; From ac4000e5b9abd8f07a60183a7bece65b66b5e965 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 12:59:06 -0700 Subject: [PATCH 23/63] update package json --- workbench/sveltekit/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 322432cda..4fd450127 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -1,7 +1,7 @@ { - "name": "sveltekit", + "name": "@workflow/example-sveltekit", "private": true, - "version": "0.0.1", + "version": "0.0.0", "type": "module", "scripts": { "dev": "vite dev --port 3000", From b0ecab6146fd8038e8ecc2787a29f5e6830b1236 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 13:14:34 -0700 Subject: [PATCH 24/63] add demo workflow trigger --- workbench/sveltekit/src/app.html | 81 ++++++++++++++++--- workbench/sveltekit/src/routes/+page.svelte | 5 +- .../src/routes/api/trigger/+server.ts | 38 ++++++--- workbench/sveltekit/workflows/0_calc.ts | 15 ++++ 4 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 workbench/sveltekit/workflows/0_calc.ts diff --git a/workbench/sveltekit/src/app.html b/workbench/sveltekit/src/app.html index f273cc58f..44e6779cb 100644 --- a/workbench/sveltekit/src/app.html +++ b/workbench/sveltekit/src/app.html @@ -1,11 +1,72 @@ - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- + + + + + + Workflows DevKit + SvelteKit Example + + %sveltekit.head% + + + + %sveltekit.body% + + diff --git a/workbench/sveltekit/src/routes/+page.svelte b/workbench/sveltekit/src/routes/+page.svelte index cc88df0ea..8cf31343c 100644 --- a/workbench/sveltekit/src/routes/+page.svelte +++ b/workbench/sveltekit/src/routes/+page.svelte @@ -1,2 +1,3 @@ -

Welcome to SvelteKit

-

Visit svelte.dev/docs/kit to read the documentation

+

Workflows DevKit + SvelteKit Example

+
+ \ No newline at end of file diff --git a/workbench/sveltekit/src/routes/api/trigger/+server.ts b/workbench/sveltekit/src/routes/api/trigger/+server.ts index 24ad1d682..98efaa98d 100644 --- a/workbench/sveltekit/src/routes/api/trigger/+server.ts +++ b/workbench/sveltekit/src/routes/api/trigger/+server.ts @@ -1,10 +1,18 @@ import { json, type RequestHandler } from '@sveltejs/kit'; import { getRun, start } from 'workflow/api'; import { hydrateWorkflowArguments } from 'workflow/internal/serialization'; +import * as calcWorkflow from '../../../../workflows/0_calc'; import * as batchingWorkflow from '../../../../workflows/6_batching'; import * as duplicateE2e from '../../../../workflows/98_duplicate_case'; import * as e2eWorkflows from '../../../../workflows/99_e2e'; +const WORKFLOW_MODULES = { + 'workflows/0_calc.ts': calcWorkflow, + 'workflows/6_batching.ts': batchingWorkflow, + 'workflows/98_duplicate_case.ts': duplicateE2e, + 'workflows/99_e2e.ts': e2eWorkflows, +} as const; + export const POST: RequestHandler = async ({ request }) => { const url = new URL(request.url); const workflowFile = @@ -13,6 +21,25 @@ export const POST: RequestHandler = async ({ request }) => { console.log('calling workflow', { workflowFile, workflowFn }); + const workflows = + WORKFLOW_MODULES[workflowFile as keyof typeof WORKFLOW_MODULES]; + if (!workflows) { + return json( + { error: `Workflow file "${workflowFile}" not found` }, + { status: 404 } + ); + } + + const workflow = workflows[workflowFn as keyof typeof workflows]; + if (!workflow) { + return json( + { + error: `Workflow "${workflowFn}" not found in "${workflowFile}"`, + }, + { status: 404 } + ); + } + let args: any[] = []; // Args from query string @@ -36,16 +63,7 @@ export const POST: RequestHandler = async ({ request }) => { ); try { - let workflows: any; - if (workflowFile === 'workflows/99_e2e.ts') { - workflows = e2eWorkflows; - } else if (workflowFile === 'workflows/6_batching.ts') { - workflows = batchingWorkflow; - } else { - workflows = duplicateE2e; - } - - const run = await start((workflows as any)[workflowFn], args); + const run = await start(workflow as any, args); console.log('Run:', run); return json(run); } catch (err) { diff --git a/workbench/sveltekit/workflows/0_calc.ts b/workbench/sveltekit/workflows/0_calc.ts new file mode 100644 index 000000000..3323945e6 --- /dev/null +++ b/workbench/sveltekit/workflows/0_calc.ts @@ -0,0 +1,15 @@ +// import { FatalError } from 'workflow'; + +export async function calc(n: number) { + 'use workflow'; + console.log('Simple workflow started'); + n = await pow(n); + console.log('Simple workflow finished'); + return n; +} + +async function pow(a: number): Promise { + 'use step'; + console.log('Running step pow with arg:', a); + return a * a; +} From 4f1fc09aa00b641fd8c30e6629a615d906b42d60 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 14:44:42 -0700 Subject: [PATCH 25/63] test letting sveltekit handle route generation --- packages/sveltekit/src/index.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 191b2e56f..a7d35249c 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,15 +1,16 @@ -import { LocalBuilder, VercelBuilder } from './builders.js'; +import { LocalBuilder } from './builders.js'; export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', async configResolved() { - if (process.env.VERCEL === '1') { - await new VercelBuilder({}).build(); - } else { - await new LocalBuilder({}).build(); - } + await new LocalBuilder({}).build(); }, + // async buildEnd() { + // if (process.env.VERCEL === '1') { + // await new VercelBuilder({}).build(); + // } + // }, }; } From 289bc3e815c3f0372fb96fedf3ae049f90ebed3b Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 14:53:39 -0700 Subject: [PATCH 26/63] fix: exclude git ignore for local builder outputs --- packages/sveltekit/src/builders.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 13ad9a509..130e05956 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -64,7 +64,9 @@ export class LocalBuilder extends BaseBuilder { await mkdir(workflowGeneratedDir, { recursive: true }); // Add .gitignore to exclude generated files from version control - await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); + if (process.env.VERCEL !== '1') { + await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); + } // Get workflow and step files to bundle const inputFiles = await this.getInputFiles(); From ec35febc4d7e50a6b14d18e06051b12d6df5fecf Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 15:54:35 -0700 Subject: [PATCH 27/63] update config --- workbench/sveltekit/package.json | 3 +-- workbench/sveltekit/svelte.config.js | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 4fd450127..7ed399e09 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -6,8 +6,7 @@ "scripts": { "dev": "vite dev --port 3000", "build": "vite build", - "preview": "vite preview", - "start": "node build/index.js --port 3000", + "start": "vite preview --port 3000", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index 29881d03e..2d4fe3249 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -2,14 +2,17 @@ import node from '@sveltejs/adapter-node'; import vercel from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; -const adapter = process.env.VERCEL === '1' ? vercel() : node(); +const adapter = process.env.VERCEL_DEPLOYMENT_ID === '1' ? vercel() : node(); /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), - kit: { adapter: adapter, csrf: { trustedOrigins: ['*'] } }, + kit: { + adapter: adapter, + csrf: { trustedOrigins: ['*'] }, + }, }; export default config; From 4bd162bb21114bd07e24da3d0bc5e68861628f6b Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:05:35 -0700 Subject: [PATCH 28/63] add debug logs --- packages/core/e2e/local-build.test.ts | 2 ++ workbench/sveltekit/package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/e2e/local-build.test.ts b/packages/core/e2e/local-build.test.ts index 237d6628c..282a5d483 100644 --- a/packages/core/e2e/local-build.test.ts +++ b/packages/core/e2e/local-build.test.ts @@ -18,6 +18,8 @@ describe.each(['nextjs-webpack', 'nextjs-turbopack', 'nitro', 'sveltekit'])( cwd: getWorkbenchAppPath(project), }); + console.error(result.stderr.toString(), result.stdout.toString()); + expect(result.stderr).not.toContain('Error:'); }); } diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 7ed399e09..1f650bc79 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite dev --port 3000", - "build": "vite build", + "build": "vite build && find .sveltekit", "start": "vite preview --port 3000", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", From 9b10ed40ecbfa7ec83c2bb45f460675f01dad3bb Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:07:35 -0700 Subject: [PATCH 29/63] update debug --- workbench/sveltekit/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 1f650bc79..c924efa0e 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite dev --port 3000", - "build": "vite build && find .sveltekit", + "build": "vite build && find .svelte-kit", "start": "vite preview --port 3000", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", From f3a71ce3706e281c373c605b2b63249a5b07b993 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:09:47 -0700 Subject: [PATCH 30/63] update turbo.json --- turbo.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/turbo.json b/turbo.json index ca0f500f6..4fa23084a 100644 --- a/turbo.json +++ b/turbo.json @@ -4,17 +4,17 @@ "tasks": { "build": { "dependsOn": ["^build"], - "outputs": ["dist/**"] + "outputs": ["dist/**", "build", ".svelte-kit"] }, "dev": { "dependsOn": ["^build"], - "outputs": ["dist/**"] + "outputs": ["dist/**", "build", ".svelte-kit"] }, "typecheck": { - "dependsOn": ["^build"] + "outputs": ["dist/**", "build", ".svelte-kit"] }, "test": { - "dependsOn": ["^build"] + "outputs": ["dist/**", "build", ".svelte-kit"] }, "clean": { "cache": false From e45e258eb971445ef154add497a5d7e5efd198b0 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:12:50 -0700 Subject: [PATCH 31/63] fix env check --- workbench/sveltekit/svelte.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index 2d4fe3249..2c488d929 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -2,7 +2,7 @@ import node from '@sveltejs/adapter-node'; import vercel from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; -const adapter = process.env.VERCEL_DEPLOYMENT_ID === '1' ? vercel() : node(); +const adapter = process.env.VERCEL_DEPLOYMENT_ID ? vercel() : node(); /** @type {import('@sveltejs/kit').Config} */ const config = { From d935d87fe65a97e9594ac333b0cbc8a472fc4d29 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:14:08 -0700 Subject: [PATCH 32/63] another output --- turbo.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/turbo.json b/turbo.json index 4fa23084a..6226d9ae2 100644 --- a/turbo.json +++ b/turbo.json @@ -4,17 +4,17 @@ "tasks": { "build": { "dependsOn": ["^build"], - "outputs": ["dist/**", "build", ".svelte-kit"] + "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "dev": { "dependsOn": ["^build"], - "outputs": ["dist/**", "build", ".svelte-kit"] + "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "typecheck": { - "outputs": ["dist/**", "build", ".svelte-kit"] + "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "test": { - "outputs": ["dist/**", "build", ".svelte-kit"] + "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "clean": { "cache": false From 9003f84dabd80efaef10d7d55abcaf297af12b47 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:15:44 -0700 Subject: [PATCH 33/63] use top-level await --- packages/sveltekit/src/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index a7d35249c..6991839c0 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,11 +1,10 @@ import { LocalBuilder } from './builders.js'; +await new LocalBuilder({}).build(); + export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', - async configResolved() { - await new LocalBuilder({}).build(); - }, // async buildEnd() { // if (process.env.VERCEL === '1') { // await new VercelBuilder({}).build(); From c8915d94640dfdbcd0cfb310f498bfa0dd5278dd Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:30:50 -0700 Subject: [PATCH 34/63] ensure vercel functions are patched --- packages/sveltekit/src/index.ts | 61 +++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 6991839c0..2fab69c0d 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,15 +1,64 @@ +import fs from 'node:fs/promises'; import { LocalBuilder } from './builders.js'; -await new LocalBuilder({}).build(); +const localBuilder = new LocalBuilder({}); + +// This needs to be in the top-level as we need to create these +// entries before svelte plugin is started or the entries are +// a race to be created before svelte discovers entries +await localBuilder.build(); export function workflowPlugin() { return { name: 'workflow-sveltekit-plugin', - // async buildEnd() { - // if (process.env.VERCEL === '1') { - // await new VercelBuilder({}).build(); - // } - // }, + async writeBundle() { + // don't attempt patching functions output if not Vercel adapter + if (!process.env.VERCEL_DEPLOYMENT_ID) { + return; + } + + for (const { file, config } of [ + { + file: '.vercel/output/functions/.well-known/workflow/v1/flow.func/.vc-config.json', + config: { + experimentalTriggers: [ + { + type: 'queue/v1beta', + topic: '__wkf_workflow_*', + consumer: 'default', + maxDeliveries: 64, + retryAfterSeconds: 5, + initialDelaySeconds: 0, + }, + ], + }, + }, + { + file: '.vercel/output/functions/.well-known/workflow/v1/step.func/.vc-config.json', + config: { + experimentalTriggers: [ + { + type: 'queue/v1beta', + topic: '__wkf_step_*', + consumer: 'default', + maxDeliveries: 64, + retryAfterSeconds: 5, + initialDelaySeconds: 0, + }, + ], + }, + }, + ]) { + const existingConfig = JSON.parse(await fs.readFile(file, 'utf8')); + await fs.writeFile( + file, + JSON.stringify({ + ...existingConfig, + config, + }) + ); + } + }, }; } From 10a564b44cfe4d5bf3e991cdb7c6db0df95377c6 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:34:27 -0700 Subject: [PATCH 35/63] change hook --- packages/sveltekit/src/index.ts | 97 +++++++++++++++++---------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 2fab69c0d..eded09896 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,4 +1,4 @@ -import fs from 'node:fs/promises'; +import fs from 'node:fs'; import { LocalBuilder } from './builders.js'; const localBuilder = new LocalBuilder({}); @@ -8,57 +8,58 @@ const localBuilder = new LocalBuilder({}); // a race to be created before svelte discovers entries await localBuilder.build(); -export function workflowPlugin() { - return { - name: 'workflow-sveltekit-plugin', - async writeBundle() { - // don't attempt patching functions output if not Vercel adapter - if (!process.env.VERCEL_DEPLOYMENT_ID) { - return; - } +process.on('exit', () => { + // don't attempt patching functions output if not Vercel adapter + if (!process.env.VERCEL_DEPLOYMENT_ID) { + return; + } - for (const { file, config } of [ - { - file: '.vercel/output/functions/.well-known/workflow/v1/flow.func/.vc-config.json', - config: { - experimentalTriggers: [ - { - type: 'queue/v1beta', - topic: '__wkf_workflow_*', - consumer: 'default', - maxDeliveries: 64, - retryAfterSeconds: 5, - initialDelaySeconds: 0, - }, - ], + for (const { file, config } of [ + { + file: '.vercel/output/functions/.well-known/workflow/v1/flow.func/.vc-config.json', + config: { + experimentalTriggers: [ + { + type: 'queue/v1beta', + topic: '__wkf_workflow_*', + consumer: 'default', + maxDeliveries: 64, + retryAfterSeconds: 5, + initialDelaySeconds: 0, }, - }, - { - file: '.vercel/output/functions/.well-known/workflow/v1/step.func/.vc-config.json', - config: { - experimentalTriggers: [ - { - type: 'queue/v1beta', - topic: '__wkf_step_*', - consumer: 'default', - maxDeliveries: 64, - retryAfterSeconds: 5, - initialDelaySeconds: 0, - }, - ], + ], + }, + }, + { + file: '.vercel/output/functions/.well-known/workflow/v1/step.func/.vc-config.json', + config: { + experimentalTriggers: [ + { + type: 'queue/v1beta', + topic: '__wkf_step_*', + consumer: 'default', + maxDeliveries: 64, + retryAfterSeconds: 5, + initialDelaySeconds: 0, }, - }, - ]) { - const existingConfig = JSON.parse(await fs.readFile(file, 'utf8')); - await fs.writeFile( - file, - JSON.stringify({ - ...existingConfig, - config, - }) - ); - } + ], + }, }, + ]) { + const existingConfig = JSON.parse(fs.readFileSync(file, 'utf8')); + fs.writeFileSync( + file, + JSON.stringify({ + ...existingConfig, + config, + }) + ); + } +}); + +export function workflowPlugin() { + return { + name: 'workflow-sveltekit-plugin', }; } From 7fa2da9728c5569e0f5b6740cad1c12500b9865b Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:38:51 -0700 Subject: [PATCH 36/63] update --- packages/sveltekit/src/index.ts | 4 +++- workbench/sveltekit/package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index eded09896..bf688f6ae 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -8,7 +8,8 @@ const localBuilder = new LocalBuilder({}); // a race to be created before svelte discovers entries await localBuilder.build(); -process.on('exit', () => { +process.on('beforeExit', () => { + console.log('BEFORE EXIT'); // don't attempt patching functions output if not Vercel adapter if (!process.env.VERCEL_DEPLOYMENT_ID) { return; @@ -46,6 +47,7 @@ process.on('exit', () => { }, }, ]) { + console.log('UPDATED FUNCTION CONFIG', file); const existingConfig = JSON.parse(fs.readFileSync(file, 'utf8')); fs.writeFileSync( file, diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index c924efa0e..7ed399e09 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite dev --port 3000", - "build": "vite build && find .svelte-kit", + "build": "vite build", "start": "vite preview --port 3000", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", From 26e1ac53fe513928d63be91bf300a7d70f52dea2 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:41:44 -0700 Subject: [PATCH 37/63] fix spread --- packages/sveltekit/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index bf688f6ae..6128519fa 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -53,7 +53,7 @@ process.on('beforeExit', () => { file, JSON.stringify({ ...existingConfig, - config, + ...config, }) ); } From 35ee459247780c2f3e193c3611026204922bda38 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 16:52:34 -0700 Subject: [PATCH 38/63] debug --- packages/sveltekit/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 6128519fa..20c8acaaa 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -47,7 +47,6 @@ process.on('beforeExit', () => { }, }, ]) { - console.log('UPDATED FUNCTION CONFIG', file); const existingConfig = JSON.parse(fs.readFileSync(file, 'utf8')); fs.writeFileSync( file, @@ -56,6 +55,8 @@ process.on('beforeExit', () => { ...config, }) ); + + console.log('UPDATED FUNCTION CONFIG', file, fs.readFileSync(file, 'utf8')); } }); From d0a38b2d84b8a4ed9cf5f7de697904f0726fa9f4 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Oct 2025 17:16:42 -0700 Subject: [PATCH 39/63] update --- packages/sveltekit/package.json | 2 ++ packages/sveltekit/src/index.ts | 21 +++++++++++++-- pnpm-lock.yaml | 46 +++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index da478fc65..2b62773b5 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -31,9 +31,11 @@ "@workflow/core": "workspace:*", "@workflow/swc-plugin": "workspace:*", "exsolve": "^1.0.7", + "fs-extra": "^11.3.2", "workflow": "workspace:*" }, "devDependencies": { + "@types/fs-extra": "^11.0.4", "@types/node": "catalog:", "@workflow/tsconfig": "workspace:*", "vite": "^7.1.11" diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 20c8acaaa..daadb11eb 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -1,4 +1,5 @@ -import fs from 'node:fs'; +import path from 'node:path'; +import fs from 'fs-extra'; import { LocalBuilder } from './builders.js'; const localBuilder = new LocalBuilder({}); @@ -14,7 +15,6 @@ process.on('beforeExit', () => { if (!process.env.VERCEL_DEPLOYMENT_ID) { return; } - for (const { file, config } of [ { file: '.vercel/output/functions/.well-known/workflow/v1/flow.func/.vc-config.json', @@ -47,6 +47,23 @@ process.on('beforeExit', () => { }, }, ]) { + // we need to un-symlink these as they can't be shared due to different + // experimental triggers config + const toCopy = fs.readdirSync(path.dirname(file)); + fs.unlinkSync(path.dirname(file)); + fs.mkdirSync(path.dirname(file), { recursive: true }); + + for (const item of toCopy) { + fs.copySync( + path.join( + path.dirname(file).replace(/\.func$/, ''), + '__data.json.func', + item + ), + path.join(path.dirname(file), item) + ); + } + const existingConfig = JSON.parse(fs.readFileSync(file, 'utf8')); fs.writeFileSync( file, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89b33c73e..05b7d0fba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -528,10 +528,16 @@ importers: exsolve: specifier: ^1.0.7 version: 1.0.7 + fs-extra: + specifier: ^11.3.2 + version: 11.3.2 workflow: specifier: workspace:* version: link:../workflow devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 '@types/node': specifier: 'catalog:' version: 24.6.2 @@ -4711,6 +4717,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} @@ -4723,6 +4732,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/jsonlines@0.1.5': resolution: {integrity: sha512-/zOl7I350g4/G6fEW9dktpTrkcKqZDMRkr2SuDla0utgwkUXrm7OFXq2WZT0W9Jl7BYoisGbn1EZsV/Z2F9LGg==} @@ -6445,6 +6457,10 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + engines: {node: '>=14.14'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -7035,6 +7051,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonlines@0.1.1: resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} @@ -9336,6 +9355,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unplugin-utils@0.2.5: resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} engines: {node: '>=18.12.0'} @@ -13928,6 +13951,11 @@ snapshots: '@types/estree@1.0.8': {} + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 24.6.2 + '@types/geojson@7946.0.16': {} '@types/graceful-fs@4.1.9': @@ -13941,6 +13969,10 @@ snapshots: '@types/json-schema@7.0.15': optional: true + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 24.6.2 + '@types/jsonlines@0.1.5': dependencies: '@types/node': 24.6.2 @@ -15774,6 +15806,12 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@11.3.2: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -16394,6 +16432,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsonlines@0.1.1: {} katex@0.16.25: @@ -19534,6 +19578,8 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + unplugin-utils@0.2.5: dependencies: pathe: 2.0.3 From 22ed0ca09876d67951ec439f1032173229bd0104 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:29:43 -0700 Subject: [PATCH 40/63] chore: remove vercel builder --- packages/sveltekit/src/builders.ts | 36 +----------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 130e05956..9f3eae9bc 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -1,8 +1,7 @@ import { constants } from 'node:fs'; -import { access, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; +import { access, mkdir, stat, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { BaseBuilder } from '@workflow/cli/dist/lib/builders/base-builder.js'; -import { VercelBuildOutputAPIBuilder } from '@workflow/cli/dist/lib/builders/vercel-build-output-api.js'; import type { WorkflowConfig } from '@workflow/cli/dist/lib/config/types.js'; const CommonBuildOptions = { @@ -13,39 +12,6 @@ const CommonBuildOptions = { webhookBundlePath: '', // unused in base }; -export class VercelBuilder extends VercelBuildOutputAPIBuilder { - constructor(config: Partial) { - super({ - ...CommonBuildOptions, - ...config, - workingDir: config.workingDir || process.cwd(), - }); - } - override async build(): Promise { - const configPath = join( - this.config.workingDir, - '.vercel/output/config.json' - ); - - let existingConfig: { version?: number; routes?: any[] } | null = null; - try { - const existingConfigContent = await readFile(configPath, 'utf-8'); - existingConfig = JSON.parse(existingConfigContent); - } catch {} - - await super.build(); - - if (existingConfig?.routes) { - const workflowConfig = JSON.parse(await readFile(configPath, 'utf-8')); - const mergedConfig = { - ...workflowConfig, - routes: [...workflowConfig.routes, ...existingConfig.routes], - }; - await writeFile(configPath, JSON.stringify(mergedConfig, null, 2)); - } - } -} - export class LocalBuilder extends BaseBuilder { constructor(config: Partial) { super({ From 65c9cb54f709a023aa8bc4b36a07db0aa5984e28 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:30:02 -0700 Subject: [PATCH 41/63] chore: update comments in sveltekit workflow package --- packages/sveltekit/src/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index daadb11eb..2e82b44bd 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -11,7 +11,7 @@ await localBuilder.build(); process.on('beforeExit', () => { console.log('BEFORE EXIT'); - // don't attempt patching functions output if not Vercel adapter + // Don't patch functions output if not in Vercel adapter if (!process.env.VERCEL_DEPLOYMENT_ID) { return; } @@ -47,7 +47,7 @@ process.on('beforeExit', () => { }, }, ]) { - // we need to un-symlink these as they can't be shared due to different + // Un-symlink these as they can't be shared due to different // experimental triggers config const toCopy = fs.readdirSync(path.dirname(file)); fs.unlinkSync(path.dirname(file)); @@ -64,6 +64,7 @@ process.on('beforeExit', () => { ); } + // Update .vc-config.json with the new experimental triggers config const existingConfig = JSON.parse(fs.readFileSync(file, 'utf8')); fs.writeFileSync( file, @@ -72,8 +73,6 @@ process.on('beforeExit', () => { ...config, }) ); - - console.log('UPDATED FUNCTION CONFIG', file, fs.readFileSync(file, 'utf8')); } }); From 85b2e12b58f30b926a2b2d278d200e71be657dcb Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:30:47 -0700 Subject: [PATCH 42/63] chore: remove console comment --- packages/sveltekit/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 2e82b44bd..b76cc375b 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -10,7 +10,6 @@ const localBuilder = new LocalBuilder({}); await localBuilder.build(); process.on('beforeExit', () => { - console.log('BEFORE EXIT'); // Don't patch functions output if not in Vercel adapter if (!process.env.VERCEL_DEPLOYMENT_ID) { return; From ca5a5d26c2a2f4e8e14ac99cb09ad0b2e7513194 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:35:55 -0700 Subject: [PATCH 43/63] refactor: workflow svelte plugin --- packages/sveltekit/src/index.ts | 8 +------- workbench/sveltekit/vite.config.ts | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index b76cc375b..8deb98f04 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -75,10 +75,4 @@ process.on('beforeExit', () => { } }); -export function workflowPlugin() { - return { - name: 'workflow-sveltekit-plugin', - }; -} - -export { workflowRollupPlugin } from 'workflow/rollup-plugin'; +export { workflowRollupPlugin as workflowPlugin } from 'workflow/rollup-plugin'; diff --git a/workbench/sveltekit/vite.config.ts b/workbench/sveltekit/vite.config.ts index 462ea2b81..f6ed40ad9 100644 --- a/workbench/sveltekit/vite.config.ts +++ b/workbench/sveltekit/vite.config.ts @@ -2,13 +2,7 @@ import { sveltekit } from '@sveltejs/kit/vite'; import { workflowPlugin } from '@workflow/sveltekit'; import { defineConfig } from 'vite'; import devtoolsJson from 'vite-plugin-devtools-json'; -import { workflowRollupPlugin } from 'workflow/rollup-plugin'; export default defineConfig({ - plugins: [ - workflowPlugin(), - workflowRollupPlugin(), - devtoolsJson(), - sveltekit(), - ], + plugins: [workflowPlugin(), devtoolsJson(), sveltekit()], }); From e54ec440a9da9a8c1ed67ecc89000c7ac259f9a3 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:36:38 -0700 Subject: [PATCH 44/63] refactor: simplify local builder config --- packages/sveltekit/src/builders.ts | 4 ++-- packages/sveltekit/src/index.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 9f3eae9bc..7b0875d79 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -13,11 +13,11 @@ const CommonBuildOptions = { }; export class LocalBuilder extends BaseBuilder { - constructor(config: Partial) { + constructor(config?: Partial) { super({ ...CommonBuildOptions, ...config, - workingDir: config.workingDir || process.cwd(), + workingDir: config?.workingDir || process.cwd(), }); } diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 8deb98f04..a1a3c07b5 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -2,7 +2,7 @@ import path from 'node:path'; import fs from 'fs-extra'; import { LocalBuilder } from './builders.js'; -const localBuilder = new LocalBuilder({}); +const localBuilder = new LocalBuilder(); // This needs to be in the top-level as we need to create these // entries before svelte plugin is started or the entries are From a75e2989e65b2b7db3f8018b9e258f849c2593b3 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 18:38:04 -0700 Subject: [PATCH 45/63] chore: remove unused deps --- packages/sveltekit/package.json | 4 ---- pnpm-lock.yaml | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 2b62773b5..a15e805a3 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -26,11 +26,7 @@ }, "dependencies": { "@sveltejs/kit": "^2.48.2", - "@swc/core": "1.11.24", "@workflow/cli": "workspace:*", - "@workflow/core": "workspace:*", - "@workflow/swc-plugin": "workspace:*", - "exsolve": "^1.0.7", "fs-extra": "^11.3.2", "workflow": "workspace:*" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05b7d0fba..810a6dbcb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -513,21 +513,9 @@ importers: '@sveltejs/kit': specifier: ^2.48.2 version: 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) - '@swc/core': - specifier: 1.11.24 - version: 1.11.24 '@workflow/cli': specifier: workspace:* version: link:../cli - '@workflow/core': - specifier: workspace:* - version: link:../core - '@workflow/swc-plugin': - specifier: workspace:* - version: link:../swc-plugin-workflow - exsolve: - specifier: ^1.0.7 - version: 1.0.7 fs-extra: specifier: ^11.3.2 version: 11.3.2 From 4b808af0a78bd004c30eddabe825684a6b93575d Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 19:02:31 -0700 Subject: [PATCH 46/63] chore: add comment for workbench svelte app --- workbench/sveltekit/svelte.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index 2c488d929..088e919d0 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -2,6 +2,7 @@ import node from '@sveltejs/adapter-node'; import vercel from '@sveltejs/adapter-vercel'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +// Node adapter needed for ci tests const adapter = process.env.VERCEL_DEPLOYMENT_ID ? vercel() : node(); /** @type {import('@sveltejs/kit').Config} */ From 5c23668c9fb1d113eebc538e03fa65f6db0e445b Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 19:06:20 -0700 Subject: [PATCH 47/63] chore: add sveltekit export to workflow --- packages/workflow/package.json | 4 +++- packages/workflow/src/sveltekit.ts | 0 pnpm-lock.yaml | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 packages/workflow/src/sveltekit.ts diff --git a/packages/workflow/package.json b/packages/workflow/package.json index de26b0124..8d6a49f3e 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -34,6 +34,7 @@ "./internal/private": "./dist/internal/private.js", "./next": "./dist/next.js", "./nitro": "./dist/nitro.js", + "./sveltekit": "./dist/sveltekit.js", "./rollup-plugin": "./dist/rollup-plugin.js", "./runtime": "./dist/runtime.js" }, @@ -51,7 +52,8 @@ "@workflow/typescript-plugin": "workspace:*", "ms": "2.1.3", "@workflow/next": "workspace:*", - "@workflow/nitro": "workspace:*" + "@workflow/nitro": "workspace:*", + "@workflow/sveltekit": "workspace:*" }, "devDependencies": { "@types/ms": "^2.1.0", diff --git a/packages/workflow/src/sveltekit.ts b/packages/workflow/src/sveltekit.ts new file mode 100644 index 000000000..e69de29bb diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 810a6dbcb..8ada3fee0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -732,6 +732,9 @@ importers: '@workflow/nitro': specifier: workspace:* version: link:../nitro + '@workflow/sveltekit': + specifier: workspace:* + version: link:../sveltekit '@workflow/typescript-plugin': specifier: workspace:* version: link:../typescript-plugin From fe82169adbd30f44671905b7ad5695f7f43f37fc Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 19:11:47 -0700 Subject: [PATCH 48/63] export sveltekit from workflow --- packages/sveltekit/package.json | 2 +- packages/sveltekit/src/index.ts | 2 +- packages/workflow/src/sveltekit.ts | 1 + workbench/sveltekit/package.json | 1 - workbench/sveltekit/vite.config.ts | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index a15e805a3..474770527 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -28,7 +28,7 @@ "@sveltejs/kit": "^2.48.2", "@workflow/cli": "workspace:*", "fs-extra": "^11.3.2", - "workflow": "workspace:*" + "@workflow/nitro": "workspace:*" }, "devDependencies": { "@types/fs-extra": "^11.0.4", diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index a1a3c07b5..595cd5f03 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -75,4 +75,4 @@ process.on('beforeExit', () => { } }); -export { workflowRollupPlugin as workflowPlugin } from 'workflow/rollup-plugin'; +export { workflowRollupPlugin as workflowPlugin } from '@workflow/nitro/rollup-plugin'; diff --git a/packages/workflow/src/sveltekit.ts b/packages/workflow/src/sveltekit.ts index e69de29bb..7de66f9c0 100644 --- a/packages/workflow/src/sveltekit.ts +++ b/packages/workflow/src/sveltekit.ts @@ -0,0 +1 @@ +export * from '@workflow/sveltekit'; diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index 7ed399e09..aa6a928ba 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -15,7 +15,6 @@ "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", "@types/lodash.chunk": "^4.2.9", - "@workflow/sveltekit": "workspace:*", "svelte": "^5.39.5", "svelte-check": "^4.3.2", "typescript": "^5.9.2", diff --git a/workbench/sveltekit/vite.config.ts b/workbench/sveltekit/vite.config.ts index f6ed40ad9..aede7b139 100644 --- a/workbench/sveltekit/vite.config.ts +++ b/workbench/sveltekit/vite.config.ts @@ -1,7 +1,7 @@ import { sveltekit } from '@sveltejs/kit/vite'; -import { workflowPlugin } from '@workflow/sveltekit'; import { defineConfig } from 'vite'; import devtoolsJson from 'vite-plugin-devtools-json'; +import { workflowPlugin } from 'workflow/sveltekit'; export default defineConfig({ plugins: [workflowPlugin(), devtoolsJson(), sveltekit()], From 0c9471f2d16c4733d10716c98e1ac69ec81e3df3 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 19:11:55 -0700 Subject: [PATCH 49/63] lockfile --- pnpm-lock.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ada3fee0..4558871bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -516,12 +516,12 @@ importers: '@workflow/cli': specifier: workspace:* version: link:../cli + '@workflow/nitro': + specifier: workspace:* + version: link:../nitro fs-extra: specifier: ^11.3.2 version: 11.3.2 - workflow: - specifier: workspace:* - version: link:../workflow devDependencies: '@types/fs-extra': specifier: ^11.0.4 @@ -1254,9 +1254,6 @@ importers: '@types/lodash.chunk': specifier: ^4.2.9 version: 4.2.9 - '@workflow/sveltekit': - specifier: workspace:* - version: link:../../packages/sveltekit svelte: specifier: ^5.39.5 version: 5.43.0 From ae6c230c82ff00139e07da1dbebbe97f76004d16 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 19:12:37 -0700 Subject: [PATCH 50/63] chore: remove unused deps svelte workbench --- pnpm-lock.yaml | 12 ------------ workbench/sveltekit/package.json | 1 - 2 files changed, 13 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4558871bd..41ff4110d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1217,9 +1217,6 @@ importers: '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 - '@sveltejs/adapter-auto': - specifier: ^7.0.0 - version: 7.0.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) '@sveltejs/adapter-node': specifier: ^5.4.0 version: 5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0))) @@ -4369,11 +4366,6 @@ packages: peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-auto@7.0.0': - resolution: {integrity: sha512-ImDWaErTOCkRS4Gt+5gZuymKFBobnhChXUZ9lhUZLahUgvA4OOvRzi3sahzYgbxGj5nkA6OV0GAW378+dl/gyw==} - peerDependencies: - '@sveltejs/kit': ^2.0.0 - '@sveltejs/adapter-node@5.4.0': resolution: {integrity: sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==} peerDependencies: @@ -13581,10 +13573,6 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/adapter-auto@7.0.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': - dependencies: - '@sveltejs/kit': 2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)) - '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.48.2(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))(svelte@5.43.0)(vite@7.1.11(@types/node@24.6.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.0)))': dependencies: '@rollup/plugin-commonjs': 28.0.8(rollup@4.52.5) diff --git a/workbench/sveltekit/package.json b/workbench/sveltekit/package.json index aa6a928ba..a901376ec 100644 --- a/workbench/sveltekit/package.json +++ b/workbench/sveltekit/package.json @@ -25,7 +25,6 @@ "@ai-sdk/react": "2.0.76", "@node-rs/xxhash": "1.7.6", "@opentelemetry/api": "^1.9.0", - "@sveltejs/adapter-auto": "^7.0.0", "@sveltejs/adapter-node": "^5.4.0", "@sveltejs/adapter-vercel": "^6.1.1", "@vercel/otel": "^1.13.0", From 38a2b7c5f52575a8fdb45677df4c715011e9a747 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 20:12:29 -0700 Subject: [PATCH 51/63] update styling --- docs/app/(home)/components/frameworks.tsx | 20 ++++++++++---------- docs/app/docs/[[...slug]]/page.tsx | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/app/(home)/components/frameworks.tsx b/docs/app/(home)/components/frameworks.tsx index f5bbbeb40..19e7b68b6 100644 --- a/docs/app/(home)/components/frameworks.tsx +++ b/docs/app/(home)/components/frameworks.tsx @@ -485,11 +485,18 @@ export const Frameworks = () => { - - + + + - + + + + + + +
@@ -508,13 +515,6 @@ export const Frameworks = () => {
-
handleRequest('SvelteKit')} - > - - -
handleRequest('Nuxt')} diff --git a/docs/app/docs/[[...slug]]/page.tsx b/docs/app/docs/[[...slug]]/page.tsx index e1426eefd..93d9fa412 100644 --- a/docs/app/docs/[[...slug]]/page.tsx +++ b/docs/app/docs/[[...slug]]/page.tsx @@ -34,7 +34,7 @@ function Card({ title, href, className, children, disabled }: CardProps) { From c49cac1bd2cc8a830d486affe6d3899aa5b9626b Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 20:12:36 -0700 Subject: [PATCH 52/63] add sveltekit getting started docs --- docs/content/docs/getting-started/index.mdx | 3 +- .../docs/getting-started/sveltekit.mdx | 258 ++++++++++++++++++ 2 files changed, 259 insertions(+), 2 deletions(-) create mode 100644 docs/content/docs/getting-started/sveltekit.mdx diff --git a/docs/content/docs/getting-started/index.mdx b/docs/content/docs/getting-started/index.mdx index 773827587..44822bc01 100644 --- a/docs/content/docs/getting-started/index.mdx +++ b/docs/content/docs/getting-started/index.mdx @@ -25,10 +25,9 @@ Start by choosing your framework. Each guide will walk you through the steps to Nitro - + SvelteKit - Coming soon diff --git a/docs/content/docs/getting-started/sveltekit.mdx b/docs/content/docs/getting-started/sveltekit.mdx new file mode 100644 index 000000000..58afef803 --- /dev/null +++ b/docs/content/docs/getting-started/sveltekit.mdx @@ -0,0 +1,258 @@ +--- +title: SvelteKit +--- + +# SvelteKit + +This guide will walk through setting up your first workflow in a SvelteKit app. Along the way, you'll learn more about the concepts that are fundamental to using the development kit in your own projects. + +--- + + + + +## Create Your SvelteKit Project + +Start by creating a new Next.js project. This command will create a new directory named `my-workflow-app` and setup a Next.js project inside it. + +```bash +npx sv create my-workflow-app --template=minimal --types=ts --no-add-ons +``` + +Enter the newly made directory: + +```bash +cd my-workflow-app +``` + +### Install `workflow` + + + + + npm i workflow + + + + + pnpm i workflow + + + + + yarn add workflow + + + + +### Configure Vite + +Add `workflowPlugin()` to your Vite confnig. This enables usage of the `"use workflow"` and `"use step"` directives. + +```typescript title="vite.config.ts" lineNumbers +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; +import { workflowPlugin } from "workflow/sveltekit"; // [!code highlight] + +export default defineConfig({ + plugins: [sveltekit(), workflowPlugin()], // [!code highlight] +}); +``` + +### Update `package.json` + +Update your `package.json` to include port `3000` for the development server: + +```json title="package.json" lineNumbers +{ + // ... + "scripts": { + "dev": "vite dev --port 3000" + // ... + }, +} +``` + + + + + ### Setup IntelliSense for TypeScript (Optional) + + + +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] + } + ] + } +} +``` + + + + + + + + + +## Create Your First Workflow + +Create a new file for our first workflow: + +```typescript title="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="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. + + +We'll dive deeper into workflows, steps, and other ways to suspend or handle events in [Foundations](/docs/foundations). + + + + + + +## Create Your Route Handler + +To invoke your new workflow, we'll have to add your workflow to a `POST` API route handler, `src/routes/api/signup/+server.ts` with the following code: + +```typescript title="src/routes/api/+server.ts" +import { start } from "workflow/api"; +import { handleUserSignup } from "../../../../workflows/user-signup"; +import { json, type RequestHandler } from "@sveltejs/kit"; + +export const POST: RequestHandler = async ({ + request, +}: { + request: Request; +}) => { + const { email } = await request.json(); + + // Executes asynchronously and doesn't block your app + await start(handleUserSignup, [email]); + + return json({ message: "User signup workflow started" }); +}; + +``` + +This route handler creates a `POST` request endpoint at `/api/signup` that will trigger your workflow. + + +Workflows can be triggered from API routes or any server-side code. + + + + + + +## Run in development + +To start your development server, run the following command in your terminal in the SvelteKit 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":"hello@example.com"}' http://localhost:3000/api/signup +``` + +Check the Next.js 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 +``` + +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. + +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). From 53ef3f9eb963c094da079319264c1ba97fe17ac4 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 20:13:28 -0700 Subject: [PATCH 53/63] update sveltekit docs getting started --- docs/content/docs/getting-started/sveltekit.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/docs/getting-started/sveltekit.mdx b/docs/content/docs/getting-started/sveltekit.mdx index 58afef803..d11ecbba2 100644 --- a/docs/content/docs/getting-started/sveltekit.mdx +++ b/docs/content/docs/getting-started/sveltekit.mdx @@ -13,7 +13,7 @@ This guide will walk through setting up your first workflow in a SvelteKit app. ## Create Your SvelteKit Project -Start by creating a new Next.js project. This command will create a new directory named `my-workflow-app` and setup a Next.js project inside it. +Start by creating a new SvelteKit project. This command will create a new directory named `my-workflow-app` with a minimal setup and setup a SvelteKit project inside it. ```bash npx sv create my-workflow-app --template=minimal --types=ts --no-add-ons @@ -232,7 +232,7 @@ Once your development server is running, you can trigger your workflow by runnin curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup ``` -Check the Next.js development server logs to see your workflow execute as well as the steps that are being processed. +Check the SvelteKit 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. From 479ce93569dda6ec8c5e2e95f4c2ebb813df1163 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 20:22:47 -0700 Subject: [PATCH 54/63] changeset --- .changeset/purple-regions-vanish.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/purple-regions-vanish.md diff --git a/.changeset/purple-regions-vanish.md b/.changeset/purple-regions-vanish.md new file mode 100644 index 000000000..540aca355 --- /dev/null +++ b/.changeset/purple-regions-vanish.md @@ -0,0 +1,9 @@ +--- +"@workflow/world-local": patch +"@workflow/sveltekit": patch +"workflow": patch +"@workflow/core": patch +"@workflow/cli": patch +--- + +Add sveltekit workflow integration From 1729fe587e91b9e65d2c6e9d8c2bbb4048451875 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 30 Oct 2025 20:24:58 -0700 Subject: [PATCH 55/63] Apply suggestion from @vercel[bot] Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- turbo.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/turbo.json b/turbo.json index 6226d9ae2..3b5c81471 100644 --- a/turbo.json +++ b/turbo.json @@ -11,9 +11,11 @@ "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "typecheck": { + "dependsOn": ["^build"], "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "test": { + "dependsOn": ["^build"], "outputs": ["dist/**", "build", ".svelte-kit", ".vercel/output"] }, "clean": { From 2e8c7f551ad68662cf8e3608bb07c8852d74eef9 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Thu, 30 Oct 2025 20:41:27 -0700 Subject: [PATCH 56/63] use proper env var --- packages/sveltekit/src/builders.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sveltekit/src/builders.ts b/packages/sveltekit/src/builders.ts index 7b0875d79..bea422bbe 100644 --- a/packages/sveltekit/src/builders.ts +++ b/packages/sveltekit/src/builders.ts @@ -30,7 +30,7 @@ export class LocalBuilder extends BaseBuilder { await mkdir(workflowGeneratedDir, { recursive: true }); // Add .gitignore to exclude generated files from version control - if (process.env.VERCEL !== '1') { + if (process.env.VERCEL_DEPLOYMENT_ID === undefined) { await writeFile(join(workflowGeneratedDir, '.gitignore'), '*'); } From 604db6948a02b26542be917609f56510cdfa611e Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 30 Oct 2025 20:42:00 -0700 Subject: [PATCH 57/63] Update packages/sveltekit/src/index.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/sveltekit/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sveltekit/src/index.ts b/packages/sveltekit/src/index.ts index 595cd5f03..df9b09ba7 100644 --- a/packages/sveltekit/src/index.ts +++ b/packages/sveltekit/src/index.ts @@ -49,7 +49,7 @@ process.on('beforeExit', () => { // Un-symlink these as they can't be shared due to different // experimental triggers config const toCopy = fs.readdirSync(path.dirname(file)); - fs.unlinkSync(path.dirname(file)); + fs.removeSync(path.dirname(file)); fs.mkdirSync(path.dirname(file), { recursive: true }); for (const item of toCopy) { From c073b97d700d5137e1b39414403badd7dde8554d Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 30 Oct 2025 20:59:26 -0700 Subject: [PATCH 58/63] Update docs/content/docs/getting-started/sveltekit.mdx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/content/docs/getting-started/sveltekit.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/getting-started/sveltekit.mdx b/docs/content/docs/getting-started/sveltekit.mdx index d11ecbba2..d64f9ae25 100644 --- a/docs/content/docs/getting-started/sveltekit.mdx +++ b/docs/content/docs/getting-started/sveltekit.mdx @@ -47,7 +47,7 @@ cd my-workflow-app ### Configure Vite -Add `workflowPlugin()` to your Vite confnig. This enables usage of the `"use workflow"` and `"use step"` directives. +Add `workflowPlugin()` to your Vite config. This enables usage of the `"use workflow"` and `"use step"` directives. ```typescript title="vite.config.ts" lineNumbers import { sveltekit } from "@sveltejs/kit/vite"; From 6fff1b721178ec0c11154c10e12496a298c696c1 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 21:08:24 -0700 Subject: [PATCH 59/63] Document CSRF protection bypass in SvelteKit workbench config (#157) * Initial plan * docs: add CSRF security warning to svelte.config.js Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com> --- workbench/sveltekit/svelte.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/workbench/sveltekit/svelte.config.js b/workbench/sveltekit/svelte.config.js index 088e919d0..5d665261c 100644 --- a/workbench/sveltekit/svelte.config.js +++ b/workbench/sveltekit/svelte.config.js @@ -12,6 +12,10 @@ const config = { preprocess: vitePreprocess(), kit: { adapter: adapter, + // WARNING: CSRF protection is disabled for testing/development purposes. + // This configuration trusts all origins and should NOT be used in production. + // In production, specify only trusted origins or remove this configuration + // to use SvelteKit's default CSRF protection. csrf: { trustedOrigins: ['*'] }, }, }; From c8943848e04baa676d7c9582a4889095721115c0 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 21:08:36 -0700 Subject: [PATCH 60/63] refactor: deduplicate SvelteKit request conversion logic (#156) * Initial plan * refactor: extract duplicated SvelteKit request conversion to helper Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: adriandlam <93681064+adriandlam@users.noreply.github.com> --- packages/cli/src/lib/builders/base-builder.ts | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/cli/src/lib/builders/base-builder.ts b/packages/cli/src/lib/builders/base-builder.ts index f12298ea5..422ecdff7 100644 --- a/packages/cli/src/lib/builders/base-builder.ts +++ b/packages/cli/src/lib/builders/base-builder.ts @@ -18,6 +18,20 @@ const enhancedResolve = promisify(enhancedResolveOriginal); const EMIT_SOURCEMAPS_FOR_DEBUGGING = process.env.WORKFLOW_EMIT_SOURCEMAPS_FOR_DEBUGGING === '1'; +// Helper function code for converting SvelteKit requests to standard Request objects +const SVELTEKIT_REQUEST_CONVERTER = ` +async function convertSvelteKitRequest(request) { + const options = { + method: request.method, + headers: new Headers(request.headers) + }; + if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { + options.body = await request.arrayBuffer(); + } + return new Request(request.url, options); +} +`; + export abstract class BaseBuilder { protected config: WorkflowConfig; @@ -264,15 +278,9 @@ export abstract class BaseBuilder { entryContent += ` // API entrypoint import { stepEntrypoint } from 'workflow/runtime'; + ${SVELTEKIT_REQUEST_CONVERTER} export const POST = async ({request}) => { - const body = await request.arrayBuffer() - const normalRequest = new Request(request.url, { - method: request.method, - headers: new Headers(request.headers), - ...(['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) ? {} : { - body - } - }) + const normalRequest = await convertSvelteKitRequest(request); return stepEntrypoint(normalRequest); } `; @@ -484,15 +492,9 @@ const workflowCode = \`${workflowBundleCode.replace(/[\\`$]/g, '\\$&')}\`; `; if (this.config.buildTarget === 'sveltekit') { workflowFunctionCode += ` +${SVELTEKIT_REQUEST_CONVERTER} export const POST = async ({ request }) => { - const body = await request.arrayBuffer() - const normalRequest = new Request(request.url, { - method: request.method, - headers: new Headers(request.headers), - ...(['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) ? {} : { - body - } - }) + const normalRequest = await convertSvelteKitRequest(request); return workflowEntrypoint(workflowCode)(normalRequest); }`; } else { @@ -644,15 +646,9 @@ async function handler(request) { }`; if (this.config.buildTarget === 'sveltekit') { routeContent += ` +${SVELTEKIT_REQUEST_CONVERTER} const createSvelteKitHandler = (method) => async ({ request }) => { - const options = { - method: request.method, - headers: new Headers(request.headers) - }; - if (!['GET', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'].includes(request.method)) { - options.body = await request.arrayBuffer(); - } - const normalRequest = new Request(request.url, options); + const normalRequest = await convertSvelteKitRequest(request); return handler(normalRequest); }; From 1e0297de365dbb9c0c4628283541147fe795b48b Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 30 Oct 2025 21:17:53 -0700 Subject: [PATCH 61/63] Update packages/core/e2e/local-build.test.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- packages/core/e2e/local-build.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/e2e/local-build.test.ts b/packages/core/e2e/local-build.test.ts index 282a5d483..237d6628c 100644 --- a/packages/core/e2e/local-build.test.ts +++ b/packages/core/e2e/local-build.test.ts @@ -18,8 +18,6 @@ describe.each(['nextjs-webpack', 'nextjs-turbopack', 'nitro', 'sveltekit'])( cwd: getWorkbenchAppPath(project), }); - console.error(result.stderr.toString(), result.stdout.toString()); - expect(result.stderr).not.toContain('Error:'); }); } From 0ce501bef36f02938e8864c1987dda4d5b9778b3 Mon Sep 17 00:00:00 2001 From: Adrian Lam Date: Mon, 3 Nov 2025 10:22:40 -0800 Subject: [PATCH 62/63] docs: fix getting staretd sveltekit missing folder --- docs/content/docs/getting-started/sveltekit.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/getting-started/sveltekit.mdx b/docs/content/docs/getting-started/sveltekit.mdx index d64f9ae25..1c15df29d 100644 --- a/docs/content/docs/getting-started/sveltekit.mdx +++ b/docs/content/docs/getting-started/sveltekit.mdx @@ -188,7 +188,7 @@ We'll dive deeper into workflows, steps, and other ways to suspend or handle eve To invoke your new workflow, we'll have to add your workflow to a `POST` API route handler, `src/routes/api/signup/+server.ts` with the following code: -```typescript title="src/routes/api/+server.ts" +```typescript title="src/routes/api/signup/+server.ts" import { start } from "workflow/api"; import { handleUserSignup } from "../../../../workflows/user-signup"; import { json, type RequestHandler } from "@sveltejs/kit"; From 335e00958ea8d77311164ecee9efd753c8ec844e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Nov 2025 19:46:51 +0000 Subject: [PATCH 63/63] Initial plan