59 lines
2.3 KiB
Markdown
59 lines
2.3 KiB
Markdown
# OpenSpec Change: drive-transport-webrtc-port
|
|
|
|
- **Change ID**: drive-transport-webrtc-port
|
|
- **Package**: `@suaveplan/drive-transport-webrtc` (new)
|
|
- **Status**: PROPOSED
|
|
- **Date**: 2026-04-28
|
|
|
|
## Summary
|
|
|
|
WebRTC datachannel implementation of the `DriveTransport` interface for browser-to-browser chunk transfer. Wraps `RTCPeerConnection` + `RTCDataChannel`, frames chunks for transmission, handles backpressure via `bufferedAmount` watermark, and integrates with a signalling channel (typically WebSocket via `@suaveplan/network-websockets` once ported, or any caller-supplied signaller).
|
|
|
|
## API surface
|
|
|
|
```ts
|
|
const transport = webrtcTransport({
|
|
signaller: SignallerClient, // injectable
|
|
iceServers: RTCIceServer[],
|
|
dataChannel: { ordered: true, maxRetransmits: 0 }, // configurable
|
|
});
|
|
// Implements DriveTransport
|
|
transport.requestChunk(peerId, fileId, chunkId): AsyncIterable<Uint8Array>;
|
|
transport.advertise(peerId, fileId, bitset);
|
|
transport.onAdvertisement(handler);
|
|
transport.peers(): Iterable<PeerInfo>;
|
|
```
|
|
|
|
## Wire framing
|
|
|
|
Each datachannel message is a length-prefixed frame:
|
|
|
|
```text
|
|
[4 B uint32 BE frameLen]
|
|
[1 B uint8 frameType] // 0x01 chunk-request, 0x02 chunk-response, 0x03 advertisement
|
|
[frameLen-1 B payload]
|
|
```
|
|
|
|
- **Chunk request:** `fileId(32) ‖ chunkId(4)`.
|
|
- **Chunk response:** raw 164+`payloadLen` byte chunk.
|
|
- **Advertisement:** `fileId(32) ‖ gzipped-bitset`.
|
|
|
|
Datachannel messages may be fragmented by the WebRTC stack; receiver buffers until `frameLen` bytes are accumulated.
|
|
|
|
## Backpressure
|
|
|
|
- High-water mark: `bufferedAmount > 16 MiB` → pause sends, await `bufferedamountlow` event.
|
|
- Low-water mark: `bufferedAmount < 4 MiB` → resume.
|
|
- Configurable via `transport.bufferThresholds`.
|
|
|
|
## Dependencies
|
|
|
|
- **Consumes:** `@suaveplan/drive-mesh` (interface), `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/streams`, `@opentelemetry/api`, `zod`.
|
|
- **Blocked on:** `drive-mesh-port`. Will integrate with `@suaveplan/network-webrtc` once that is ported (provides `RTCPeerConnection` lifecycle helpers).
|
|
|
|
## Out of scope
|
|
|
|
- Signalling protocol details — caller supplies the `SignallerClient`.
|
|
- TURN credential rotation — handled by `iceServers` provider.
|
|
- DataChannel encryption beyond DTLS — chunk payload is already AEAD+sig-protected by the chunks plugin.
|