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

immutable-selectors

v1.0.5

Published

Converts a nested objects tree to tree of selector-functions, which can be used for convenient data access and modifications

Downloads

12

Readme

immutable-selectors

travis build status Coverage Status

This package is used for comfort reusable access to parts of deep nested immutable structures. It also allows you to make modification of this structures.

Usage

Example immutable structure

const state = Immutable.fromJS({
  moduleA: {
    foo: {
      id:100500,
      deep:{
        val:500
      },
      message:'SomeStringMessage'
    },
    bar:{}
  },
  moduleB:{}
});

Create selector tree Describe nested selector - object with properties you want to get access:

    const selectors = {
      foo:{
        deep:{val:{}},
        message:{}
      }
    }

Make selectors from this object:

import extendSelecors from 'immutable-selectors';
extendSelecors(selectors, ['moduleA']);

extendSelecors(selectorsTree, [path]) function recursively converts each key in object to a function(state), which returns corresponding part of immutable structure. At the same time, it saves the hierarchy. It is not returns a new selector - object, but it converts selectors object itself. This allows to use intelliSence in most of IDEs.

Use selector

console.log(selectors.foo.message(state)); //SomeStringMessage
console.log(selectors.foo(state)); // Map { "id": 100500, "deep": Map { "val": 500 }, "message": "SomeStringMessage" }
console.log(selectors.foo(state).get('message')); // SomeStringMessage
console.log(selectors.foo.deep.val(state)); // 500

flat option: Each unique key of selectors-tree is dublicated in selectors.flat object:

console.log(selectors.flat.val(state)); //500
console.log(selectors.flat.message(state)); // SomeStringMessage

root option:

const moduleAData = selectors.root(state);
console.log(moduleAData.getIn(['foo', 'id'])); //100500

Modifications Each selector-function in tree has replace(state, newValue) child function, which returns new immutable structure with changed corresponding part.

var newState = selectors.foo.message.replace(state, 'updated message');
console.log(newState.getIn(['moduleA','foo', 'message'])); //updated message
var newState = selectors.flat.val.replace(state, 'new value');
console.log(newState.getIn(['moduleA','foo', 'deep', 'val'])); //new value
var part = selectors.foo(state).asMutable();
part.setIn(['deep', 'val'], 'fivehundred');
var newState = selectors.foo.replace(state, part.asImmutable());
console.log(newState.getIn(['moduleA','foo', 'deep', 'val']));//fivehundred

Parameters

It is possible to use selectors for collection items access (Lists and Maps). You should specify param property in selector-object at collection level.

Example immutable structure

const state = Immutable.fromJS({
  moduleA: {
    bar: {
      listItems: [
        {
          key: 100,
          caption: 'firstListItem',
          deep:{ description:'someText'}
        },
        {
          key: 200,
          caption: 'secondLIstItem'
        }
      ]}}
});

Create selector tree

    const selectors = {
        bar:{
          listItems:{
            param:'x',
            key:{},
            caption:{},
            deep:{description:{}}
          }
        }
    }

   extendSelecors(selectors, ['moduleA']);

Use

  console.log(selectors.bar.listItems.caption(state, '1')); //secondLIstItem
  console.log(selectors.flat.key(state, '0')); //100
  console.log(selectors.flat.description(state, '0')); //someText
  console.log(selectors.bar.listItems(state, '1'));//Map { "key": 200, "caption": "secondLIstItem" }
  console.log(selectors.bar.listItems(state));//List [ Map { "key": 100, "caption":...

Modifications Use third parameter of replace function to specify collection item.

var newState = selectors.bar.listItems.caption.replace(state, 'updated-first', '0');
console.log(newState.getIn(['moduleA', 'bar', 'listItems', '0', 'caption'])); // updated-first

Use with redux

One of use-cases is to replace redux reducers with action-creators, which generates new global state. Example of action-creator:

export function showMessage(message) {
  return function (dispatch, getState) {
    dispatch({
      type: 'show message',
      setState: selectors.message.replace(getState(), message)
    });
  };
}

Root reducer:

function setStateReducer(state = initialState, action) {
  if (action.setState) {
    return action.setState;
  } else {
    return state;
    // return combinedReducers(state, action);  // You can mix this pattern with classical combineReducers - function.
  }
}

Example of using immutable-selectors with redux without reducers.