import { Server as SocketIOServer, Socket } from "socket.io"; import type { Server as HTTPServer } from "http"; // Socket event types interface ServerToClientEvents { "test-message": (data: { originalMessage: any; serverResponse: string; serverTimestamp: string; socketId: string; }) => void; "pick-made": (data: any) => void; "draft-started": (data: { seasonId: string; currentPickNumber: number }) => void; "draft-completed": () => void; "timer-update": (data: { seasonId: string; teamId: string; timeRemaining: number; currentPickNumber: number; }) => void; } interface ClientToServerEvents { "join-draft": (seasonId: string) => void; "leave-draft": (seasonId: string) => void; "test-event": (data: any) => void; } // Global type augmentation declare global { var __socketIO: SocketIOServer | undefined; } let io: SocketIOServer | null = null; /** * Initialize Socket.IO server */ export function initializeSocketIO(httpServer: HTTPServer): SocketIOServer { if (io) { console.log("Socket.IO already initialized"); return io; } // Create typed Socket.IO server io = new SocketIOServer(httpServer, { cors: process.env.NODE_ENV === "production" && process.env.APP_URL ? { origin: process.env.APP_URL, credentials: true, } : undefined, }); // Connection handling io.on("connection", (socket: Socket) => { console.log("Client connected:", socket.id); socket.on("join-draft", (seasonId: string) => { if (!seasonId) { console.error("No seasonId provided for join-draft"); return; } socket.join(`draft-${seasonId}`); console.log(`Socket ${socket.id} joined draft-${seasonId}`); }); socket.on("leave-draft", (seasonId: string) => { if (!seasonId) return; socket.leave(`draft-${seasonId}`); console.log(`Socket ${socket.id} left draft-${seasonId}`); }); socket.on("test-event", (data: any) => { console.log("📨 Received test-event from client:", socket.id, data); socket.emit("test-message", { originalMessage: data, serverResponse: "Hello from server!", serverTimestamp: new Date().toISOString(), socketId: socket.id, }); console.log("✅ Sent test-message response to client:", socket.id); }); socket.on("disconnect", () => { console.log("Client disconnected:", socket.id); }); }); // Store globally for route handlers global.__socketIO = io; console.log("Socket.IO initialized"); // Start the draft timer system (async import but don't await) import("./timer").then(({ startDraftTimerSystem }) => { startDraftTimerSystem(); }).catch((error) => { console.error("Failed to start timer system:", error); }); return io; } /** * Get the Socket.IO server instance */ export function getSocketIO(): SocketIOServer { const instance = io || global.__socketIO; if (!instance) { throw new Error("Socket.IO not initialized. Call initializeSocketIO first."); } return instance; }