Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
# 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.

View File

@@ -0,0 +1,33 @@
# Drive Transport WebRTC — Spec Delta (drive-transport-webrtc-port)
## ADDED Requirements
### TRANSPORT-WRTC-01 — Frame format
Datachannel messages MUST use the framing `[uint32 BE frameLen][uint8 frameType][payload (frameLen-1 B)]`. `frameType` values: `0x01` chunk-request, `0x02` chunk-response, `0x03` advertisement. Receivers MUST buffer until `frameLen` bytes accumulate before parsing.
**Verified by:** `src/framing/codec.spec-conformance.test.ts` (`TRANSPORT-WRTC-01`).
### TRANSPORT-WRTC-02 — Request/response correlation
Each chunk-response frame MUST be matched to its outstanding chunk-request via `(fileId, chunkId)`. Concurrent requests for different chunks MUST resolve independently. A response with no pending request MUST be discarded silently (with telemetry).
**Verified by:** `src/transport.spec-conformance.test.ts` (`TRANSPORT-WRTC-02`).
### TRANSPORT-WRTC-03 — Advertisement broadcast
`transport.advertise(peerId, fileId, bitset)` MUST send a `0x03` frame on the relevant peer's datachannel. `onAdvertisement` handlers MUST fire on receipt with the decoded `(fileId, bitset)`.
**Verified by:** `src/transport.spec-conformance.test.ts` (`TRANSPORT-WRTC-03`).
### TRANSPORT-WRTC-04 — Backpressure honours bufferedAmount
When `dataChannel.bufferedAmount > highWatermark` (default 16 MiB), the transport MUST stop sending and await the `bufferedamountlow` event before resuming. The watermarks MUST be configurable via `bufferThresholds`.
**Verified by:** `src/transport.spec-conformance.test.ts` (`TRANSPORT-WRTC-04`).
### TRANSPORT-WRTC-05 — Lifecycle on peer-connection close
When a peer's `RTCPeerConnection` transitions to `closed`, `failed`, or `disconnected`, the transport MUST: cancel all pending requests for that peer with `MeshError(MESH.TRANSPORT_ERROR)`, remove the peer from `peers()`, and emit a peer-removed event.
**Verified by:** `src/transport.spec-conformance.test.ts` (`TRANSPORT-WRTC-05`).

View File

@@ -0,0 +1,43 @@
# Tasks: drive-transport-webrtc-port
> Blocked on: `drive-mesh-port`. Soft-blocked on `network-webrtc-port` (will integrate when available).
## 1. Scaffold
- [ ] 1.1 `packages/drive/drive-transport-webrtc/` with `package.json` (`@suaveplan/drive-transport-webrtc@0.0.0`), `tsconfig.json`, `vitest.config.ts`, `README.md`.
- [ ] 1.2 Workspace deps: `@suaveplan/drive-mesh` (interface), `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/streams`, `@opentelemetry/api`, `zod`.
## 2. Framing codec
- [ ] 2.1 `src/framing/encode.ts` — length-prefix + frame-type writer.
- [ ] 2.2 `src/framing/decode.ts` — accumulator-based reader; surfaces complete frames.
- [ ] 2.3 `src/framing/types.ts` — `FrameType` enum, frame structs.
## 3. Peer connection
- [ ] 3.1 `src/peer/connection.ts` — wraps `RTCPeerConnection`, lifecycle, ICE handling via injected `SignallerClient`.
- [ ] 3.2 `src/peer/datachannel.ts` — open/close, send with backpressure, receive with framing decode.
## 4. Transport impl
- [ ] 4.1 `src/transport.ts` — `webrtcTransport(options)` factory. Maintains a `Map<peerId, PeerConnection>`. Implements `requestChunk`, `advertise`, `onAdvertisement`, `peers`.
- [ ] 4.2 `src/transport.ts` — pending-request map (request-id ↔ deferred), so chunk-response frames resolve the right awaiter.
## 5. Backpressure
- [ ] 5.1 `src/backpressure/watermark.ts` — `bufferedamountlow` event integration; pause/resume.
## 6. Spec
- [ ] 6.1 `openspec/specs/drive-transport-webrtc/spec.md` — `TRANSPORT-WRTC-01` … `-05` with `**Verified by:**` lines.
## 7. Conformance tests
- [ ] 7.1 `src/framing/codec.spec-conformance.test.ts` — round-trip framing (`TRANSPORT-WRTC-01`).
- [ ] 7.2 `src/transport.spec-conformance.test.ts` — request/response correlation, advertisement broadcast, backpressure pause (`TRANSPORT-WRTC-02` … `-05`) — uses fake `RTCPeerConnection` doubles.
## 8. Verify
- [ ] 8.1 `bunx turbo lint typecheck test --filter=@suaveplan/drive-transport-webrtc` green.
- [ ] 8.2 `bunx turbo test:coverage --filter=@suaveplan/drive-transport-webrtc` 100/100/100/100.
- [ ] 8.3 `bun scripts/openspec-conformance.ts @suaveplan/drive-transport-webrtc` PASS.