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}`);