I have a Y.Doc that is shared using WebSocketProvider in a room, room A. I now want to clone the document to another room (room B), so that a client of room B will initially see the same as the client of room A at the moment of cloning, but, thereafter, room B will not be updated with changes in room A and vice versa. I have tried this:
// ...
// code to create a ydoc with shared types linked to room 'A' using 'websocket' and apply various insertions etc.
// ...
//
let state = Y.encodeStateAsUpdate(ydoc);
let clonedDoc = new Y.Doc();
let ws = new WebsocketProvider(websocket, 'B', clonedDoc)
ws.on('sync', () => {
Y.applyUpdate(clonedDoc, state)
});
I am assuming that applying state as an update to the empty clonedDoc will yield a copy of the state of room A in room B. However, if I run the above code, and access the cloned room, I find a ydoc that has the same structure (i.e. has the same shared types) as the room being cloned, but all the values are missing. What am I doing wrong?
When you recreate the document, you need to reinitialise the types. Normally, clonedDoc.get('network') should yield an AbstractType, because you haven’t defined what network is. So you need to do clonedDoc.getMap('network').
If that is not the issue, could you check if example.ydoc.store.pendingStack is empty?
If it is empty, could you post the encoded document here?
I’m a bit lost here - apologies. clonedDoc.get('network') does indeed return an AbstractType (a YMap to be specific). When the client in room B starts up, it does (showing only the code that is relevant):
The examples I showed in the earlier message were obtained after running the above code. So I think I have done “clonedDoc.get('network')”.
In room A, ydoc.store.pendingStack is empty. So is clonedDoc.store.pendingStack in room B.
If it is empty, could you post the encoded document here?
If you mean the result of Y.encodeStateAsUpdate(ydoc) in room A, it is a Uint8Array of about 257kB, so I suppose it is not very useful to view - did you mean something else?
These are two different things. AbstractType is a retainer that is unable to interpret the underlying CRDT structure. Y.Map is an implementation of AbstractType that can extract content. So you want to do clonedDoc.getMap('network'), and not clonedDoc.get('network')
That would be perfect. Ideally you upload it as a file to some server (e.g. binpaste or github gist). Then I can debug your issue by parsing the Uint8Array. Alternatively, you could create a minimal reproducible example (I can’t reproduce the above code).
It would be better if I did a minimal example, but it will take a few days to get to that (I didn’t do it originally because I assumed the problem just arose from my conceptual mistake).
I created a minimal example, and found that it worked perfectly! Eventually, I discovered a trivial mistake in my original code (the name of the new, cloned room was wrong) and once I had corrected that, all was well. Thanks for your help @dmonad.