Repository navigation
Expand file tree
/
Copy pathstatic-server.js
More file actions
executable file
·105 lines (91 loc) · 2.7 KB
/
Copy pathstatic-server.js
File metadata and controls
executable file
·105 lines (91 loc) · 2.7 KB
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
#!/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}`);