import { getToken } from "./storage"; interface WebSocketConfig { onMessage: (data: any) => void; onOpen?: () => void; onClose?: () => void; onError?: (error: Event) => void; enableReconnect?: boolean; reconnectDelay?: number; } let activeWebSocket: WebSocket | null = null; let reconnectTimeout: ReturnType | null = null; function createWebSocket(config: WebSocketConfig): WebSocket | null { const token = getToken(); if (!token) { console.warn( "No authentication token found - skipping WebSocket connection", ); return null; } // Clean up existing connection if (activeWebSocket) { activeWebSocket.close(); } if (reconnectTimeout) { clearTimeout(reconnectTimeout); reconnectTimeout = null; } 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"); if (config.onOpen) { try { config.onOpen(); } catch (error) { console.error("Error in onOpen callback:", error); } } }; ws.onmessage = (event: MessageEvent) => { try { const message = JSON.parse(event.data); config.onMessage(message); } catch (error) { console.error("Error parsing WebSocket message:", error); console.error("Raw message:", event.data); } }; ws.onerror = (error: Event) => { console.error("WebSocket error:", error); if (config.onError) { try { config.onError(error); } catch (err) { console.error("Error in onError callback:", err); } } }; ws.onclose = () => { console.log("WebSocket disconnected"); if (config.onClose) { try { config.onClose(); } catch (error) { console.error("Error in onClose callback:", error); } } // Auto-reconnect if enabled if (config.enableReconnect !== false) { const delay = config.reconnectDelay || 5000; console.log(`Reconnecting in ${delay / 1000}s...`); reconnectTimeout = setTimeout(() => { createWebSocket(config); }, delay); } }; activeWebSocket = ws; return ws; } function disconnectWebSocket(): void { if (reconnectTimeout) { clearTimeout(reconnectTimeout); reconnectTimeout = null; } if (activeWebSocket) { activeWebSocket.close(); activeWebSocket = null; } } export { createWebSocket, disconnectWebSocket };