first commit
This commit is contained in:
65
docs/foundation/flow/cbor/src/deterministic/deterministic.md
Normal file
65
docs/foundation/flow/cbor/src/deterministic/deterministic.md
Normal 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.
|
||||
Reference in New Issue
Block a user