@@ -14,7 +14,7 @@ export default function handleRequest(
1414 responseStatusCode : number ,
1515 responseHeaders : Headers ,
1616 routerContext : EntryContext ,
17- loadContext : AppLoadContext ,
17+ loadContext : AppLoadContext
1818 // If you have middleware enabled:
1919 // loadContext: unstable_RouterContextProvider
2020) {
@@ -29,24 +29,38 @@ export default function handleRequest(
2929 ? "onAllReady"
3030 : "onShellReady" ;
3131
32+ // Abort the rendering stream after the `streamTimeout` so it has time to
33+ // flush down the rejected boundaries
34+ let timeoutId : ReturnType < typeof setTimeout > | undefined = setTimeout (
35+ ( ) => abort ( ) ,
36+ streamTimeout + 1000
37+ ) ;
38+
3239 const { pipe, abort } = renderToPipeableStream (
3340 < ServerRouter context = { routerContext } url = { request . url } /> ,
3441 {
3542 [ readyOption ] ( ) {
3643 shellRendered = true ;
37- const body = new PassThrough ( ) ;
44+ const body = new PassThrough ( {
45+ final ( callback ) {
46+ // Clear the timeout to prevent retaining the closure and memory leak
47+ clearTimeout ( timeoutId ) ;
48+ timeoutId = undefined ;
49+ callback ( ) ;
50+ } ,
51+ } ) ;
3852 const stream = createReadableStreamFromReadable ( body ) ;
3953
4054 responseHeaders . set ( "Content-Type" , "text/html" ) ;
4155
56+ pipe ( body ) ;
57+
4258 resolve (
4359 new Response ( stream , {
4460 headers : responseHeaders ,
4561 status : responseStatusCode ,
46- } ) ,
62+ } )
4763 ) ;
48-
49- pipe ( body ) ;
5064 } ,
5165 onShellError ( error : unknown ) {
5266 reject ( error ) ;
@@ -60,11 +74,7 @@ export default function handleRequest(
6074 console . error ( error ) ;
6175 }
6276 } ,
63- } ,
77+ }
6478 ) ;
65-
66- // Abort the rendering stream after the `streamTimeout` so it has time to
67- // flush down the rejected boundaries
68- setTimeout ( abort , streamTimeout + 1000 ) ;
6979 } ) ;
7080}
0 commit comments