/ concept-collection / commoncall
Sign in
concept-collection / commoncall
commoncall / CLAUDE.md
39 lines · 1.7 KBCodeBlameHistory
3Tips for future agents working in this repo. It borrows the p2p techniques of
4the sibling project `commonview` — read that first; this file only covers what
5is different here.
7## Architecture
9```
10src/p2p/
11 identity.ts schnorr keypair; pubkey hex = peer ID — ported from commonview
12 nostr.ts minimal relay client + topic scheme — ported (adds event-id dedup)
13 peer.ts WebRTC wrapper: media tracks + a control data channel
14 network.ts the heart: presence roster + the call state machine
15src/App.tsx join form, roster, ring/accept UI, video views
16```
18## Key design decisions
20- **No auto-connect.** Unlike commonview (which meshes every peer), WebRTC is
21 only brought up after an explicit `call-request``call-accept` handshake;
22 `getUserMedia` is also deferred until then. All pre-call messaging rides on
23 nostr per-peer topics.
24- **One call at a time.** A second incoming ring is auto-declined with
25 `busy: true`. Glare (both users call each other) is treated as mutual
26 acceptance.
27- **Ephemeral events need retries.** The caller re-publishes its ring every 4 s
28 (the `Nostr` class dedupes by event id on the receiving side); a callee in
29 `connecting` answers a re-ring by re-sending `call-accept`. Ring and connect
30 phases both time out at 45 s.
31- **Deterministic initiator.** The smaller peer ID creates the offer, same as
32 commonview — no perfect-negotiation glare handling. Both sides add their
33 tracks before signaling starts so one offer/answer round covers all media.
35## Testing
37`npm run dev`, then open two browsers (identity is per-browser-profile via
38localStorage, so two tabs in one profile are the SAME peer — use a private
39window or second browser). `npm run build` type-checks (`tsc -b`) and bundles.
moveopenescclose