feat(server): scaffold Bun HTTP+WS server with health + logging (P4.1)

This commit is contained in:
Joey Yakimowich-Payne 2026-04-16 17:03:42 -06:00
commit 25695d69b2
No known key found for this signature in database
4 changed files with 59 additions and 1 deletions

View file

@ -11,5 +11,8 @@
"@paratype/rete": "workspace:*",
"pino": "^9.0.0",
"zod": "^3.23.0"
},
"devDependencies": {
"bun-types": "^1.3.12"
}
}

View file

@ -1,2 +1,53 @@
// @paratype/chess-server — authoritative Bun WebSocket server
export {};
import { randomUUID } from "node:crypto";
import { logger } from "./logger.js";
interface ClientData {
clientId: string;
}
const port = parseInt(process.env["PORT"] ?? "7357", 10);
export const server = Bun.serve<ClientData>({
port,
fetch(req, srv) {
const url = new URL(req.url);
if (url.pathname === "/ws") {
const upgraded = srv.upgrade(req, {
data: { clientId: randomUUID() },
});
if (upgraded) return undefined;
return new Response("Upgrade failed", { status: 500 });
}
if (url.pathname === "/healthz") {
return Response.json({ ok: true, version: "1.0.0" });
}
return new Response("Not Found", { status: 404 });
},
websocket: {
open(ws) {
const log = logger.child({ clientId: ws.data.clientId });
log.info("ws connected");
},
message(ws, msg) {
const log = logger.child({ clientId: ws.data.clientId });
const length = typeof msg === "string" ? msg.length : msg.byteLength;
log.info({ length }, "ws message");
},
close(ws, code, reason) {
const log = logger.child({ clientId: ws.data.clientId });
log.info({ code, reason }, "ws closed");
},
},
});
logger.info({ port }, "server started");
process.on("SIGINT", () => {
logger.info("shutting down");
server.stop(true);
process.exit(0);
});

View file

@ -0,0 +1,3 @@
import pino from "pino";
export const logger = pino({ level: process.env["LOG_LEVEL"] ?? "info" });

View file

@ -2,6 +2,7 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"lib": ["ES2022"],
"types": ["bun-types"],
"composite": true,
"outDir": "dist",
"rootDir": "src"