@@ -2,72 +2,83 @@ import { createServer } from "http";
22import { parse } from "url" ;
33import path from "path" ;
44import fs from "fs" ;
5- // DELETE: import { fileURLToPath } from "url";
6-
7- // DELETE these lines. They crash in CJS.
8- // const __filename = fileURLToPath(import.meta.url);
9- // const __dirname = path.dirname(__filename);
105
116// 1. SET ENV VARS
127// @ts -ignore
138process . env [ 'NODE_ENV' ] = "production" ;
149process . env [ 'NEXT_PRIVATE_MINIMAL_MODE' ] = "1" ;
1510
16- console . log ( "🚀 Starting Native Adapter..." ) ;
17-
1811async function start ( ) {
19- // CRITICAL FIX: Use the native __dirname directly.
20- // We use @ts -ignore because TypeScript might complain if it thinks this is ESM.
2112 // @ts -ignore
2213 const serverDir = __dirname ;
2314
24- try {
25- // 2. Load the Serialized Config relative to THIS script
26- const configPath = path . join ( serverDir , "firebase-next-config.json" ) ;
15+ // 2. IMPORT NEXT.JS INTERNALS (REQUIRED FOR PPR)
16+ // We need this symbol to attach the postponed state
17+ const nextMetaPath = require . resolve ( "next/dist/server/request-meta" , { paths : [ serverDir ] } ) ;
18+ const { NEXT_REQUEST_META } = require ( nextMetaPath ) ;
19+
20+ // 3. LOAD CONFIG
21+ const configPath = path . join ( serverDir , "firebase-next-config.json" ) ;
22+ const rawConfig = fs . readFileSync ( configPath , 'utf-8' ) ;
23+ const buildContext = JSON . parse ( rawConfig ) ;
24+
25+ // Helper to find the postponed state for a path
26+ const getPostponedState = ( path : string ) => {
27+ // 1. Try exact match
28+ let prerender = buildContext . outputs . prerenders . find ( ( it : any ) => it . pathname === path ) ;
2729
28- console . log ( `📥 Loading config from ${ configPath } ` ) ;
29- const rawConfig = fs . readFileSync ( configPath , 'utf-8' ) ;
30- const buildContext = JSON . parse ( rawConfig ) ;
30+ // 2. Try dynamic match
31+ if ( ! prerender ) {
32+ const dynamicMatch = buildContext . routes . dynamicRoutes . find ( ( it : any ) =>
33+ path . match ( new RegExp ( it . sourceRegex ) )
34+ ) ?. source ;
35+ prerender = buildContext . outputs . prerenders . find ( ( it : any ) => it . pathname === dynamicMatch ) ;
36+ }
3137
32- // 3. Resolve Next.js Server relative to THIS script
33- const nextPath = require . resolve ( "next/dist/server/next-server" , { paths : [ serverDir ] } ) ;
34- const NextServer = require ( nextPath ) . default ;
38+ return prerender ?. fallback ?. postponedState ;
39+ } ;
3540
36- // 4. Initialize Server with the loaded config
37- const server = new NextServer ( {
38- dir : serverDir ,
39- hostname : '0.0.0.0' ,
40- port : parseInt ( process . env . PORT || "8080" ) ,
41- conf : buildContext . config
42- } ) ;
41+ // 4. SETUP SERVER
42+ const nextPath = require . resolve ( "next/dist/server/next-server" , { paths : [ serverDir ] } ) ;
43+ const NextServer = require ( nextPath ) . default ;
44+
45+ const server = new NextServer ( {
46+ dir : serverDir ,
47+ hostname : '0.0.0.0' ,
48+ port : parseInt ( process . env . PORT || "8080" ) ,
49+ conf : buildContext . config ,
50+ } ) ;
4351
44- console . log ( "⏳ Preparing server..." ) ;
45- const requestHandler = server . getRequestHandler ( ) ;
46- await server . prepare ( ) ;
52+ await server . prepare ( ) ;
53+ const requestHandler = server . getRequestHandler ( ) ;
4754
48- // 5. Start HTTP Listener
49- createServer ( async ( req : any , res : any ) => {
50- try {
51- const parsedUrl = parse ( req . url , true ) ;
55+ createServer ( async ( req : any , res : any ) => {
56+ try {
57+ const parsedUrl = parse ( req . url , true ) ;
58+ const { pathname } = parsedUrl ;
5259
53- if ( ! req . headers [ 'x-matched-path' ] ) {
54- req . headers [ 'x-matched-path' ] = parsedUrl . pathname ;
60+ if ( req . headers [ 'next-resume' ] === '1' && pathname ) {
61+ const postponed = getPostponedState ( pathname ) ;
62+ if ( postponed ) {
63+ console . log ( `⚡️ Injecting Postponed State for ${ pathname } ` ) ;
64+
65+ req [ NEXT_REQUEST_META ] = {
66+ postponed : postponed
67+ } ;
5568 }
69+ }
5670
57- await requestHandler ( req , res , parsedUrl ) ;
58- } catch ( err ) {
59- console . error ( "Request Error:" , err ) ;
60- res . statusCode = 500 ;
61- res . end ( "Internal Error" ) ;
71+ if ( ! req . headers [ 'x-matched-path' ] ) {
72+ req . headers [ 'x-matched-path' ] = pathname ;
6273 }
63- } ) . listen ( parseInt ( process . env . PORT || "8080" ) , ( ) => {
64- console . log ( `> Ready on http://localhost:${ process . env . PORT || 8080 } ` ) ;
65- } ) ;
6674
67- } catch ( e ) {
68- console . error ( "❌ Critical Error:" , e ) ;
69- process . exit ( 1 ) ;
70- }
75+ await requestHandler ( req , res , parsedUrl ) ;
76+ } catch ( err ) {
77+ console . error ( err ) ;
78+ res . statusCode = 500 ;
79+ res . end ( "Internal Error" ) ;
80+ }
81+ } ) . listen ( parseInt ( process . env . PORT || "8080" ) ) ;
7182}
7283
7384start ( ) ;
0 commit comments