README.md

icarus-presence

Live presence for cloud strategies: who else has a strategy open (the avatars in the editor's window strip) and where their cursor is on the map. A Cloudflare Worker with one Durable Object per strategy relays it. Nothing is stored: cursors live in memory for as long as someone is connected.

How a client gets in

  1. The app calls the Convex mutation presence:issueRoomPass (convex/presence.ts). Convex checks the caller can view the strategy and returns the room URL and a pass signed with PRESENCE_PASS_SECRET, valid for two minutes. It returns null if the deployment has no PRESENCE_URL, and the app then shows no presence.
  2. The app opens wss://<worker>/v1/rooms/<strategyPublicId>?pass=<pass>. The Worker verifies the pass (src/pass.ts, shared with Convex) and hands the socket to that strategy's room (src/room.ts).
  3. The app sends a renew with a fresh pass every minute. The room closes any socket whose pass runs out, so someone whose access is revoked drops out within two minutes.

Messages are JSON. From the client: cursor {page, x, y} (canonical attack-side world coordinates, at most 20 a second), hide, renew {pass}, and the text ping, which the runtime answers with pong without waking the room. From the room: welcome {self, uid, peers}, join {peer}, leave {sid}, cursor {sid, page, x, y}, hide {sid}, renewed {exp}. Close code 4001 means the pass ran out or a renewal was refused.

Environments

WorkerURLPaired Convex deployment
icarus-presence-dev (--env dev)https://icarus-presence-dev.shawnadedeji.workers.devdevelopment, majestic-eel-413
icarus-presence (--env production)https://icarus-presence.shawnadedeji.workers.devproduction, basic-dove-69

Each pair shares one secret. Convex holds it with the Worker's URL:

sh
1# Generate a secret, then set it on both sides of one pair.
2npx wrangler secret put PRESENCE_PASS_SECRET --env dev # from presence/
3npx convex env set PRESENCE_PASS_SECRET <secret> # CONVEX_DEPLOYMENT=dev:majestic-eel-413
4npx convex env set PRESENCE_URL https://icarus-presence-dev.shawnadedeji.workers.dev

For production, use --env production, npx convex env set --prod, and the production URL. Rotating the secret signs everyone out of presence until they rejoin (about a minute); nothing else notices.

Working on it

sh
1cd presence
2npm ci
3npm test # Worker and room, in the real Workers runtime (Miniflare)
4npm run typecheck
5npm run deploy:dev # wrangler deploy --env dev

The Deploy Web workflow deploys --env production on every push to icarus-cloud, before the web build. CI runs the tests and typecheck.