Stream each task's transcript over its own SSE; keep session note order

This commit is contained in:
Ian Gulliver
2026-10-14 23:53:17 -07:00
parent eabfc10c8d
commit 2b4d92e7d5
18 changed files with 304 additions and 191 deletions
+24 -6
View File
@@ -103,7 +103,12 @@ export const del = <P extends PathsWith<"delete">>(path: P, opts?: Options<Op<P,
const staleAfterMs = 40_000;
const retryAfterMs = 2_000;
export function subscribe(after: number, onEvent: (ev: ByreEvent) => void, onState: (connected: boolean) => void): void {
export function subscribe(
after: number,
taskId: string | undefined,
onEvent: (ev: ByreEvent) => void,
onState: (connected: boolean) => void,
): () => void {
let last = after;
let heard = Date.now();
let source: EventSource | undefined;
@@ -113,7 +118,11 @@ export function subscribe(after: number, onEvent: (ev: ByreEvent) => void, onSta
clearTimeout(retry);
source?.close();
heard = Date.now();
const s = new EventSource(`/api/events?after=${last}`);
const query = new URLSearchParams({ after: String(last) });
if (taskId) {
query.set("task_id", taskId);
}
const s = new EventSource(`/api/events?${query}`);
source = s;
s.onopen = () => {
heard = Date.now();
@@ -146,12 +155,21 @@ export function subscribe(after: number, onEvent: (ev: ByreEvent) => void, onSta
connect();
};
setInterval(check, 5_000);
addEventListener("online", connect);
document.addEventListener("visibilitychange", () => {
const onVisible = () => {
if (document.visibilityState === "visible") {
check();
}
});
};
const interval = setInterval(check, 5_000);
addEventListener("online", connect);
document.addEventListener("visibilitychange", onVisible);
connect();
return () => {
clearInterval(interval);
clearTimeout(retry);
removeEventListener("online", connect);
document.removeEventListener("visibilitychange", onVisible);
source?.close();
};
}