import { useEffect, useRef, useCallback } from 'react'; import { wsUrl } from '../api/client'; import type { WSMessage } from '../types'; type MessageHandler = (msg: WSMessage) => void; export function useWebSocket(onMessage: MessageHandler) { const wsRef = useRef(null); const reconnectTimer = useRef(0); const onMessageRef = useRef(onMessage); onMessageRef.current = onMessage; const connect = useCallback(() => { if (wsRef.current?.readyState === WebSocket.OPEN) return; const ws = new WebSocket(wsUrl()); wsRef.current = ws; ws.addEventListener('message', (evt) => { try { const msg = JSON.parse(evt.data) as WSMessage; onMessageRef.current(msg); } catch { /* ignore parse errors */ } }); ws.addEventListener('close', () => { wsRef.current = null; reconnectTimer.current = window.setTimeout(connect, 2000); }); ws.addEventListener('error', () => { ws.close(); }); }, []); useEffect(() => { connect(); return () => { clearTimeout(reconnectTimer.current); wsRef.current?.close(); wsRef.current = null; }; }, [connect]); }