@@ -10,14 +10,21 @@ import { generate_html_template } from "@/build/generate_html_template.js";
1010import { logger } from "@/utils/logger.js" ;
1111import { measureTime } from "@/utils/time-perf.js" ;
1212import fse from "fs-extra" ;
13- import { defineHandler , H3 , html , serve , serveStatic } from "h3" ;
13+ import {
14+ defineHandler ,
15+ type EventHandlerRequest ,
16+ H3 ,
17+ type H3Event ,
18+ html ,
19+ serve ,
20+ serveStatic ,
21+ } from "h3" ;
1422import kleur from "kleur" ;
1523import { readFile , stat } from "node:fs/promises" ;
16- import { join , resolve } from "pathe" ;
24+ import { extname , join , resolve } from "pathe" ;
1725import { Fragment , h } from "preact" ;
1826import { renderToStringAsync } from "preact-render-to-string" ;
1927import type { HYDRATE_DATA , PageModule , SERVER_MANIFEST , ServerEntryModule } from "types/index.js" ;
20- import * as ufo from "ufo" ;
2128
2229export async function start ( ) {
2330 measureTime ( "pranx-start" ) ;
@@ -39,93 +46,69 @@ export async function start() {
3946 const { default : page , getServerSideProps } = ( await import ( file_absolute ) ) as PageModule ;
4047
4148 const hydrate_data = ( await fse . readJSON ( SITE_MANIFEST_OUTPUT_PATH ) ) as HYDRATE_DATA ;
49+ const url_for_routing_match = filePathToRoutingPath ( route . path , false ) ;
4250
4351 app . on (
4452 "GET" ,
45- filePathToRoutingPath ( route . path , false ) ,
46- defineHandler ( {
47- middleware : [ ] ,
48- meta : { } ,
49- handler : async ( event ) => {
50- const url_parsed = ufo . parseURL ( event . req . url ) ;
51- const params = new URLSearchParams ( url_parsed . search ) ;
52- const return_only_props = Boolean ( params . get ( "props" ) ) ;
53-
54- let props_to_return = { } ;
55-
56- if ( getServerSideProps ) {
57- props_to_return = await getServerSideProps ( ) ;
58- }
59-
60- if ( return_only_props ) {
61- return {
62- props : props_to_return ,
63- } ;
64- }
65-
66- const target_route_index = hydrate_data . routes . findIndex ( ( r ) => r . path === route . path ) ;
67-
68- if ( target_route_index === - 1 || ! hydrate_data . routes [ target_route_index ] ) {
69- logger . error ( `Route not found in hydrate data: ${ route . path } ` ) ;
70- event . res . status = 500 ;
71- return html ( event , "Internal Server Error" ) ;
72- }
73-
74- hydrate_data . routes [ target_route_index ] . props = props_to_return ;
75-
76- const page_prerendered = await renderToStringAsync (
77- h ( server_entry_module ?. default || Fragment , { } , h ( page , props_to_return , null ) )
78- ) ;
79-
80- const html_string = generate_html_template ( {
81- page_prerendered,
82- hydrate_data_as_string : JSON . stringify ( hydrate_data ) ,
83- minify : true ,
84- css : route . css ,
85- } ) ;
86-
87- event . res . headers . set ( "Content-Type" , "text/html" ) ;
88-
89- return html ( event , html_string ) ;
90- } ,
91- } )
92- ) ;
93- }
94- }
53+ url_for_routing_match ,
54+ defineHandler ( async ( event ) => {
55+ // For files that match with dynamic routes
56+ if ( extname ( event . url . pathname . split ( "/" ) . at ( - 1 ) || "" ) ) {
57+ return createServeStatic ( event ) ;
58+ }
59+
60+ let props_to_return = { } ;
61+
62+ if ( getServerSideProps ) {
63+ props_to_return = await getServerSideProps ( ) ;
64+ }
9565
96- app . on ( "GET" , "**" , ( event ) => {
97- return serveStatic ( event , {
98- indexNames : [ "/index.html" ] ,
66+ const target_route_index = hydrate_data . routes . findIndex ( ( r ) => r . path === route . path ) ;
9967
100- getContents : async ( id ) => {
101- const target_file = join ( OUTPUT_BUNDLE_BROWSER_DIR , id ) ;
102- const target_public_file = join ( PUBLIC_USER_DIR , id ) ;
68+ if ( target_route_index === - 1 || ! hydrate_data . routes [ target_route_index ] ) {
69+ logger . error ( `Route not found in hydrate data: ${ route . path } ` ) ;
70+ event . res . status = 500 ;
71+ return html ( event , "Internal Server Error" ) ;
72+ }
10373
104- const existsTargetFile = await fse . exists ( target_file ) ;
74+ hydrate_data . routes [ target_route_index ] . props = props_to_return ;
10575
106- const buffer = await readFile ( existsTargetFile ? target_file : target_public_file ) ;
76+ const page_prerendered = await renderToStringAsync (
77+ h ( server_entry_module ?. default || Fragment , { } , h ( page , props_to_return , null ) )
78+ ) ;
10779
108- return new Uint8Array ( buffer ) ;
109- } ,
80+ const html_string = generate_html_template ( {
81+ page_prerendered,
82+ hydrate_data_as_string : JSON . stringify ( hydrate_data ) ,
83+ minify : true ,
84+ css : route . css ,
85+ } ) ;
11086
111- getMeta : async ( id ) => {
112- const target_file = join ( OUTPUT_BUNDLE_BROWSER_DIR , id ) ;
113- const target_public_file = join ( PUBLIC_USER_DIR , id ) ;
87+ event . res . headers . set ( "Content-Type" , "text/html" ) ;
11488
115- const existsTargetFile = await fse . exists ( target_file ) ;
89+ return html ( event , html_string ) ;
90+ } )
91+ ) ;
11692
117- const stats = await stat ( existsTargetFile ? target_file : target_public_file ) . catch (
118- ( ) => { }
119- ) ;
93+ app . on (
94+ "GET" ,
95+ `/_internal_/${ route . server_data_api_key } ` ,
96+ defineHandler ( async ( ) => {
97+ let props_to_return = { } ;
12098
121- if ( stats ?. isFile ( ) ) {
122- return stats ;
123- }
99+ if ( getServerSideProps ) {
100+ props_to_return = await getServerSideProps ( ) ;
101+ }
124102
125- return undefined ;
126- } ,
127- } ) ;
128- } ) ;
103+ return {
104+ props : props_to_return ,
105+ } ;
106+ } )
107+ ) ;
108+ }
109+ }
110+
111+ app . on ( "GET" , "**" , ( event ) => createServeStatic ( event ) ) ;
129112
130113 const SERVER = serve ( app , { port : PORT } ) ;
131114
@@ -135,3 +118,34 @@ export async function start() {
135118
136119 logger . success ( `Start in ${ START_TIME } ms` ) ;
137120}
121+
122+ const createServeStatic = ( event : H3Event < EventHandlerRequest > ) =>
123+ serveStatic ( event , {
124+ indexNames : [ "/index.html" ] ,
125+
126+ getContents : async ( id ) => {
127+ const target_file = join ( OUTPUT_BUNDLE_BROWSER_DIR , id ) ;
128+ const target_public_file = join ( PUBLIC_USER_DIR , id ) ;
129+
130+ const existsTargetFile = await fse . exists ( target_file ) ;
131+
132+ const buffer = await readFile ( existsTargetFile ? target_file : target_public_file ) ;
133+
134+ return new Uint8Array ( buffer ) ;
135+ } ,
136+
137+ getMeta : async ( id ) => {
138+ const target_file = join ( OUTPUT_BUNDLE_BROWSER_DIR , id ) ;
139+ const target_public_file = join ( PUBLIC_USER_DIR , id ) ;
140+
141+ const existsTargetFile = await fse . exists ( target_file ) ;
142+
143+ const stats = await stat ( existsTargetFile ? target_file : target_public_file ) . catch ( ( ) => { } ) ;
144+
145+ if ( stats ?. isFile ( ) ) {
146+ return stats ;
147+ }
148+
149+ return undefined ;
150+ } ,
151+ } ) ;
0 commit comments