redux-share-server
redux-share-server copied to clipboard
Synchronize server and client states
As actions can be sometimes not pure or clients can disconnect and reconnect. There is a need to be able to synchronize the state of the server and the client.
As a reminder, on both sides, the states must be updated only by actions so we must avoid to do through the socket anything else than passing actions.
Sending states and updating either side is already possible by implementing custom actions. The question is: how much can provide in each middleware to help that?
My current idea would be to send a @@SYNC_REQUEST_[FULL/PARTIAL] action.
SYNC_REQUEST_FULL can be send either by the client or the server. When received the middleware would emit another action SYNC_FULL to the emiter of the source action, with the store state given as "state" parameter in the action. SYNC_REQUEST_PARTIAL would require an expression that would locate a branch in the state.tree (Ex: 'car.door.knob'). When received the middleware would emit an action SYNC_PARTIAL to the emiter of the action.
If a parameter 'hashSha1' is given, both SYNC response would only be answered if the hash of the states do not match each other.
Do you think it could be great to have that built-in? (the code could be shared by the client and the server).
Totally legit demand. More generally, I think we need to provide pluggable protocols such as:
- connect: to establish connections or deconnections.
- sync actions: to exchange actions between client <-> server.
- sync state (your sounding proposal): to exchange the state between client <-> server.
- custom home-made protocols.
sha1 / adler32 : I checked the codebase of React, and it uses adler32 for dirty checks on the state. It apparently tradeoffs precision for speed and is dedicated for checksums.
From an implementation point of view, a protocol would be a set of [action creators + reducers]. As you said, It would be awesome if we can avoid having to expose the hooks functions for the protocol ...
- onActionReceived received is mostly used right for authenticating action origins.
- shouldDispatch could be implemented via simple reducers
- shouldSend could use a node in the state to know if it should be sent or not, and the middleware would inspect the state. => I'm not sure it makes the life easier though, expect that it helps with composing those...
In my opinion the hooks are what is making the server easy to use right now. I would not remove them. I would also include their default behaviors in the server to avoid having to re-code them when you have to use them. By default a callback should not replace/erase any feature of the server when provided.
As for the action creators/reducers I totally agree, those methods could be in fact used by any projects. The logic of syncing two stores could be used across servers or across clients or inside a single server/client. There should be an easy way to setup what you accept to sync.
For the Hashing I agree it should be hashCheck:true, hashType: 'whatever' with the same default values on client and server side.