Events & Sync
Mistakes when handling events and the distributed nature of CRDTs.
Ignoring Local vs Remote
// WRONG: runs twice (local + sync confirmation)
content.observe(event => {
saveToLocalStorage(content.toJSON())
sendAnalytics('changed')
})Observers fire for both local and remote changes.
Fix: Check transaction.local:
content.observe((event, transaction) => {
updateUI() // Always
if (transaction.local) {
saveToLocalStorage(content.toJSON()) // Only local
}
})Flooding Awareness Updates
// WRONG: 60+ messages/second
document.addEventListener('mousemove', e => {
awareness.setLocalStateField('cursor', { x: e.clientX, y: e.clientY })
})Floods network, overwhelms clients.
Fix: Throttle to 10-20 updates/second:
const updateCursor = throttle((x, y) => {
awareness.setLocalStateField('cursor', { x, y })
}, 50)Expecting Sync Order
// WRONG: assumes remote sees operations in order
yDoc.transact(() => items.set('config', { init: false }))
yDoc.transact(() => items.set('config', { init: true }))CRDT sync order isn’t guaranteed across clients.
Fix: Design for eventual consistency. Use timestamps if order matters.
Checklist
- Observers check
transaction.localfor side effects - Awareness updates throttled (10-20/sec max)
- No assumptions about sync order