import { useEffect, useLayoutEffect, useRef } from "react"; import ReconnectingEventSource from "reconnecting-eventsource"; import { devlog } from "../utils"; export function useSSESubscription({ enabled = true, url, onNewData, onDisconnect, marker = "" }: { enabled?: boolean; url: string; onNewData: (data: T[]) => void; onDisconnect?: () => void; marker?: string; }) { 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 { console.log("EVENT") console.log(event) const newData = JSON.parse(event.data) as T; if (!(typeof newData === "object" && newData !== null && "event" in newData && newData.event === "ping")) { 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]); }