Skip to content

DX-2705: feat: eager-start QStash dev server on serve() across all adapters#203

Draft
ytkimirti wants to merge 2 commits into
mainfrom
DX-2705-auto-dev-eager-start-on-serve
Draft

DX-2705: feat: eager-start QStash dev server on serve() across all adapters#203
ytkimirti wants to merge 2 commits into
mainfrom
DX-2705-auto-dev-eager-start-on-serve

Conversation

@ytkimirti

Copy link
Copy Markdown
Contributor

Summary

Eager-starts the QStash dev server whenever serve() is called, so local dev "just works" without manually running the dev binary.

  • Call void startDevServer() in all 10 platform adapters (astro, cloudflare, express, h3, hono, nextjs, react-router, solidjs, svelte, tanstack), plus nextjs servePagesRouter and express serveMany.
  • Derive devMode onto the serve-side Client in src/serve/multi-region/handlers.ts so the multi-region path respects dev mode.
  • Tests: new src/serve/dev-server-eager-start.test.ts; updates to multi-region.test.ts and dev-server-integration.test.ts (the integration test spawns the real dev binary).

Dependency

Pins @upstash/qstash to CI snapshot 0.0.0-ci.8c658c13532090cf00f778d2216eacbad68f85f9-20260618065901 (which exports startDevServer) for integration testing.

Depends on / pins the qstash-js CI snapshot from upstash/qstash-js#269. To be repinned to a stable @upstash/qstash release before merge.

Local verification

  • tsc --noEmit clean
  • eslint clean
  • bun run build succeeds
  • changed/new tests: 62 pass, 0 fail

- call startDevServer() in all 10 platform adapters
- also in nextjs servePagesRouter and express serveMany
- derive devMode onto the serve-side Client in multi-region handlers
- add dev-server-eager-start unit tests; update multi-region + integration tests
- pin @upstash/qstash to CI snapshot for integration testing
@linear-code

linear-code Bot commented Jun 18, 2026

Copy link
Copy Markdown

DX-2705

@ytkimirti

Copy link
Copy Markdown
Contributor Author

CI note: the only failing job is Sveltekit Local Build. It fails at the SvelteKit prerender/analyse step with:

SyntaxError: The requested module '@upstash/qstash' does not provide an export named 'startDevServer'

Root cause: examples/sveltekit/package.json pins @upstash/qstash: "latest", so that example installs the stable published qstash (which does not yet export startDevServer), while the built @upstash/workflow (from dist) now imports it. SvelteKit's analyse step eagerly loads the module, so the missing named export crashes the build. Other example builds pass because they don't eagerly resolve named exports at build time.

This is a transitional failure tied to the qstash-js release: it will clear once the qstash change (upstash/qstash-js#269) ships as a stable release that latest picks up. The core gating job (Upstash Workflow Tests) passes: 401 pass / 0 fail across 19 files, including the new eager-start + dev-mode tests, run against the pinned qstash CI snapshot. The release/deploy jobs were skipped only because they depend on the sveltekit build.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes local development “just work” by eagerly starting the QStash dev server whenever a workflow route is defined via serve() (and the relevant serveMany()/pages-router variants), and ensures multi-region handler construction respects dev mode derived from adapter-provided environment bindings (e.g. Cloudflare env).

Changes:

  • Eager-start the QStash dev server by calling startDevServer() at serve() factory-call time across adapters and the framework-agnostic src/serve entry.
  • Propagate devMode (derived from the adapter-provided environment) into the multi-region Client construction so client behavior matches receiver behavior.
  • Add/adjust tests to pin the eager-start behavior and validate multi-region dev mode + integration reachability.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/serve/index.ts Calls startDevServer() when serve() is invoked.
platforms/astro.ts Eager-start dev server when Astro serve() defines a route.
platforms/cloudflare.ts Eager-start dev server when Cloudflare serve() defines a route.
platforms/express.ts Eager-start dev server in Express serve() and serveMany().
platforms/h3.ts Eager-start dev server when H3 serve() defines a route.
platforms/hono.ts Eager-start dev server when Hono serve() defines a route.
platforms/nextjs.ts Eager-start dev server in Next.js app + pages-router serve*() variants.
platforms/react-router.ts Eager-start dev server when React Router serve() defines a route.
platforms/solidjs.ts Eager-start dev server when SolidJS serve() defines a route.
platforms/svelte.ts Eager-start dev server when SvelteKit serve() defines a route.
platforms/tanstack.ts Eager-start dev server when TanStack serve() defines a route.
src/serve/dev-server-eager-start.test.ts New unit test that mocks startDevServer and asserts eager-start across factories.
src/serve/multi-region/handlers.ts Mirrors receiver dev-mode decision onto the constructed QStash Client in multi/single-region paths.
src/serve/multi-region/multi-region.test.ts Adds unit tests that assert serve-side client dev mode is derived from environment bindings.
src/serve/multi-region/dev-server-integration.test.ts Adds an integration assertion that the dev server is reachable immediately after serve() (before any inbound request).
package.json Pins @upstash/qstash to a CI snapshot to access startDevServer.
bun.lock Updates lockfile to match the pinned @upstash/qstash snapshot.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 65 to +69
const client = new Client({
...clientOptions,
baseUrl: clientEnv.QSTASH_URL!,
token: clientEnv.QSTASH_TOKEN!,
// Mirror the receiver's dev-mode decision so a single QSTASH_DEV=true points
Comment thread src/serve/index.ts
routeFunction: RouteFunction<TInitialPayload, TResult>,
options?: WorkflowServeOptions<TInitialPayload, TResult>
): ReturnType<typeof serveBase<TInitialPayload, TRequest, TResponse, TResult>> => {
void startDevServer();
Comment thread package.json
},
"dependencies": {
"@upstash/qstash": "^2.11.0"
"@upstash/qstash": "0.0.0-ci.8c658c13532090cf00f778d2216eacbad68f85f9-20260618065901"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants