Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a04de9a4f | |||
| 66168e95cc | |||
| 17d01aff21 |
+1
-1
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "bun --hot src/server.tsx",
|
||||
"build": "rm -rf dist && bun build --target=bun ./src/server.tsx --outdir ./dist",
|
||||
"build": "rm -rf dist && bun build --minify --target=browser ./src/index.html --outdir ./dist/public && bun build --target=bun ./src/server.tsx --outdir ./dist",
|
||||
"start": "cd dist && DATABASE_PATH=../data/excalidraw.sqlite bun ./server.js",
|
||||
"test": "bun test",
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
||||
+47
-2
@@ -14,7 +14,16 @@ export function createServer() {
|
||||
const drawing = drawingStore.ensureInitialDrawing();
|
||||
return Response.redirect(new URL(`/d/${drawing.id}`, request.url), 302);
|
||||
},
|
||||
"/d/:id": index,
|
||||
...(process.cwd().endsWith("/dist") ? {
|
||||
"/d/:id": async (req: Request) => {
|
||||
let file = Bun.file("./public/index.html");
|
||||
return new Response(file, {
|
||||
headers: { "Content-Type": "text/html; charset=utf-8" }
|
||||
});
|
||||
}
|
||||
} : {
|
||||
"/d/:id": index
|
||||
}),
|
||||
"/api/health": {
|
||||
GET: () => api.health(),
|
||||
},
|
||||
@@ -28,7 +37,43 @@ export function createServer() {
|
||||
DELETE: (request: Request & { params: Record<string, string> }) => api.deleteDrawing(request),
|
||||
},
|
||||
},
|
||||
fetch() {
|
||||
async fetch(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
const isProd = process.cwd().endsWith("/dist");
|
||||
|
||||
if (!isProd) {
|
||||
return Response.json({ ok: false, error: "Not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
// Remove any "/public" prefix from the request URL if it accidentally got included
|
||||
let reqPath = url.pathname;
|
||||
if (reqPath.startsWith("/public/")) {
|
||||
reqPath = reqPath.substring(7);
|
||||
}
|
||||
|
||||
// In dist, static files are inside public
|
||||
const path = "./public" + reqPath;
|
||||
const file = Bun.file(path);
|
||||
if (await file.exists()) {
|
||||
// Cache indefinitely except index.html
|
||||
const headers: Record<string, string> = {};
|
||||
if (!reqPath.endsWith("index.html")) {
|
||||
// Add etag logic or use bun's hashes by only caching files that actually have hashes in them.
|
||||
// Bun generates hashes like chunk-02ahh9r5.js, we can check for that pattern
|
||||
// If we wanted to do ETag we could use Bun.file(path).size + lastModified but hashing is safer
|
||||
const isHashed = reqPath.match(/-[a-zA-Z0-9]{8}\.(js|css)$/);
|
||||
if (isHashed) {
|
||||
headers["Cache-Control"] = "public, max-age=31536000, immutable";
|
||||
} else {
|
||||
headers["Cache-Control"] = "no-cache";
|
||||
}
|
||||
} else {
|
||||
headers["Content-Type"] = "text/html; charset=utf-8";
|
||||
headers["Cache-Control"] = "no-cache";
|
||||
}
|
||||
return new Response(file, { headers });
|
||||
}
|
||||
return Response.json({ ok: false, error: "Not found" }, { status: 404 });
|
||||
},
|
||||
} satisfies Parameters<typeof Bun.serve>[0];
|
||||
|
||||
Reference in New Issue
Block a user