Intercept model changes?

I am looking at designing a cooperative edit application of a GraphLinksModel, and for that to make sense, I would like the “edit changes” to be intercepted, forwarded to the backend, and model is updated when the server confirms the changes.

I have managed to make the front-end react correctly to backend changes over websockets, BUT I can’t figure out how I can prevent “Insert Link”, “Delete” and so on to happen in the JS model and instead should first be sent to the backend, and eventually the change will arrive back via the websocket .

Thanks for any pointers

We do not recommend such a conservative design, where nothing can happen on the client side without first happening on the server. What happens when the connection with the server is slow or broken?

Instead it is normal to adopt an optimistic design, where changes may happen on the client first. The server will merge all changes and send out what each client needs to receive.

Ok, so you don’t recommend it, but is it possible?

As for slow/breaking connections; It is actually an advantage in these situations, since user know for a fact whether changes have been accepted or not, rather than the rather complex algorithm of storing incremental changes locally and “depend on” the user remembering to save those later. And when multiple people are working on the same graph, “merge” means that conflict resolution must also be implemented, compared to the very simple algorithm “Refresh All” when a websocket is (re-)opened.
And the fact that Google Docs does this across the world, makes me less concerned with “we don’t recommend it”.

As I am not dealing with global level latency, I would like to do this path because it is both easier on myself as well as on the user’s mental model of what is happening.


As I understand it, in Operational Transform each client works on their local copy in a non-blocking manner.

So, yes, it is possible to do what you say you want, but I strongly recommend against it except for rare special cases.

So, I am looking for the mechanism of intercepting the “add link”, i.e. when it completes, I can stop the link to be added, and instead forward the request to the backend and the “add link” arrives back a 200ms later and I do the transaction then.
I am not looking for whether the practice is recommended/better/worse than any other way, but for the mechanics on doing this in Go.JS.

THANKS (remarkable to get replies on Christmas!)


and a lot of methods on CommandHandler:

If there are any user actions that do not have clearly identifiable overridable methods, just ask.

Thanks!!! I managed to do what I wanted. addNode from my button, addLink via the LinkingTool, removeNode/removeLink via the CommandHandler. And it is in the “local network” case indistinguishable by me.

I also need to do the same for changes initiated by the UndoManager. And starting that, I realized that I have a small issue with the Undo/Redo feature. Incoming changes are seen by the UndoManager, so User B will have an Undo buffer/history containing changes made by User A. The transaction of incoming changes could be skipsUndoManager, IF I could figure out a reasonable way to remember which requests have been sent, and only have the UndoManager ON when it is “incoming result from my own command”.

This is a non-trivial consequence of my approach, but I still want to continue down this path. But thought I should report back and let others know.

I think that you can handle undo and redo if you record special ChangedEvent(s) in each transaction, similar to how the default behavior records ChangedEvents when inserting, modifying, or removing node data or link data. Then when an undo or redo happens, as detected by a Transaction-type ChangedEvent, you can ask the server to make the corresponding changes. But I’m not sure that the details all work smoothly. Alas I do not have time now to investigate this.

That might be possible. I have left that out for now, as there is so much else to work on with higher priority.

  1. It goes quite smoothly. I like the whole framework very very much. It fits with my mental model, even though I am not a UI programmer at all.

  2. The documentation is remarkably good. Even though there is a lot written (i.e. “too much” complaints) it is still easy to find what I need.

  3. The YouTube videos has also been Gold to get going. Kudos!!