import { useEffect, useRef, useState, useCallback } from "react"; import { getApi } from "./useApi"; interface ItemSseHandlers { onEvent: (data: any) => void; onOpen?: () => void; onError?: (evt: Event) => void; } interface ItemSseResult { connected: boolean; events: any[]; } export function useItemSse(url: string | null, handlers: ItemSseHandlers): ItemSseResult { const [connected, setConnected] = useState(false); const [events, setEvents] = useState([]); const handlersRef = useRef(handlers); handlersRef.current = handlers; useEffect(() => { if (!url) return; const api = getApi(); const baseUrl = (api.defaults.baseURL ?? "").replace(/\/+$/, ""); const fullUrl = baseUrl + url; const es = new EventSource(fullUrl); es.onopen = () => { setConnected(true); handlersRef.current.onOpen?.(); }; es.onmessage = (e) => { try { const data = JSON.parse(e.data); setEvents((prev) => [...prev, data]); handlersRef.current.onEvent(data); } catch { // ignore malformed JSON } }; es.onerror = (e) => { setConnected(false); handlersRef.current.onError?.(e); }; return () => { es.close(); setConnected(false); }; }, [url]); const clearEvents = useCallback(() => setEvents([]), []); return { connected, events }; }