Streaming Element streams
Element streams
Add one complete row per async-iterable element.
Use connectElementStream when every yielded value is a complete row. The chat grid below starts empty; each element the async generator yields is appended as a new row:
Turn a streaming LLM response into rows with connectElementStream and append them to the grid as they arrive.
Signature
function connectElementStream<
TRow extends object,
TRowId extends string | number,
>(
rowModel: RowModelLike<TRow, TRowId>,
stream: AsyncIterable<TRow>,
): StreamConnection;The structural RowModelLike contract accepts atomic { add, update, remove } transactions. A Pretable local row model satisfies it directly.
React recipe
The grid above owns its rowModel with useMemo, opens the connection inside
useEffect, and disposes both the connection and the row model on unmount —
see its ChatGrid.tsx in the Code tab. It passes prompt through to a
responseEventsToChatRows async generator, since Responses API streams yield
lifecycle and text-delta events, not rows: the generator accumulates text
deltas and yields a complete { id, role, content, tokens, latencyMs } value
only when a response.completed event arrives (response-events-to-chat-rows.ts,
same tab).
Two required props are easy to drop when hand-rolling this: PretableSurface
needs both ariaLabel and viewportHeight, as the grid above passes them —
neither is optional.
SSE recipe
connectElementStream(rowModel, fromEventSource("/api/events"));Raw JSON
const response = await fetch("/api/events");
const strings = response.body!.pipeThrough(new TextDecoderStream());
connectElementStream(rowModel, parseElementStream<Row>(strings));See Parsers →.