Problem
Streaming-LLM apps need an SSE client. Hand-written SSE parsing is a known footgun (RFC 6455-style event:/data:/blank-line state machine). Shipping a tested, typed primitive saves users that footgun.
Proposed solution
Port frontend/src/lib/api/client.js from Teller into frontend/src/lib/api/client.ts. Type the event shapes with discriminated unions. Keep the parser pure (no DOM dependency). Add a vitest unit test for the parser using a fake ReadableStream.
Acceptance criteria
Priority rationale
High: this is one of the most copy-pasted-incorrectly primitives in LLM-frontend code. Shipping it correctly is a portfolio differentiator.
Depends on
#21
Problem
Streaming-LLM apps need an SSE client. Hand-written SSE parsing is a known footgun (RFC 6455-style
event:/data:/blank-line state machine). Shipping a tested, typed primitive saves users that footgun.Proposed solution
Port
frontend/src/lib/api/client.jsfrom Teller intofrontend/src/lib/api/client.ts. Type the event shapes with discriminated unions. Keep the parser pure (no DOM dependency). Add a vitest unit test for the parser using a fakeReadableStream.Acceptance criteria
client.tsexports a typedconsumeSSEfunction returning anAsyncIterableof typed events.event:/data:parsing, multi-linedata:, blank-line dispatch, partial-chunk reassembly.Priority rationale
High: this is one of the most copy-pasted-incorrectly primitives in LLM-frontend code. Shipping it correctly is a portfolio differentiator.
Depends on
#21