'use client'; import { useEffect, useCallback, useRef } from 'react'; import { RealtimeEvent, RealtimeMessage } from '@/lib/realtime/events'; type EventHandler = (data: T) => void; export function useRealtime() { const eventSourceRef = useRef(null); const handlersRef = useRef>>(new Map()); useEffect(() => { // Connect to SSE endpoint const eventSource = new EventSource('/api/v1/realtime/events'); eventSourceRef.current = eventSource; eventSource.onmessage = (event) => { try { const message: RealtimeMessage = JSON.parse(event.data); // Skip connection message if ((message as any).type === 'connected') { console.log('[Realtime] Connected'); return; } // Dispatch to handlers const handlers = handlersRef.current.get(message.event); if (handlers) { handlers.forEach(handler => handler(message.data)); } } catch (error) { console.error('[Realtime] Parse error:', error); } }; eventSource.onerror = (error) => { console.error('[Realtime] Connection error:', error); // EventSource will auto-reconnect }; return () => { eventSource.close(); eventSourceRef.current = null; }; }, []); const subscribe = useCallback(( event: RealtimeEvent, handler: EventHandler ): (() => void) => { if (!handlersRef.current.has(event)) { handlersRef.current.set(event, new Set()); } handlersRef.current.get(event)!.add(handler); // Return unsubscribe function return () => { handlersRef.current.get(event)?.delete(handler); }; }, []); return { subscribe }; }