/** * Custom Next.js server with integrated Socket.IO. * Runs everything in a single process — ideal for HF Spaces / Docker. */ import { createServer } from "http"; import next from "next"; import { Server as SocketIOServer } from "socket.io"; const PORT = parseInt(process.env.PORT || "7860", 10); const dev = process.env.NODE_ENV !== "production"; const app = next({ dev }); const handle = app.getRequestHandler(); export interface AgentEvent { type: | "scan_start" | "scan_complete" | "deal_found" | "deal_analyzed" | "negotiation_update" | "transaction_update" | "queue_update" | "error" | "status_change"; data: Record; timestamp: string; } let io: SocketIOServer | null = null; export function emitAgentEvent(event: AgentEvent): void { if (io) { io.emit("agent_event", { ...event, timestamp: event.timestamp || new Date().toISOString(), }); } } export function getIo(): SocketIOServer | null { return io; } app.prepare().then(() => { const httpServer = createServer((req, res) => { // Let Next.js handle all HTTP requests handle(req, res); }); // Initialize Socket.IO on the same server io = new SocketIOServer(httpServer, { cors: { origin: "*", methods: ["GET", "POST"], }, pingTimeout: 60000, pingInterval: 25000, }); io.on("connection", (socket) => { console.log(`[WS] Client connected: ${socket.id}`); socket.emit("connected", { clientId: socket.id, timestamp: new Date().toISOString(), }); socket.on("subscribe", (room: string) => { socket.join(room); }); socket.on("agent_command", (command: { action: string; payload?: unknown }) => { console.log(`[WS] Command from ${socket.id}:`, command); io?.emit("agent_command_ack", { command, received: new Date().toISOString(), }); }); socket.on("disconnect", () => { console.log(`[WS] Client disconnected: ${socket.id}`); }); }); httpServer.listen(PORT, () => { console.log(`> Ready on http://localhost:${PORT}`); console.log(`> WebSocket integrated on same port`); }); });