Initial Commit
This commit is contained in:
108
packages/networking/network/network-gundb-server/README.md
Normal file
108
packages/networking/network/network-gundb-server/README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# @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)://<host>:<port>/gun` in their `peers[]` list and gossip
|
||||
signed peer-announces through the relay.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [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) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
<!-- end:auto-docs --> - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_ - [health](./src/health/health.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_ - [server](./src/server/server.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ - [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(no submodules)_ - [validation](./src/validation/validation.md) — <!-- begin:auto-docs --> _(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.
|
||||
Reference in New Issue
Block a user