feat: broadcast full CRDT state to other clients after manual save

When a user saves, the full Yjs document state is broadcast so all
connected clients converge, even if they missed incremental updates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Gustavo Henrique Santos Souza de Miranda 2026-01-24 16:12:58 -03:00
parent 34815d70ee
commit cdaae6b965
2 changed files with 14 additions and 0 deletions

View File

@ -1143,6 +1143,9 @@ function FlowchartEditorInner({ projectId, projectName, userId, userDisplayName,
// Update last saved data ref to mark as not dirty // Update last saved data ref to mark as not dirty
lastSavedDataRef.current = flowchartData lastSavedDataRef.current = flowchartData
// Broadcast full CRDT state so other connected clients sync up
crdtRef.current?.broadcastFullState()
setToast({ message: 'Project saved successfully', type: 'success' }) setToast({ message: 'Project saved successfully', type: 'success' })
} catch (error) { } catch (error) {
console.error('Failed to save project:', error) console.error('Failed to save project:', error)

View File

@ -173,6 +173,17 @@ export class CRDTManager {
this.callbacks.onEdgesChange(this.getEdges()) this.callbacks.onEdgesChange(this.getEdges())
} }
/** Broadcast the full document state to sync all connected clients */
broadcastFullState(): void {
if (!this.channel || this.isDestroyed) return
const fullState = Y.encodeStateAsUpdate(this.doc)
this.channel.send({
type: 'broadcast',
event: BROADCAST_EVENT,
payload: { update: Array.from(fullState) },
})
}
private broadcastUpdate(update: Uint8Array): void { private broadcastUpdate(update: Uint8Array): void {
if (!this.channel || this.isDestroyed) return if (!this.channel || this.isDestroyed) return
this.channel.send({ this.channel.send({