Shouldn't the authority in the collab-example store the serialized change data?

Hey all,

I think I may have encountered a potential error in the collab example. However, I did not want to create an issue just yet, since I wanted to confirm whether its just me again misunderstanding something, or whether its a genuine error.

The collab-example has the document authority store updates like so:

let changes = ChangeSet.fromJSON(update.changes)
updates.push({changes, clientID: update.clientID})
doc = changes.apply(doc)

This means that the updates in the array are stored in their revitalized form, NOT in the JSON representation. Later, when a client requests updates, it receives them as such:

resp(updates.slice(data.version))

When implemented with a webworker (or, in my testbed case, just with a promise) this obviously works well, since both the example setup as well as my testbed worked. I now proceeded to implement the testbed inside an Electron app. In there, the way to facilitate server/client communication is via IPC calls, which is basically just a glorified JSON.stringify-call.

When I just copied over the code from my testbed to the application, I received a strange error, indicating that the ChangeSet was in a falsy format. After some debugging, I then proceeded to just store the updates in their JSON representation and returned that. That worked flawlessly all of a sudden.

Edit: I just double-checked the source code, and indeed fromJSON() returns an instantiated class object whose data will be sent over the pipe, whereas the instantiated object will be stripped.

While I’m not entirely sure what ChangeSet does during the deserialization step, I’m pretty sure it somehow is being messed with during the transferral over IPC. Furthermore, since we always perform (de)serialization, it does indeed make sense that we would want to store the serialized update, especially since you’re basically just going to send that back to another client, and not the revitalized one, or do I overlook something here?

Long story short, shouldn’t the snippet in the example be like this?

let changes = ChangeSet.fromJSON(update.changes)
updates.push(update)
doc = changes.apply(doc)

If so, I can offer to open a PR, otherwise, did I overlook something?

Thanks a bunch!

This is a bit subtle, but JSON.stringify will automatically call toJSON on objects that have that method. So JSON.stringify({toJSON: () => [1, 2, 3]}) gives you "[1, 2, 3]", and resp will JSON-ify the data before sending it over.