Motivation

I created refinery trying to solve problems I encounter the best way possible. Doing so I was inspired by other libraries and took what I found clever, filling the gap where I felt something was missing.

Inspiration

Refinery follows the same principle as Redux. Which is : whenever something happen a serializable action is dispatched and the new app state is computed with a reducer function. newState = reducer( action, oldState ).

In fact, you can see refinery as a convenient way to write your reducer to pass to the redux store creator. With smarter listeners.

Redux encourage you to break your application state into isolated reducer, which are responsible for only a small piece of the state.

Which is great, but I always find myself having to enlarge the scope of reducer when I have a value that depends on many parts of the state.

Let me explain why I came to develop refinery with an example.

Example

Let's take an example,

Reducers are composed like this :

const state = {
    listA : [],     // updated by reducerA
    listB : [],     // updated by reducerB
}

Let says ReducerA handles many complex thing, with many actions. Same thing for ReducerB.

const reducerA = ( action, previousListA ) => {
    switch( action.type ) {
        //
        // very large switch with complex stuff
        // ...

const reducerB = ( action, previousListB ) => {
    switch( action.type ) {
        //
        // even larger switch, with unrelated to listA, yet complex stuff
        // ...

This is a good use of combineReducers

const reducer = combineReducers( reducerA, reducerB )

Issue

Now let say we need to maintain the sum of all element in listA + listB, and have it in the state.

const state = {
    listA : [],
    listB : [],
    sum   : 0,
}

We can merge the two reducers, but we don't want to, they are complex enought left alone.

We could probably go with composing reducer.

The state pass throught the first reducer, then to another one reducerCount

const reducer = compose( combineReducers( reducerA, reducerB ), reducerCount )
const reducerCount = ({ listA, listB }) =>
    ({
        listA,
        listB,
        sum : listA.length + listB.length
    })

This is acceptable. However as the application grows it becomes painful to determine by hand which reducer should be called first.

Solution

This is what refinery do.

You describe the application with dependency relation between piece of state.

const sum = ( listA, listB ) =>
    listA.length + listB.length

sum.dependencies = [ listA, listB ]

Refinery handles for you to call the update function when needed.

results matching ""

    No results matching ""