Then it seems like one of the setNulls should be discarded automatically (the second one), which would make us have the following list of ops:
<client1: setnull-op>
<client1: insert-op>
<client2: insert-op>
Which should work right now right? If that doesn't work, what happens in normal situations where there's a long time delay between client1 and 2's actions? (i.e. when two clients pushes items to an array generally speaking). Or am I missing something? Maybe I'm just unaware of the OT code and my assumptions are completely off - but from a user perspective it seems like both should be inserted. It should however probably be possible to re-set the whole array and then it's a different question. Generally, it seems like option 3 is favourable.
My 5 cents for schemas:
To implement schemas at the livedb-layer would be pretty nice. In Derby (or more specifically Racer), it's possible to have schemas but hard to make them very useful. From a Derby-perspective, there are three things which schemas can add:
1. Enforce only certain data gets added to the actual DB/server-side
- Existing solutions for this work ok and it's pretty easy to add support for this. However, this should be last resort since this does not necessarily make for good UX. Further, currently it doesn't really work to revert operations in the client afterwards - at least not reliably. (although it sounds like support for this can be more easily added with the new OT code if each op have an inverted op)
2. Hook up certain model paths for schema validation (fields as well as more complicated objects).
- There are a lot of things to think about for this and a lot of different options would probably be needed (such as if the schema should enforce it, just throw errors, or put all errors at another path, etcetera). Generally, it seems this discussion is only partly related to this discussion so I'll skip it.
3. Have default values.
- This seems also to be quite difficult, or at least quite impractical, to implement at a Derby/Racer-level since neither really touches the data when transmitted to the server (please correct me if I'm wrong) - it seems it goes more or less straight to Share/LiveDB. Thus, it needs to be added somewhere in that part of the stack. Currently, one could possibly do it in the hooks of Share. However, this does not fare well with the client, since the client just expects the operation to have gone through (not have been modified). Possibly, this could be fixed in Racer by comparing the actual data to the data returned by Share after an operation has been applied (i.e. when any default values would have been set), but it seems we're then also blurring the lines of what an operation actually means (since it can also add default values).
Generally, adding schemas to the stack would be really really neat and might be one of the largest missing pieces of the Derby-ecosystem currently.
Yeah, that's what I'm implementing!
If you remember we had this discussion for json0 and i think my pull request is still hanging somewhere :)I was trying to achieve a solution for creating an editable object on the client who connects first, taking in mind possible concurrency. In my case, I need to insert child Rich Text object into parent JSON to start working on it. For example:initial: {}client1: { doc: {--rich text object format--} }, client 1 do some edits hereclient2 (concurrently): { doc: {--rich text object format--} }, client 2 do some edits hereexpected result:{doc: {client1 edits + client2 edits} }so here neither "first wins" nor "last wins" works.