automerge-classic: Can't send changes over network
Version used: 1.0.1-preview.2
I just started working with automerge a few days ago, so not much experience.
I am trying to accomplish the synchronization of a JSON document with a websocket server between the clients. Currently the server does nothing but sending the messages to all clients except for the sender. This is the document used for this test:
doc = Automerge.from({
text: new Automerge.Text(),
});
When changing a document on one client and sending the changes like so:
const changes = Automerge.getChanges(this.doc, newDoc);
this.ws.send(JSON.stringify(changes))
and parsing them on another client like so:
const changes = JSON.parse(message.data);
Automerge.applyChanges(this.doc, changes)
I get the following error:
ERROR TypeError: Not a byte array: [object Object]
Decoder encoding.js:304
Also tried another approach with generateSyncMessage and receiveSyncMessage.
However I am not sure whether I used that correctly.
Sender:
const [syncState, binarySyncMsg] = Automerge.generateSyncMessage(
this.doc,
this.syncState
);
this.ws.send(JSON.stringify(binarySyncMsg))
Recipient:
const binarySyncMsg = JSON.parse(message.data);
const receiveSyncMsg = Automerge.receiveSyncMessage(
this.doc,
this.syncState,
binarySyncMsg
);
this.doc = Automerge.Frontend.applyPatch(this.doc, receiveSyncMsg[2])
This resulted in the same error.
Is this even the correct approach to syncing the document? Or should my server handle parts of the merging?
Also should I rather use the generateSyncMessage and receiveSyncMessage instead of sending the changes directly?
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (9 by maintainers)
Should be fine – we shouldn’t have let you get into trouble in the first place but I’m not sure quite what the fix ought to be yet.
Thanks for the example code, here’s one that works as expected: https://codesandbox.io/s/magical-wu-7dbv8
What’s happening in your first example is that the documents don’t have a shared history, so the changes aren’t applying like you expect. In your example, I would expect that there would be a conflict on
.cardssince both peers create an empty array independently of each other, but I haven’t quite figured out why there isn’t one. It seems to me that if this isn’t working we should probably throw an error.The question of whether to merge fields created independently but at similarly named locations is tricky but is an ongoing conversation. We want to avoid merging things that shouldn’t be merged, but merge things that should… but how to tell? While you can see the problem of not merging here, Martin’s JSON CRDT paper of a few years ago shows examples of what can go wrong if you merge too aggressively – “torn” objects and incoherent combinations of types.
What my revision of your example is doing is having one “user” create a document and the other user load it. From then on both users will have a shared starting point and either one can make objects and share them back and forth.
Hope that helps get you on the right path.
I made a minimal example here:
I would expect the changes from the original doc to appear on the final one, since they both have the same initial state.
EDIT: Here is the code in case the sandbox doesn’t work