Real-Time Collaboration #56
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Real-Time Collaboration (Technical Overview)
This document covers the real-time collaboration mechanism added to the PaperTrail plugin. It explains how the server hub and client UI interact over the platform WebSocket server so multiple users can edit a board concurrently.
Architecture
platform/src/ws/server.js): The existing/wshub authenticates API sessions via cookies and keepsprojectId → clientsmaps. Clientspt:joina project to subscribe; when one client sendspt:update(after a successful board save), the hub rebroadcasts that snapshot to every other watcher.projectWatcherstracks which clients watch which boards so we only send updates to relevant viewers, andbroadcastProjectUpdatehandles the filtered push.ws://<host>/ws, emitspt:join(withprojectId), and queues outgoing updates until the socket is open.Client-side flow (
plugins/papertrail/src/Flow.jsx)createSaverwas extended with anonSuccesscallback that now triggerssendRealtimeUpdate, streaming the latest snapshot over WebSocket immediately after the server confirms persistence.pt:updatepackets and, when a newer version arrives from another client, applies the snapshot directly instead of re-fetching. Incoming updates include asnapshotpayload plussourceId/versionso the receiver can skip duplicates and respect the local version.boardVersionRefand only applies remote snapshots when they have a greater version number. This avoids overwriting newer local edits with delayed broadcasts./wsevery few seconds until the hub accepts the connection.Server expectations
{ "type": "pt:update", "payload": { "projectId": "mi6abc...", "version": "2025-11-19T18:54:11.799Z:6", "sourceId": "client-...", "snapshot": { "nodes": [...], "edges": [...], "version": ... } } }projectId, and clients ignore packets wheresourceIdmatches themselves (to avoid echoing their own save).Benefits and limitations
Next-level improvements