Files
skills/docs/foundation/flow/cbor/src/sequences/sequences.md
2026-05-29 08:20:56 +01:00

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 via decodeOne until the buffer is exhausted.
  • decodeSequenceStream(stream, options?, tags?) — async generator over an AsyncIterable<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): Uint8Array
  • decodeSequence(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.