nicobarray / aquedux

Redux over the wire
46 stars 3 forks source link

Towards the next (last?) API for aquedux-client #30

Closed nicobarray closed 6 years ago

nicobarray commented 6 years ago

After much discussion with @chabou we decide on a new - simpler - api for aquedux-client.

To create a working aquedux project, the client-side must at least:

The new api must be as follow:

eg.

import { createAquedux } from 'aquedux-client'
import { createStore, applyMiddleware } from 'redux'

const aquedux = createAquedux({
    endpoint: 'http://localhost:4242/aquedux',
    hydratedActionTypes: [ADD_TODO, CHECK_TODO],
    channels: [
        'users',
        'todos',
        {
            name: 'todo',
            reduce: (prevState, snapshot) => {
                  return {
                       ...prevState,
                       todos: {
                           ...prevState.todos,
                           [`todo-${snapshot.id}`]: snapshot.payload
                       }
                  }
            }
        }
     ]
})

const store = createStore(/* some reducer */, applyMiddleware(aquedux))

Middleware & Client

The middleware behaves like it used to AND is also the socket server instance (that createAqueduxClient used to return). It must start the socket connection as soon as it is created. An option start: boolean (default to true) could be introduce to delay the connection.

Reducer

No more aquedux reducer. The internal aquedux state is kept in the aquedux middleware. That way we don't polute the user store, nor contraint its shape.

The new middleware must user store.replaceReducer to add the wrapStoreReducers by itself.

Action Creators

We should also expose action creators as an api to interact with aquedux - some are local, others are wired. All communications are handled with classic redux actions interpreted by the middleware. Those action can be used by the used to reducer metrics in its own reducers.

* RENAME: unsubscribeFromChannel to unsubscribe of type "@aquedux/unsubscribe"

* NEW: restart of type "@aquedux/restart"

* NEW: stop of type "@aquedux/stop"

(1) The start action creator is mandatory only if the start: boolean option is implemented

The new action creators are used to manually restart or close the middleware's socket connection.

chabou commented 6 years ago

The new middleware must user store.replaceReducer to add the wrapStoreReducers by itself.

This is not obvious when the new middleware should add the wrapStoreReducers. On first non-@@INIT event?


Another point with this only-middelware architecture: how an user will know that a channel subscribe is in progress? Maybe user would have to reduce @aquedux/subscribe by himself to keep a track of these subscribes? The idea is to show a spinner during this subscribe.


I think that we should add another action: @aquedux/status with data like:

{
  status: 'connecting',
  tries: 2, // If there was previous failed attempt
  delay: 2000 // Delay before a real connection retry
}

State transtions can be: connecting -> [resynchronizing (in a restart) ->] ready -> disconnected (if aquedux is stopped). Be careful: We should ensure that user store is ready before launching first connection (and trigger a redux action). User won't be able to get aquedux status, he will only see status changes, thanks to actions.

I would suggest to name option autoStart: boolean