# `schemas/frame.schemas` _(no submodules)_ ## Purpose Zod boundary schemas for the two structured payload shapes the WebRTC drive transport speaks on the wire: chunk-request and advertisement. Frames themselves are length-prefixed binary blobs validated by the `framing/frame` module; once the type discriminator is read, the payload bytes are projected into one of the shapes validated here so that consumers handling the payload at the application layer get a Zod-safe value rather than raw bytes. The shapes match the canonical `DriveTransport` contract from `@suaveplan/drive-mesh`: file ids are hex-encoded (`64` lowercase hex chars) and advertisements carry a `totalChunks` field alongside the gzipped bitset. Anything else fails Zod validation and surfaces as a `DriveTransportWebRtcError(FRAME_INVALID)` at the transport boundary. ## Features - `RequestChunkPayloadSchema` — `{ fileId: string(hex64), chunkId: uint32 }`. - `AdvertisementPayloadSchema` — `{ fileId: string(hex64), totalChunks: uint32, bitsetGzip: Uint8Array(>0) }`. - `FILE_ID_BYTES` — the raw 32-byte wire length constant. - `FILE_ID_HEX_LENGTH` — the corresponding `64` hex-char length. ## Usage: Basic Example ```ts import { RequestChunkPayloadSchema, } from "@suaveplan/drive-transport-webrtc"; const parsed = RequestChunkPayloadSchema.parse({ fileId: "ab".repeat(32), chunkId: 42, }); ``` ## Usage: Advanced Example ```ts import { AdvertisementPayloadSchema, decodeAdvertisement, decodeFrame, FRAME_TYPE, } from "@suaveplan/drive-transport-webrtc"; function projectAdvertisement(frameBytes: Uint8Array) { const frame = decodeFrame(frameBytes); if (frame.type !== FRAME_TYPE.ADVERTISEMENT) return undefined; const decoded = decodeAdvertisement(frame.payload); return AdvertisementPayloadSchema.parse(decoded); } ``` ## API Reference - `FILE_ID_BYTES: 32` — re-exported raw-bytes constant for the on-the-wire form. - `FILE_ID_HEX_LENGTH: 64` — corresponding hex-char length for the public API form. - `RequestChunkPayloadSchema` — Zod object with exact-64-char hex `fileId` refinement and `chunkId` clamped to non-negative uint32. - `AdvertisementPayloadSchema` — Zod object enforcing the hex `fileId`, a uint32 `totalChunks`, and a non-empty `bitsetGzip` payload. - `RequestChunkPayload` / `AdvertisementPayload` — inferred TypeScript types. ## Implementation Notes The schemas live outside the codec module so that consumers who want to validate at the application boundary (e.g. before queueing a request for retry) can do so without re-importing the binary codec. The `bitsetGzip` field is asserted non-empty because every well-formed gzip stream is at least a few bytes; an empty value usually indicates a slicing bug at the sender, which we surface eagerly. `chunkId` and `totalChunks` are clamped to uint32 to match the wire encoding (`DataView.setUint32`).