Spaces:
Sleeping
Sleeping
| export type ProgressState = | |
| | { phase: "idle" } | |
| | { | |
| phase: "running"; | |
| kind: "single" | "dialog"; | |
| turn: number; | |
| total: number; | |
| elapsedS: number; | |
| } | |
| | { phase: "done"; elapsedS: number } | |
| | { phase: "error"; message: string }; | |
| type ProgressEvent = { | |
| type: "start" | "tick" | "turn_complete" | "done" | "error"; | |
| elapsed_s: number; | |
| kind?: "single" | "dialog"; | |
| turn?: number; | |
| total_turns?: number; | |
| message?: string; | |
| seed_used?: number | null; | |
| }; | |
| export function subscribeProgress( | |
| onState: (s: ProgressState) => void, | |
| ): () => void { | |
| const es = new EventSource("/api/progress"); | |
| let doneTimer: number | null = null; | |
| es.onmessage = (m: MessageEvent) => { | |
| if (doneTimer !== null) { | |
| window.clearTimeout(doneTimer); | |
| doneTimer = null; | |
| } | |
| let evt: ProgressEvent; | |
| try { | |
| evt = JSON.parse(m.data) as ProgressEvent; | |
| } catch { | |
| return; | |
| } | |
| if (evt.type === "start" || evt.type === "tick" || evt.type === "turn_complete") { | |
| onState({ | |
| phase: "running", | |
| kind: (evt.kind ?? "single"), | |
| turn: evt.turn ?? 0, | |
| total: evt.total_turns ?? 1, | |
| elapsedS: evt.elapsed_s ?? 0, | |
| }); | |
| return; | |
| } | |
| if (evt.type === "done") { | |
| onState({ phase: "done", elapsedS: evt.elapsed_s }); | |
| doneTimer = window.setTimeout(() => onState({ phase: "idle" }), 1000); | |
| return; | |
| } | |
| if (evt.type === "error") { | |
| onState({ phase: "error", message: evt.message ?? "Generation failed" }); | |
| } | |
| }; | |
| return () => { | |
| if (doneTimer !== null) window.clearTimeout(doneTimer); | |
| es.close(); | |
| }; | |
| } | |
| import { useEffect, useState } from "react"; | |
| export function useProgress(): ProgressState { | |
| const [state, setState] = useState<ProgressState>({ phase: "idle" }); | |
| useEffect(() => { | |
| const close = subscribeProgress(setState); | |
| return close; | |
| }, []); | |
| return state; | |
| } | |