I’m using hocuspocus, yjs, and prosemirror to build my collaborative online document library. I’ve encountered a strange phenomenon: when user A and user B are simultaneously editing the same document, user A stops editing to do other things and then goes home, putting their browser to sleep. User B continues editing. The next morning, user B finds that their newly written content has been overwritten by user A’s old document content.
After investigating this issue, I discovered that once the browser goes to sleep, it no longer receives or executes user B’s new content. User A’s document remains the old one. When user A turns on their computer the next day, the startSync method in hocuspocus is executed first, and then the content is overwritten.
I checked hocuspocus-server and found that if applyAwarenessUpdate doesn’t pass an update request, it won’t be overwritten.
applyAwarenessUpdate method
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
awareness.emit('update', [
{
added,
// updated passing an empty array solves this problem
// but the user's cursor will no longer update.
updated,
removed,
},
origin,
]);
}
I don’t understand why. Has anyone encountered the same problem?
We are encountering something very similar, maybe even the same. But what makes it even stranger is that it doesn’t go wrong always. Our stack is Hocuspocus (latest one today, 3.4.4) with SyncedStore(React) on top.
I was able to make a multi-browser scenario in Playwright which basically works like this:
BrowserA makes a document, adds some content to it.
BrowserB joins the document, both make changes, all fine.
BrowserB goes offline, but stays on the document editor (similar to sleep).
BrowserA still adds some content, which doesn’t show up in BrowserB (makes sense).
BrowserA leaves the document editor.
BrowserB goes back online.
Now the strange thing occurs: usually BrowserB gets updated to see the latest document. as it was left by BrowserA in step 5, but sometimes the document gets overwritten by the state it was in when BrowserB went offline in step 3.
I am digging deeper now, but did you find any resolution for your case already?
I haven’t resolved this issue yet, but during troubleshooting, I discovered that if yjs update encounters an error, it will stop accepting content from other collaborators, and then the same problem occurs after the socket connection is broken and reconnected.
Error-related issues account for about 50% of the problems in my application.
hocuspocusProvider → startSync
startSync() {
if (this.document._transactionCleanups.length) window.location.reload();
......
}