I'm currently playing with the idea of writing a set of RxJS bindings for the ShareDB client (which would also be useful
outside of this context) and then use redux-observable to fit those in to our Redux app. Together with something like
the diff/patch libraries you linked we would have most of the necessary pieces for a first implementation.
The question then is what actions (and action creators) would be needed and what the state should look like.
I've drafted a rough outline of what I think would be needed bellow:
## State shape ##
Collections shape
{ [name]: <collection reducer> }
Collection shape
{
subscriptions: {
[query]: {
isFetching: <bool>,
subscribers: count,
result: [list of doc ids]
}
// ...
},
requests: {
[query]: {
isFetching: <bool>,
lastUpdated: <timestamp>,
result: [list of doc ids]
}
},
documents: {
[id]: snapshot,
// ...
}
}
(The collection reduces should probably also be broken in to smaller pieces...)
## Actions ##
SHARE_FETCH (collection, query)
SHARE_SUBSCRIBE (collection, query)
SHARE_UNSUBSCRIBE (collection, query)
SHARE_FETCH_DOC (collection, id)
SHARE_SUBSCRIBE_DOC (collection, id)
SHARE_UNSUBSCRIBE_DOC (collection, id)
SHARE_OP_ * (collection, id, payload) (eg, insert, update, increment etc)
SHARE_UPDATE (collection, { id: snapshot, ... })
SHARE_FETCH_SUCCESS
We could then write a set of action creators that diffs against the state as needed in order to generate the required OPs.
All actions (except SHARE_UPDATE and SHARE_FETCH_SUCCESS) would then be handled by the RxJS layer,
which would emit SHARE_UPDATE actions whenever a query result or document changes and
SHARE_FETCH_SUCCESS once a fetch completes. A set of generic selectors could then be used to get the correct
documents/requests states/etc for each query or fetch.
(The state shape and action list above is obviously not complete. Some additional props and actions are needed in order
to properly handle errors, etc.)
The main drawback of this approach is that we cant use plain reducers to describe the state changes for any of our
ShareDB documents/collections. Some kind of solution that observers the redux state and then dispatches OPs
accordingly would fix that, but then we have a whole new set of problems of matching state to ShareDB docs and
probably a bit too much magic going on behind the scenes. One of the main benefits of redux IMO is the whole
no-magic thing.
Doing text based OP would probably require a custom input component as well, in order to not mess with the
cursor/caret too much. DraftJS (or maybe Quill) could be a good fit if you want to do more than just plain text.
What are your thoughts on this?
Cheers,
Jonatan