Collaboration Server (server/)
Realtime collaboration server for Songbird. Manages project rooms, syncs file changes between connected clients, performs structured merges on .bird and JSON state files, and provides real-time presence features including Figma-style multiplayer cursors and optimistic mixer sync.
For the full deep-dive into collaboration architecture, see docs/collaboration.md.
Quick Start
Files
| File | Purpose |
|---|---|
server.js | WebSocket server — room management (create/join via invite codes), push/pull sync, presence broadcasting, cursor relaying, merge orchestration |
merge/bird-merge.js | Structured .bird file parser, serializer, and three-way merge at track-per-section granularity |
merge/json-merge.js | Recursive deep-merge for daw.mixer.json (mixer) and daw.plugins.json (plugins). Handles arrays element-by-element |
gitea/ | daw.club — React frontend for Gitea-based git hosting (see gitea/README.md) |
mock-ws-bridge.mjs | Mock WebSocket bridge for standalone React UI development |
test-merge.js | Merge engine tests — 7 tests covering parse, round-trip, auto-merge, and conflict resolution |
package.json | Dependencies: ws (WebSocket), nanoid (invite codes) |
Merge Strategy
.birdfiles: Parsed into structured tree (sig → tracks → arr → sections → tracks). Merged at track-per-section granularity. Two users editing different tracks in the same section auto-merge cleanly..mixer.json: Recursive deep-merge at the per-track-property level. Two users adjusting different mixer controls auto-merge..plugins.json: Same deep-merge strategy applied to plugin state.- Conflicts: All conflicts resolved via last-write-wins (the incoming push takes precedence).
Real-Time Features
Figma-Style Multiplayer Cursors
Each connected client broadcasts cursor position (track, beat) at throttled intervals. Other clients render colored cursor indicators with user names on the arrangement view. Cursor updates are relayed through the WebSocket server with no persistence.Optimistic Mixer Sync
Mixer parameter changes (volume, pan, mute, solo) are broadcast optimistically to all connected clients. The sender’s change is applied locally immediately, and other clients receive the update via WebSocket. Conflicts are resolved via last-write-wins. ThecollabMixerSync.ts service on the React side handles debouncing and deduplication.
Built-In Tunnel
The Rust backend can start a built-in tunnel (via thecollab.* sync-engine channel and songbird-collab) for zero-config remote collaboration — no port forwarding or ngrok required. The tunnel URL is shared via the collaboration panel’s invite flow.
Deployment
The server is a single Node.js process with no external dependencies (no database, no Redis). Works on any machine with Node.js 18+.deploy/ for Fly.io and GCP deployment configurations.