@@ -39,6 +39,11 @@ export type Router = {
39
39
_app ?: Route ;
40
40
} ;
41
41
42
+ export type CSRContext = {
43
+ readonly router : Router ;
44
+ readonly modules : RouteModule [ ] ;
45
+ } ;
46
+
42
47
export type RouteRegExp = {
43
48
prefix : string ;
44
49
test ( filename : string ) : boolean ;
@@ -148,48 +153,71 @@ export function loadRouterFromTag(): Router {
148
153
return { routes : [ ] , prefix : "" } ;
149
154
}
150
155
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 ( ) ;
153
163
const el = window . document . getElementById ( "ssr-data" ) ;
154
164
if ( el ) {
155
165
try {
156
166
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 ) ;
172
178
} else {
173
- rest . data = Promise . resolve ( null ) ;
179
+ deferedData = null ;
174
180
}
175
181
}
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 ) ;
179
186
}
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
+ } ;
188
203
} catch ( e ) {
189
- throw new Error ( `loadSSRModulesFromTag : ${ e . message } ` ) ;
204
+ throw new Error ( `createCSRContext : ${ e . message } ` ) ;
190
205
}
191
206
}
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
+ } ;
193
221
}
194
222
195
223
export async function fetchRouteData ( dataCache : Map < string , RouteData > , dataUrl : string , defer ?: boolean ) {
@@ -254,7 +282,6 @@ export function watchRouter(
254
282
dataCache : Map < string , RouteData > ,
255
283
onRedirect : ( url : URL , modules : RouteModule [ ] ) => void ,
256
284
) : ( ) => void {
257
- const { importRouteModule } = Reflect . get ( window , "__aleph" ) ;
258
285
const router = loadRouterFromTag ( ) ;
259
286
260
287
// `popstate` event handler
@@ -267,7 +294,7 @@ export function watchRouter(
267
294
url : new URL ( ret . pathname . input + url . search , url . href ) ,
268
295
params : ret . pathname . groups ,
269
296
filename,
270
- exports : await importRouteModule ( filename ) ,
297
+ exports : await importModule ( filename ) ,
271
298
} ;
272
299
const dataUrl = rmod . url . pathname + rmod . url . search ;
273
300
const dataConfig = rmod . exports . data as Record < string , unknown > | true | undefined ;
0 commit comments