-
Notifications
You must be signed in to change notification settings - Fork 0
records
io.records consumes streamed record responses — JSONL / NDJSON and RFC 7464
application/json-seq — as a lazy async iterable of parsed records. One record at a time, memory
stays flat, and the request fires on the first iteration.
import io from 'double-meh';
for await (const user of io.records.get('https://api.example.com/users/export')) {
process(user); // already parsed — {id: 42, name: 'Bob', ...}
}Both return an AsyncIterableIterator of parsed records. get takes a query as the 2nd argument;
post sends the 2nd argument as the request body (a streamed search is the classic case). The
request runs through the full pipeline (inspectors, retry if opted in); stream: true is implied,
so the response is never tracked or cached.
-
Framing is negotiated from the response content type: a type containing
json-seqselects RS-delimited RFC 7464 framing; anything else parses as JSONL/NDJSON (one JSON value per line, blank lines ignored). Force it with{framing: 'jsonl' | 'json-seq'}. -
The default
Acceptisapplication/x-ndjson, application/json-seq(overridable withaccept). -
Lazy and cancelable: nothing is sent until the first
next();breaking out of the loop cancels the response stream and releases the connection; anAbortSignalinoptions.signalstops iteration even when a custom transport ignores signals.
- A non-2xx reads the streamed error body first and throws a
BadStatuswhosedatais the parsed body (problem+jsonfriendly) — you never receive an error carrying an unread stream. - A malformed record throws a
FailedIOwith theSyntaxErroron.cause; records before it are delivered normally.
try {
for await (const row of io.records.post('https://api.example.com/search', {q: 'audio'})) {
render(row);
}
} catch (error) {
if (error instanceof io.BadStatus) console.error(error.status, error.data);
}io.records is the consume-simply path. For record processing pipelines (transforms,
fan-out, backpressure tuning, file edges) and for the upload/encode side, use
stream-chain on top of the byte-level
io.stream surface — see
Cookbook: streaming pipelines for the recipes. double-meh
deliberately ships no JSONL stringer or pipeline machinery of its own.
Guides
Concepts
Services
Modules
- fetch transport
- keys & URLs
- helpers
- records
- sse
- storage backends
- compression encoders
- Service Worker integration
Cookbook