import { createReadStream, readFileSync } from "node:fs"; import path from "node:path"; import { pipeline } from "node:stream"; import { createGunzip } from "node:zlib"; export function contentMimeType(logicalPath) { return ({ ".glb": "model/gltf-binary", ".json": "application/json", ".js": "text/javascript", ".wasm": "application/wasm", ".ktx2": "image/ktx2", ".png": "image/png", ".webp": "image/webp", ".avif": "image/avif", ".svg": "image/svg+xml", ".mp3": "audio/mpeg", ".ogg": "audio/ogg", ".wav": "audio/wav", ".webm": "video/webm", })[path.extname(logicalPath)] ?? "application/octet-stream"; } function acceptsGzip(value = "") { const encodings = new Map(String(value).split(",").map((entry) => { const [name, ...parameters] = entry.trim().toLowerCase().split(";"); const quality = parameters.find((part) => part.trim().startsWith("q=")); return [name, quality ? Number(quality.trim().slice(2)) : 1]; })); return (encodings.get("gzip") ?? encodings.get("*") ?? 0) > 0; } /** Resolve logical URLs to one immutable bundled object without expanding it on disk. */ export function createBundledContentHandler(root) { let manifest; return (request, response, pathname) => { if (!["GET", "HEAD"].includes(request.method) || !/^\/(assets|basis|data)\//.test(pathname)) return false; if (manifest === undefined) { try { manifest = JSON.parse(readFileSync(path.join(root, "content/bootstrap-manifest.json"), "utf8")); } catch (error) { if (error.code !== "ENOENT") throw error; manifest = null; } } const entry = manifest?.files[pathname]; if (!entry) return false; const object = entry.download ?? entry; if (!/^\/content\/bundled\/[a-f0-9]{64}\.[a-z0-9]+(?:\.g(?:z|zip))?$/.test(object.url)) return false; const encoded = entry.download?.encoding === "gzip"; const sendGzip = encoded && acceptsGzip(request.headers["accept-encoding"]); response.writeHead(200, { "Content-Type": contentMimeType(pathname), "Content-Length": sendGzip ? object.bytes : entry.bytes, "Cache-Control": "public, max-age=3600", "X-Content-Type-Options": "nosniff", Vary: "Accept-Encoding", ...(sendGzip ? { "Content-Encoding": "gzip" } : {}), }); if (request.method === "HEAD") { response.end(); return true; } const stream = createReadStream(path.join(root, object.url.slice(1))); const done = (error) => { if (error) response.destroy(error); }; if (encoded && !sendGzip) pipeline(stream, createGunzip(), response, done); else pipeline(stream, response, done); return true; }; }