2.4 KiB
deterministic
(no submodules)
Purpose
Convenience entry point for RFC 8949 §4.2 deterministic encoding. The
underlying encode accepts a deterministic: true option; this module
exposes a tiny encodeDeterministic(value, options?) wrapper that pins the
flag at true and forbids the caller from overriding it. Use this when the
encoded bytes must be byte-stable across runs — content-addressable storage,
hash digests, signature payloads, COSE structures, and CWT claim sets are
the canonical consumers.
Features
- Sorted map keys — lexicographic byte order over the canonical CBOR-encoded key bytes, NOT the JavaScript Map iteration order.
- Shortest-form integers — always-on regardless of mode.
- No indefinite-length items — caller cannot opt in.
- Half-float disabled in deterministic mode; floats serialise as the
shortest exact width among
{float32, float64}. - Rejects
undefinedwithCborError(NON_DETERMINISTIC)—undefinedhas no canonical CBOR representation, so it cannot be deterministically encoded.
Usage: Basic Example
import { encodeDeterministic } from "@suaveplan/cbor/deterministic";
const m = new Map<string, number>([["b", 2], ["a", 1]]);
const bytes = encodeDeterministic(m);
// bytes are sorted by canonical key order
Usage: Advanced Example
import { encodeDeterministic } from "@suaveplan/cbor/deterministic";
const a = encodeDeterministic({ z: 1, a: 2 });
const b = encodeDeterministic({ a: 2, z: 1 });
// a and b are byte-identical because key order is canonical, not insertion-order.
import { sha256 } from "@suaveplan/crypto-hash/sha256";
const digest = await sha256(a);
API Reference
encodeDeterministic(value: unknown, options?: Omit<EncoderOptions, "deterministic">): Uint8Array
The omitted deterministic field guarantees the flag stays pinned. Other
options (maxDepth, maxItems, preferFloat16) are honoured but
preferFloat16 has no effect when deterministic is on.
Implementation Notes
This module exists primarily for ergonomics — direct encode(v, { deterministic: true })
is identical at runtime. The wrapper guards against accidental
deterministic: false overrides and gives downstream readers a clear signal
about intent at the call site. Consumers who need to assert byte-stability
across runs should pair this with property tests over arbitrary
JsonValue-like inputs.