first commit
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# request
|
||||
|
||||
## Purpose
|
||||
|
||||
Encodes and decodes `cd:request` envelope payloads for the chunk-request side of the mesh protocol. Owns the wire format that downstream packages (`drive-mesh`, `network-plugin-content-delivery`) round-trip through bus transports, and enforces the DMP-01 / DMP-03 / DMP-07 / DMP-21 / DMP-22 invariants at every entry point so that no malformed payload ever reaches the logic layer.
|
||||
|
||||
## Features
|
||||
|
||||
- `encodeRequestPayload(payload)` — schema-validates, enforces `maxChunks` cap, rejects empty `kind:'specific'` arrays, base64-wraps bitset bytes, and returns UTF-8 JSON bytes.
|
||||
- `decodeRequestPayload(bytes)` — inverse with the same gates plus the `bitpacker-compressed` magic check on bitset payloads (DMP-21).
|
||||
- `encodeRequest(request)` — lower-level helper that converts a runtime `ChunkRequest` to its JSON-friendly wire shape.
|
||||
- Strong typing: every public surface is parameterised by `ChunkRequestPayload` from `@suaveplan/drive-mesh-protocol/types`.
|
||||
- Errors are coded: `DMP.EMPTY_REQUEST`, `DMP.MAX_CHUNKS_EXCEEDED`, `DMP.ENVELOPE_MALFORMED`, `DMP.CODEC_MISMATCH`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
decodeRequestPayload,
|
||||
encodeRequestPayload,
|
||||
selectWhole,
|
||||
} from "@suaveplan/drive-mesh-protocol";
|
||||
|
||||
const wire = encodeRequestPayload({
|
||||
fileId: "a".repeat(64),
|
||||
request: selectWhole(),
|
||||
priority: "normal",
|
||||
});
|
||||
const back = decodeRequestPayload(wire);
|
||||
console.log(back.request.kind); // "whole"
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
chunkIdsToRawBitset,
|
||||
encodeFramedBitset,
|
||||
encodeRequestPayload,
|
||||
} from "@suaveplan/drive-mesh-protocol";
|
||||
|
||||
const need = [3, 7, 200, 999];
|
||||
const raw = chunkIdsToRawBitset(need, 1000);
|
||||
const framed = encodeFramedBitset(raw, 1000);
|
||||
const wire = encodeRequestPayload({
|
||||
fileId,
|
||||
request: { kind: "bitset", bytes: framed },
|
||||
priority: "high",
|
||||
maxChunks: 256,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `encodeRequestPayload(payload: ChunkRequestPayload): Uint8Array`.
|
||||
- `decodeRequestPayload(bytes: Uint8Array): ChunkRequestPayload`.
|
||||
- `encodeRequest(request: ChunkRequest): WireRequest` — JSON-friendly wire shape; `bitset` form's `bytes` becomes `{ _b: <base64> }`.
|
||||
- Throws `DmpError` with one of the namespaced codes above for every rejection path.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Bitset bytes round-trip through base64 so JSON parsers don't lose the high bit of any byte. The Zod schema deliberately permits empty `chunkIds` arrays so the explicit DMP-03 / DMP-22 gate (which throws `DMP.EMPTY_REQUEST` rather than `DMP.ENVELOPE_MALFORMED`) is the visible failure path. The `maxChunks` schema check is lower-bound only; the upper-bound mandate (DMP-07) lives in `enforceMaxChunks` so the failure carries the spec-mandated `DMP.MAX_CHUNKS_EXCEEDED` code.
|
||||
Reference in New Issue
Block a user