export interface StaticAssets { files: Record; indexHtml: Blob; } const CONTENT_TYPES: Record = { ".css": "text/css; charset=utf-8", ".html": "text/html; charset=utf-8", ".js": "text/javascript; charset=utf-8", ".json": "application/json; charset=utf-8", ".mjs": "text/javascript; charset=utf-8", ".png": "image/png", ".svg": "image/svg+xml", ".woff": "font/woff", ".woff2": "font/woff2", }; export function contentTypeFor(path: string): string { const dot = path.lastIndexOf("."); if (dot === -1) return "application/octet-stream"; const ext = path.slice(dot); return CONTENT_TYPES[ext] ?? "application/octet-stream"; } export function hasFileExtension(path: string): boolean { const lastSlash = path.lastIndexOf("/"); const segment = lastSlash === -1 ? path : path.slice(lastSlash + 1); return segment.includes("."); } export function htmlResponse(html: Blob): Response { return new Response(html, { headers: { "Cache-Control": "no-cache", "Content-Type": "text/html; charset=utf-8", }, }); } export function serveStaticAsset(pathname: string, assets: StaticAssets): Response { if (pathname === "/") { return htmlResponse(assets.indexHtml); } const file = assets.files[pathname]; if (file) { return new Response(file, { headers: { "Cache-Control": "public, max-age=31536000, immutable", "Content-Type": contentTypeFor(pathname), }, }); } if (hasFileExtension(pathname)) { return new Response("Not found", { status: 404 }); } return htmlResponse(assets.indexHtml); }