feat: make vinext fully compatible with clerk middleware#126
Open
nbardy wants to merge 1 commit intocloudflare:mainfrom
Open
feat: make vinext fully compatible with clerk middleware#126nbardy wants to merge 1 commit intocloudflare:mainfrom
nbardy wants to merge 1 commit intocloudflare:mainfrom
Conversation
04daac0 to
7f5034d
Compare
…es to Cloudflare Worker ctx - Instantiates `NextFetchEvent` with `waitUntil` shim and passes to `middlewareFn` - Extracts `_waitUntilPromises` from the middleware result and attaches them to the `Response` object via `__vinextWaitUntil` - Updates the generated Cloudflare Worker `fetch` signature to include `ctx: ExecutionContext` - Iterates over `__vinextWaitUntil` on the final response and delegates to Cloudflare's native `ctx.waitUntil(promise)` - Enables background tasks (like telemetry and session sync in `@clerk/nextjs`) to survive the worker response lifecycle - Updates `vinext check` to explicitly report `@clerk/nextjs` as supported - Adds `app-router.test.ts` assertion to verify `waitUntil` injection
7f5034d to
0cbbe57
Compare
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR makes
vinextfully compatible with@clerk/nextjsby implementing theNextFetchEvent.waitUntilbackground task API across the middleware and Worker layers.What changed
NextFetchEventto middleware: Construct the event with awaitUntilarray and pass it as the second argument tomiddlewareFn. This is the standard Next.js middleware signature — Clerk usesevent.waitUntil()to schedule session sync and telemetry as background tasks.waitUntilPromisesfrom the middleware result and attach them to theResponseobject via a non-enumerable__vinextWaitUntilproperty so they survive the routing pipeline.ctx: ExecutionContextto the generated Workerfetchsignature, collect promises from bothrunMiddlewareand__vinextWaitUntil, and delegate to Cloudflare's nativectx.waitUntil(). This ensures background work survives the serverless response lifecycle.vinext checknow reports@clerk/nextjsas supported.app-router.test.tscoverage verifyingevent.waitUntilis injected correctly.Architectural note: from workaround to native API support
The original framing of this work was "making Clerk not crash." The paired Clerk PR changes that picture: once Clerk's ESM imports are fixed,
@clerk/nextjsloads cleanly in Vite/Workers. What vinext needs to do is provide the correct API surface — specifically, a realNextFetchEventwith a functioningwaitUntil(). This is not a shim to paper over bugs; it is the standard Next.js middleware contract that Clerk (and any other middleware library) legitimately depends on.Architectural Decision: The 'Bubble Up' Pattern
Background promises need to travel from the middleware layer up to the Cloudflare Worker's
ctx.waitUntil(). This PR uses a hidden property (Object.defineProperty(response, '__vinextWaitUntil', ...)).Alternatives considered:
ReadableStreamis returned; the ALS scope can tear down before background tasks are safely handed off to Cloudflare.{ response, tasks }): Changes the core router return type fromResponseto a tuple — massive blast radius across every caching, proxy, and error boundary layer.WeakMapkeyed toRequest: Fragile because the framework frequently clones requests when manipulating headers and URLs, which drops the reference.Attaching promises directly to the
Responseas a non-enumerable property lets them travel safely up the execution chain, survive streaming, and require zero signature changes across the broader codebase.Clerk API contact points
NextFetchEvent+event.waitUntil()NextResponse.next({ request: { headers } })/x-middleware-request-*req.cookies/res.cookies.set()req.nextUrl/NextURLNextResponse.redirect()early return@clerk/nextjspackage