# @suaveplan/network-gundb-server - Server-tier GunDB relay daemon for @suaveplan/network-discovery-gundb clients — Node-only HTTP/WebSocket relay with structural Zod wire-payload validation, AbortSignal lifecycle, health/ready/live endpoints, OTel observability, and injectable Gun factory for real-fake integration tests. ## Summary Server-tier GunDB relay daemon. Hosts a Gun relay peer plus standard `/health` / `/ready` / `/live` probes on a single Node `http.Server`. Browser-tier clients running `@suaveplan/network-discovery-gundb` pass `http(s)://:/gun` in their `peers[]` list and gossip signed peer-announces through the relay. ## Documentation tree - [errors](./src/errors/errors.md) — _(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)_ - [listen-http](./src/server/listen-http.md) — Free function that binds a `node:http` server to `(port, host)` and translates the resulting Node EventEmitter signals… - [server](./src/server/server.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_ - [validation](./src/validation/validation.md) — _(no submodules)_ - [validation](./src/validation/validation.md) — _(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)_- [server](./src/server/server.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(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)_- [server](./src/server/server.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(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)_- [server](./src/server/server.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(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)_ - [server](./src/server/server.md) — _(no submodules)_- [types](./src/types/types.md) — _(no submodules)_ - [types](./src/types/types.md) — _(no submodules)_- [validation](./src/validation/validation.md) — _(no submodules)_ - [validation](./src/validation/validation.md) — _(no submodules)_ ## Why this package - **Single daemon, no orchestrator coupling.** Boot the relay, publish the endpoint, watch the health probes. - **Defensive by default.** Every inbound announce is structurally validated against the shared Zod schema; malformed records are dropped silently and counted on `gundb_server.invalid_messages_total{reason}`. - **Injection-friendly.** The Gun runtime is a peer dep — production wires real `Gun`, tests bind a deterministic in-memory fake. - **Lifecycle-correct.** `start({ signal? })` resolves with the bound `{ address, port }`. `stop()` is idempotent. ## Run the daemon ```ts import { GunDBServer } from "@suaveplan/network-gundb-server"; import Gun from "gun"; const server = new GunDBServer({ port: 8765, host: "0.0.0.0", storagePath: "./data/gun", radisk: true, maxConnections: 256, gunFactory: (cfg) => Gun(cfg), }); const { address, port } = await server.start(); console.log(`relay listening on ${address}:${port}/gun`); process.on("SIGTERM", async () => { await server.stop(); process.exit(0); }); ``` ## Configuration reference See [`src/types/types.md`](./src/types/types.md) for the full strict `GunDBServerConfig`. All fields except `port` and `gunFactory` are optional and have spec-documented defaults. ## 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`](./src/health/health.md). ## Observability OpenTelemetry instrument names emitted by the daemon: - `gundb_server.start` / `gundb_server.stop` — spans. - `gundb_server.connections_total{outcome}` — counter. - `gundb_server.messages_relayed_total{outcome}` — counter. - `gundb_server.invalid_messages_total{reason}` — security counter. - `gundb_server.active_connections` — up-down gauge. - `gundb_server.start_duration_ms` — histogram. See [`src/otel/otel.md`](./src/otel/otel.md). ## Security model The relay does **not** verify Ed25519 signatures on inbound announces — signature verification is the client's responsibility per the gossip security model. The relay structurally validates the presence and shape of every signature field so a malformed announce cannot poison the namespace, then forwards the signed payload unchanged. See [`src/validation/validation.md`](./src/validation/validation.md). ## Companion package [`@suaveplan/network-discovery-gundb`](../network-discovery-gundb) is the browser-tier client this daemon serves.