@@ -30,6 +30,8 @@ import serverFnManifest from "solidstart:server-fn-manifest";
3030import { isRunnableDevEnvironment } from "vite" ;
3131import { getFetchEvent , mergeResponseHeaders } from "./fetchEvent.js" ;
3232import { getExpectedRedirectStatus } from "./util.js" ;
33+ import { FetchEvent , PageEvent } from "./types.js" ;
34+ import { createPageEvent } from "./index.jsx" ;
3335
3436function createChunk ( data : string ) {
3537 const encodeData = new TextEncoder ( ) . encode ( data ) ;
@@ -218,9 +220,9 @@ export async function handleServerFunction(h3Event: H3Event) {
218220 return serverFunction ( ...parsed ) ;
219221 } ) ;
220222
221- // if (singleFlight && instance) {
222- // result = await handleSingleFlight(event, result);
223- // }
223+ if ( singleFlight && instance ) {
224+ result = await handleSingleFlight ( event , result ) ;
225+ }
224226
225227 // handle responses
226228 if ( result instanceof Response ) {
@@ -245,9 +247,9 @@ export async function handleServerFunction(h3Event: H3Event) {
245247 return serializeToStream ( instance , result ) ;
246248 } catch ( x ) {
247249 if ( x instanceof Response ) {
248- // if (singleFlight && instance) {
249- // x = await handleSingleFlight(event, x);
250- // }
250+ if ( singleFlight && instance ) {
251+ x = await handleSingleFlight ( event , x ) ;
252+ }
251253 // forward headers
252254 if ( ( x as any ) . headers ) mergeResponseHeaders ( h3Event , ( x as any ) . headers ) ;
253255 // forward non-redirect statuses
@@ -309,83 +311,83 @@ function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boole
309311 } ) ;
310312}
311313
312- // let App: any;
313- // function createSingleFlightHeaders(sourceEvent: FetchEvent) {
314- // // cookie handling logic is pretty simplistic so this might be imperfect
315- // // unclear if h3 internals are available on all platforms but we need a way to
316- // // update request headers on the underlying H3 event.
314+ let App : any ;
315+ function createSingleFlightHeaders ( sourceEvent : FetchEvent ) {
316+ // cookie handling logic is pretty simplistic so this might be imperfect
317+ // unclear if h3 internals are available on all platforms but we need a way to
318+ // update request headers on the underlying H3 event.
317319
318- // const headers = new Headers(sourceEvent.request.headers);
319- // const cookies = parseCookies(sourceEvent.nativeEvent);
320- // const SetCookies = sourceEvent.response.headers.getSetCookie();
321- // headers.delete("cookie");
322- // let useH3Internals = false;
323- // if (sourceEvent.nativeEvent.node?.req) {
324- // useH3Internals = true;
325- // sourceEvent.nativeEvent.node.req.headers.cookie = "";
326- // }
327- // SetCookies.forEach(cookie => {
328- // if (!cookie) return;
329- // const keyValue = cookie.split(";")[0]!;
330- // const [key, value] = keyValue.split("=");
331- // key && value && (cookies[key] = value);
332- // });
333- // Object.entries(cookies).forEach(([key, value]) => {
334- // headers.append("cookie", `${key}=${value}`);
335- // useH3Internals && (sourceEvent.nativeEvent.node.req.headers.cookie += `${key}=${value};`);
336- // });
320+ const headers = new Headers ( sourceEvent . request . headers ) ;
321+ const cookies = parseCookies ( sourceEvent . nativeEvent ) ;
322+ const SetCookies = sourceEvent . response . headers . getSetCookie ( ) ;
323+ headers . delete ( "cookie" ) ;
324+ let useH3Internals = false ;
325+ if ( sourceEvent . nativeEvent . node ?. req ) {
326+ useH3Internals = true ;
327+ sourceEvent . nativeEvent . node . req . headers . cookie = "" ;
328+ }
329+ SetCookies . forEach ( cookie => {
330+ if ( ! cookie ) return ;
331+ const keyValue = cookie . split ( ";" ) [ 0 ] ! ;
332+ const [ key , value ] = keyValue . split ( "=" ) ;
333+ key && value && ( cookies [ key ] = value ) ;
334+ } ) ;
335+ Object . entries ( cookies ) . forEach ( ( [ key , value ] ) => {
336+ headers . append ( "cookie" , `${ key } =${ value } ` ) ;
337+ useH3Internals && ( sourceEvent . nativeEvent . node . req . headers . cookie += `${ key } =${ value } ;` ) ;
338+ } ) ;
337339
338- // return headers;
339- // }
340- // async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise<Response> {
341- // let revalidate: string[];
342- // let url = new URL(sourceEvent.request.headers.get("referer")!).toString();
343- // if (result instanceof Response) {
344- // if (result.headers.has("X-Revalidate"))
345- // revalidate = result.headers.get("X-Revalidate")!.split(",");
346- // if (result.headers.has("Location"))
347- // url = new URL(
348- // result.headers.get("Location")!,
349- // new URL(sourceEvent.request.url).origin + import.meta.env.SERVER_BASE_URL
350- // ).toString();
351- // }
352- // const event = { ...sourceEvent } as PageEvent;
353- // event.request = new Request(url, { headers: createSingleFlightHeaders(sourceEvent) });
354- // return await provideRequestEvent(event, async () => {
355- // await createPageEvent(event);
356- // /* @ts -ignore */
357- // App || (App = (await import("#start/app")).default);
358- // /* @ts -ignore */
359- // event.router.dataOnly = revalidate || true;
360- // /* @ts -ignore */
361- // event.router.previousUrl = sourceEvent.request.headers.get("referer");
362- // try {
363- // renderToString(() => {
364- // /* @ts -ignore */
365- // sharedConfig.context.event = event;
366- // App();
367- // });
368- // } catch (e) {
369- // console.log(e);
370- // }
340+ return headers ;
341+ }
342+ async function handleSingleFlight ( sourceEvent : FetchEvent , result : any ) : Promise < Response > {
343+ let revalidate : string [ ] ;
344+ let url = new URL ( sourceEvent . request . headers . get ( "referer" ) ! ) . toString ( ) ;
345+ if ( result instanceof Response ) {
346+ if ( result . headers . has ( "X-Revalidate" ) )
347+ revalidate = result . headers . get ( "X-Revalidate" ) ! . split ( "," ) ;
348+ if ( result . headers . has ( "Location" ) )
349+ url = new URL (
350+ result . headers . get ( "Location" ) ! ,
351+ new URL ( sourceEvent . request . url ) . origin + import . meta. env . SERVER_BASE_URL
352+ ) . toString ( ) ;
353+ }
354+ const event = { ...sourceEvent } as PageEvent ;
355+ event . request = new Request ( url , { headers : createSingleFlightHeaders ( sourceEvent ) } ) ;
356+ return await provideRequestEvent ( event , async ( ) => {
357+ await createPageEvent ( event ) ;
358+ /* @ts -ignore */
359+ App || ( App = ( await import ( "#start/app" ) ) . default ) ;
360+ /* @ts -ignore */
361+ event . router . dataOnly = revalidate || true ;
362+ /* @ts -ignore */
363+ event . router . previousUrl = sourceEvent . request . headers . get ( "referer" ) ;
364+ try {
365+ renderToString ( ( ) => {
366+ /* @ts -ignore */
367+ sharedConfig . context . event = event ;
368+ App ( ) ;
369+ } ) ;
370+ } catch ( e ) {
371+ console . log ( e ) ;
372+ }
371373
372- // /* @ts -ignore */
373- // const body = event.router.data;
374- // if (!body) return result;
375- // let containsKey = false;
376- // for (const key in body) {
377- // if (body[key] === undefined) delete body[key];
378- // else containsKey = true;
379- // }
380- // if (!containsKey) return result;
381- // if (!(result instanceof Response)) {
382- // body["_$value"] = result;
383- // result = new Response(null, { status: 200 });
384- // } else if ((result as any).customBody) {
385- // body["_$value"] = (result as any).customBody();
386- // }
387- // result.customBody = () => body;
388- // result.headers.set("X-Single-Flight", "true");
389- // return result;
390- // });
391- // }
374+ /* @ts -ignore */
375+ const body = event . router . data ;
376+ if ( ! body ) return result ;
377+ let containsKey = false ;
378+ for ( const key in body ) {
379+ if ( body [ key ] === undefined ) delete body [ key ] ;
380+ else containsKey = true ;
381+ }
382+ if ( ! containsKey ) return result ;
383+ if ( ! ( result instanceof Response ) ) {
384+ body [ "_$value" ] = result ;
385+ result = new Response ( null , { status : 200 } ) ;
386+ } else if ( ( result as any ) . customBody ) {
387+ body [ "_$value" ] = ( result as any ) . customBody ( ) ;
388+ }
389+ result . customBody = ( ) => body ;
390+ result . headers . set ( "X-Single-Flight" , "true" ) ;
391+ return result ;
392+ } ) ;
393+ }
0 commit comments