11import React , { ComponentType , createContext , useCallback , useEffect , useState } from 'https://esm.sh/react'
2- import { hydrate , render } from 'https://esm.sh/react-dom'
32import { DataContext } from './data.ts'
43import { E404Page , E501 } from './error.ts'
54import events from './events.ts'
65import route from './route.ts'
76import { RouterContext } from './router.ts'
8- import type { AppManifest , RouterURL } from './types.ts'
7+ import type { AppManifest , Module , RouterURL } from './types.ts'
98import util , { hashShort } from './util.ts'
109
1110export const AppManifestContext = createContext < AppManifest > ( {
@@ -15,7 +14,7 @@ export const AppManifestContext = createContext<AppManifest>({
1514} )
1615AppManifestContext . displayName = 'AppManifestContext'
1716
18- function ALEPH ( { initial } : {
17+ export function ALEPH ( { initial } : {
1918 initial : {
2019 manifest : AppManifest
2120 pageModules : Record < string , { moduleId : string , hash : string } >
@@ -168,115 +167,6 @@ function ALEPH({ initial }: {
168167 )
169168}
170169
171- export async function redirect ( url : string , replace : boolean ) {
172- const { location, document, history } = window as any
173-
174- if ( util . isHttpUrl ( url ) ) {
175- location . href = url
176- return
177- }
178-
179- url = util . cleanPath ( url )
180- if ( location . protocol === 'file:' ) {
181- const dataEl = document . getElementById ( 'ssr-data' )
182- if ( dataEl ) {
183- const ssrData = JSON . parse ( dataEl . innerHTML )
184- if ( ssrData && 'url' in ssrData ) {
185- const { url : { pagePath : initialPagePath } } = ssrData
186- location . href = location . href . replace (
187- `/${ util . trimPrefix ( initialPagePath , '/' ) || 'index' } .html` ,
188- `/${ util . trimPrefix ( url , '/' ) || 'index' } .html`
189- )
190- }
191- }
192- return
193- }
194-
195- if ( replace ) {
196- history . replaceState ( null , '' , url )
197- } else {
198- history . pushState ( null , '' , url )
199- }
200- events . emit ( 'popstate' , { type : 'popstate' } )
201- }
202-
203- interface Module {
204- moduleId : string ,
205- hash : string ,
206- }
207-
208- export async function bootstrap ( {
209- baseUrl,
210- defaultLocale,
211- locales,
212- keyModules,
213- pageModules
214- } : AppManifest & {
215- keyModules : Record < string , Module >
216- pageModules : Record < string , Module >
217- } ) {
218- const { document } = window as any
219- const mainEl = document . querySelector ( 'main' )
220- const dataEl = document . getElementById ( 'ssr-data' )
221-
222- let url : RouterURL
223- if ( dataEl ) {
224- const data = JSON . parse ( dataEl . innerHTML )
225- if ( util . isPlainObject ( data . url ) ) {
226- url = data . url
227- } else {
228- throw new Error ( "invalid ssr-data" )
229- }
230- } else {
231- url = route (
232- baseUrl ,
233- Object . keys ( pageModules ) ,
234- {
235- defaultLocale,
236- locales : Object . keys ( locales )
237- }
238- )
239- }
240-
241- const pageModule = pageModules [ url . pagePath ] !
242- const [
243- { default : data } ,
244- { default : App } ,
245- { default : E404 } ,
246- { default : Page }
247- ] = await Promise . all ( [
248- keyModules . data ? import ( getModuleImportUrl ( baseUrl , keyModules . data ) ) : Promise . resolve ( { default : { } } ) ,
249- keyModules . app ? import ( getModuleImportUrl ( baseUrl , keyModules . app ) ) : Promise . resolve ( { } ) ,
250- keyModules [ '404' ] ? import ( getModuleImportUrl ( baseUrl , keyModules [ '404' ] ) ) : Promise . resolve ( { } ) ,
251- pageModule ? import ( getModuleImportUrl ( baseUrl , pageModule ) ) : Promise . resolve ( { } ) ,
252- ] )
253- const el = React . createElement (
254- ALEPH ,
255- {
256- initial : {
257- manifest : { baseUrl, defaultLocale, locales } ,
258- pageModules,
259- url,
260- data,
261- components : { E404 , App, Page }
262- }
263- }
264- )
265- if ( dataEl ) {
266- hydrate ( el , mainEl )
267- // remove ssr head elements, set a timmer to avoid tab title flash
268- setTimeout ( ( ) => {
269- Array . from ( document . head . children ) . forEach ( ( el : any ) => {
270- if ( el . hasAttribute ( 'ssr' ) ) {
271- document . head . removeChild ( el )
272- }
273- } )
274- } , 0 )
275- } else {
276- render ( el , mainEl )
277- }
278- }
279-
280- function getModuleImportUrl ( baseUrl : string , { moduleId, hash } : Module ) {
170+ export function getModuleImportUrl ( baseUrl : string , { moduleId, hash } : Module ) {
281171 return util . cleanPath ( baseUrl + '/_aleph/' + moduleId . replace ( / \. j s $ / , `.${ hash . slice ( 0 , hashShort ) } .js` ) )
282172}
0 commit comments