File size: 3,040 Bytes
3165745
 
 
8173aa6
3165745
7da3a72
3165745
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1fbccb3
3165745
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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}`);