Files
skills/docs/networking/drive/drive-webrtc/README.md
2026-05-29 08:20:56 +01:00

396 lines
40 KiB
Markdown

# @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.
---
<!-- begin:auto-docs -->
## Documentation tree
- [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [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) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [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) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [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) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [security-validator](./src/security/security-validator/security-validator.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [chunk-source](./src/chunk-source/chunk-source/chunk-source.md) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [security-validator](./src/security/security-validator/security-validator.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_- [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_ - [client](./src/client/client/client.md) — <!-- begin:auto-docs --> _(no submodules)_- [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_ - [ice](./src/client/ice/ice.md) — <!-- begin:auto-docs --> _(no submodules)_- [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_ - [offer-answer](./src/client/offer-answer/offer-answer.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_ - [reconnect](./src/client/reconnect/reconnect.md) — <!-- begin:auto-docs --> _(no submodules)_- [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [data-channel-manager](./src/data-channel/data-channel-manager/data-channel-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [chunk-discovery-manager](./src/discovery/chunk-discovery-manager/chunk-discovery-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_ - [typed-event-emitter](./src/events/typed-event-emitter/typed-event-emitter.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_ - [chunk-integrity](./src/integrity/chunk-integrity/chunk-integrity.md) — <!-- begin:auto-docs --> _(no submodules)_- [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_ - [lru-cache](./src/lru-cache/lru-cache/lru-cache.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_ - [peer-bandwidth-tracker](./src/peer-manager/peer-bandwidth-tracker/peer-bandwidth-tracker.md) — <!-- begin:auto-docs --> _(no submodules)_- [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [peer-manager](./src/peer-manager/peer-manager/peer-manager.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_ - [webrtc-plugin](./src/plugin/webrtc-plugin/webrtc-plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(no submodules)_ - [rate-limiter](./src/rate-limiter/rate-limiter/rate-limiter.md) — <!-- begin:auto-docs --> _(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) — <!-- begin:auto-docs --> _(no submodules)_ - [security-validator](./src/security/security-validator/security-validator.md) — <!-- begin:auto-docs --> _(no submodules)_- [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_ - [signaling-client](./src/signaling/signaling-client/signaling-client.md) — <!-- begin:auto-docs --> _(no submodules)_- [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(no submodules)_ - [sub-chunk](./src/sub-chunk/sub-chunk/sub-chunk.md) — <!-- begin:auto-docs --> _(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<THandle>` 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.