feat: add Express + WebSocket server entry point

This commit is contained in:
plenarius
2026-04-20 18:25:10 -04:00
parent 55a49134ee
commit 421d591c1e
2 changed files with 80 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
import express from "express";
import cors from "cors";
import { createServer } from "http";
import path from "path";
import { fileURLToPath } from "url";
import { initWebSocket, getClientCount } from "./services/ws.service.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const app = express();
const server = createServer(app);
app.use(cors());
app.use(express.json());
initWebSocket(server);
app.get("/api/health", (_req, res) => {
res.json({
status: "ok",
wsClients: getClientCount(),
uptime: process.uptime(),
});
});
const frontendDist = path.resolve(__dirname, "../../frontend/dist");
app.use(express.static(frontendDist));
app.get("*path", (_req, res) => {
res.sendFile(path.join(frontendDist, "index.html"));
});
const PORT = parseInt(process.env.PORT || "3000", 10);
server.listen(PORT, "0.0.0.0", () => {
console.log(`Layonara Forge listening on http://0.0.0.0:${PORT}`);
});
@@ -0,0 +1,46 @@
import { WebSocketServer, WebSocket } from "ws";
import type { Server } from "http";
type EventType = "docker" | "build" | "log" | "toolset" | "git";
interface ForgeEvent {
type: EventType;
action: string;
data: unknown;
timestamp: number;
}
const clients = new Set<WebSocket>();
let wss: WebSocketServer;
export function initWebSocket(server: Server): WebSocketServer {
wss = new WebSocketServer({ server, path: "/ws" });
wss.on("connection", (ws) => {
clients.add(ws);
ws.on("close", () => clients.delete(ws));
ws.on("error", () => clients.delete(ws));
});
return wss;
}
export function broadcast(type: EventType, action: string, data: unknown): void {
const event: ForgeEvent = {
type,
action,
data,
timestamp: Date.now(),
};
const message = JSON.stringify(event);
for (const client of clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
}
}
export function getClientCount(): number {
return clients.size;
}