Files
skills/docs/networking/network/network-discovery-trystero/README.md
2026-05-29 08:20:56 +01:00

18 KiB

@suaveplan/network-discovery-trystero - Browser-tier Trystero DiscoveryStrategy: serverless WebRTC peer discovery via four interchangeable transports (BitTorrent / Nostr / MQTT / IPFS) behind a single TrysteroTransportAdapter contract. Insecure-default rejection: every transport requires explicit relay / tracker / broker lists. AbortSignal + EventBusLike + ServiceRegistry + OTel + Zod boundaries.

Summary

Browser-tier DiscoveryStrategy for @suaveplan/network-bootstrap. Serverless WebRTC peer discovery via Trystero, with four interchangeable transports — BitTorrent trackers, Nostr relays, MQTT brokers, and IPFS libp2p pubsub — all sitting behind a single TrysteroTransportAdapter contract. Construction-time transport selection; zero runtime branching on transport-id strings. Optional inter-transport fallback chain using @suaveplan/retry's exponential backoff.

Insecure-default rejection. Every transport requires an explicit non-empty relay / tracker / broker / bootstrap list. The constructor throws INVALID_OPTIONS if any list is empty or missing. No implicit public defaults survive anywhere in the code.

Documentation tree

- [ipfs-transport](./src/core/ipfs-transport/ipfs-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-manager.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-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)_- [ipfs-transport](./src/core/ipfs-transport/ipfs-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-manager.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-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)_- [ipfs-transport](./src/core/ipfs-transport/ipfs-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-manager.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-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)_- [ipfs-transport](./src/core/ipfs-transport/ipfs-transport.md) — _(no submodules)_- [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_ - [mqtt-transport](./src/core/mqtt-transport/mqtt-transport.md) — _(no submodules)_- [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_ - [nostr-transport](./src/core/nostr-transport/nostr-transport.md) — _(no submodules)_- [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_ - [torrent-transport](./src/core/torrent-transport/torrent-transport.md) — _(no submodules)_- [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_ - [trystero-discovery](./src/core/trystero-discovery/trystero-discovery.md) — _(no submodules)_- [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_ - [trystero-fallback](./src/core/trystero-fallback/trystero-fallback.md) — _(no submodules)_- [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_ - [trystero-intervals](./src/core/trystero-intervals/trystero-intervals.md) — _(no submodules)_- [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_ - [trystero-message-handlers](./src/core/trystero-message-handlers/trystero-message-handlers.md) — _(no submodules)_- [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-manager.md) — _(no submodules)_ - [trystero-peer-manager](./src/core/trystero-peer-manager/trystero-peer-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

bun add @suaveplan/network-discovery-trystero
# plus the trystero peer dep if you want the real transports
bun add trystero

Basic example

import { TrysteroDiscovery } from "@suaveplan/network-discovery-trystero";

const strategy = new TrysteroDiscovery({
  appId: "my-app",
  transport: "nostr",
  nostr: { relays: ["wss://relay.example"] },
  nostrRoomFactory: async (appId, config) => {
    const { joinRoom } = await import("trystero/nostr");
    return joinRoom({ relayUrls: config.relays }, appId);
  },
});

await strategy.start();
const peers = await strategy.discover(5000);
console.log(peers);
await strategy.stop();

Advanced example — fallback chain + ServiceRegistry + EventBus

import { EventBus } from "@suaveplan/events";
import { ServiceRegistry } from "@suaveplan/service-discovery";
import {
  TrysteroDiscovery,
  type TrysteroEventMap,
} from "@suaveplan/network-discovery-trystero";

const bus = new EventBus<TrysteroEventMap>();
const registry = new ServiceRegistry();

bus.on("trystero:fallback", (e) =>
  console.log(`fell back ${e.from} -> ${e.to}`),
);
bus.on("trystero:transport-failed", (e) =>
  console.warn(`transport ${e.transport} failed: ${e.reason}`),
);

const strategy = new TrysteroDiscovery({
  appId: "my-app",
  transport: "nostr",
  nostr: { relays: ["wss://nostr.example"] },
  mqtt: { brokers: ["wss://broker.example:1883"] },
  torrent: { trackers: ["wss://tracker.example"] },
  fallbackTransports: ["mqtt", "torrent"],
  nostrRoomFactory: realNostrJoin,
  mqttRoomFactory: realMqttJoin,
  torrentRoomFactory: realTorrentJoin,
  bus,
  registry,
});

await strategy.start();

Documentation

Every implementation file has a sibling .md with full API reference, basic + advanced examples, and implementation notes:

  • src/core/trystero-discovery/trystero-discovery.md — orchestrator
  • src/core/trystero-peer-manager/trystero-peer-manager.md
  • src/core/trystero-intervals/trystero-intervals.md
  • src/core/trystero-fallback/trystero-fallback.md
  • src/core/trystero-message-handlers/trystero-message-handlers.md
  • src/core/torrent-transport/torrent-transport.md
  • src/core/nostr-transport/nostr-transport.md
  • src/core/mqtt-transport/mqtt-transport.md
  • src/core/ipfs-transport/ipfs-transport.md
  • src/errors/errors.md
  • src/otel/otel.md
  • src/types/types.md

License

MIT