Streaming Parsers

Parsers

Lower-level parse* helpers if you need to feed the engine yourself.

The parse* helpers sit one layer below connect*. They accept an AsyncIterable<string> (raw JSON chunks from fetch, Response.body, SSE, etc.) and yield typed values. Pipe their output into the connect helpers.

The grid below builds its AsyncIterable<ChatRow> with a hand-written generator, because its source is a typed Responses API event stream. parseElementStream solves the same problem for a plainer source: raw streaming JSON text, with no event envelope to unwrap.

Streaming chat grid

Turn a streaming LLM response into rows with connectElementStream and append them to the grid as they arrive.

.md

parseElementStream<TRow>(stream)

Source emits a streaming JSON array. The parser yields each element as it parses — you don't wait for the array to close.

ts
import { parseElementStream } from "@pretable/stream-adapter";
 
const res = await fetch("/api/events");
const decoded = res.body!.pipeThrough(new TextDecoderStream());
for await (const row of parseElementStream<Row>(decoded)) {
  console.log("got row", row);
}

In the connect-element pattern:

ts
import {
  connectElementStream,
  parseElementStream,
} from "@pretable/stream-adapter";
 
const res = await fetch("/api/events");
const decoded = res.body!.pipeThrough(new TextDecoderStream());
connectElementStream(rowModel, parseElementStream<Row>(decoded));

parsePartialStream<TRow>(stream)

Source emits a streaming JSON object. The parser yields successive Partial<TRow> snapshots as keys complete.

ts
import { parsePartialStream } from "@pretable/stream-adapter";
 
const res = await fetch("/api/single-row-events");
const decoded = res.body!.pipeThrough(new TextDecoderStream());
for await (const partial of parsePartialStream<Row>(decoded)) {
  console.log("snapshot so far", partial);
}

In the connect-partial pattern:

ts
import {
  connectPartialStream,
  parsePartialStream,
} from "@pretable/stream-adapter";
 
const res = await fetch("/api/single-row-events");
const decoded = res.body!.pipeThrough(new TextDecoderStream());
connectPartialStream(rowModel, parsePartialStream<Row>(decoded), {
  rowId: "row-001",
});

Errors

Both parsers throw on malformed JSON. Wrap the consumer (or the connect call) in a try/catch and inspect via the done promise:

ts
const decoded = res.body!.pipeThrough(new TextDecoderStream());
const conn = connectElementStream(rowModel, parseElementStream(decoded));
conn.done.catch((err) => console.error("stream failed:", err));