Initial Commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# OpenSpec Change: enterprise-browser-network-discovery-peerjs
|
||||
|
||||
- **Change ID**: enterprise-browser-network-discovery-peerjs
|
||||
- **Package**: `@suaveplan/network-discovery-peerjs`
|
||||
- **Category**: browser
|
||||
- **Target path**: `browser/network/network-discovery-peerjs`
|
||||
- **Status**: SUPERSEDED-BY-GENESIS-WAVE
|
||||
- **Date**: 2026-04-24
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/network-discovery-peerjs.md`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Deliver `@suaveplan/network-discovery-peerjs` on the genesis branch at enterprise quality. The package implements `DiscoveryStrategy` for `@suaveplan/network` wrapping the PeerJS signalling client. Ships `PeerJSDiscovery`, `PeerConnectionManager`, `RoomManager`, `PeerJSEventEmitter`, `PeerJSIntervals`, and `PeerJSMessageHandlers` with strict-mode that refuses the public PeerJS cloud, Zod-validated messages, full unit tests for every module, and an ICE-passthrough config.
|
||||
|
||||
---
|
||||
|
||||
## Current-state audit (genesis)
|
||||
|
||||
Fresh build — does not exist on genesis yet.
|
||||
|
||||
---
|
||||
|
||||
## Available workspace deps on genesis
|
||||
|
||||
| Package | Role |
|
||||
|---|---|
|
||||
| `@suaveplan/network` (`workspace:^`) | `DiscoveryStrategy` interface |
|
||||
| `@suaveplan/error` (`workspace:^`) | Typed PeerJS errors |
|
||||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
||||
| `@suaveplan/crypto` (`workspace:^`) | Optional signed metadata |
|
||||
| `@suaveplan/schema-registry` (`workspace:^`) | Message schema registration |
|
||||
| `zod` (`catalog:forms`) | `PeerJSMessage` Zod schemas |
|
||||
| `@opentelemetry/api` (`catalog:observability`) | Connection/room metrics |
|
||||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||||
|
||||
External: `peerjs` (Bun catalog). React in devDeps for story.
|
||||
|
||||
---
|
||||
|
||||
## Preserved public API surface
|
||||
|
||||
```ts
|
||||
class PeerJSDiscovery implements DiscoveryStrategy {
|
||||
constructor(config: PeerJSDiscoveryConfig)
|
||||
start(): Promise<void>
|
||||
stop(): Promise<void>
|
||||
getPeers(): PeerInfo[]
|
||||
on(event: string, handler: Function): void
|
||||
|
||||
static selfHosted(options: { host: string; port: number; path: string; secure: boolean }): PeerJSDiscovery
|
||||
}
|
||||
|
||||
interface PeerJSDiscoveryConfig {
|
||||
host: string // Required; no default to 0.peerjs.com
|
||||
port: number
|
||||
path: string
|
||||
secure: boolean // Must be true in production
|
||||
roomId: string
|
||||
iceServers?: RTCIceServer[]
|
||||
strict?: boolean // Default true; rejects default cloud host
|
||||
}
|
||||
// + PeerJSMessage, PeerJSMessageType, PeerJSPeerMetadata
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## New additions for genesis
|
||||
|
||||
### 1. Strict-mode gate
|
||||
|
||||
Refuses to start if `host` is the public PeerJS cloud (`0.peerjs.com` / `peerjs.com`) when `strict: true`.
|
||||
|
||||
### 2. `selfHosted` static factory
|
||||
|
||||
`PeerJSDiscovery.selfHosted({ host, port, path, secure })` — a self-hosting preset that enforces strict mode automatically.
|
||||
|
||||
### 3. Zod-validated messages
|
||||
|
||||
`PeerJSMessageSchema` variants for `PEER_ANNOUNCE`, `PEER_LEAVE`, `PING`, `PONG`; validated in `PeerJSMessageHandlers` with `PEERJS_MESSAGE_REJECTED` on failure.
|
||||
|
||||
### 4. Reconnection policy
|
||||
|
||||
Exponential backoff + jitter on signalling dropouts; `'connection:lost'` + `'connection:restored'` typed events.
|
||||
|
||||
### 5. Optional signed metadata
|
||||
|
||||
When `config.sign: true`, metadata signed with `@suaveplan/crypto` ed25519.
|
||||
|
||||
### 6. ICE server passthrough
|
||||
|
||||
`PeerJSDiscoveryConfig.iceServers` forwarded to PeerJS's WebRTC config.
|
||||
|
||||
### 7. Error codes
|
||||
|
||||
`PEERJS_SIGNALING_UNREACHABLE`, `PEERJS_ROOM_FULL`, `PEERJS_CONNECTION_FAILED`, `PEERJS_MESSAGE_REJECTED`.
|
||||
|
||||
### 8. OTel metrics
|
||||
|
||||
Counter `discovery.peerjs.connections_opened_total`, counter `discovery.peerjs.rooms_joined_total`, histogram `discovery.peerjs.signaling_rtt_ms`.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```text
|
||||
browser/network/network-discovery-peerjs/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
index.ts
|
||||
error-codes.ts
|
||||
peerjs-discovery/
|
||||
peerjs-discovery.ts
|
||||
peerjs-discovery.md
|
||||
peerjs-discovery.types.ts
|
||||
peerjs-discovery.test.ts
|
||||
index.ts
|
||||
peer-connection-manager/
|
||||
peer-connection-manager.ts
|
||||
peer-connection-manager.md
|
||||
peer-connection-manager.test.ts
|
||||
index.ts
|
||||
room-manager/
|
||||
room-manager.ts
|
||||
room-manager.md
|
||||
room-manager.test.ts
|
||||
index.ts
|
||||
peerjs-connection/
|
||||
peerjs-connection.ts
|
||||
peerjs-connection.md
|
||||
peerjs-connection.test.ts
|
||||
index.ts
|
||||
peerjs-message-handlers/
|
||||
peerjs-message-handlers.ts
|
||||
peerjs-message-handlers.md
|
||||
peerjs-message-handlers.test.ts
|
||||
index.ts
|
||||
peerjs-intervals/
|
||||
peerjs-intervals.ts
|
||||
peerjs-intervals.md
|
||||
peerjs-intervals.test.ts
|
||||
index.ts
|
||||
peerjs-event-emitter/
|
||||
peerjs-event-emitter.ts
|
||||
peerjs-event-emitter.md
|
||||
peerjs-event-emitter.test.ts
|
||||
index.ts
|
||||
schema/
|
||||
peerjs-schema/
|
||||
peerjs-schema.ts
|
||||
peerjs-schema.md
|
||||
index.ts
|
||||
tests/
|
||||
integration.test.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
**Downstream**: `@suaveplan/network-discovery-hybrid`.
|
||||
|
||||
**Prerequisites**: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/crypto` on Verdaccio.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Tasks: enterprise-browser-network-discovery-peerjs
|
||||
|
||||
**Change ID**: enterprise-browser-network-discovery-peerjs
|
||||
**Package**: `@suaveplan/network-discovery-peerjs`
|
||||
**Target path**: `browser/network/network-discovery-peerjs`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/crypto`
|
||||
|
||||
---
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] Create directory tree per `proposal.md`.
|
||||
- [x] `package.json` v0.0.0, `"sideEffects": false`.
|
||||
- `dependencies`: `@suaveplan/network workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/crypto workspace:^`, `peerjs`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`
|
||||
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@suaveplan/testing workspace:^`, `react catalog:browser`, `@types/react catalog:browser`
|
||||
- [x] `tsconfig.json`, `vitest.config.ts` (pool: forks).
|
||||
|
||||
---
|
||||
|
||||
## 2. Error codes
|
||||
|
||||
- [x] `PEERJS_SIGNALING_UNREACHABLE`, `PEERJS_ROOM_FULL`, `PEERJS_CONNECTION_FAILED`, `PEERJS_MESSAGE_REJECTED`.
|
||||
- [x] `registerPeerJSErrorCodes()` — call eagerly.
|
||||
|
||||
---
|
||||
|
||||
## 3. Schema (`src/schema/peerjs-schema/`)
|
||||
|
||||
- [x] `PeerJSMessageSchema` variants for `PEER_ANNOUNCE`, `PEER_LEAVE`, `PING`, `PONG`.
|
||||
- [x] Register in `@suaveplan/schema-registry`. Write `peerjs-schema.md`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Supporting modules
|
||||
|
||||
For each: `PeerJSEventEmitter`, `PeerJSIntervals`, `PeerJSMessageHandlers` (validates with Zod), `PeerJSConnection`, `PeerConnectionManager`, `RoomManager`:
|
||||
|
||||
- [x] Implement module.
|
||||
- [x] Write `*.test.ts` (real PeerJS API, no stubs), `*.md`.
|
||||
|
||||
---
|
||||
|
||||
## 5. PeerJSDiscovery (`src/peerjs-discovery/`)
|
||||
|
||||
- [x] Implement with strict-mode gate (reject `0.peerjs.com` when `strict: true`).
|
||||
- [x] `static selfHosted(...)` factory.
|
||||
- [x] Reconnection policy with exponential backoff.
|
||||
- [x] Optional signed metadata via `@suaveplan/crypto`.
|
||||
- [x] ICE server passthrough to PeerJS `RTCConfiguration`.
|
||||
- [x] Wire OTel metrics.
|
||||
- [x] Write `peerjs-discovery.test.ts`, `peerjs-discovery.md`, `peerjs-discovery.types.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Story
|
||||
|
||||
- [x] `src/peerjs-discovery/peerjs-discovery.stories.tsx` with React devDep declared.
|
||||
|
||||
---
|
||||
|
||||
## 7. Integration test (`tests/integration.test.ts`)
|
||||
|
||||
- [x] Strict-mode rejects public cloud host.
|
||||
- [x] Two `PeerJSDiscovery` instances against a local PeerJS server; assert peer discovery.
|
||||
- [x] Reconnection: drop + restore WebSocket; verify `connection:restored` fires.
|
||||
- [x] ICE server config passed through to RTC connection.
|
||||
|
||||
---
|
||||
|
||||
## 8. Docs + verify
|
||||
|
||||
- [x] Write `.md` per module; `README.md` with self-hosted relay guidance.
|
||||
- [x] `bunx turbo lint typecheck test --filter=@suaveplan/network-discovery-peerjs` — green.
|
||||
- [x] `bunx turbo test:coverage` — 100%.
|
||||
- [x] Every supporting module has its own test suite.
|
||||
- [x] `bun scripts/publish.ts --package @suaveplan/network-discovery-peerjs`.
|
||||
- [x] Archive to `openspec/archive/2026-04-24-enterprise-browser-network-discovery-peerjs/`.
|
||||
Reference in New Issue
Block a user