chunker and ui
This commit is contained in:
81
ui/chunker/src/hooks/useEventStream.ts
Normal file
81
ui/chunker/src/hooks/useEventStream.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { PipelineEvent } from "../types";
|
||||
|
||||
/**
|
||||
* SSE hook — connects to /api/chunker/stream/{jobId} via native EventSource.
|
||||
*
|
||||
* Demonstrates: real-time event streaming from backend to UI.
|
||||
*/
|
||||
export function useEventStream(jobId: string | null) {
|
||||
const [events, setEvents] = useState<PipelineEvent[]>([]);
|
||||
const [connected, setConnected] = useState(false);
|
||||
const [done, setDone] = useState(false);
|
||||
const esRef = useRef<EventSource | null>(null);
|
||||
|
||||
const close = useCallback(() => {
|
||||
if (esRef.current) {
|
||||
esRef.current.close();
|
||||
esRef.current = null;
|
||||
setConnected(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!jobId) return;
|
||||
|
||||
setEvents([]);
|
||||
setDone(false);
|
||||
|
||||
const es = new EventSource(`/api/chunker/stream/${jobId}`);
|
||||
esRef.current = es;
|
||||
|
||||
es.onopen = () => setConnected(true);
|
||||
es.onerror = () => setConnected(false);
|
||||
|
||||
const handleEvent = (eventType: string) => (e: MessageEvent) => {
|
||||
try {
|
||||
const data = JSON.parse(e.data) as PipelineEvent;
|
||||
setEvents((prev) => [...prev, { ...data, status: eventType }]);
|
||||
} catch {
|
||||
// ignore parse errors
|
||||
}
|
||||
};
|
||||
|
||||
// Listen to all chunker event types
|
||||
const eventTypes = [
|
||||
"waiting",
|
||||
"pending",
|
||||
"chunking",
|
||||
"processing",
|
||||
"collecting",
|
||||
"completed",
|
||||
"failed",
|
||||
"cancelled",
|
||||
"done",
|
||||
"timeout",
|
||||
];
|
||||
|
||||
for (const type of eventTypes) {
|
||||
es.addEventListener(type, handleEvent(type));
|
||||
}
|
||||
|
||||
es.addEventListener("done", () => {
|
||||
setDone(true);
|
||||
es.close();
|
||||
setConnected(false);
|
||||
});
|
||||
|
||||
es.addEventListener("timeout", () => {
|
||||
setDone(true);
|
||||
es.close();
|
||||
setConnected(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
es.close();
|
||||
esRef.current = null;
|
||||
};
|
||||
}, [jobId]);
|
||||
|
||||
return { events, connected, done, close };
|
||||
}
|
||||
Reference in New Issue
Block a user