To provide some context, I am storing base64-encoded snapshots on the server. When attempting to retrieve and decode these snapshots upon a page refresh, I encounter an issue – the ProseMirror editor does not render the expected diff changes. Strangely, I can observe the snapshot version changes successfully when staying on the page without a refresh.
I am seeking your expertise to identify and address what might be going wrong in this scenario. Specifically, I have ensured the proper initialization of both the Y.Doc and ProseMirror editor to match the state of the snapshot. Additionally, the initial state of the ProseMirror editor is set correctly.
If you could spare a moment to review the provided information and offer insights into potential solutions or debugging approaches, it would be greatly appreciated.
I might try starting with a working example like the demo and closely comparing the two, or incrementally porting the demo over to your designed use case. There are too many potential causes now (decoding, snapshot handling, ProseMirror, …), so from a debugging perspective I would be testing different hypotheses and narrowing down the problem space.
hi @raine, I’m working on the same project and we were able to narrow this down to interaction with y-websocket. If I write the document state and snapshots to localStorage instead, it works across refreshes. I created a branch of the prosemirror-versions demo to reproduce the issue and included a screencap: Show snapshots issue with y-websocket by rebolyte · Pull Request #61 · yjs/yjs-demos · GitHub
My understanding of this so far:
Client creates a ydoc (gets a client ID, call it 123), establishes a connection to websocket server. Server creates a ydoc (gets a client ID, call it 456). Both client and server both send syncStep1 and respond with syncStep2. Initially, the document is empty on the client, so only change is from server.
Client makes changes as ID 123. Client captures snapshots, which contain clock (sequence num) for IDs 123 and 456. Rendering the snapshots is done by y-prosemirror iterating through which items were added/removed here, which works since the current IDs match?
User refreshes the page, so now client has new ID 789 and server has 012. Snapshots don’t line up, because changes made by ID 123 were now transacted on the document by 012?
This is all theory at this point. I don’t yet know enough of how the Snapshot deleteSet/state vector is applied to the internal representation to see the why here. If we got this demo working with y-websocket it would resolve our issue.
It’s strange that it works with indexeddb but not websocket. However that should give you a good basis to narrow down the problem because you have a good state and a bad state that you can triangulate from. Does the Doc get synced the same from the websocket as indexeddb? Are the arguments passed to renderSnapshot exactly the same between the websocket version as indexeddb?
I’ve never actually used ProseMirror myself, so I can’t offer anything more specific. I hope you can figure it out.
Facing the same issue here, I have tried disabled gc from server side and still no luck.
From my observation, it indeed has something to do with gc setting, since when I’m not refreshing, snapshot version changes work well, but when I refresh page and retreive ydoc via server, it seems that the latest deletion get applied to all history versions.
see that id:3 and id:4 used to be 1234 and 12345 now get changed to 123(latest deletion is applied)
The version list on the left is implemented as below (ReactJS)
I have done further research on the issue, here are some testing result for reference:
id
scenario
issue occur
1
convert ydoc uint8array to base64, persisting in a db via a backend
yes
2
convert ydoc uint8array to base64, persisting in localstorage
yes
3
persist in leveldb and store in y-websocket server disk
yes
4
persist in indexeddb and store in browser
no
5
persist in y-websocket server without refresh(store in y-websocket server memory)
no
Garbage collection has been disabled for all testings above, it seems to me that we can tell from scenario no.1 and no.2 that websocket isn’t the issue here.
It’s more likely that certain information is lost during the process of encoding Uint8Array to string.
Below is a screenshot of the printed Uint8Array for snapshots before and after a base64 encoding from scenario no.2, they look identical to me
however they actually generate different output from Y.createDocFromSnapshot(ydoc, snapshot).getText(‘quill’).toString() @dmonad@raine really appreciate if you guys could help look into this issue and point me to a direction for debugging, baffles me a lot.
Thank you !