# @suaveplan/drive-transport-webrtc - WebRTC datachannel transport for the drive mesh. Implements DriveTransport over @suaveplan/drive-webrtc's WebRTCClient + DataChannelManager with a length-prefixed binary framing protocol. ## Summary WebRTC datachannel transport for the drive mesh. Implements the canonical `DriveTransport` interface from `@suaveplan/drive-mesh` over a `@suaveplan/drive-webrtc` `WebRTCClient` + `DataChannelManager` pair, multiplexing chunk requests, chunk responses, and presence advertisements over a single named data-channel label per peer. This package re-exports `DriveTransport` / `ChunkAdvertisement` / `AdvertisementHandler` / `Unsubscribe` from `@suaveplan/drive-mesh` — there is no local interface mirror. A drive-mesh `DriveMesh` instance slots a `WebRTCDriveTransport` into its transport plane and consumes this transport's `requestChunk` / `advertise` / `onAdvertisement` / `peers` surface directly. For the HTTPS / server-fallback path, mesh ships its own built-in `ServerFallback` (no separate transport package). ## Documentation tree - [error-codes](./src/error-codes/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… - [error-codes](./src/error-codes/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… - [frame](./src/framing/frame/frame.md) — _(no submodules)_ - [frame](./src/framing/frame/frame.md) — _(no submodules)_ - [schemas](./src/schemas/frame.schemas.md) — _(no submodules)_ - [frame.schemas](./src/schemas/frame.schemas.md) — _(no submodules)_ - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_ - [bitset-codec](./src/transport/webrtc-transport/bitset-codec.md) — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk… - [hex](./src/transport/webrtc-transport/hex.md) — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve… - [payload-codec](./src/transport/webrtc-transport/payload-codec.md) — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk… - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_ - [frame](./src/framing/frame/frame.md) — _(no submodules)_- [schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [frame.schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [bitset-codec](./src/transport/webrtc-transport/bitset-codec.md) — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk… - [hex](./src/transport/webrtc-transport/hex.md) — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve… - [payload-codec](./src/transport/webrtc-transport/payload-codec.md) — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk… - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… - [frame](./src/framing/frame/frame.md) — _(no submodules)_- [schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [frame.schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [bitset-codec](./src/transport/webrtc-transport/bitset-codec.md) — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk… - [hex](./src/transport/webrtc-transport/hex.md) — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve… - [payload-codec](./src/transport/webrtc-transport/payload-codec.md) — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk… - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… - [frame](./src/framing/frame/frame.md) — _(no submodules)_- [schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [frame.schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [bitset-codec](./src/transport/webrtc-transport/bitset-codec.md) — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk… - [hex](./src/transport/webrtc-transport/hex.md) — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve… - [payload-codec](./src/transport/webrtc-transport/payload-codec.md) — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk… - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… - [frame](./src/framing/frame/frame.md) — _(no submodules)_- [schemas](./src/schemas/frame.schemas.md) — _(no submodules)_ - [frame.schemas](./src/schemas/frame.schemas.md) — _(no submodules)_- [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_ - [bitset-codec](./src/transport/webrtc-transport/bitset-codec.md) — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk… - [hex](./src/transport/webrtc-transport/hex.md) — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve… - [payload-codec](./src/transport/webrtc-transport/payload-codec.md) — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk… - [webrtc-transport](./src/transport/webrtc-transport/webrtc-transport.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Defines the typed error-code registry and `DriveTransportWebRtcError` class used by every public boundary of `@suavepla… ## Quick start ```ts import { DataChannelManager, WebRTCClient, } from "@suaveplan/drive-webrtc"; import { WebRTCDriveTransport } from "@suaveplan/drive-transport-webrtc"; const client = new WebRTCClient({ peerId: "self", config: { signaling: { url: "wss://signal.example.com" } }, }); const channels = new DataChannelManager({ client }); // negotiate connection out of band via SignalingClient ... const transport = new WebRTCDriveTransport({ client, dataChannels: channels, defaultLabel: "drive-chunks", maxConcurrentRequests: 16, requestTimeoutMs: 10_000, }); // pull a chunk from a peer (fileId is the hex-encoded 32-byte digest) const fileId = "ab".repeat(32); const bytes = await transport.requestChunk("bob", fileId, 0); // broadcast presence — single `ChunkAdvertisement` object await transport.advertise("bob", { fileId, bitset: ourBitset, totalChunks: 1024, }); // subscribe to incoming advertisements (peerId + advert two-arg form) const unsubscribe = transport.onAdvertisement((peerId, advert) => { presenceIndex.update(peerId, advert.fileId, advert.bitset); }); // teardown await transport.dispose(); unsubscribe(); ``` ## Integration with `drive-mesh` `WebRTCDriveTransport` implements the canonical `DriveTransport` contract from `@suaveplan/drive-mesh`. A mesh instance accepts a list of `DriveTransport` implementations: ```ts import { DriveMesh } from "@suaveplan/drive-mesh"; import { WebRTCDriveTransport } from "@suaveplan/drive-transport-webrtc"; const mesh = new DriveMesh({ transports: [ new WebRTCDriveTransport({ client, dataChannels }), ], // ...peer registry, signed-chunk source, optional ServerFallback }); ``` The HTTPS / server-fallback path lives inside drive-mesh itself (`ServerFallback` — see `@suaveplan/drive-mesh`'s `./server-fallback/server-fallback` module), so there is no companion `drive-transport-https` package to plug in. ## Wire framing Every datachannel message is a length-prefixed binary frame: ```text +--------+--------+----------------------+ | 4 B | 1 B | frameLen - 1 B | | length | type | payload | +--------+--------+----------------------+ ``` - `length` — big-endian uint32 byte count of `type + payload`. - `type` — `0x01` chunk-request, `0x02` chunk-response, `0x03` advertisement. - `payload` shape varies by type: - Chunk request: `fileId(32 raw bytes) ‖ chunkId(4 BE uint32)`. - Chunk response: raw chunk bytes (length is already known from the outer header). - Advertisement: `fileId(32 raw bytes) ‖ totalChunks(4 BE uint32) ‖ gzip(bitset)`. Public API takes / returns the hex-encoded form (`fileId: string`, 64 lowercase hex chars). The codec converts to / from raw bytes at the boundary; on-the-wire bytes are unchanged from the pre-rewrite representation except for the new 4-byte `totalChunks` field. Frame bodies are capped at 16 MiB. Malformed frames are dropped on the receive side and surface as `DriveTransportWebRtcError(FRAME_INVALID)` on the send side. ## Backpressure Outgoing sends route through `DataChannelManager.send`, which pauses when `bufferedAmount` exceeds the data-channel high-water mark and resumes on the `bufferedamountlow` event. No additional flow-control state is held in this package. ## OTel surface | Instrument | Kind | Attributes | | --------------------------------------------------- | --------- | ------------------------------------- | | `drive.transport.webrtc.requests_total` | counter | `outcome` ∈ ok / timeout / aborted / send_failed / rejected_overflow | | `drive.transport.webrtc.advertisements_total` | counter | `direction` ∈ inbound / outbound | | `drive.transport.webrtc.request_duration_ms` | histogram | `outcome` | | `drive.transport.webrtc.frame_size_bytes` | histogram | `type` ∈ chunk-request / advertisement | ## Error codes All errors are instances of `DriveTransportWebRtcError`: - `FRAME_INVALID` — frame header or payload failed validation. - `FRAME_TOO_LARGE` — frame body exceeded the 16 MiB cap. - `REQUEST_TIMEOUT` — chunk request did not receive a response in time. - `PEER_NOT_CONNECTED` — no data channel could be opened for the peer. - `DATA_CHANNEL_CLOSED` — channel closed before / during send. - `BITSET_COMPRESSION_FAILED` — gzip codec failed. - `ABORTED` — `AbortSignal` fired or transport was disposed. ## License MIT