# @suaveplan/network-discovery-webtorrent - Browser-tier WebTorrent DiscoveryStrategy: WebTorrent-tracker-driven WebRTC peer discovery via p2pt. Tracker list REQUIRED — no public-tracker fallback. AbortSignal + EventBusLike + ServiceRegistry + OTel + Zod boundaries. ## Summary Browser-tier `DiscoveryStrategy` for `@suaveplan/network-bootstrap` chains. Wraps a [`p2pt`](https://github.com/subins2000/p2pt) instance — WebTorrent-tracker-driven WebRTC peer discovery — and exposes a deduped, capped peer set to the bootstrap pipeline. ## Documentation tree - [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.md) — _(no submodules)_ - [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.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)_ - [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.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)_- [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.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)_- [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.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)_- [webtorrent-discovery](./src/core/webtorrent-discovery/webtorrent-discovery.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)_ ## Why this package - Plug-and-play `DiscoveryStrategy` slot for network bootstrap chains. Works alongside `@suaveplan/network-discovery-peerjs`, `@suaveplan/network-discovery-trystero`, and `@suaveplan/network-discovery-crdt`. - **Tracker list REQUIRED.** Upstream's hard-coded public-tracker fallback was removed. Callers must supply their own tracker infrastructure. - Injectable `p2ptFactory` — production wires the real `p2pt`; tests bind a deterministic `P2PTLike` fake (no `vi.mock` ever used). - Typed `EventBusLike` integration. - Optional `@suaveplan/service-discovery` `ServiceRegistry` mirroring. - OTel surface: `disc_webtorrent.start` span; `peers_discovered_total{outcome}`, `tracker_errors_total{tracker}`, `tracker_announce_duration_ms` instruments. - AbortSignal honoured on every async public method. - 100% test + branch + function + line coverage. ## Basic example ```ts import { WebTorrentDiscovery } from "@suaveplan/network-discovery-webtorrent"; const discovery = new WebTorrentDiscovery({ trackers: ["wss://my-tracker.example.com"], p2ptFactory: async (trackers, announceId) => { const { default: P2PT } = await import("p2pt"); return new P2PT(trackers as string[], announceId); }, }); await discovery.start(); const peers = await discovery.discover(5_000); console.log(`found ${peers.length} peers`); await discovery.stop(); ``` ## Advanced example ```ts import { EventBus } from "@suaveplan/events"; import { ServiceRegistry } from "@suaveplan/service-discovery"; import { DiscoveryChain } from "@suaveplan/network-bootstrap"; import { WebTorrentDiscovery, type WebTorrentEventMap, } from "@suaveplan/network-discovery-webtorrent"; const bus = new EventBus(); const registry = new ServiceRegistry(); bus.on("webtorrent:peer-discovered", ({ peer }) => { console.log("peer:", peer.id, peer.addresses); }); bus.on("webtorrent:tracker-error", ({ reason }) => { console.warn("tracker:", reason); }); const discovery = new WebTorrentDiscovery({ trackers: [ "wss://my-tracker-a.example.com", "wss://my-tracker-b.example.com", ], announceId: "my-app/v1", maxPeers: 256, p2ptFactory: async (trackers, id) => { const { default: P2PT } = await import("p2pt"); return new P2PT(trackers as string[], id); }, bus, registry, }); const chain = new DiscoveryChain([discovery]); const peers = await chain.discover(5_000); ``` ## API See sibling co-located markdown: - [`src/types/types.md`](./src/types/types.md) - [`src/errors/errors.md`](./src/errors/errors.md) - [`src/otel/otel.md`](./src/otel/otel.md) - [`src/core/webtorrent-discovery/webtorrent-discovery.md`](./src/core/webtorrent-discovery/webtorrent-discovery.md) ## License MIT