Files
ThothII/frontend/src/stream/useSessionStream.ts
T

41 lines
1.3 KiB
TypeScript

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 };
}