11import type { OutgoingHttpHeaders } from 'http'
22
33import { ComputeJsOutgoingMessage , toComputeResponse , toReqRes } from '@fastly/http-compute-js'
4- import { Context } from '@netlify/functions'
54import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
65import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js'
76
@@ -16,10 +15,12 @@ import { nextResponseProxy } from '../revalidate.js'
1615
1716import { createRequestContext , getLogger , getRequestContext } from './request-context.cjs'
1817import { getTracer } from './tracer.cjs'
19- import { setWaitUntil } from './wait-until.cjs'
18+ import { setupWaitUntil } from './wait-until.cjs'
2019
2120const nextImportPromise = import ( '../next.cjs' )
2221
22+ setupWaitUntil ( )
23+
2324let nextHandler : WorkerRequestHandler , nextConfig : NextConfigComplete
2425
2526/**
@@ -45,15 +46,9 @@ const disableFaultyTransferEncodingHandling = (res: ComputeJsOutgoingMessage) =>
4546 }
4647}
4748
48- // TODO: remove once https://github.com/netlify/serverless-functions-api/pull/219
49- // is released and public types are updated
50- interface FutureContext extends Context {
51- waitUntil ?: ( promise : Promise < unknown > ) => void
52- }
53-
54- export default async ( request : Request , context : FutureContext ) => {
49+ export default async ( request : Request ) => {
5550 const tracer = getTracer ( )
56- setWaitUntil ( context )
51+
5752 if ( ! nextHandler ) {
5853 await tracer . withActiveSpan ( 'initialize next server' , async ( ) => {
5954 // set the server config
@@ -129,19 +124,19 @@ export default async (request: Request, context: FutureContext) => {
129124 return new Response ( body || null , response )
130125 }
131126
132- if ( context . waitUntil ) {
133- context . waitUntil ( requestContext . backgroundWorkPromise )
134- }
135-
136127 const keepOpenUntilNextFullyRendered = new TransformStream ( {
137128 async flush ( ) {
138129 // it's important to keep the stream open until the next handler has finished
139130 await nextHandlerPromise
140- if ( ! context . waitUntil ) {
141- // if waitUntil is not available, we have to keep response stream open until background promises are resolved
142- // to ensure that all background work executes
143- await requestContext . backgroundWorkPromise
144- }
131+
132+ // Next.js relies on `close` event emitted by response to trigger running callback variant of `next/after`
133+ // however @fastly /http-compute-js never actually emits that event - so we have to emit it ourselves,
134+ // otherwise Next would never run the callback variant of `next/after`
135+ res . emit ( 'close' )
136+
137+ // if waitUntil is not available, we have to keep response stream open until background promises are resolved
138+ // to ensure that all background work executes
139+ await requestContext . backgroundWorkPromise
145140 } ,
146141 } )
147142
0 commit comments