import { getToken } from "./storage"; type MessageListener = (message: any) => void; let activeWebSocket: WebSocket | null = null; let reconnectTimeout: ReturnType | null = null; let listeners: Set = new Set(); let currentConfig: { enableReconnect?: boolean; reconnectDelay?: number } = {}; function connectWebSocket(): WebSocket | null { const token = getToken(); if (!token) { return null; } if (activeWebSocket) { return activeWebSocket; } const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const wsUrl = `${protocol}//${window.location.host}/ws/sync?token=${token}`; const ws = new WebSocket(wsUrl); ws.onopen = () => { console.log("WebSocket connected"); }; ws.onmessage = (event: MessageEvent) => { try { const message = JSON.parse(event.data); listeners.forEach((listener) => { try { listener(message); } catch (error) { console.error("Error in WebSocket listener:", error); } }); } catch (error) { console.error("Error parsing WebSocket message:", error); } }; ws.onerror = (error: Event) => { console.error("WebSocket error:", error); }; ws.onclose = () => { console.log("WebSocket disconnected"); activeWebSocket = null; if (currentConfig.enableReconnect !== false) { const delay = currentConfig.reconnectDelay || 5000; console.log(`Reconnecting in ${delay / 1000}s...`); reconnectTimeout = setTimeout(() => { connectWebSocket(); }, delay); } }; activeWebSocket = ws; return ws; } function addListener(listener: MessageListener): void { listeners.add(listener); if (!activeWebSocket) { connectWebSocket(); } } function removeListener(listener: MessageListener): void { listeners.delete(listener); if (listeners.size === 0) { disconnectWebSocket(); } } function disconnectWebSocket(): void { if (reconnectTimeout) { clearTimeout(reconnectTimeout); reconnectTimeout = null; } if (activeWebSocket) { activeWebSocket.close(); activeWebSocket = null; } } function createWebSocket(config: { onMessage: (data: any) => void; onOpen?: () => void; onClose?: () => void; onError?: (error: Event) => void; enableReconnect?: boolean; reconnectDelay?: number; }): WebSocket | null { currentConfig = config; const listener: MessageListener = (message) => { config.onMessage(message); }; listeners.add(listener); if (activeWebSocket) { activeWebSocket.close(); activeWebSocket = null; } const ws = connectWebSocket(); if (ws && config.onOpen) { if (ws.readyState === WebSocket.OPEN) { config.onOpen(); } else { ws.addEventListener("open", () => config.onOpen?.(), { once: true }); } } return ws; } export { addListener, createWebSocket, disconnectWebSocket, removeListener, };