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

trampss-redux-data-store

v4.1.0

Published

Factory of Redux reducers and their associated actions and selectors. > Make your Redux code base tinier and simpler to maintain

Downloads

15

Readme

trampss-redux-data-store

Factory of Redux reducers and their associated actions and selectors.

Make your Redux code base tinier and simpler to maintain

CircleCI Coverage Status NPM Version

Contents

Purpose

trampss-redux-data-store creates generic reducers, actions and selectors in two lines.

import factory from 'trampss-redux-data-store'
export default factory(/* middlewares */)('id')('api')('todos')

That's it, you exported a reducer function you can register thanks to combinerReducer in Redux.

In this example, we have a todos reducer, it has to be combined into state.api.todos

Why

We like to write Redux code as simple as possible and use its middlewares to handle real world problems. From this point of view, our Redux code base simpler : it's like a key/value store. But one drawback is the amount of duplicated code, each resource has its own reducers, actions and selectors.

To avoid Redux code base from growing, inconsistency and lowering maintainability, we created this lightweight library (<4Kb) that is a factory of reducers, actions and selectors.

Installation

  • yarn add trampss-redux-data-store
  • npm i trampss-redux-data-store

peer dependency

  • lodash : we use the minimum of lodash function trying to have a lightweight webpack bundle.
    • keyBy
    • without
    • uniq
    • omit
    • at

API

factory

You need to use the factory to get a new set of reducer/actions/selectors :

import factory from 'trampss-redux-data-store'

This factory takes four parameters, you could use between these signatures :

  • factory(middlewares, fieldKey, path, name)
  • factory(middlewares, fieldKey, path)(name)
  • factory(middlewares, fieldKey)(path)(name)
  • factory(middlewares)(fieldKey)(path)(name)

Parameters are :

  • middlewares (optional), contain an object with pre and post fields. Both are an array of middlewares to apply before and after the core middleware.
  • fieldKey (mandatory), the field used to identify your objects (id for example)
    • you have to set this parameter.
  • path (optional), where the reducer will be combined via combineReducer
    • if empty export default factory('id')()('todos'), the reducer will be register ate the root level of the redux state
    • you can use dot notation, like api.raw: your reducer will be combined into state.api.raw.<your_reducer>
  • name (mandatory), the reducer name (for instance: todos)
    • it's used to generate actions types
    • it's used to retrieve informations from selectors

Example:

  • this reducer will use id as key field
  • it's combined into state.api.raw
  • its name is todos
import factory from 'trampss-redux-data-store'
// factory(fieldKey)(path)(name)
export default factory()('id')('api.raw')('todos')

Data will be stored into state.api.raw.todos

reducer

The previous factory returns a function which is a reducer. You just have to combine it like any other reducer :

import { createStore, combineReducers, compose, applyMiddleware } from 'redux'

// import your reducer
// (created by tramps-redux-data-store factory)
import todos from './myTodosReducer'

// create your Redux store as usual
const store = createStore(
  combineReducers({
    // [other reducer]
    api: combineReducers({
      // [other reducer]
      raw: combineReducers({
        // import your reducer into api.raw
        // since we configured this path
        todos,
      }),
      // [other reducer]
    }),
    // [other reducer]
  }),
  /* your Redux middlewares */
)

export default store

actions

The factory returns a function (this is the reducer) that also contains actions and selectors as fields. Some generic actions are available. By now, it's not possible to add custom ones.

Actions are:

| function name | description | signature | generated action | |---|---|---|---| | set | set an array of instances of your resource | set(<array>) | { type: '@trampss/SET_TODOS', payload: <array> } | | add | add an instance of your resource | add(<instance>) | { type: '@trampss/ADD_TODOS', payload: <instance> } | | remove | remove one instance of your resource by its key | remove(<key>) | { type: '@trampss/REMOVE_TODOS', payload: <key> } | | reset | reset the reducer (wipe all data) | reset() | { type: '@trampss/RESET_TODOS' } |

Example, we set todos to our reducer:

// import your reducer
// (created by tramps-redux-data-store factory)
import todos from './myTodosReducer'

// dispatch can be given by one of your middleware (redux-thunk, redux-saga, etc)
// or it can be given by react-redux for example (mapDispatchToProps)
dispatch(
  // set todos
  todos.set([
    {
      id: '1', // we set 'id' as key in the factory
      visible: true,
      label: 'My first todo',
    },
    {
      id: '2',
      visible: false,
      label: 'This todo is done',
    },
  ])
)

selectors

The factory returns a function (this is the reducer) that also contains actions and selectors as fields. Some generic selectors are available. By now, it's not possible to add custom ones.

Selectors are:

| signature | description | comment | |---|---|---| | get(<id>)(state) | returns all data, or specific(s) one(s) (by key(s)) | if <id> is undefined, it returns all dataif <id> is an array, it returns all instances that match one of idsin other cases, it returns the instance with its id that that match the parameter | | getBy(<propertyPath>, <value>)(state) | get data specified by the field you want to filter with (take care, selectors are not memoized) | Example: getBy('visible', true)(state) returns all visible todos. | getKeys(state) | returns all store keys (in array) | | | getAsArray(state) | returns all data in array (raw) | | | getLength(state) | returns number of stored instances | | | isInitialized(state) | return true if the store has been initialized (by add or by set action) | | | getState(state) | returns the global state of your reducer | The global state contains :data: key/value storearray: raw datakeys: keys arrayinitialized: boolean (set to true by set and add actions)

Example, we retrieve the todo with id 1:

// import your reducer
// (created by tramps-redux-data-store factory)
import todos from './myTodosReducer'

// state can be given by one of your middleware (redux-thunk, redux-saga, etc)
// or it can be given by react-redux for example (mapStateToProps)
todos.get('1')(state)