import { useEffect, useState } from "react"; import { BASE } from "../api/client"; import { joinBackendPath } from "../api/runtime-config"; import { useSessionStore } from "../store/sessionStore"; import type { StreamEvent } from "../api/types"; export function useSessionStream(sessionId: string | null) { const [connected, setConnected] = useState(false); const applyEvent = useSessionStore((s) => s.applyEvent); useEffect(() => { if (!sessionId) return; const es = new EventSource(joinBackendPath(BASE, `/sessions/${sessionId}/events`)); es.onopen = () => setConnected(true); es.onerror = () => setConnected(false); const handle = (ev: MessageEvent) => { try { applyEvent(JSON.parse(ev.data) as StreamEvent); } catch { /* ignore malformed */ } }; // onmessage catches unnamed events; addEventListener catches named events // (the backend sends event: ui_request, event: text_delta, etc.) es.onmessage = handle; const namedEvents = ["ui_request", "text_delta", "info", "system_event"] as const; for (const name of namedEvents) es.addEventListener(name, handle); return () => { for (const name of namedEvents) es.removeEventListener(name, handle); es.close(); setConnected(false); }; }, [sessionId, applyEvent]); return { connected }; }