Files
gibbz/README.md
T
developer 2b950e4953
Build and Publish / Metadata (push) Successful in 4s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 14s
eventsourced-ai live check live check
refactor: port backend and frontend to TypeScript classes (bun + vite)
Backend (src/server, runs on Bun):
- GibbzHttpServer (health, /api/ice, /api/rooms, static, keepalive tuning)
- SignalingServer with Peer/Room/RoomRegistry classes and typed messages
- IceConfigProvider (env STUN/TURN + coturn HMAC ephemeral creds)
- StaticFileServer (dist/ with public/ fallback, traversal guard)
- Tracing (OpenTelemetry SDK), AppConfig; createApp() factory for tests

Frontend (src/client, built by Vite):
- VoiceApp orchestrator implementing VoiceAppContext
- WebRtcManager + PeerSession (perfect negotiation, pc rebuild, quality monitor)
- SignalingClient + ReconnectController, AudioManager, SpatialAudio,
  Microphone/ScreenShare controllers, ScreensUi/RosterUi/SpatialMap/
  SpeakingMonitor, Settings/Welcome dialogs, LayoutManager, MatrixChat

Tooling: bun scripts (dev/start/test/typecheck), vite.config.ts root
src/client with publicDir public/static, vitest-config for CI-less runs,
bun-based Dockerfile (oven/bun:1), Makefile + README updated, legacy
server.js/tracing.js/test.js/public js removed.

Verified locally: tsc --noEmit clean, vitest run 6/6 green, vite build ok,
server smoke-tested serving dist + signaling endpoints under Node. Local
bun binary segfaults (SIGILL) on this host, so 'bun test' itself was not
executable here; tests are vitest-API compatible which bun test maps.
2026-09-24 07:43:04 +00:00

83 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# gibbz voice — POC
Discord-clone proof of concept: peer-to-peer WebRTC voice chat + screen sharing
with position-based spatial audio and pluggable STUN/TURN.
TypeScript everywhere: the backend runs on [Bun](https://bun.sh), the client is
built with [Vite](https://vite.dev), and both are organized into classes.
## Layout
```
src/server/ Bun (Node-compatible) WebSocket/HTTP backend
index.ts entrypoint + createApp() factory (used by tests)
http-server.ts GibbzHttpServer — health probes, /api/ice, /api/rooms, static
signaling.ts Peer / Room / RoomRegistry / SignalingServer (ws)
ice.ts IceConfigProvider — env-driven STUN/TURN + HMAC TURN creds
static-files.ts StaticFileServer — dist/ (or public/) with traversal guard
tracing.ts Tracing — OpenTelemetry SDK setup
config.ts AppConfig — env + static dir resolution
src/client/ Vite root (index.html, style.css)
app.ts VoiceApp — orchestrator implementing VoiceAppContext
context.ts the subsystem-facing application interface
state.ts AppState — shared cross-cutting voice state
webrtc/ WebRtcManager, PeerSession, SignalingClient, ReconnectController
media/ AudioManager (mic chain), SpatialAudio, Microphone-, ScreenShareController
ui/ roster/screens/spatial-map renderers, settings, welcome, layout
chat/ MatrixChat (OAuth2/OIDC text channel)
public/static/ PWA assets served verbatim (icons, manifest, service worker)
tests/ bun test / vitest compatible suite (tests/server.test.ts)
```
## Develop
```sh
bun install
bun run dev:server # backend on :8080 (bun --watch)
bun run dev # vite dev server for the client
bun test # tests (vitest-compatible; `bun run test:node` = vitest run)
bun run typecheck # tsc --noEmit
bun run build # production client bundle into dist/
bun run start # serve dist/ + signaling (bun src/server/index.ts)
```
The server also runs under Node 22.18+/23+ (`node src/server/index.ts`) since it
only uses erasable TypeScript, but Bun is the supported runtime (the Dockerfile
is `oven/bun:1`). A `bun.lock` is generated on first `bun install`.
## What works
- Mesh WebRTC voice (perfect negotiation; lowest peer id initiates), full
pc-rebuild recovery on ICE failure with TURN-relay fallback
- Screen share with audio (mic is spatialized, screen audio plays direct),
spotlight/grid tiles and pop-out windows
- Spatial audio: drag your avatar on the plane; remote mics run through a
`PannerNode` (HRTF, inverse distance). Positions sync over signaling.
- Hi-Fi rooms (Code, Gaming): stereo Opus 256 kbps, echo cancellation off
- Custom STUN/TURN: gear icon → JSON override in `localStorage`, applied on
next join. Server default comes from env (below).
- Mute (M), deafen (D), per-peer volume, speaking indicators, quality
diagnostics (loss/jitter/RTT), auto-reconnect with countdown banner
- Matrix-backed text channel (OAuth2/OIDC against matrix.k6n.net)
## ICE configuration (server side)
| Env var | Meaning |
|---|---|
| `STUN_URLS` | comma-separated `stun:` urls |
| `TURN_URLS` | comma-separated `turn:`/`turns:` urls |
| `TURN_USERNAME` / `TURN_CREDENTIAL` | static TURN creds |
| `TURN_SECRET` | coturn static-auth-secret → ephemeral HMAC creds |
| `ICE_TRANSPORT_POLICY` | WebRTC ICE policy: `all`, `relay`, or `none` |
| `ICE_SERVERS_JSON` | full `{"iceServers":[...]}` override, wins over the above |
| `PORT` / `HOST` | listen address (default 8080 / 0.0.0.0) |
## POC shortcuts (productionize later)
- No auth, rooms are in-memory, signaling is plain ws behind the ingress.
- No media server: N² mesh — fine for small rooms, needs SFU beyond ~6–8
participants.
- Text channels are a single live Matrix room; no history pagination.