summaryrefslogtreecommitdiffhomepage
path: root/src/core/wire/conformance.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-07 00:02:32 +0900
committerAdam Malczewski <[email protected]>2026-06-07 00:02:32 +0900
commit312ed5a9fe0d7f2660a66d61baf429b8e021ffb1 (patch)
treedad46b8b88a6bc5629d50f18912ff944eaef4e95 /src/core/wire/conformance.ts
parenta062045579de1bd0903f0f2c7f3e742162bcb7cc (diff)
downloaddispatch-web-312ed5a9fe0d7f2660a66d61baf429b8e021ffb1.tar.gz
dispatch-web-312ed5a9fe0d7f2660a66d61baf429b8e021ffb1.zip
Slice 2 wave 1: transcript reducer, wire conformance, ws chat, cache core
- core/chunks: the one pure transcript reducer (foldEvent live deltas + applyHistory seq-keyed reconcile + selectChunks/selectMessages); 27 tests - core/wire: FE-side contract-conformance exhaustiveness guards + drift smoke tests over wire/transport-contract unions (§2.9 drift signal); 10 tests - adapters/ws: additively multiplex chat.send/chat.delta/chat.error on the existing surface socket (onChat + widened send); surface API unchanged - features/conversation-cache: pure reconcileCache/nextSinceSeq/selectEvictions + ConversationChunkStore port + injected createConversationCache; 26 tests Verified green: svelte-check 0/0, vitest 169, biome clean, build ok.
Diffstat (limited to 'src/core/wire/conformance.ts')
-rw-r--r--src/core/wire/conformance.ts100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/core/wire/conformance.ts b/src/core/wire/conformance.ts
new file mode 100644
index 0000000..5d75a60
--- /dev/null
+++ b/src/core/wire/conformance.ts
@@ -0,0 +1,100 @@
+import type { WsClientMessage, WsServerMessage } from "@dispatch/transport-contract";
+import type { AgentEvent, Chunk } from "@dispatch/wire";
+
+/**
+ * Compile-time exhaustiveness guard for `AgentEvent.type`.
+ * If a variant is added/removed/renamed in `@dispatch/wire`, this function's
+ * default branch becomes reachable → TypeScript error at build time.
+ */
+export function assertAgentEventExhaustive(event: AgentEvent): string {
+ switch (event.type) {
+ case "status":
+ return "status";
+ case "turn-start":
+ return "turn-start";
+ case "text-delta":
+ return "text-delta";
+ case "reasoning-delta":
+ return "reasoning-delta";
+ case "tool-call":
+ return "tool-call";
+ case "tool-result":
+ return "tool-result";
+ case "tool-output":
+ return "tool-output";
+ case "usage":
+ return "usage";
+ case "error":
+ return "error";
+ case "done":
+ return "done";
+ case "turn-sealed":
+ return "turn-sealed";
+ default:
+ return event satisfies never;
+ }
+}
+
+/**
+ * Compile-time exhaustiveness guard for `Chunk.type`.
+ */
+export function assertChunkExhaustive(chunk: Chunk): string {
+ switch (chunk.type) {
+ case "text":
+ return "text";
+ case "thinking":
+ return "thinking";
+ case "tool-call":
+ return "tool-call";
+ case "tool-result":
+ return "tool-result";
+ case "error":
+ return "error";
+ case "system":
+ return "system";
+ default:
+ return chunk satisfies never;
+ }
+}
+
+/**
+ * Compile-time exhaustiveness guard for `WsServerMessage.type`.
+ * Covers both surface ops and chat ops.
+ */
+export function assertWsServerMessageExhaustive(msg: WsServerMessage): string {
+ switch (msg.type) {
+ case "catalog":
+ return "catalog";
+ case "surface":
+ return "surface";
+ case "update":
+ return "update";
+ case "error":
+ return "error";
+ case "chat.delta":
+ return "chat.delta";
+ case "chat.error":
+ return "chat.error";
+ default:
+ return msg satisfies never;
+ }
+}
+
+/**
+ * Compile-time exhaustiveness guard for `WsClientMessage.type`.
+ * Covers both surface ops and chat ops.
+ */
+export function assertWsClientMessageExhaustive(msg: WsClientMessage): string {
+ switch (msg.type) {
+ case "subscribe":
+ return "subscribe";
+ case "unsubscribe":
+ return "unsubscribe";
+ case "invoke":
+ return "invoke";
+ case "chat.send":
+ return "chat.send";
+ default:
+ return msg satisfies never;
+ }
+}