12 KiB
@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 — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla…- error-codes — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla…
- error-codes — Defines the typed error-code registry and
- frame — (no submodules)
- frame — (no submodules)
- schemas — (no submodules)
- frame.schemas — (no submodules)
- webrtc-transport — (no submodules)
- bitset-codec — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk…
- hex — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve…
- payload-codec — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk…
- webrtc-transport — (no submodules)
- hex — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve…
- payload-codec — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk…
- webrtc-transport — (no submodules)- error-codes — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla… - frame — (no submodules)- schemas — (no submodules)- frame.schemas — (no submodules)- webrtc-transport — (no submodules)- bitset-codec — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk…
- hex — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve…
- payload-codec — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk…
- webrtc-transport — (no submodules)- error-codes — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla…
- frame — (no submodules)- schemas — (no submodules)- frame.schemas — (no submodules)- webrtc-transport — (no submodules)- bitset-codec — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk…
- hex — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve…
- payload-codec — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk…
- webrtc-transport — (no submodules)- error-codes — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla…
- frame — (no submodules)- schemas — (no submodules) - frame.schemas — (no submodules)- webrtc-transport — (no submodules) - bitset-codec — Provides the gzip codec used to compress advertisement bitsets before they hit the wire. Bitsets describing which chunk…
- hex — Boundary helpers converting between the on-the-wire 32-byte file id representation and the hex-encoded form used by eve…
- payload-codec — Implements the byte-level encoder/decoder for the two structured frame bodies the WebRTC drive transport carries: chunk…
- webrtc-transport — (no submodules)- error-codes — Defines the typed error-code registry and
DriveTransportWebRtcErrorclass used by every public boundary of `@suavepla…
Quick start
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:
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:
+--------+--------+----------------------+
| 4 B | 1 B | frameLen - 1 B |
| length | type | payload |
+--------+--------+----------------------+
length— big-endian uint32 byte count oftype + payload.type—0x01chunk-request,0x02chunk-response,0x03advertisement.payloadshape 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).
- Chunk request:
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—AbortSignalfired or transport was disposed.
License
MIT