first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
# `deterministic`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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 `undefined` with `CborError(NON_DETERMINISTIC)` — `undefined` has
no canonical CBOR representation, so it cannot be deterministically encoded.
## Usage: Basic Example
```ts
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
```ts
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.