deduce

    2.0.0-2 • Public • Published

    deduce

    NPM version Downloads Build Status Coverage Status Tip

    Ridiculously easy JavaScript state containers with reducer methods. Like Redux without all of the boilerplate.

    Install

    npm install --save deduce
    

    Usage

    // reducers.js
     
    export function increment(state, val = 1) {
        return state + val;
    }
     
    export function decrement(state, val = 1) {
        return increment(state, -val);
    }
     
    // store.js
     
    import deduce from 'deduce';
    import * as reducers from './reducers';
     
    const store = deduce(1, reducers);
     
    store.addListener(() => {
        console.log(store.state);
    });
     
    store.increment();  // -> 2
    store.increment(2); // -> 4
    store.decrement();  // -> 3
    store.decrement(2); // -> 1

    API

    deduce(initialState, reducers) : Store

    • initialState {*}
    • reducers {Object<String,Function>}

    Store

    .state

    Current state of the store.

    const store = deduce({ foo: 1 });
     
    console.log(store.state); // -> { foo: 1 }

    .addReducers(reducers): Store

    • reducers {Object<String,Function>}

    Registers reducers to modify the state. Chainable.

    store.addReducers({
        increment(state, val) {
            return {
                ...state,
                foo: state.foo + val,
            };
        },
    });

    .addReducersFor(property, reducers): Store

    • property {String}
    • reducers {Object<String,Function>}

    Registers reducers to modify a specific state property. Chainable.

    store.addReducersFor('foo', {
        increment(state, val) {
            return state + val;
        },
    });

    .addListener(callback): Function

    • callback {Function}

    Adds a listener to be called any time the state is updated. Returns a function to remove the listener.

    const removeListener = store.addListener(() => {
        console.log(store.state);
    });
     
    store.increment();

    Why?

    The typical Redux patterns entail a lot of boilerplate. The documented and accepted patterns for reducing boilerplate really just swap one kind for another:

    Redux Example

    Consider the following Redux example that creates a store with two numbers: foo which may be incremented and bar which may be decremented.

    // foo
     
    const FOO_INCREMENT = 'FOO_INCREMENT';
     
    const fooInitial = 0;
     
    const fooReducers = {
        [FOO_INCREMENT]: (state = fooInitial, action) {
            return state + action.payload;
        }
    };
     
    function foo(state = {}, action) {
        if (action.type in fooReducers) {
            return fooReducers[action.type](state, action);
        }
     
        return state;
    }
     
    function createFooIncrementAction(payload) {
        return {
            type: FOO_INCREMENT,
            payload
        };
    }
     
    // bar
     
    const BAR_DECREMENT = 'BAR_DECREMENT';
     
    const barInitial = 0;
     
    const barReducers = {
        [BAR_DECREMENT]: (state = barInitial, action) {
            return state - action.payload;
        }
    };
     
    function bar(state, action) {
        if (action.type in barReducers) {
            return barReducers[action.type](state, action);
        }
     
        return state;
    }
     
    function createBarDecrementAction(payload) {
        return {
            type: BAR_DECREMENT,
            payload
        };
    }
     
    // store
     
    import { createStore, combineReducers } from 'redux';
     
    const reducer = combineReducers({ foo, bar });
    const store = createStore(reducer, {});
     
    // application
     
    store.dispatch(createFooIncrementAction(1));
    store.dispatch(createBarDecrementAction(1));
     
    console.log(store.getState());
    // {
    //   foo: 1,
    //   bar: -1
    // }

    Split that up into modules and you can see how new-comers could easily be overwhelmed when the underlying principles are beautifully clean and simple.

    Deduce Example

    Compare the above with this deduce example that does the same thing:

    // foo
     
    const fooInitial = 0;
     
    const fooReducers = {
        incrementFoo(state = fooInitial, val) {
            return state + val;
        }
    };
     
    // bar
     
    const barInitial = 0;
     
    const barReducers = {
        decrementBar(state = barInitial, val) {
            return state - val;
        }
    };
     
    // store
     
    import deduce from 'deduce';
     
    const store = deduce()
        .addReducersFor('foo', fooReducers)
        .addReducersFor('bar', barReducers);
     
    // application
     
    store.incrementFoo(1);
    store.decrementBar(1);
     
    console.log(store.state);
    // {
    //   foo: 1,
    //   bar: -1
    // }

    Contribute

    Standards for this project, including tests, code coverage, and semantics are enforced with a build tool. Pull requests must include passing tests with 100% code coverage and no linting errors.

    Test

    $ npm test
    

    MIT © Shannon Moeller

    Install

    npm i deduce

    DownloadsWeekly Downloads

    1

    Version

    2.0.0-2

    License

    MIT

    Unpacked Size

    20.1 kB

    Total Files

    7

    Last publish

    Collaborators

    • shannonmoeller