2.7 KiB
sequences
(no submodules)
Purpose
@suaveplan/cbor/sequences implements RFC 8742 — the CBOR Sequence format,
which is just the concatenation of zero-or-more well-formed CBOR data items
with no enclosing array, tag, or framing byte. Sequences are the natural
encoding for log streams, event journals, and any wire format where items
arrive incrementally and the consumer does not know the count ahead of time.
Features
encodeSequence(items, options?)produces the byte-concatenated form of an arbitrary item list. Empty input → empty output (zero bytes).decodeSequence(bytes, options?, tags?)walks the input from offset 0, pulling one item at a time viadecodeOneuntil the buffer is exhausted.decodeSequenceStream(stream, options?, tags?)— async generator over anAsyncIterable<Uint8Array>. Yields each complete item as it becomes available; buffers only what is needed for the next pending item.- All three preserve the strict / lax mode and tag-handling semantics of the underlying decoder — sequence framing is a pure outer concern.
Usage: Basic Example
import { decodeSequence, encodeSequence } from "@suaveplan/cbor/sequences";
const wire = encodeSequence([{ id: 1, ok: true }, { id: 2, ok: false }]);
const items = decodeSequence(wire);
Usage: Advanced Example
import { decodeSequenceStream } from "@suaveplan/cbor/sequences";
async function consumeLog(stream: AsyncIterable<Uint8Array>) {
for await (const event of decodeSequenceStream(stream)) {
handle(event);
}
}
API Reference
encodeSequence(items: readonly unknown[], options?: EncoderOptions): Uint8ArraydecodeSequence(bytes: Uint8Array, options?: DecoderOptions, tags?: ReadonlyMap<number, TagHandler>): DecodedValue[]decodeSequenceStream(stream: AsyncIterable<Uint8Array>, options?, tags?): AsyncGenerator<DecodedValue>
Throws CborError(MALFORMED) for sequence-internal incompleteness (e.g.
trailing bytes that don't form a complete item at end-of-stream).
Implementation Notes
The streaming form coalesces partial chunks via a growing Uint8Array
buffer. After each new chunk is appended, the loop attempts as many full
decodeOne calls as the buffer allows; on the first failure (which signals
"need more bytes"), the loop breaks and waits for the next chunk. This
strategy is correct as long as decodeOne either succeeds and reports
exactly consumed bytes OR throws — both invariants are guaranteed by the
strict-mode decoder. The buffer is reallocated rather than subarrayd after
each successful decode so backing-buffer ownership stays bound to the
generator and does not leak into yielded values.