11import  {  FileSystemRouter  }  from  "bun" ; 
22import  {  NJSON  }  from  "next-json" ; 
3- import  {  statSync  }  from  "node:fs" ; 
3+ import  {  readFileSync ,   statSync  }  from  "node:fs" ; 
44import  {  join ,  relative  }  from  "node:path" ; 
5- import  {  preloadModule  }  from  "react-dom" ; 
65import  {  renderToReadableStream  }  from  "react-dom/server" ; 
76import  {  ClientOnlyError  }  from  "./client" ; 
87import  {  MetaContext ,  PreloadModule  }  from  "./preload" ; 
98
109export  class  StaticRouters  { 
11-   readonly  server : FileSystemRouter ; 
12-   readonly  client : FileSystemRouter ; 
13-   readonly  #routes: Map < string ,  string > ; 
14-   readonly  #routes_dump: string ; 
15-   readonly  #dependencies: Record < string ,  string [ ] > ; 
16-   readonly  #hashed: Record < string ,  string > ; 
10+   server ! : FileSystemRouter ; 
11+   client ! : FileSystemRouter ; 
12+   #routes! : Map < string ,  string > ; 
13+   #routes_dump! : string ; 
14+   #dependencies! : Record < string ,  string [ ] > ; 
15+   #hashed! : Record < string ,  string > ; 
16+   #cached =  new  Set < string > ( ) ; 
1717
1818  constructor ( 
1919    public  baseDir : string , 
2020    public  buildDir  =  ".build" , 
2121    public  pageDir  =  "pages" 
2222  )  { 
23+     this . reload ( ) ; 
24+   } 
25+ 
26+   reload ( excludes : RegExp [ ]  =  [ ] )  { 
27+     const  {  baseDir,  pageDir,  buildDir }  =  this ; 
28+     const  metafile  =  Bun . fileURLToPath ( 
29+       import . meta. resolve ( join ( baseDir ,  buildDir ,  ".meta.json" ) ) 
30+     ) ; 
31+     delete  require . cache [ metafile ] ; 
32+     if  ( this . #cached. size )  { 
33+       for  ( const  cached  of  this . #cached)  { 
34+         delete  require . cache [ cached ] ; 
35+         for  ( const  dep  of  scanCacheDependencies ( cached ,  excludes ) )  { 
36+           delete  require . cache [ dep ] ; 
37+         } 
38+       } 
39+       this . #cached. clear ( ) ; 
40+     } 
2341    this . server  =  new  FileSystemRouter ( { 
2442      dir : join ( baseDir ,  pageDir ) , 
2543      style : "nextjs" , 
@@ -28,7 +46,7 @@ export class StaticRouters {
2846      dir : join ( baseDir ,  buildDir ,  pageDir ) , 
2947      style : "nextjs" , 
3048    } ) ; 
31-     const  parsed  =  require ( join ( baseDir ,   buildDir ,   ".meta.json" ) ) ; 
49+     const  parsed  =  require ( metafile ) ; 
3250    this . #hashed =  parsed . hashed ; 
3351    this . #dependencies =  parsed . dependencies ; 
3452    this . #routes =  new  Map ( 
@@ -83,7 +101,8 @@ export class StaticRouters {
83101        "No client-side script found for server-side component: "  + 
84102          serverSide . filePath 
85103      ) ; 
86-     const  module  =  await  import ( serverSide . filePath ) ; 
104+     const  module  =  require ( serverSide . filePath ) ; 
105+     this . #cached. add ( serverSide . filePath ) ; 
87106    const  result  =  await  module . getServerSideProps ?.( { 
88107      params : serverSide . params , 
89108      req : request , 
@@ -156,32 +175,36 @@ export class StaticRouters {
156175  } 
157176} 
158177
159- function  DirectPreloadModule ( { 
160-   target, 
161-   dependencies, 
162- } : { 
163-   target : string ; 
164-   dependencies : Record < string ,  string [ ] > ; 
165- } )  { 
166-   preloadModule ( target ,  {  as : "script"  } ) ; 
167-   preloadModule ( target ,  {  as : "script"  } ) ; 
168-   for  ( const  dep  of  walkDependencies ( target ,  dependencies ) )  { 
169-     preloadModule ( dep ,  {  as : "script"  } ) ; 
170-     preloadModule ( dep ,  {  as : "script"  } ) ; 
171-   } 
172-   return  null ; 
173- } 
174- 
175- function *  walkDependencies ( 
178+ function *  scanCacheDependencies ( 
176179  target : string , 
177-   dependencies :  Record < string ,   string [ ] > 
180+   excludes :  RegExp [ ]   =   [ ] 
178181) : Generator < string >  { 
179-   if  ( dependencies [ target ] )  { 
180-     for  ( const  dep  of  dependencies [ target ] )  { 
181-       yield  dep ; 
182-       yield *  walkDependencies ( dep ,  dependencies ) ; 
182+   try  { 
183+     const  imports  =  new  Bun . Transpiler ( { 
184+       loader : target . endsWith ( ".tsx" ) 
185+         ? "tsx" 
186+         : target . endsWith ( ".ts" ) 
187+         ? "ts" 
188+         : "jsx" , 
189+     } ) . scanImports ( readFileSync ( target ) ) ; 
190+     for  ( const  imp  of  imports )  { 
191+       if  ( imp . kind  ===  "import-statement" )  { 
192+         const  path  =  Bun . fileURLToPath ( import . meta. resolve ( imp . path ,  target ) ) ; 
193+         if  ( 
194+           path . includes ( "/node_modules/" )  || 
195+           excludes . some ( ( x )  =>  path . match ( x ) ) 
196+         ) 
197+           continue ; 
198+         const  resolved  =  Object . keys ( require . cache ) . find ( ( x )  => 
199+           x . startsWith ( path ) 
200+         ) ; 
201+         if  ( resolved )  { 
202+           yield  resolved ; 
203+           yield *  scanCacheDependencies ( resolved ,  excludes ) ; 
204+         } 
205+       } 
183206    } 
184-   } 
207+   }   catch   { } 
185208} 
186209
187210export  async  function  serveFromDir ( config : { 
0 commit comments