# @suaveplan/drive-webrtc - WebRTC P2P mesh plugin for @suaveplan/drive: signaling, peer management, data channels, chunk discovery, real signature verification. ## Summary Browser-tier WebRTC P2P chunk-distribution plugin for [`@suaveplan/drive`](../drive/README.md). Provides a complete mesh networking stack — signalling client, ICE-aware WebRTC client, peer manager, data-channel manager, integrity verifier, chunk-discovery engine, and a `ChunkSource` consumable by Drive — wrapped in a single `WebRTCDrivePlugin` orchestrator. Every layer is constructed with real implementations (`@suaveplan/crypto-curve` Ed25519, `@suaveplan/crypto-hash` SHA-256, `@suaveplan/events` event bus, `@suaveplan/error` error codes), and every async path threads `AbortSignal` so cooperative cancellation works end-to-end. This package targets the browser (`globalThis.WebSocket`, `globalThis.RTCPeerConnection`) but accepts constructor injections so tests and SSR contexts can wire deterministic doubles. --- ## Documentation tree - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_ - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_ - [client](./src/client/client/client.md) — _(no submodules)_ - [client](./src/client/client/client.md) — _(no submodules)_ - [ice](./src/client/ice/ice.md) — _(no submodules)_ - [ice](./src/client/ice/ice.md) — _(no submodules)_ - [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_ - [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_ - [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_ - [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_ - [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_ - [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_ - [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_ - [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_ - [error-codes](./src/error-codes/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… - [error-codes](./src/error-codes/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… - [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_ - [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_ - [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_ - [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_ - [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_ - [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_ - [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_ - [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_ - [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_ - [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_ - [full-mesh](./src/peer-manager/topology/full-mesh.md) — Every peer connects to every other peer up to a configurable cap. This is the default topology and matches the assumpti… - [hub-and-spoke](./src/peer-manager/topology/hub-and-spoke.md) — `HubAndSpokeStrategy` pins the mesh into a star topology: a single designated hub accepts connections from every spoke,… - [super-peer](./src/peer-manager/topology/super-peer.md) — The super-peer topology lets well-resourced nodes act as relays for the rest of the mesh. Super peers form a full mesh… - [topology-strategy](./src/peer-manager/topology/topology-strategy.md) — `TopologyStrategy` is the pure-function contract `PeerManager` consults when a new peer is announced. A strategy decide… - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_ - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_ - [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_ - [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_ - [config.schemas](./src/schemas/config.schemas.md) — The `config.schemas.ts` module defines Zod boundary schemas for the configuration surface declared in `types/config.typ… - [signaling.schemas](./src/schemas/signaling.schemas.md) — The `signaling.schemas.ts` module exposes Zod schemas mirroring every variant of `SignalingMessage` from `types/message… - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_ - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_ - [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_ - [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_ - [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_ - [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_ - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [full-mesh](./src/peer-manager/topology/full-mesh.md) — Every peer connects to every other peer up to a configurable cap. This is the default topology and matches the assumpti… - [hub-and-spoke](./src/peer-manager/topology/hub-and-spoke.md) — `HubAndSpokeStrategy` pins the mesh into a star topology: a single designated hub accepts connections from every spoke,… - [super-peer](./src/peer-manager/topology/super-peer.md) — The super-peer topology lets well-resourced nodes act as relays for the rest of the mesh. Super peers form a full mesh… - [topology-strategy](./src/peer-manager/topology/topology-strategy.md) — `TopologyStrategy` is the pure-function contract `PeerManager` consults when a new peer is announced. A strategy decide… - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [config.schemas](./src/schemas/config.schemas.md) — The `config.schemas.ts` module defines Zod boundary schemas for the configuration surface declared in `types/config.typ… - [signaling.schemas](./src/schemas/signaling.schemas.md) — The `signaling.schemas.ts` module exposes Zod schemas mirroring every variant of `SignalingMessage` from `types/message… - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [full-mesh](./src/peer-manager/topology/full-mesh.md) — Every peer connects to every other peer up to a configurable cap. This is the default topology and matches the assumpti… - [hub-and-spoke](./src/peer-manager/topology/hub-and-spoke.md) — `HubAndSpokeStrategy` pins the mesh into a star topology: a single designated hub accepts connections from every spoke,… - [super-peer](./src/peer-manager/topology/super-peer.md) — The super-peer topology lets well-resourced nodes act as relays for the rest of the mesh. Super peers form a full mesh… - [topology-strategy](./src/peer-manager/topology/topology-strategy.md) — `TopologyStrategy` is the pure-function contract `PeerManager` consults when a new peer is announced. A strategy decide… - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [config.schemas](./src/schemas/config.schemas.md) — The `config.schemas.ts` module defines Zod boundary schemas for the configuration surface declared in `types/config.typ… - [signaling.schemas](./src/schemas/signaling.schemas.md) — The `signaling.schemas.ts` module exposes Zod schemas mirroring every variant of `SignalingMessage` from `types/message… - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [full-mesh](./src/peer-manager/topology/full-mesh.md) — Every peer connects to every other peer up to a configurable cap. This is the default topology and matches the assumpti… - [hub-and-spoke](./src/peer-manager/topology/hub-and-spoke.md) — `HubAndSpokeStrategy` pins the mesh into a star topology: a single designated hub accepts connections from every spoke,… - [super-peer](./src/peer-manager/topology/super-peer.md) — The super-peer topology lets well-resourced nodes act as relays for the rest of the mesh. Super peers form a full mesh… - [topology-strategy](./src/peer-manager/topology/topology-strategy.md) — `TopologyStrategy` is the pure-function contract `PeerManager` consults when a new peer is announced. A strategy decide… - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [config.schemas](./src/schemas/config.schemas.md) — The `config.schemas.ts` module defines Zod boundary schemas for the configuration surface declared in `types/config.typ… - [signaling.schemas](./src/schemas/signaling.schemas.md) — The `signaling.schemas.ts` module exposes Zod schemas mirroring every variant of `SignalingMessage` from `types/message… - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — _(no submodules)_- [client](./src/client/client/client.md) — _(no submodules)_ - [client](./src/client/client/client.md) — _(no submodules)_- [ice](./src/client/ice/ice.md) — _(no submodules)_ - [ice](./src/client/ice/ice.md) — _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_ - [offer-answer](./src/client/offer-answer/offer-answer.md) — _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_ - [reconnect](./src/client/reconnect/reconnect.md) — _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_ - [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_ - [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_ - [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_ - [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_ - [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_ - [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_ - [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — _(no submodules)_- [full-mesh](./src/peer-manager/topology/full-mesh.md) — Every peer connects to every other peer up to a configurable cap. This is the default topology and matches the assumpti… - [hub-and-spoke](./src/peer-manager/topology/hub-and-spoke.md) — `HubAndSpokeStrategy` pins the mesh into a star topology: a single designated hub accepts connections from every spoke,… - [super-peer](./src/peer-manager/topology/super-peer.md) — The super-peer topology lets well-resourced nodes act as relays for the rest of the mesh. Super peers form a full mesh… - [topology-strategy](./src/peer-manager/topology/topology-strategy.md) — `TopologyStrategy` is the pure-function contract `PeerManager` consults when a new peer is announced. A strategy decide… - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_ - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_ - [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — _(no submodules)_- [config.schemas](./src/schemas/config.schemas.md) — The `config.schemas.ts` module defines Zod boundary schemas for the configuration surface declared in `types/config.typ… - [signaling.schemas](./src/schemas/signaling.schemas.md) — The `signaling.schemas.ts` module exposes Zod schemas mirroring every variant of `SignalingMessage` from `types/message… - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_ - [security-validator](./src/security/security-validator/security-validator.md) — _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_ - [signaling-client](./src/signaling/signaling-client/signaling-client.md) — _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_ - [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — The `error-codes.ts` module defines the closed registry of error codes that `@suaveplan/drive-webrtc` may throw, plus t… ## Quick Start ```bash bun add @suaveplan/drive-webrtc ``` ```ts import { Drive } from "@suaveplan/drive"; import { WebRTCDrivePlugin } from "@suaveplan/drive-webrtc"; const plugin = new WebRTCDrivePlugin({ peerId: crypto.randomUUID(), config: { signaling: { url: "wss://signal.example.com/p2p" }, p2p: { iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }], }, }, signalingUrl: "wss://signal.example.com/p2p", }); await plugin.start(); const drive = new Drive(/* storage */); // Drive integration: hand the chunk source to your read pipeline. const bytes = await plugin.chunkSource.fetchChunk("chunk:42"); // Subscribe to any of the plugin-level events. plugin.on("webrtc:connected", ({ peerId }) => { console.info(`p2p peer ${peerId} is up`); }); // On shutdown: await plugin.stop(); ``` --- ## Subpath Map Every internal subsystem is published under a dedicated subpath so downstream apps tree-shake to the minimum surface they need. Eleven tree-shake snapshots in `tests/bundle-size/` enforce the leaf boundaries. | Subpath | Primary export | Purpose | | -------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------- | | `.` (root) | Everything | Convenience barrel — re-exports every public surface below. | | `./plugin/webrtc-plugin` | `WebRTCDrivePlugin` | Top-level orchestrator. Start here. | | `./client/webrtc-client` | `WebRTCClient`, `resolveConfig` | ICE-aware peer-connection lifecycle. | | `./signaling/signaling-client` | `SignalingClient` | WebSocket signalling with bounded-backoff reconnect. | | `./peer-manager/peer-manager` | `PeerManager` | Peer admission / eviction + bandwidth-scored ranking. | | `./data-channel/data-channel-manager` | `DataChannelManager` | Multiplexed `RTCDataChannel` lifecycle + backpressure. | | `./integrity/chunk-integrity` | `ChunkIntegrityManager` | Real SHA-256 + Ed25519 verify per inbound chunk. | | `./chunk-source/chunk-source` | `WebRTCChunkSource` | Drive-facing `ChunkSource` backed by the discovery manager. | | `./rate-limiter/rate-limiter` | `RateLimiter` | Token-bucket rate limiter. | | `./lru-cache/lru-cache` | `LRUCache` | Bounded LRU cache for chunk hot-path memoisation. | | `./security/security-validator` | `validateSignalingUrl`, `generateSecurePeerId`, ... | UUID v4 + signalling-URL guards. | | `./sub-chunk/sub-chunk-splitter` | `splitIntoSubChunks`, `SubChunkReassembler` | Sub-chunk fragmentation + reassembly for data-channel transfers. | | `./errors` | `DRIVE_WEBRTC_CODES`, `DriveWebRtcError` | Stable typed error registry. | | `./schemas` | Zod schemas | Wire-format validation for every signalling + config surface. | --- ## ICE / TURN Operations WebRTC peers exchange ICE candidates over signalling; in production networks behind symmetric NATs or restrictive firewalls, peers cannot reach each other directly and require a TURN relay. The `p2p.iceServers` list is exhaustively typed as `RTCIceServer[]`: ```ts { p2p: { iceServers: [ // STUN: enough on permissive networks. { urls: ["stun:stun.l.google.com:19302"] }, // TURN: relays the media path through your infra; required // for restrictive corp / cell networks. Costs egress. { urls: [ "turn:turn.example.com:3478?transport=udp", "turn:turn.example.com:3478?transport=tcp", "turns:turn.example.com:5349?transport=tcp", ], username: "user", credential: "secret", }, ], }, } ``` ### TURN URL format ``` turn://username:credential@host:port?transport={udp,tcp} turns://username:credential@host:port?transport=tcp ``` `turn:` is unencrypted; `turns:` runs TURN over TLS (required for some mobile carrier networks). Always provide BOTH UDP and TCP transports — some networks block UDP/3478 entirely. ### ICE-restart policy `WebRTCClient` automatically restarts ICE up to `maxIceRestartAttempts` times (default `3`) when the connection enters the `failed` state. After the cap is exhausted, `ice:state` reports `failed` once more without a further restart and the plugin evicts the peer. Tune the cap with the `maxIceRestartAttempts` option on `WebRTCClient` (the plugin forwards this through `config`). ### Exhaustion symptoms - Many `webrtc:failed` events: peers cannot complete ICE — check TURN reachability, credentials, port allowlists. - Bandwidth blackholes: high `bytesIn`, zero `bytesOut` — direct path blocked, TURN relay forced; verify TURN provider quota. - `signaling:reconnect` storms: signalling URL or TLS misconfiguration — check `SignalingClient.state` + `reconnect:exhausted` events. --- ## Topology Strategies `PeerManager` consumes a `TopologyStrategy`. Three are bundled: - **`FullMeshStrategy`** (default): every peer connects to every other peer. Best for small meshes (<30 peers) where every pair benefits from a direct edge. Memory + CPU scales O(n^2) with mesh size. - **`SuperPeerStrategy`**: nominate one or more high-bandwidth / high-uptime peers as super peers; other peers only connect to super peers + a small set of equal peers. Best for asymmetric capacity (server-grade super peer + browser leaves). Reduces edge count to O(n). - **`HubAndSpokeStrategy`**: every peer connects to one of a small configured hub set. Best for centralised topologies (e.g. server- assisted mesh). Lowest edge count, simplest debug surface, no peer- to-peer privacy. Pick `FullMeshStrategy` by default. Move to `SuperPeerStrategy` when peer counts exceed ~20 and `HubAndSpokeStrategy` when the application is fundamentally hub-mediated. --- ## Telemetry Every long-lived component emits OpenTelemetry instrumentation. Names are stable across patch releases: | Metric | Type | Attributes | Description | | ------------------------------------------------- | --------- | --------------------------- | ---------------------------------------------------- | | `drive.webrtc.peers_connected_total` | counter | - | Peers that have reached ICE `connected`. | | `drive.webrtc.chunks_served_total` | counter | `outcome` | Local chunk-serve outcomes (`ok`/`not-found`/...). | | `drive.webrtc.peer_rtt_ms` | histogram | `peer_id` | Round-trip latency per peer (ms). | | `drive.webrtc.signaling_reconnect_ms` | histogram | `attempt`,`outcome` | Reconnect wall-time. | | `drive.webrtc.signaling_messages_total` | counter | `direction`,`outcome` | Signalling messages by direction (in/out) + outcome. | Every collaborator additionally emits its own span (`signaling.connect`, `plugin.start`, `webrtc.ice.restart`, ...). Wire your OTel exporter at process boot — the package does nothing else to initialise the API. --- ## Architecture (text diagram) ``` +---------------------------+ | WebRTCDrivePlugin | | (start / stop / stats) | +-----+----------+----------+ | | +-------------+ +--------------+ v v +-------------------+ +----------------------+ | SignalingClient | wss frames | WebRTCClient | | (WebSocket) | <--------------> | (RTCPeerConnection) | +---------+---------+ +----------+-----------+ | | | peer-joined / peer-left | datachannel v v +-------------------+ +----------------------+ | PeerManager | selects peers | DataChannelManager | | + topology | <--------------> | + backpressure | +---------+---------+ +----------+-----------+ | | | peer rank, bandwidth | sub-chunk v v +-------------------+ +----------------------+ | PeerBandwidth | | SubChunkReassembler | | Tracker | | | +-------------------+ +----------+-----------+ | v +----------------------+ | ChunkDiscoveryMgr | | (ranks, dedups, ver) | +----------+-----------+ | v +----------------------+ | ChunkIntegrityMgr | | (SHA-256, Ed25519) | +----------+-----------+ | v +----------------------+ | WebRTCChunkSource | | (Drive surface) | +----------------------+ ``` Leaf utilities (`LRUCache`, `RateLimiter`, `security-validator`, `sub-chunk-splitter`) are referenced from the components above but have no upward dependency — they remain individually importable. --- ## Configuration Schemas All wire-format and configuration shapes are validated with Zod under `./schemas`. The discriminator-bearing `SignalingMessageSchema` is the single source of truth for every signalling frame; `WebRTCPluginConfigSchema` validates plugin construction options. Direct schema access is available via: ```ts import { SignalingMessageSchema, WebRTCPluginConfigSchema, } from "@suaveplan/drive-webrtc/schemas"; ``` --- ## Error Codes Every boundary throws `DriveWebRtcError` carrying one of the codes from `DRIVE_WEBRTC_CODES`: - `SIGNALING_UNREACHABLE` - `PEER_HANDSHAKE_FAILED` - `CHUNK_INTEGRITY_FAILED` - `ICE_FAILED` - `PEER_BANDWIDTH_EXCEEDED` - `RATE_LIMIT_EXCEEDED` - `SIGNALING_MESSAGE_INVALID` - `CONFIG_INVALID` - `PEER_NOT_FOUND` - `DATA_CHANNEL_CLOSED` - `SUB_CHUNK_TIMEOUT` - `SUB_CHUNK_MISSING` - `CHUNK_NOT_AVAILABLE` Import them directly from the leaf module: ```ts import { DRIVE_WEBRTC_CODES, DriveWebRtcError, } from "@suaveplan/drive-webrtc/errors"; ``` --- ## Drive plugin contract deviation The Drive package exposes the `DrivePlugin` interface with an `install(drive)` shape. The new `WebRTCDrivePlugin` orchestrator surface specified by the migration uses `start()` / `stop()` / `stats()` instead — these two contracts are not directly compatible. The orchestrator class therefore exposes its own lifecycle and a `name: "drive-webrtc"` literal; consumers wire it to Drive with a thin adapter: ```ts const adapter = { name: "drive-webrtc", async install() { await plugin.start(); return { chunkSource: plugin.chunkSource }; }, async dispose() { await plugin.stop(); }, }; await drive.usePlugin(adapter); ``` This deviation is intentional and documented in `webrtc-plugin.md`. --- ## License MIT.