receive$, lines$, or terminalText$SerialSession exposes three receive-side text streams. Pick by what you want to do, not by which name sounds “raw.” This page is the decision guide; for option tables and formal contracts, see API concepts and the TypeDoc API Reference.
Parent: #555 · Issue: #559 · Related: Communication pattern Recipes
| Goal | Recommend |
|---|---|
| Read newline-delimited logs | lines$ |
| Read JSON Lines | lines$ |
| Handle decoder chunks as they arrive | receive$ |
Handle display control that uses \r |
receive$ or terminalText$ |
| Bind terminal-style text to a UI | terminalText$ |
Receive raw Uint8Array (wire bytes) |
Not supported — see Supported data, Binary receive design, and #545 |
| Stream | Role |
|---|---|
receive$ |
UTF-8 decoded chunks from the read pump. Not line-aligned. Preserves \r and other control characters. Not wire bytes. |
lines$ |
Complete lines framed with \n, \r\n, and lone interior \r. For logs, one-line replies, and parsers. |
terminalText$ |
Cumulative display text derived from receive$. Folds \r redraws; by default strips ANSI for plain-text UIs. Equivalent to createTerminalBuffer(receive$).text$. |
All three are driven by the same connect$ read pump. They are not subscription-lazy: late subscribers see only new data (and terminalText$ is a cumulative view of what the buffer has folded so far after you subscribe to its shared replay).
receive$ emissions follow the browser’s ReadableStream read sizes and the streaming TextDecoder — not your protocol’s message boundaries.
receive$ chunks.receive$ chunk may contain several complete lines (those complete lines also appear on lines$).receive$.For custom delimiters beyond the built-in line buffer, compose on receive$ — see Advanced Usage – Line framing.
lines$Use lines$ when the device speaks a newline-framed text protocol:
\n-delimited JSON objects)\n or \r\n (for example OK)Incomplete tails (no terminator yet) stay in an internal buffer and are not emitted until a line completes. The incomplete tail is capped by SerialSessionOptions.lineBuffer (default maxChars: 1_048_576); overflow discards leading tail data and emits non-fatal LINE_BUFFER_OVERFLOW on errors$ without disconnecting.
Avoid feeding lines$ into a terminal widget that must preserve \r redraws — the line buffer may treat interior \r as a boundary and break progress/shell output.
receive$Use receive$ when you need unframed decoded text:
\r, as the peer sent themcreateTerminalBuffer yourself)In docs and JSDoc, “raw” on receive$ means unframed decoded text chunks, not raw wire bytes and not a Uint8Array stream. See What “raw” means on receive$.
terminalText$Use terminalText$ when you want a single string suitable for a terminal-like viewport (<textarea>, log panel, etc.):
\r) while keeping normal newline behaviorstripAnsi: true); set SerialSessionOptions.terminalBuffer.stripAnsi to false to keep escapes in the display streamterminalBuffer (maxLines / maxChars; defaults 10,000 lines and 1,048,576 characters)Prefer terminalText$ for display binding. Prefer receive$ when you need the undecorated chunk stream (raw escapes, custom folding, or non-display consumers).
There is no receiveBytes$ or public Uint8Array receive stream. The read pump always decodes with a streaming UTF-8 TextDecoder.
send$(Uint8Array).Current limits and design notes: Supported data. Design decision (defer for now): Binary receive API — design decision (#545).
lines$receive$lines$ or receive$, then send