sigourney icon indicating copy to clipboard operation
sigourney copied to clipboard

Store the current working draft in the local storage

Open rakyll opened this issue 11 years ago • 13 comments

I wanted to implement it, but I'm not sure what would be the best approach. Why not returning a list of all objects after each connection/disconnection event?

If this is implemented, #4 will be able to recover from the existing working draft. Less frustration for the user.

rakyll avatar Mar 02 '14 22:03 rakyll

The data model in the front end is just the object divs and their jsPlumb connections. This makes it hard to serialize the state. That's kinda gross.

I think what we need is yet another representation for the object graph, this time in the front end, so that when the back end or the user performs an operation on the graph (add, remove, connect, etc) the corresponding operation is performed on the back end or the UI.

nf avatar Mar 02 '14 22:03 nf

I don't want to duplicate code, and reimplement the object graph on the front-end again. The object graph will likely to be used only for initialization (and maybe to check if there are any changes), so why doesn't the server messaging the front-end the latest graph once a while? Is it harder to maintain than the duplicated code?

Note for the future: Add some optimistic locking for late arrivals.

rakyll avatar Mar 02 '14 22:03 rakyll

It's not really duplicated code. It's more a formalization of what the JS is already doing, plus separating the presentation layer (a mess of JS libraries and the DOM) from the actual data model. It's possible to make the front end data model look identical (in JSON form) to the ui package's data model (while it's not possible to make the ui package's data model look like the DOM). In the long run this could simplify a lot of stuff.

A motivating example: the jsPlumb library lets you handle a "connected" event when a connection is made between two endpoints. In the event handler we send a message to the back end to create the connection. But that event handler fires regardless of whether the user made the connection or the the connection was created programmatically after receiving a "connect" message from the back end. jsPlumb provides no way to tell the two situations apart, so in both cases a "connect' message is sent to the back end. In the latter case this is a redundant message (which the server handles gracefully, but I don't think it should be happening at all).

As the program becomes more complex, I can only see these kinds of interactions getting messier.

nf avatar Mar 02 '14 22:03 nf

But that event handler fires regardless of whether the user made the connection or the the connection was created programmatically after receiving a "connect" message from the back end.

I guess this is why front-end thinks the graph has changed after a fresh load and warns if I want to load another graph. Agreed that it's going to be more complicated as code grows not to have the full graph on the client side and try to implement features that require diffing, patching, re-rendering, etc.

Do you think that incremental updates to the server is necessary? Why not updating the server with the current state of the full graph? I don't like the possibility of having two different states that are unable to sync with each other.

rakyll avatar Mar 02 '14 23:03 rakyll

I would prefer that the server is the source of truth, and that each client sends incremental updates to the server, and the server sends incremental updates to the client (with a full update on load/reconnect, of course). The websocket wire format will probably need to change (or be re-designed) to accommodate this. I share your concerns about the front and back ends falling out of sync, but I think if the design is clean enough we won't need to worry about it.

I would prefer the back end clobber the front end changes than vice versa. At least then the user is seeing what they're hearing.

Ultimately I want multiple people to be able to collaborate in real time on the same patch. Also I would like to be able to swap the front end out entirely (to turn it into an Android or iPhone app, for example). A clean abstraction on the front end and a protocol to sync it with the back end will make this easy.

nf avatar Mar 02 '14 23:03 nf

Note that I don't want to go overboard here and implement OT. Simple at this stage is fine.

nf avatar Mar 02 '14 23:03 nf

Please let me know when you address these issues, and fix the data model. I'd like to contribute, but there are many long term plans you have I can't foresee.

rakyll avatar Mar 03 '14 01:03 rakyll

Understood. FWIW this front end data model thing is on the top of my mind, having done a bunch of UI work over the weekend, so I'll be addressing this very soon.

nf avatar Mar 03 '14 01:03 nf

I've just finished a large-scale refactoring of the front- and back-ends UI layers. It should be ready for you to tackle these issues, if you're still interested.

nf avatar Mar 06 '14 08:03 nf

@nf, your front-end data model contains circular references, element references, etc. Not a perfect scene to start working on serialization :(

rakyll avatar Mar 15 '14 22:03 rakyll

@rakyll if you exempt the ui and el fields then the rest of Object can be easily serialized. Open to suggestions the best way to separate that. I'm still not totally happy with the front-end stuff but it's better than it was. If you want to hack on it further please do.

nf avatar Mar 15 '14 22:03 nf

I will try to get rid of Sigourney.Object.prototype.ui and Sigourney.Object.prototype.el. It looks like Sigourney.Object.name is already a unique identifier.

rakyll avatar Mar 15 '14 22:03 rakyll

Thanks. I hate JS. I guess that shows.

nf avatar Mar 15 '14 22:03 nf