import { useEffect, useLayoutEffect, useRef } from "react"; import ReconnectingEventSource from "reconnecting-eventsource"; import { devlog } from "../utils"; export function useSSESubscription({ enabled = true, url, onNewData, onDisconnect, marker = "", consolelog = false }: { enabled?: boolean; url: string; onNewData: (data: T[]) => void; onDisconnect?: () => void; marker?: string; consolelog?: boolean; }) { const onNewDataRef = useRef(onNewData); const onDisconnectRef = useRef(onDisconnect); useLayoutEffect(() => { onNewDataRef.current = onNewData; onDisconnectRef.current = onDisconnect; }, [onNewData, onDisconnect]); useEffect(() => { if (!enabled) return; const eventSource = new ReconnectingEventSource(url); eventSource.addEventListener("open", () => devlog(`EventSource connected with ${url}`)); eventSource.addEventListener("close", () => devlog(`EventSource closed with ${url}`)); eventSource.addEventListener("message", event => { try { if (consolelog) console.log(event); const newData = JSON.parse(event.data) as T; devlog(`new SSE: ${marker}`, newData); onNewDataRef.current([newData]); } catch (error) { devlog(`SSE parsing error: ${marker}`, event.data, error); } }); eventSource.addEventListener("error", event => { devlog("SSE Error:", event); }); return () => { eventSource.close(); onDisconnectRef.current?.(); }; }, [enabled, marker, url]); }