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

@suaveplan/network-trystero-server - Server-tier Trystero signaling daemon — hosts an MQTT broker shim or Nostr relay shim over plain WebSocket for browser-tier @suaveplan/network-discovery-trystero clients. Construction-time mode selection, injectable broker factory, AbortSignal lifecycle, health/ready/live endpoints, OTel observability, real-fake integration tests.

Summary

Server-tier Trystero signaling daemon. Hosts an MQTT-style or Nostr-style WebSocket broker shim plus standard /health / /ready / /live probes on a single Node http.Server. Browser-tier clients running @suaveplan/network-discovery-trystero connect to the daemon's published relayUrl for relay-backed P2P signaling.

Documentation tree

  • errors — (no submodules)
  • health — (no submodules)
  • otel — (no submodules)
    • otel — (no submodules)
  • server — (no submodules)
    • broker-select — The broker-select module resolves which broker factory the daemon hosts and bundles the matching mode-specific options…
    • health-listener — The health-listener helper extracts the http.Server.listen promise adapter out of the main daemon module so the daemo…
    • peer-events — The peer-events module owns the daemon-side wiring of broker lifecycle callbacks into the daemon's connection table, OT…
    • server — (no submodules)
  • types — (no submodules)
    • types — (no submodules)
- [errors](./src/errors/errors.md) — _(no submodules)_- [health](./src/health/health.md) — _(no submodules)_- [health](./src/health/health.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [server](./src/server/server.md) — _(no submodules)_- [broker-select](./src/server/broker-select.md) — The broker-select module resolves which broker factory the daemon hosts and bundles the matching mode-specific options…
  • health-listener — The health-listener helper extracts the http.Server.listen promise adapter out of the main daemon module so the daemo…
  • peer-events — The peer-events module owns the daemon-side wiring of broker lifecycle callbacks into the daemon's connection table, OT…
  • server — (no submodules)- types — (no submodules)- types — (no submodules)- errors — (no submodules)- health — (no submodules)- health — (no submodules)- otel — (no submodules)- otel — (no submodules)- server — (no submodules)- broker-select — The broker-select module resolves which broker factory the daemon hosts and bundles the matching mode-specific options…
  • health-listener — The health-listener helper extracts the http.Server.listen promise adapter out of the main daemon module so the daemo…
  • peer-events — The peer-events module owns the daemon-side wiring of broker lifecycle callbacks into the daemon's connection table, OT…
  • server — (no submodules)- types — (no submodules)- types — (no submodules)- errors — (no submodules)- health — (no submodules)- health — (no submodules)- otel — (no submodules)- otel — (no submodules)- server — (no submodules)- broker-select — The broker-select module resolves which broker factory the daemon hosts and bundles the matching mode-specific options…
  • health-listener — The health-listener helper extracts the http.Server.listen promise adapter out of the main daemon module so the daemo…
  • peer-events — The peer-events module owns the daemon-side wiring of broker lifecycle callbacks into the daemon's connection table, OT…
  • server — (no submodules)- types — (no submodules)- types — (no submodules)- errors — (no submodules)- health — (no submodules) - health — (no submodules)- otel — (no submodules) - otel — (no submodules)- server — (no submodules) - broker-select — The broker-select module resolves which broker factory the daemon hosts and bundles the matching mode-specific options…
  • health-listener — The health-listener helper extracts the http.Server.listen promise adapter out of the main daemon module so the daemo…
  • peer-events — The peer-events module owns the daemon-side wiring of broker lifecycle callbacks into the daemon's connection table, OT…
  • server — (no submodules)- types — (no submodules) - types — (no submodules)

Why this package

  • One daemon, one mode. Construction-time selection between "mqtt" and "nostr". No runtime branching past the broker factory, so dashboards split cleanly by mode label.
  • Defensive by default. Malformed frames flow through onMalformedFrame and increment trystero_server.messages_relayed_total{outcome="error"} without ever crashing the relay.
  • Injection-friendly. The broker shim is a peer dependency on intent — production wires a real WebSocket broker, tests bind a deterministic in-memory FakeBroker.
  • Lifecycle-correct. start({ signal? }) resolves with { address, port, mode, relayUrl }. stop() is idempotent and drains in-flight peers.

Run the daemon

import {
    TrysteroServer,
    type BrokerFactory,
} from "@suaveplan/network-trystero-server";

const mqttBrokerFactory: BrokerFactory = (deps) => {
    // attach to the daemon's http.Server, handle WS upgrade, etc.
    return {
        mode: deps.mode,
        activeConnections: 0,
        async start({ httpServer, callbacks }) {
            // real broker wiring
        },
        async stop() {
            // drain sockets, close listeners
        },
    };
};

const server = new TrysteroServer({
    mode: "mqtt",
    port: 8765,
    host: "0.0.0.0",
    maxConnections: 256,
    mqttBrokerFactory,
});

const { relayUrl } = await server.start();
console.log(`trystero relay listening on ${relayUrl}`);

process.on("SIGTERM", async () => {
    await server.stop();
    process.exit(0);
});

Modes

Mode Wire path Mode-specific options
mqtt /mqtt { password? }
nostr /nostr { relayName? }

Both modes follow the same wire-formatting contract from the browser-tier companion package @suaveplan/network-discovery-trystero — the daemon publishes the matching relayUrl and the discovery client treats it as a relay endpoint.

Configuration reference

See src/types/types.md for the full strict TrysteroServerConfig. The only required fields are mode, port, and the per-mode broker factory. Every other field is optional with a spec-documented default.

Health endpoints

Verb 200 OK when 503 when
/live process alive (always, until stop) after stop()
/ready started AND below maxConnections starting, at-cap, or stopped
/health started AND below maxConnections starting, at-cap, or stopped

See src/health/health.md.

Observability

OpenTelemetry instrument names emitted by the daemon:

  • trystero_server.start / trystero_server.stop — spans.
  • trystero_server.connections_total{mode,outcome} — counter.
  • trystero_server.messages_relayed_total{mode,outcome} — counter.
  • trystero_server.active_connections{mode} — up-down gauge.
  • trystero_server.start_duration_ms{mode} — histogram.

See src/otel/otel.md.

Companion package

@suaveplan/network-discovery-trystero is the browser-tier client this daemon serves.