@@ -39,6 +39,11 @@ export type Router = {
3939 _app ?: Route ;
4040} ;
4141
42+ export type CSRContext = {
43+ readonly router : Router ;
44+ readonly modules : RouteModule [ ] ;
45+ } ;
46+
4247export type RouteRegExp = {
4348 prefix : string ;
4449 test ( filename : string ) : boolean ;
@@ -148,48 +153,71 @@ export function loadRouterFromTag(): Router {
148153 return { routes : [ ] , prefix : "" } ;
149154}
150155
151- export function loadSSRModulesFromTag ( ) : RouteModule [ ] {
152- const { getRouteModule } = Reflect . get ( window , "__aleph" ) ;
156+ export function importModule ( filename : string ) : Promise < Record < string , unknown > > {
157+ const v = document . body . getAttribute ( "data-deployment-id" ) ;
158+ return import ( filename . slice ( 1 ) + ( v ? "?v=" + v : "" ) ) ;
159+ }
160+
161+ export async function createCSRContext ( ) : Promise < CSRContext > {
162+ const router = loadRouterFromTag ( ) ;
153163 const el = window . document . getElementById ( "ssr-data" ) ;
154164 if ( el ) {
155165 try {
156166 const data = JSON . parse ( el . innerText ) ;
157- if ( Array . isArray ( data ) ) {
158- let deferedData : Record < string , unknown > | null | undefined = undefined ;
159- return data . map ( ( { url, filename, dataDefered, ...rest } ) => {
160- const mod = getRouteModule ( filename ) ;
161- if ( dataDefered ) {
162- if ( deferedData === undefined ) {
163- const el = window . document ?. getElementById ( "defered-data" ) ;
164- if ( el ) {
165- deferedData = JSON . parse ( el . innerText ) ;
166- } else {
167- deferedData = null ;
168- }
169- }
170- if ( deferedData ) {
171- rest . data = deferedData [ url ] ;
167+ if ( ! Array . isArray ( data ) ) {
168+ throw new Error ( "invalid SSR data" ) ;
169+ }
170+ let deferedData : Record < string , unknown > | null | undefined = undefined ;
171+ const modules = await Promise . all ( data . map ( async ( { url, filename, dataDefered, ...rest } ) => {
172+ const mod = await importModule ( filename ) ;
173+ if ( dataDefered ) {
174+ if ( deferedData === undefined ) {
175+ const el = window . document ?. getElementById ( "defered-data" ) ;
176+ if ( el ) {
177+ deferedData = JSON . parse ( el . innerText ) ;
172178 } else {
173- rest . data = Promise . resolve ( null ) ;
179+ deferedData = null ;
174180 }
175181 }
176- if ( rest . error ) {
177- rest . data = new FetchError ( 500 , rest . error . message , { stack : rest . error . stack } ) ;
178- rest . error = undefined ;
182+ if ( deferedData ) {
183+ rest . data = deferedData [ url ] ;
184+ } else {
185+ rest . data = Promise . resolve ( null ) ;
179186 }
180- return < RouteModule > {
181- url : new URL ( url , location . href ) ,
182- filename,
183- exports : mod ,
184- ...rest ,
185- } ;
186- } ) ;
187- }
187+ }
188+ if ( rest . error ) {
189+ rest . data = new FetchError ( 500 , rest . error . message , { stack : rest . error . stack } ) ;
190+ rest . error = undefined ;
191+ }
192+ return < RouteModule > {
193+ url : new URL ( url , location . href ) ,
194+ filename,
195+ exports : mod ,
196+ ...rest ,
197+ } ;
198+ } ) ) ;
199+ return {
200+ router,
201+ modules,
202+ } ;
188203 } catch ( e ) {
189- throw new Error ( `loadSSRModulesFromTag : ${ e . message } ` ) ;
204+ throw new Error ( `createCSRContext : ${ e . message } ` ) ;
190205 }
191206 }
192- return [ ] ;
207+ return {
208+ router,
209+ modules : await Promise . all (
210+ matchRoutes ( new URL ( location . href ) , router ) . map ( async ( [ ret , meta ] ) => {
211+ const mod = await importModule ( meta . filename ) ;
212+ return {
213+ url : new URL ( ret . pathname . input + location . search , location . href ) ,
214+ params : ret . pathname . groups ,
215+ filename : meta . filename ,
216+ exports : mod ,
217+ } ;
218+ } ) ,
219+ ) ,
220+ } ;
193221}
194222
195223export async function fetchRouteData ( dataCache : Map < string , RouteData > , dataUrl : string , defer ?: boolean ) {
@@ -254,7 +282,6 @@ export function watchRouter(
254282 dataCache : Map < string , RouteData > ,
255283 onRedirect : ( url : URL , modules : RouteModule [ ] ) => void ,
256284) : ( ) => void {
257- const { importRouteModule } = Reflect . get ( window , "__aleph" ) ;
258285 const router = loadRouterFromTag ( ) ;
259286
260287 // `popstate` event handler
@@ -267,7 +294,7 @@ export function watchRouter(
267294 url : new URL ( ret . pathname . input + url . search , url . href ) ,
268295 params : ret . pathname . groups ,
269296 filename,
270- exports : await importRouteModule ( filename ) ,
297+ exports : await importModule ( filename ) ,
271298 } ;
272299 const dataUrl = rmod . url . pathname + rmod . url . search ;
273300 const dataConfig = rmod . exports . data as Record < string , unknown > | true | undefined ;
0 commit comments