first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user