Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
# OpenSpec Change: enterprise-browser-network-libp2p
- **Change ID**: enterprise-browser-network-libp2p
- **Package**: `@suaveplan/network-libp2p`
- **Category**: browser
- **Target path**: `browser/network/network-libp2p`
- **Status**: SUPERSEDED-BY-GENESIS-WAVE
- **Date**: 2026-04-24
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/network-libp2p.md`
---
## Summary
Deliver `@suaveplan/network-libp2p` on the genesis branch from scratch at enterprise quality. The package provides the browser-side libp2p transport for `@suaveplan/network`, stitching together the canonical libp2p stack (WebSockets, WebRTC, Noise, Yamux, identify, ping, bootstrap, circuit-relay-v2) into a `Libp2pTransport` class with connection lifecycle, peer addressing, streaming messaging, and metrics. No React dependencies — demo UI moves to a companion package.
---
## Current-state audit (genesis)
The package does not exist on genesis yet — fresh build.
---
## Available workspace deps on genesis
| Package | Role |
|---|---|
| `@suaveplan/network` (`workspace:^`) | `Transport` interface, peer/connection types |
| `@suaveplan/error` (`workspace:^`) | Typed libp2p errors |
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
| `@suaveplan/events` (`workspace:^`) | Event maps |
| `@suaveplan/serialize` (`workspace:^`) | Wire message encoding |
| `@suaveplan/schema-registry` (`workspace:^`) | Config schema registration |
| `zod` (`catalog:forms`) | `Libp2pConfig` schema |
| `@opentelemetry/api` (`catalog:observability`) | Connection/stream counters, latency histograms |
| `tslib` (`catalog:build`) | Runtime helpers |
External libp2p deps (from Bun catalog): `libp2p`, `@libp2p/websockets`, `@libp2p/webrtc`, `@libp2p/bootstrap`, `@libp2p/circuit-relay-v2`, `@libp2p/identify`, `@libp2p/ping`, `@libp2p/interface`, `@chainsafe/libp2p-noise`, `@chainsafe/libp2p-yamux`, `@multiformats/multiaddr`.
No `react` / `react-dom` in runtime deps.
Dev deps: `vitest`, `@vitest/coverage-istanbul`, `@playwright/test` (`catalog:testing`), `@suaveplan/testing workspace:^`.
---
## Preserved public API surface (from main branch)
```ts
class Libp2pTransport {
constructor(config: Libp2pConfig)
start(): Promise<void>
stop(): Promise<void>
dial(addr: Multiaddr | string): Promise<Libp2pConnection>
send(peerId: PeerId, protocol: string, message: Uint8Array): Promise<void>
request(peerId: PeerId, protocol: string, message: Uint8Array): Promise<Uint8Array>
registerHandler(protocol: string, handler: StreamHandler): void
unregisterHandler(protocol: string): void
getConnectedPeers(): PeerId[]
getMetrics(): Libp2pMetrics
on(event: 'peer:connect', handler: (peer: Libp2pPeerInfo) => void): void
on(event: 'peer:disconnect', handler: (peer: Libp2pPeerInfo) => void): void
on(event: 'error', handler: (error: Error) => void): void
}
interface Libp2pConfig {
listenAddresses?: string[]
bootstrapPeers?: string[] // Must be explicit; no public defaults unless strict: false
relayAddrs?: string[]
enableWebRTC?: boolean
enableWebSockets?: boolean
strict?: boolean // Default true; rejects public bootstrap peers
}
interface Libp2pMetrics { connectionsOpened: number; streamsOpened: number; bytesIn: number; bytesOut: number }
interface Libp2pPeerInfo { peerId: PeerId; multiaddrs: Multiaddr[]; protocols: string[] }
type StreamHandler = (stream: Stream, connection: Connection) => Promise<void>
```
---
## New additions for genesis
### 1. Structured errors via `@suaveplan/error`
Error codes: `LIBP2P_DIAL_FAILED`, `LIBP2P_STREAM_RESET`, `LIBP2P_UNSUPPORTED_TRANSPORT`, `LIBP2P_BOOTSTRAP_REJECTED`, `LIBP2P_RELAY_INVALID`.
### 2. Strict-mode bootstrap gate
When `strict: true` (default), `Libp2pConfig.bootstrapPeers` must be explicitly supplied; throw `LIBP2P_BOOTSTRAP_REJECTED` if the list is empty. Users who want public defaults must set `strict: false`.
### 3. Transport presets
```ts
const presets = {
browserP2P(): Libp2pConfig // WebRTC + WebSocket + Yamux + Noise + identify + ping
browserBrowser(): Libp2pConfig // WebRTC only
browserNode(): Libp2pConfig // WebSocket + circuit-relay
}
```
### 4. `Libp2pConfig` Zod schema
Full runtime validation of config; registered in `@suaveplan/schema-registry`.
### 5. OTel metrics
Counters `libp2p.connections_opened_total`, `libp2p.streams_opened_total`, `libp2p.bytes_in_total`, `libp2p.bytes_out_total`; histograms `libp2p.dial_ms`, `libp2p.stream_ttfb_ms`.
### 6. Relay-addr validator
`validateRelayAddrs(addrs)` checks multiaddr format and rejects obviously insecure patterns.
---
## File layout
```text
browser/network/network-libp2p/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
lib/
libp2p-connection/
libp2p-connection.ts
libp2p-connection.md
libp2p-connection.test.ts
index.ts
libp2p-messaging/
libp2p-messaging.ts
libp2p-messaging.md
libp2p-messaging.test.ts
index.ts
peer-message/
peer-message.ts
peer-message.md
peer-message.test.ts
index.ts
send-to-peer/
send-to-peer.ts
send-to-peer.md
send-to-peer.test.ts
index.ts
stream-handler/
stream-handler.ts
stream-handler.md
stream-handler.test.ts
index.ts
transport/
libp2p-transport/
libp2p-transport.ts
libp2p-transport.md
libp2p-transport.types.ts
libp2p-transport.test.ts
index.ts
presets/
presets/
presets.ts
presets.md
presets.test.ts
index.ts
config/
config-schema/
config-schema.ts
config-schema.md
index.ts
tests/
integration.test.ts
e2e/
libp2p.spec.ts (two real libp2p nodes, echo protocol)
```
---
## Impact
**Downstream**: P2P networking layers, drive distribution, real-time collaboration.
**Breaking changes**: `react` / `react-dom` removed from runtime deps (demo relocated).
**Prerequisites**: `@suaveplan/network`, `@suaveplan/serialize`, `@suaveplan/error`, `@suaveplan/events` on Verdaccio.