Supabase Realtime: live cross-session sync (signed-in)
Added
Realtime card sync in lib/use-workspace.ts — subscribes to
postgres_changes on cards (filtered to the active space) and surfaces a
full liveCards set the page applies via canvasRef.receiveSync() (drag-safe
merge). Seeding now lives in the hook and runs before the subscription so
deltas apply against a complete set.
Realtime space sync — a spaces subscription refetches the list on any
change, so create/delete/rename propagate across sessions.
Self-echo suppression — local writes stamp recentWrites; incoming events
for a card written in the last 2.5s are skipped, so your own saves don't
bounce back and fight in-progress edits.
Changed
app/page.tsx — useWorkspace(activeSpaceId) now drives seeding/realtime;
the canvas gates on ws.spaceReady; a new effect applies ws.liveCards.
lib/supabase/client.ts — browser client is now a singleton, so auth,
queries, and Realtime share one socket/session (and the channel is authorized
via realtime.setAuth).
Notes
Closes the persistence-first gap: signed-in edits now sync live across tabs
and devices. WebSocket stays for presence; localStorage remains the local cache.