npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redux-lens

v0.6.0

Published

Apply a redux reducer and an action at the specified path of your application state tree.

Downloads

16

Readme

redux-lens npm version Build Status

Apply a redux reducer and an action at the specified path of your application state tree (i.e. redux store).

Install

$ npm install --save redux-lens
$ yarn add redux-lens

Usage

const {createStore} = require('redux');
const {createReducer, reduceIn, path} = require('redux-lens');

const defaultReducer = (state) => {
    console.log('defaultReducer called');
    return state;
};

const initialState = {
    foo: {
        bar: {
            baz: [1, 42]
        }
    },
    counter: 9000
};

const {reducer, path as pathCreator} = createReducer({
    reducer: defaultReducer,
    aliases: {
        plusTwo(state = 0, action) {
            switch(action.type) {
                case 'ADD': {
                    return state + 2;
                }
            }

            return state;
        }
    }
});

const store = createStore(reducer, initialState);

const addReduce = (state = 0, action) => {
    switch(action.type) {
        case 'ADD': {
            return state + 1;
        }
    }

    return state;
};

const addAction = {
    type: 'ADD'
};

store.getState();
// => {
//     foo: {
//         bar: {
//             baz: [1, 42]
//         }
//     },
//     counter: 9000
// };

// Using an alias.
store.dispatch(reduceIn(['foo', 'bar', 'baz', 1], 'plusTwo', addAction));
// => {
//     foo: {
//         bar: {
//             baz: [1, 44]
//         }
//     },
//     counter: 9000
// };

store.dispatch(reduceIn(['counter'], addReduce, addAction));
// => {
//     foo: {
//         bar: {
//             baz: [1, 44]
//         }
//     },
//     counter: 9001
// };

// Create a lens path
const pathToCounter = path(['counter']);

store.dispatch(reduceIn(pathToCounter, addReduce, addAction));
// => {
//     foo: {
//         bar: {
//             baz: [1, 44]
//         }
//     },
//     counter: 9002
// };

API

createReducer(options)

options = {
    // Function signature: fallback_reducer(state, action) => next_state
    //
    // redux compatible reducer function (optional)
    reducer: fallback_reducer,

    // Function signature: getter(path, state) => value
    //
    // function to get the value at "path" of "state". (optional)
    get: getter,

    // Function signature: setter(path, new_value, state) => next_state
    //
    // function to set "new_value" at "path" of "state". (optional)
    set: setter,

    // Plain object mapping aliases to redux reducers. (optional)
    aliases: {
        alias: reducer
    }
}

Returns:

  • A redux reducer function. This reducer consumes actions generated by the reduceIn function.
  • Path creator. The path creator is same as path(path_to_state, getter = optional, setter = optional) => lensPath. But with getter and setter fallback to get and set functions as defined in options.

reduceIn(path, reducer, action) => action

reduceIn is an action creator, which generates an action that would be consumed by the reducer generated by createReducer(options).

  • path (Array | String | lensPath): An array of keys forming a path to the value in the state to be reduced. If path is a String, then the path will be resolved into an array using the lodash function _.toPath.

  • reducer (Function) or alias (String): redux reducer function or an alias. If an alias is passed, the redux reducer mapped to the alias must be configured through the createReducer function.

  • action (plain object / flux standard action): An action that reducer can consume. Must be flux standard action (FSA) compliant.

path(path_to_state, getter = optional, setter = optional) => lensPath

Creates a function (i.e. lensPath) whose focus is at the specified path, path_to_state.

  • getter :: (path, state) => value
  • setter :: (path, new_value, state) => next_state
  • getter and setter functions are optional. If they are not set, then internal functions will be provided and will assume redux store state are plain objects.

Similar to: http://ramdajs.com/docs/#lensPath

Type signature of lensPath:

lensPath :: Functor f => P -> getter -> setter -> lens

lens :: Functor f => intoFunctor -> R -> f U
getter :: P -> R -> T (default to `path` function)
setter :: P -> U -> R -> R' (default ot `assocPath` function)
intoFunctor :: Functor f => T -> f T

P := path
R := root
T := value_at_path
U := newValue
R' := newRoot
f T := Functor<T>
f U := Functor<U>

Functor<T> := {
    value: T,
    map: mapf -> Functor<U>
}
mapf :: T -> U

To learn more about lenses, see: https://medium.com/@dtipson/functional-lenses-d1aba9e52254

Custom set / get

If you do not assign custom set / get functions via createReducer(options), then state is assumed to be a plain object type.

Development

  • Install dependencies: yarn install

  • Lint: yarn run eslint

  • Tests: yarn run test

Credits

Credits to the following, of which I've refactored out lens functions into ~/src/lens.js:

  • https://medium.com/@dtipson/functional-lenses-d1aba9e52254
  • https://github.com/ramda/ramda

License

MIT.