Something went wrong. Try again.
Something went wrong. Try again.
codebeam-eu-2026 serve.mjs
2.4 kB · 76 lines
JavaScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#!/usr/bin/env node/* Zero-dependency static server. Markdown slides are fetched over HTTP, so file:// will not work.
Serves this directory by default; pass a path (or set DECK_ROOT) to serve somewhere else, e.g. the `nix build` output. */
import { createReadStream } from "node:fs";import { stat } from "node:fs/promises";import { createServer } from "node:http";import { extname, join, normalize, resolve, sep } from "node:path";
const ROOT = resolve(process.argv[2] ?? process.env.DECK_ROOT ?? import.meta.dirname);const PORT = Number(process.env.PORT ?? 8000);
const MIME = { ".css": "text/css; charset=utf-8", ".html": "text/html; charset=utf-8", ".jpg": "image/jpeg", ".js": "text/javascript; charset=utf-8", ".json": "application/json; charset=utf-8", ".map": "application/json; charset=utf-8", ".md": "text/markdown; charset=utf-8", ".mov": "video/quicktime", ".mp4": "video/mp4", ".png": "image/png", ".svg": "image/svg+xml", ".webp": "image/webp", ".woff2": "font/woff2",};
const server = createServer(async (req, res) => { const url = new URL(req.url, `http://localhost:${PORT}`); let path = join(ROOT, normalize(decodeURIComponent(url.pathname)));
if (path !== ROOT && !path.startsWith(ROOT + sep)) { res.writeHead(403).end("Forbidden"); return; }
try { const info = await stat(path); if (info.isDirectory()) path = join(path, "index.html"); const { size } = await stat(path);
const headers = { "Accept-Ranges": "bytes", "Cache-Control": "no-store", "Content-Type": MIME[extname(path)] ?? "application/octet-stream", };
// Video seeking needs range support const range = /^bytes=(\d*)-(\d*)$/.exec(req.headers.range ?? ""); if (range) { const start = range[1] ? Number(range[1]) : 0; const end = range[2] ? Number(range[2]) : size - 1; res.writeHead(206, { ...headers, "Content-Length": end - start + 1, "Content-Range": `bytes ${start}-${end}/${size}`, }); createReadStream(path, { start, end }).pipe(res); return; }
res.writeHead(200, { ...headers, "Content-Length": size }); createReadStream(path).pipe(res); } catch { res.writeHead(404).end("Not found"); }});
server.listen(PORT, () => { console.log(`Slides: http://localhost:${PORT}`); console.log(`Notes: press S for the speaker view`);});