summaryrefslogtreecommitdiffhomepage
path: root/scripts/probe-replay.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-10 01:36:39 +0900
committerAdam Malczewski <[email protected]>2026-10-10 01:36:39 +0900
commit551a7a050e8cd25e795026a1060c9d5b5ea028bf (patch)
treecba29eb5ada26778c09aea7cc767e2ddf665bce8 /scripts/probe-replay.ts
parentd8381e201cb1407a939b496642a0803aec58a47d (diff)
downloaddispatch-web-551a7a050e8cd25e795026a1060c9d5b5ea028bf.tar.gz
dispatch-web-551a7a050e8cd25e795026a1060c9d5b5ea028bf.zip
perf(chat): fast open of long in-flight turns
- Batch live chat events: fold a burst in one pass per animation frame (rAF + timeout fallback for hidden tabs) instead of one reactive cycle per WS frame. Flushed before send/resync to keep ordering. - De-dup the late-join replay against committed history: provisional chunks of the in-flight turn already persisted (CR-6 per-step persistence) are hidden by aligned-prefix matching (fail-safe: mismatch shows, never hides). - Memoize chunks/turnMetrics getters by state identity. - LazyCollapse: tool/thinking card bodies mount only on first open. - content-visibility:auto on transcript rows. - scripts/probe-replay.ts + bench-pure.ts for measuring the replay path.
Diffstat (limited to 'scripts/probe-replay.ts')
-rw-r--r--scripts/probe-replay.ts36
1 files changed, 36 insertions, 0 deletions
diff --git a/scripts/probe-replay.ts b/scripts/probe-replay.ts
new file mode 100644
index 0000000..8a7faf9
--- /dev/null
+++ b/scripts/probe-replay.ts
@@ -0,0 +1,36 @@
+/**
+ * Probe: subscribe to a conversation over WS, capture the late-join replay,
+ * and report event counts / bytes / time-to-receive. Saves to /tmp/replay-<id>.json.
+ * bun scripts/probe-replay.ts <conversationId> [wsUrl]
+ */
+const conv = process.argv[2];
+const url = process.argv[3] ?? "ws://localhost:24990";
+if (!conv) throw new Error("conversation id required");
+
+const ws = new WebSocket(url);
+const events: unknown[] = [];
+let bytes = 0;
+let t0 = 0;
+let lastAt = 0;
+ws.onopen = () => {
+ t0 = performance.now();
+ ws.send(JSON.stringify({ type: "chat.subscribe", conversationId: conv }));
+};
+ws.onmessage = (ev) => {
+ const s = String(ev.data);
+ const m = JSON.parse(s);
+ if (m.type !== "chat.delta") return;
+ bytes += s.length;
+ lastAt = performance.now();
+ events.push(m.event);
+};
+setTimeout(
+ async () => {
+ ws.close();
+ const counts: Record<string, number> = {};
+ for (const e of events as { type: string }[]) counts[e.type] = (counts[e.type] ?? 0) + 1;
+ console.log({ events: events.length, bytes, recvMs: Math.round(lastAt - t0), counts });
+ await Bun.write(`/tmp/replay-${conv}.json`, JSON.stringify(events));
+ },
+ Number(process.env.WAIT_MS ?? 3000),
+);