# @suaveplan/network-discovery-peerjs - Browser-tier PeerJS DiscoveryStrategy: wraps PeerJS signalling client + WebRTC DataConnections, produces deduped PeerInfo[] for @suaveplan/network-bootstrap chains with @suaveplan/events, @suaveplan/timing, AbortSignal, OTel and Zod boundaries. ## Summary Browser-tier `DiscoveryStrategy` for `@suaveplan/network-bootstrap` that wraps a [PeerJS](https://peerjs.com) signalling-server client + WebRTC `DataConnection`s into a deduped peer set. ## Documentation tree - [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_ - [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_ - [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_ - [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_ - [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_ - [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_ - [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_ - [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_ - [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_ - [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_ - [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_ - [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_ - [errors](./src/errors/errors.md) — _(no submodules)_ - [errors](./src/errors/errors.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_ - [plugin](./src/plugin/plugin.md) — _(no submodules)_ - [plugin](./src/plugin/plugin.md) — _(no submodules)_ - [transport](./src/transport/transport.md) — _(no submodules)_ - [transport](./src/transport/transport.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_ - [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [peer-connection-manager](./src/core/peer-connection-manager/peer-connection-manager.md) — _(no submodules)_- [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_ - [peerjs-connection](./src/core/peerjs-connection/peerjs-connection.md) — _(no submodules)_- [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_ - [peerjs-discovery](./src/core/peerjs-discovery/peerjs-discovery.md) — _(no submodules)_- [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_ - [peerjs-intervals](./src/core/peerjs-intervals/peerjs-intervals.md) — _(no submodules)_- [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_ - [peerjs-message-handlers](./src/core/peerjs-message-handlers/peerjs-message-handlers.md) — _(no submodules)_- [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_ - [room-manager](./src/core/room-manager/room-manager.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_ - [errors](./src/errors/errors.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_ - [plugin](./src/plugin/plugin.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_ - [transport](./src/transport/transport.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_ ## Install ```sh bun add @suaveplan/network-discovery-peerjs ``` ## Quick start ```ts import Peer from "peerjs"; import { PeerJSDiscovery } from "@suaveplan/network-discovery-peerjs"; const discovery = new PeerJSDiscovery({ host: "signaling.example.com", room: "demo", peerFactory: (peerId, opts) => new Peer(peerId, opts) as unknown as any, }); await discovery.start(); const peers = await discovery.discover(5_000); console.log("peers", peers); await discovery.stop(); ``` ## Composing into a `DiscoveryChain` ```ts import { DiscoveryChain } from "@suaveplan/network-bootstrap"; import { PeerJSDiscovery } from "@suaveplan/network-discovery-peerjs"; const chain = new DiscoveryChain({ strategies: [discovery] }); const peers = await chain.discover(2_000); ``` ## Wiring an `EventBus` and a `ServiceRegistry` ```ts import { EventBus } from "@suaveplan/events"; import { ServiceRegistry } from "@suaveplan/service-discovery"; import { PeerJSDiscovery } from "@suaveplan/network-discovery-peerjs"; const bus = new EventBus(); const registry = new ServiceRegistry(); const discovery = new PeerJSDiscovery({ host: "signaling.example.com", room: "alpha", bus, registry, peerFactory, }); bus.on("peerjs:peer-discovered", (e) => console.log("found", e.peer.id)); ``` ## Why `host` and `peerFactory` are required The constructor refuses to start without an explicit `host` (no fallback to the public `0.peerjs.com` cloud) and without an injected `peerFactory` (the underlying `peerjs` package is a peer dep so that consumers can choose their own version and so that tests can inject a deterministic stub without spinning up a real broker). See `src/core/peerjs-discovery/peerjs-discovery.md` for the full lifecycle contract. ## Modules - `peerjs-discovery` — orchestrator implementing `DiscoveryStrategy`. - `peer-connection-manager` — owns the `PeerLike` + connection registry. - `room-manager` — deduped peer set, TTL pruning, optional bus/registry fan-out. - `peerjs-connection` — low-level peer/connection helpers (pure functions). - `peerjs-message-handlers` — Zod-validated wire-format dispatch table. - `peerjs-intervals` — announce / heartbeat / cleanup loops over the `@suaveplan/timing` scheduler. - `errors` — `NET_DISC_PEERJS_CODES` registry + `NetDiscPeerJSError`. - `otel` — `disc_peerjs.*` span, counter, histogram. ## Status Wave 2.1 (migration). 100/100/100/100 coverage gate, Zod boundaries, OTel surface, AbortSignal end-to-end, no public-broker default.