Stream each task's transcript over its own SSE; keep session note order
This commit is contained in:
Vendored
+32
-28
@@ -1,4 +1,4 @@
|
||||
import { get } from "./api.js";
|
||||
import { get, subscribe } from "./api.js";
|
||||
export const state = {
|
||||
me: undefined,
|
||||
projects: [],
|
||||
@@ -71,7 +71,9 @@ export async function loadInbox() {
|
||||
state.inbox = await get("/api/inbox");
|
||||
notify("inbox");
|
||||
}
|
||||
let liveDuringLoad;
|
||||
let closeTaskStream;
|
||||
let taskBuffer = [];
|
||||
let taskFlush = 0;
|
||||
const visitsKey = "byre.visits";
|
||||
export function lastVisits() {
|
||||
return JSON.parse(localStorage.getItem(visitsKey) ?? "{}");
|
||||
@@ -82,31 +84,44 @@ function markVisited(taskId) {
|
||||
}
|
||||
localStorage.setItem(visitsKey, JSON.stringify({ ...lastVisits(), [taskId]: Date.now() }));
|
||||
}
|
||||
export async function selectTask(taskId) {
|
||||
export function selectTask(taskId) {
|
||||
markVisited(state.selectedTaskId);
|
||||
markVisited(taskId);
|
||||
closeTaskStream?.();
|
||||
closeTaskStream = undefined;
|
||||
clearTimeout(taskFlush);
|
||||
taskFlush = 0;
|
||||
taskBuffer = [];
|
||||
state.selectedTaskId = taskId;
|
||||
state.transcript = [];
|
||||
state.lastTranscriptSeq = 0;
|
||||
liveDuringLoad = undefined;
|
||||
notify("selection");
|
||||
if (!taskId) {
|
||||
return;
|
||||
}
|
||||
const held = [];
|
||||
liveDuringLoad = held;
|
||||
for (;;) {
|
||||
const page = await get("/api/tasks/{taskId}/events", { path: { taskId }, query: { after: state.lastTranscriptSeq, limit: 1000 } });
|
||||
if (state.selectedTaskId !== taskId || liveDuringLoad !== held) {
|
||||
return;
|
||||
}
|
||||
appendTranscript(page);
|
||||
if (page.length < 1000) {
|
||||
break;
|
||||
}
|
||||
closeTaskStream = subscribe(0, taskId, queueTaskEvent, () => undefined);
|
||||
}
|
||||
function queueTaskEvent(ev) {
|
||||
taskBuffer.push(ev);
|
||||
if (!taskFlush) {
|
||||
taskFlush = setTimeout(flushTaskEvents, 0);
|
||||
}
|
||||
liveDuringLoad = undefined;
|
||||
appendTranscript(held);
|
||||
}
|
||||
function flushTaskEvents() {
|
||||
const events = taskBuffer;
|
||||
taskBuffer = [];
|
||||
taskFlush = 0;
|
||||
let stored = [];
|
||||
for (const ev of events) {
|
||||
if (ev.seq !== 0) {
|
||||
stored.push(ev);
|
||||
continue;
|
||||
}
|
||||
appendTranscript(stored);
|
||||
stored = [];
|
||||
notify("stream", ev);
|
||||
}
|
||||
appendTranscript(stored);
|
||||
}
|
||||
function appendTranscript(events) {
|
||||
const fresh = events.filter((ev) => ev.seq > state.lastTranscriptSeq);
|
||||
@@ -119,20 +134,9 @@ function appendTranscript(events) {
|
||||
}
|
||||
export function handleEvent(ev) {
|
||||
if (ev.seq === 0) {
|
||||
if (ev.task_id && ev.task_id === state.selectedTaskId && !liveDuringLoad) {
|
||||
notify("stream", ev);
|
||||
}
|
||||
notify("event", ev);
|
||||
return;
|
||||
}
|
||||
if (ev.task_id && ev.task_id === state.selectedTaskId) {
|
||||
if (liveDuringLoad) {
|
||||
liveDuringLoad.push(ev);
|
||||
}
|
||||
else {
|
||||
appendTranscript([ev]);
|
||||
}
|
||||
}
|
||||
switch (ev.kind) {
|
||||
case "user.updated":
|
||||
if (ev.payload["login"] === state.me?.login) {
|
||||
|
||||
Reference in New Issue
Block a user