11import 'SHIMS' ;
22import { env } from 'ENV' ;
3- import { manifest , prerendered , base } from 'MANIFEST' ;
3+ import { manifest , prerendered } from 'MANIFEST' ;
44import { Server } from 'SERVER' ;
5+ import { readFileSync } from 'node:fs' ;
6+ import { dirname , extname , join } from 'node:path' ;
7+ import { fileURLToPath } from 'node:url' ;
58// 🔥 Use our robust converters instead of basic event parsing
69import {
710 convertLambdaEventToWebRequest ,
@@ -16,6 +19,9 @@ const server = new Server(manifest);
1619const body_size_limit = Number . parseInt ( env ( 'BODY_SIZE_LIMIT' , 'BODY_SIZE_LIMIT' ) ) ;
1720const binaryMediaTypes = BINARY_MEDIA_TYPES ;
1821
22+ // Get the directory of this handler file
23+ const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
24+
1925await server . init ( {
2026 env : process . env ,
2127} ) ;
@@ -89,19 +95,65 @@ function isALBEvent(event) {
8995 * @returns {boolean }
9096 */
9197function isStaticAsset ( pathname ) {
92- return pathname . startsWith ( `${ base } /_app/` ) ||
93- pathname . startsWith ( `${ base } /favicon.` ) ||
94- pathname . endsWith ( '.css' ) ||
95- pathname . endsWith ( '.js' ) ||
96- pathname . endsWith ( '.woff' ) ||
97- pathname . endsWith ( '.woff2' ) ||
98- pathname . endsWith ( '.png' ) ||
99- pathname . endsWith ( '.jpg' ) ||
100- pathname . endsWith ( '.jpeg' ) ||
101- pathname . endsWith ( '.gif' ) ||
102- pathname . endsWith ( '.svg' ) ||
103- pathname . endsWith ( '.webp' ) ||
104- pathname . endsWith ( '.ico' ) ;
98+ return (
99+ pathname . startsWith ( '/_app/' ) ||
100+ pathname . startsWith ( '/favicon.' ) ||
101+ pathname . endsWith ( '.css' ) ||
102+ pathname . endsWith ( '.js' ) ||
103+ pathname . endsWith ( '.woff' ) ||
104+ pathname . endsWith ( '.woff2' ) ||
105+ pathname . endsWith ( '.png' ) ||
106+ pathname . endsWith ( '.jpg' ) ||
107+ pathname . endsWith ( '.jpeg' ) ||
108+ pathname . endsWith ( '.gif' ) ||
109+ pathname . endsWith ( '.svg' ) ||
110+ pathname . endsWith ( '.webp' ) ||
111+ pathname . endsWith ( '.ico' )
112+ ) ;
113+ }
114+
115+ /**
116+ * Serve static files from the bundled client directory
117+ * @param {string } pathname - The requested pathname
118+ * @returns {Promise<Response|null> } - Response for static file or null if not found
119+ */
120+ async function tryServeStaticFile ( pathname ) {
121+ try {
122+ const fullPath = join ( __dirname , 'client' , pathname ) ;
123+ const content = readFileSync ( fullPath ) ;
124+
125+ // Determine content type
126+ const ext = extname ( pathname ) . toLowerCase ( ) ;
127+ const contentType =
128+ {
129+ '.js' : 'application/javascript' ,
130+ '.css' : 'text/css' ,
131+ '.ico' : 'image/x-icon' ,
132+ '.png' : 'image/png' ,
133+ '.jpg' : 'image/jpeg' ,
134+ '.jpeg' : 'image/jpeg' ,
135+ '.gif' : 'image/gif' ,
136+ '.svg' : 'image/svg+xml' ,
137+ '.webp' : 'image/webp' ,
138+ '.woff' : 'font/woff' ,
139+ '.woff2' : 'font/woff2' ,
140+ '.ttf' : 'font/ttf' ,
141+ '.eot' : 'application/vnd.ms-fontobject' ,
142+ } [ ext ] || 'application/octet-stream' ;
143+
144+ return new Response ( content , {
145+ status : 200 ,
146+ headers : {
147+ 'Content-Type' : contentType ,
148+ 'Cache-Control' : pathname . includes ( '/immutable/' )
149+ ? 'public, max-age=31536000, immutable'
150+ : 'public, max-age=3600' ,
151+ } ,
152+ } ) ;
153+ } catch {
154+ // File not found or error reading
155+ return null ;
156+ }
105157}
106158
107159/**
@@ -115,17 +167,20 @@ export const handler = async (event, context) => {
115167 // 🔥 Use our superior event conversion (handles all Lambda event types)
116168 const webRequest = convertLambdaEventToWebRequest ( event ) ;
117169 const pathname = new URL ( webRequest . url ) . pathname ;
118-
119- // Check for prerendered routes
120- if ( prerendered . has ( pathname ) ) {
121- // Let SvelteKit handle prerendered routes
122- // Fall through to normal processing
123- }
124170
125- // Static assets - let SvelteKit handle them
126- if ( isStaticAsset ( pathname ) ) {
127- // Let SvelteKit handle static assets
128- // Fall through to normal processing
171+ // Check for prerendered routes - let SvelteKit handle them
172+ if ( prerendered . has ( pathname ) ) {
173+ // Fall through to normal SvelteKit processing
174+ } else if ( isStaticAsset ( pathname ) ) {
175+ // Try to serve static files directly
176+ const staticFileResponse = await tryServeStaticFile ( pathname ) ;
177+ if ( staticFileResponse ) {
178+ return await convertWebResponseToLambdaEvent ( staticFileResponse , {
179+ binaryMediaTypes,
180+ multiValueHeaders : isALBEvent ( event ) ,
181+ } ) ;
182+ }
183+ // If static file not found, fall through to SvelteKit
129184 }
130185
131186 // Convert to Node.js request format for SvelteKit
0 commit comments