master
AdityaAngajala Publish 0.3.0 6d39e2e 2mo ago
// Static server for the occupancy-grid ("classic") engine demo.
// Separate from server.js so the two demo deployments can't interfere.
//
//   node serve-classic.mjs            # port 8930
//   CLASSIC_PORT=9000 node serve-classic.mjs

import { createReadStream, statSync } from "node:fs";
import { createServer } from "node:http";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const directory = dirname(fileURLToPath(import.meta.url));
const port = Number.parseInt(process.env.CLASSIC_PORT || "8930", 10);
const files = new Map([
  ["/", ["index-classic.html", "text/html; charset=utf-8"]],
  ["/index.html", ["index-classic.html", "text/html; charset=utf-8"]],
  ["/circuit-background.js", ["circuit-background.js", "text/javascript; charset=utf-8"]],
  // Reveal demo: same board, grown in instead of appearing whole. Kept on
  // its own page + engine copy so the classic demo above stays untouched.
  ["/reveal", ["index-reveal.html", "text/html; charset=utf-8"]],
  ["/reveal.html", ["index-reveal.html", "text/html; charset=utf-8"]],
  [
    "/circuit-background-reveal.js",
    ["circuit-background-reveal.js", "text/javascript; charset=utf-8"],
  ],
]);

function headers(contentType) {
  return {
    "Content-Type": contentType,
    "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
    Pragma: "no-cache",
    "Surrogate-Control": "no-store",
    "X-Content-Type-Options": "nosniff",
  };
}

const server = createServer((request, response) => {
  const url = new URL(request.url || "/", `http://${request.headers.host || "localhost"}`);

  if (url.pathname === "/health") {
    response.writeHead(200, headers("application/json; charset=utf-8"));
    response.end(
      JSON.stringify({ ok: true, service: "circuit-generator-classic", uptime: process.uptime() }),
    );
    return;
  }

  const match = files.get(url.pathname);
  if (!match) {
    response.writeHead(404, headers("text/plain; charset=utf-8"));
    response.end("Not found\n");
    return;
  }

  const [filename, contentType] = match;
  const path = join(directory, filename);
  const size = statSync(path).size;
  response.writeHead(200, { ...headers(contentType), "Content-Length": size });
  if (request.method === "HEAD") {
    response.end();
    return;
  }
  createReadStream(path).pipe(response);
});

server.listen(port, "0.0.0.0", () => {
  console.log(`[circuit-generator-classic] listening on http://0.0.0.0:${port}`);
});