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,78 @@
# msgpack-encode
## Purpose
Implements `encodeBinary`, the MessagePack counterpart to `serialize`. It converts any JavaScript value to a compact binary `Uint8Array` using the same type-registry tag scheme as the JSON encoder. By pre-processing the input into plain msgpack-compatible intermediate values before handing off to `@msgpack/msgpack`, the codec avoids the complexity of a custom extension codec while still preserving all built-in and custom registered types.
Object keys are sorted canonically before encoding, so two structurally identical objects always produce bit-identical output regardless of property insertion order.
## Features
- Produces a compact binary wire format via `@msgpack/msgpack`
- Same type-registry integration as the JSON codec: all built-in and custom types round-trip faithfully
- Canonical key ordering for deterministic binary output
- `maxDepth`, `maxSize`, and `AbortSignal` options parallel to the JSON encoder
- Cycle detection via `WeakSet` — throws `CircularReferenceError` on cycles
- Throws `MaxDepthExceededError` and `MaxSizeExceededError` on limit violations
## Usage: Basic Example
```typescript
import { decodeBinary, encodeBinary } from "@suaveplan/serialize";
const payload = { created: new Date(), ids: new Set([1, 2, 3]) };
const bytes = encodeBinary(payload);
// bytes is a compact Uint8Array — smaller than JSON for numeric-heavy data
const restored = decodeBinary(bytes);
```
## Usage: Advanced Example
```typescript
import { encodeBinary } from "@suaveplan/serialize";
const controller = new AbortController();
const bytes = encodeBinary(largeDataset, {
maxDepth: 30,
maxSize: 1_000_000, // 1 MB
signal: controller.signal,
});
// Send over WebSocket, IndexedDB, etc.
socket.send(bytes);
```
## API Reference
### `encodeBinary(value: unknown, opts?: SerializeOptions): Uint8Array`
Encodes `value` to a MessagePack binary buffer.
**Parameters:**
- `value` — any JavaScript value; functions and symbols are silently dropped
- `opts.maxDepth` — maximum recursion depth (default: `100`)
- `opts.maxSize` — maximum byte length of the binary output; checked after encoding
- `opts.signal` — `AbortSignal`; checked once before encoding begins
**Returns:** a `Uint8Array` containing the MessagePack payload.
**Throws:**
- `CircularReferenceError` on cycles
- `MaxDepthExceededError` when nesting exceeds `maxDepth`
- `MaxSizeExceededError` when output exceeds `maxSize` bytes
- The `AbortSignal`'s reason if aborted
### `SerializeOptions`
See `json-encode.md` — the same options interface is shared.
## Implementation Notes
- A single shared `Encoder` instance is reused across calls to amortise initialisation overhead; the encoder is stateless between calls.
- The `preEncode` helper mirrors the logic in `json-encode.ts` but emits plain objects/arrays instead of a JSON string, avoiding a second parse step.
- `AbortSignal` is checked once at the call boundary rather than every 256 nodes because msgpack encoding is typically fast and does not support mid-stream interruption without a custom streaming approach.
- Canonical key sorting uses the default `Array.prototype.sort` comparator (lexicographic UTF-16 code units), matching the sort used by many canonical JSON implementations.