@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)
- 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.listenpromise 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)
- health-listener — The health-listener helper extracts the
http.Server.listenpromise 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.listenpromise 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.listenpromise 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.listenpromise 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 bymodelabel. - Defensive by default. Malformed frames flow through
onMalformedFrameand incrementtrystero_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.