Skip to content

Commit

Permalink
Run Middleware within WorkStore (#70808)
Browse files Browse the repository at this point in the history
The data structure inside WorkStore (formerly StaticGenerationStore) is
a mess with a bunch of options (what hidden class?). It's also there to
support Route Handlers, App Router Pages and Actions. It should probably
be a more specific disjoint union for each use case rather than just
optional fields.

We could have a separate kind of store for Middleware but it seems like
we're going towards Middleware becoming something with same semantics as
an App Route Handler. For example, we already support `cookies()`,
`headers()`, `after()`, `revalidate` etc. That's why it already has a
RequestStore.

This becomes a requirement for [moving `AfterContext` context to
`WorkStore`](#70806).
  • Loading branch information
sebmarkbage authored Oct 4, 2024
1 parent 9813061 commit 2f8319b
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions packages/next/src/server/web/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import {
type WrapperRenderOpts,
} from '../async-storage/with-request-store'
import { requestAsyncStorage } from '../../client/components/request-async-storage.external'
import { withWorkStore } from '../async-storage/with-work-store'
import { workAsyncStorage } from '../../client/components/work-async-storage.external'
import { NEXT_ROUTER_PREFETCH_HEADER } from '../../client/components/app-router-headers'
import { getTracer } from '../lib/trace/tracer'
import type { TextMapGetter } from 'next/dist/compiled/@opentelemetry/api'
import { MiddlewareSpan } from '../lib/trace/constants'
Expand Down Expand Up @@ -234,27 +237,48 @@ export async function adapter(
try {
const previewProps = getEdgePreviewProps()

return await withRequestStore(
requestAsyncStorage,
return await withWorkStore(
workAsyncStorage,
{
req: request,
res: undefined,
url: request.nextUrl,
page: '/', // Fake Work
fallbackRouteParams: null,
renderOpts: {
onUpdateCookies: (cookies) => {
cookiesFromResponse = cookies
},
previewProps,
waitUntil,
onClose: closeController
? closeController.onClose.bind(closeController)
: undefined,
experimental: {
after: isAfterEnabled,
isRoutePPREnabled: false,
dynamicIO: false,
},
buildId: buildId ?? '',
supportsDynamicResponse: true,
},
requestEndedState: { ended: false },
isPrefetchRequest: request.headers.has(
NEXT_ROUTER_PREFETCH_HEADER
),
},
() => params.handler(request, event)
() =>
withRequestStore(
requestAsyncStorage,
{
req: request,
res: undefined,
url: request.nextUrl,
renderOpts: {
onUpdateCookies: (cookies) => {
cookiesFromResponse = cookies
},
previewProps,
waitUntil,
onClose: closeController
? closeController.onClose.bind(closeController)
: undefined,
experimental: {
after: isAfterEnabled,
},
},
},
() => params.handler(request, event)
)
)
} finally {
// middleware cannot stream, so we can consider the response closed
Expand Down

0 comments on commit 2f8319b

Please sign in to comment.