diff options
| author | Adam Malczewski <[email protected]> | 2026-10-15 10:17:38 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-10-15 10:17:38 +0900 |
| commit | ec31c045139d5ed30801cdba9868133288797659 (patch) | |
| tree | 132fd2b42fb9c9e35ec449a6c6f8ebcd93b4c30e | |
| parent | 307fe78c38b3f06cd34d5032cda40f5876801bb4 (diff) | |
| download | dispatch-web-ec31c045139d5ed30801cdba9868133288797659.tar.gz dispatch-web-ec31c045139d5ed30801cdba9868133288797659.zip | |
chore(scripts): add tab render-path probe for PII_REDACTED_CONVERSATION_SHORT_01 (lint-clean)
| -rw-r--r-- | scripts/probe-tab-PII_REDACTED_CONVERSATION_SHORT_01.ts | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/scripts/probe-tab-PII_REDACTED_CONVERSATION_SHORT_01.ts b/scripts/probe-tab-PII_REDACTED_CONVERSATION_SHORT_01.ts new file mode 100644 index 0000000..7e2fad7 --- /dev/null +++ b/scripts/probe-tab-PII_REDACTED_CONVERSATION_SHORT_01.ts @@ -0,0 +1,105 @@ +/** + * Focused probe: load conversation PII_REDACTED_CONVERSATION_SHORT_01 through the FE's REAL pure modules + * and see whether the tab's render path would throw. Not part of the test suite. + * + * bun scripts/probe-tab-PII_REDACTED_CONVERSATION_SHORT_01.ts + */ +import "fake-indexeddb/auto"; +import type { + ConversationHistoryResponse, + ConversationMetricsResponse, +} from "@dispatch/transport-contract"; +import { + applyHistory, + groupRenderedChunks, + initialState, + selectChunks, + selectMessages, +} from "../src/core/chunks/index.ts"; +import { + applyDurableMetrics, + initialMetricsState, + selectOrderedTurnMetrics, +} from "../src/core/metrics/index.ts"; + +const HTTP_BASE = process.env.PROBE_HTTP ?? "http://localhost:24991"; +const CONV = "PII_REDACTED_CONVERSATION_01"; + +async function historySync(id: string, sinceSeq: number): Promise<ConversationHistoryResponse> { + const url = `${HTTP_BASE}/conversations/${encodeURIComponent(id)}?sinceSeq=${sinceSeq}`; + const res = await fetch(url, { headers: { Origin: "http://localhost:24204" } }); + if (!res.ok) throw new Error(`history fetch ${res.status} for ${url}`); + return (await res.json()) as ConversationHistoryResponse; +} + +async function metricsSync(id: string): Promise<ConversationMetricsResponse> { + const res = await fetch(`${HTTP_BASE}/conversations/${encodeURIComponent(id)}/metrics`, { + headers: { Origin: "http://localhost:24204" }, + }); + if (!res.ok) throw new Error(`metrics fetch ${res.status}`); + return (await res.json()) as ConversationMetricsResponse; +} + +let failures = 0; +const record = (name: string, ok: boolean, detail?: string) => { + if (!ok) failures += 1; + console.log(` ${ok ? "OK" : "FAIL"} ${name}${detail ? ` — ${detail}` : ""}`); +}; + +console.log(`Probing conversation ${CONV} via ${HTTP_BASE}`); + +// 1. applyHistory (the tab's cold-load path) +try { + const hist = await historySync(CONV, 0); + const chunks = hist.chunks ?? []; + console.log(` history: ${chunks.length} chunks, latestSeq=${hist.latestSeq}`); + let state = initialState(); + try { + state = applyHistory(state, chunks as never); + record("applyHistory(145 chunks)", true, `state=${JSON.stringify(state).length} bytes`); + } catch (e) { + record("applyHistory", false, String(e)); + } + + // 2. selectMessages / selectChunks — what the transcript renders + try { + const messages = selectMessages(state); + record("selectMessages", true, `${messages.length} messages`); + } catch (e) { + record("selectMessages", false, String(e)); + } + + // 3. groupRenderedChunks — the render grouping + try { + const grouped = groupRenderedChunks(selectChunks(state)); + record("groupRenderedChunks", true, `${grouped.length} groups`); + } catch (e) { + record("groupRenderedChunks", false, String(e)); + } +} catch (e) { + record("history load", false, String(e)); +} + +// 4. metrics path +try { + const m = await metricsSync(CONV); + let ms = initialMetricsState(); + const turns = (m as { turns?: unknown[] }).turns ?? []; + try { + ms = applyDurableMetrics(ms, turns as never); + } catch (e) { + failures += 1; + console.log(` FAIL applyDurableMetrics — ${String(e)}`); + } + const ordered = selectOrderedTurnMetrics(ms); + record( + "metrics fold+apply", + true, + `${ordered.length} ordered turn metrics (${turns.length} turns)`, + ); +} catch (e) { + record("metrics load", false, String(e)); +} + +console.log(failures === 0 ? "\nALL OK — tab render path is clean." : `\n${failures} FAILURE(S).`); +process.exit(failures === 0 ? 0 : 1); |
