first commit
This commit is contained in:
129
docs/networking/network/network-libp2p-server/README.md
Normal file
129
docs/networking/network/network-libp2p-server/README.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# @suaveplan/network-libp2p-server - Server-tier libp2p relay daemon (bootstrap + circuit-relay-v2) paired with @suaveplan/network-transport-libp2p — Node-only HTTP/libp2p host with structural Zod option validation, AbortSignal lifecycle, health/ready/live endpoints, OTel observability, and injectable libp2p factory for real-fake integration tests.
|
||||
|
||||
## Summary
|
||||
|
||||
Server-tier libp2p relay daemon paired with
|
||||
[`@suaveplan/network-transport-libp2p`](../network-transport-libp2p).
|
||||
Hosts a libp2p node configured as a bootstrap + circuit-relay-v2 server
|
||||
alongside an inline HTTP listener exposing `/health`, `/ready`, `/live`
|
||||
verbs.
|
||||
|
||||
<!-- 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 -->
|
||||
- [health-listener](./src/server/health-listener.md) — Wraps the asynchronous `http.Server.listen(port, host)` flow with the listener-attach / `EADDRINUSE` classification / `…
|
||||
- [peer-events](./src/server/peer-events.md) — Wires the `peer:connect` and `peer:disconnect` event listeners onto a `Libp2pServerNodeLike` and bridges them onto the…
|
||||
- [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 -->
|
||||
<!-- 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)_- [health-listener](./src/server/health-listener.md) — Wraps the asynchronous `http.Server.listen(port, host)` flow with the listener-attach / `EADDRINUSE` classification / `…
|
||||
- [peer-events](./src/server/peer-events.md) — Wires the `peer:connect` and `peer:disconnect` event listeners onto a `Libp2pServerNodeLike` and bridges them onto the…
|
||||
- [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)_- [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)_- [health-listener](./src/server/health-listener.md) — Wraps the asynchronous `http.Server.listen(port, host)` flow with the listener-attach / `EADDRINUSE` classification / `…
|
||||
- [peer-events](./src/server/peer-events.md) — Wires the `peer:connect` and `peer:disconnect` event listeners onto a `Libp2pServerNodeLike` and bridges them onto the…
|
||||
- [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)_- [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)_- [health-listener](./src/server/health-listener.md) — Wraps the asynchronous `http.Server.listen(port, host)` flow with the listener-attach / `EADDRINUSE` classification / `…
|
||||
- [peer-events](./src/server/peer-events.md) — Wires the `peer:connect` and `peer:disconnect` event listeners onto a `Libp2pServerNodeLike` and bridges them onto the…
|
||||
- [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)_- [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)_ - [health-listener](./src/server/health-listener.md) — Wraps the asynchronous `http.Server.listen(port, host)` flow with the listener-attach / `EADDRINUSE` classification / `…
|
||||
- [peer-events](./src/server/peer-events.md) — Wires the `peer:connect` and `peer:disconnect` event listeners onto a `Libp2pServerNodeLike` and bridges them onto the…
|
||||
- [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)_
|
||||
## Run the daemon
|
||||
|
||||
```ts
|
||||
import { createLibp2p } from "libp2p";
|
||||
import { tcp } from "@libp2p/tcp";
|
||||
import { webSockets } from "@libp2p/websockets";
|
||||
import { noise } from "@chainsafe/libp2p-noise";
|
||||
import { yamux } from "@chainsafe/libp2p-yamux";
|
||||
import { identify } from "@libp2p/identify";
|
||||
import { circuitRelayServer } from "@libp2p/circuit-relay-v2";
|
||||
import { bootstrap } from "@libp2p/bootstrap";
|
||||
import { Libp2pServer } from "@suaveplan/network-libp2p-server";
|
||||
|
||||
const server = new Libp2pServer({
|
||||
listen: ["/ip4/0.0.0.0/tcp/9090", "/ip4/0.0.0.0/tcp/9091/ws"],
|
||||
bootstrap: ["/dnsaddr/bootstrap.libp2p.io/p2p/QmNnoo..."],
|
||||
autoRelay: { enabled: true, maxConnections: 500 },
|
||||
healthPort: 9099,
|
||||
libp2pFactory: async (cfg) =>
|
||||
createLibp2p({
|
||||
addresses: { listen: [...cfg.listen] },
|
||||
transports: [tcp(), webSockets()],
|
||||
connectionEncrypters: [noise()],
|
||||
streamMuxers: [yamux()],
|
||||
peerDiscovery:
|
||||
cfg.bootstrap.length > 0
|
||||
? [bootstrap({ list: [...cfg.bootstrap] })]
|
||||
: [],
|
||||
services: {
|
||||
identify: identify(),
|
||||
relay: circuitRelayServer({
|
||||
reservations: {
|
||||
maxReservations: cfg.autoRelay.maxConnections,
|
||||
},
|
||||
}),
|
||||
},
|
||||
connectionManager: { maxConnections: cfg.maxConnections },
|
||||
}),
|
||||
});
|
||||
|
||||
const { peerId, multiaddrs } = await server.start();
|
||||
console.log(`libp2p relay ${peerId} on:`);
|
||||
for (const a of multiaddrs) console.log(` ${a}`);
|
||||
|
||||
// Graceful shutdown
|
||||
process.on("SIGTERM", () => server.stop());
|
||||
```
|
||||
|
||||
## Test environment
|
||||
|
||||
Tests inject a deterministic `FakeLibp2pServerNode` so the native
|
||||
transitive deps of the real `libp2p` package never enter the test
|
||||
surface — the daemon never resolves `libp2p` at module evaluation time
|
||||
and the integration suite boots a real `Libp2pServer` inside the test
|
||||
process.
|
||||
|
||||
```ts
|
||||
import { Libp2pServer } from "@suaveplan/network-libp2p-server";
|
||||
import {
|
||||
FakeLibp2pHub,
|
||||
makeFakeServerFactory,
|
||||
} from "./tests/setup/fake-libp2p-server.js";
|
||||
|
||||
const hub = new FakeLibp2pHub();
|
||||
const { factory } = makeFakeServerFactory(hub);
|
||||
const server = new Libp2pServer({
|
||||
libp2pFactory: factory,
|
||||
listen: ["/ip4/0.0.0.0/tcp/0"],
|
||||
healthPort: 0,
|
||||
});
|
||||
await server.start();
|
||||
// ... drive the daemon, then:
|
||||
await server.stop();
|
||||
```
|
||||
|
||||
## Acceptance gates
|
||||
|
||||
- `bunx turbo lint typecheck test --filter=@suaveplan/network-libp2p-server`
|
||||
- `bunx turbo test:coverage --filter=@suaveplan/network-libp2p-server` → 100/100/100/100
|
||||
- `bun run docs:check --filter=@suaveplan/network-libp2p-server`
|
||||
|
||||
## API
|
||||
|
||||
See per-module `.md` docs:
|
||||
|
||||
- [`src/server/server.md`](src/server/server.md) — `Libp2pServer` daemon
|
||||
- [`src/server/peer-events.md`](src/server/peer-events.md) — peer
|
||||
connect/disconnect bridging
|
||||
- [`src/server/health-listener.md`](src/server/health-listener.md) —
|
||||
inline-HTTP `listenHttp` helper
|
||||
- [`src/health/health.md`](src/health/health.md) — `/health` / `/ready`
|
||||
/ `/live` verb pipeline
|
||||
- [`src/otel/otel.md`](src/otel/otel.md) — OTel instrumentation surface
|
||||
- [`src/errors/errors.md`](src/errors/errors.md) — error registry
|
||||
- [`src/types/types.md`](src/types/types.md) — public type contracts
|
||||
Reference in New Issue
Block a user