Spaces:
Running
Running
File size: 2,764 Bytes
3165745 8173aa6 3165745 7da3a72 3165745 67a499d 3165745 67a499d 3165745 67a499d 3165745 67a499d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
#!/usr/bin/env bun
// Simple static file server for Svelte build output
import { join } from "path";
const PORT = process.env.PORT || 8000;
const BUILD_DIR = "./build";
// MIME types for common web assets
const MIME_TYPES = {
".html": "text/html",
".css": "text/css",
".js": "application/javascript",
".json": "application/json",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".woff": "font/woff",
".woff2": "font/woff2",
".ttf": "font/ttf",
".eot": "application/vnd.ms-fontobject",
".webp": "image/webp",
".avif": "image/avif",
".mp4": "video/mp4",
".webm": "video/webm"
};
function getMimeType(filename) {
const ext = filename.substring(filename.lastIndexOf("."));
return MIME_TYPES[ext] || "application/octet-stream";
}
const server = Bun.serve({
port: PORT,
hostname: "0.0.0.0",
async fetch(req) {
const url = new URL(req.url);
let pathname = url.pathname;
// Remove leading slash and default to index.html for root
if (pathname === "/") {
pathname = "index.html";
} else {
pathname = pathname.substring(1); // Remove leading slash
}
try {
// Try to serve the requested file
const filePath = join(BUILD_DIR, pathname);
const file = Bun.file(filePath);
if (await file.exists()) {
const mimeType = getMimeType(pathname);
const headers = {
"Content-Type": mimeType
};
// Set cache headers
if (pathname.includes("/_app/immutable/")) {
// Long-term cache for immutable assets
headers["Cache-Control"] = "public, max-age=31536000, immutable";
} else if (pathname.endsWith(".html")) {
// No cache for HTML files
headers["Cache-Control"] = "public, max-age=0, must-revalidate";
} else {
// Short cache for other assets
headers["Cache-Control"] = "public, max-age=3600";
}
return new Response(file, { headers });
}
// If file not found and no extension, serve index.html for SPA routing
if (!pathname.includes(".")) {
const indexFile = Bun.file(join(BUILD_DIR, "index.html"));
if (await indexFile.exists()) {
return new Response(indexFile, {
headers: {
"Content-Type": "text/html",
"Cache-Control": "public, max-age=0, must-revalidate"
}
});
}
}
return new Response("Not Found", {
status: 404,
headers: { "Content-Type": "text/plain" }
});
} catch (error) {
console.error("Server error:", error);
return new Response("Internal Server Error", {
status: 500,
headers: { "Content-Type": "text/plain" }
});
}
}
});
console.log(`π Static server running on http://localhost:${server.port}`);
console.log(`π Serving files from: ${BUILD_DIR}`);
|