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-entity-manager

v0.0.3

Published

Easy domain entity managenent with Redux

Downloads

6

Readme

Redux Entity Manager

Build Status

A framework-agnostic library for easy domain entity management

Demo

React with Redux and Thunk

Coming soon: demo and examples using React with redux-observable and Angular with ngrx.

Prerequisites

  1. Any Redux library such as Redux, ngrx or custom implementation.
  2. Any side-effect library such as Redux Thunk, redux-observable, ngrx or custom implementation.
  3. Domain entities must have a primary key.

Installation

yarn add redux-entity-manager

or

npm install redux-entity-manager

Motivation

In some Redux tutorials you have probably seen code that looks like this:

const initialState = {
    selectedId: null,
    todos: [
        {
            id: 1,
            name: 'Foo',
        },
    ],
};

While this works fine for a simple project, in real life applications it will cause problems because:

  • the state is not normalized
  • client state and domain entities are mixed together.

A better state structure would look like this:

{
    "entities": {
        "todo": {
            "1": {
                "id": 1,
                "name": "Foo"
            }
        }
    },
    "pages": {
        "account": {
            "todos": {
                "selectedId": null
            }
        }
    }
}

To create our root reducer for this state structure we'd probably write something like this:

import { combineReducers } from 'your-favourite-redux-library';

const rootReducer = combineReducers({
    entities: {
        todo: todoReducer,
        user: userReducer,
        // Other entity reducers
    },
    // Other reducers
});

Notice that we have to write a separate reducer with its own actions and selectors for each entity. Again, this is fine for simple projects, but what if we have dozens of domain entities? A possible solution would be using a reducer factory:

import { combineReducers } from 'your-favourite-redux-library';

const rootReducer = combineReducers({
    entities: {
        todo: makeEntityReducer('todo'),
        user: makeEntityReducer('user'),
        // Other entity reducers
    },
    // Other reducers
});

This approach has one more serious advantage: we can now create reusable components such as data tables, forms, etc.

React example:

<DataTable entityName="todo" columns={['id', 'name']} />
<DataTable entityName="user" columns={['id', 'name', 'address', 'phone']} />

Angular example:

<app-data-table entityName="todo" [columns]="['id', 'name']"></app-data-table>
<app-data-table entityName="user" [columns]="['id', 'name', 'address', 'phone']"></app-data-table>

Basics

Redux Entity Manager provides a reducer factory, action creators and selectors. All action creators and selectors have two mandatory parameters: entityName and query which are probably best explained by examples:

const entityName = 'user';
const query = null;
const action = makeReadRequestAction(entityName, query);
const users = entitiesSelector(state, { entityName, query });
const entityName = 'user';
const query = {
    id: 1,
};
const action = makeReadRequestAction(entityName, query);
const users = entitiesSelector(state, { entityName, query });
const entityName = 'user';
const query = {
    page: 1,
    limit: 10,
};
const action = makeReadRequestAction(entityName, query);
const users = entitiesSelector(state, { entityName, query });
const entityName = 'user';
const query = {
    banned: true,
};
const action = makeReadRequestAction(entityName, query);
const users = entitiesSelector(state, { entityName, query });

Think of how you write a SQL query:

SELECT * FROM users WHERE id = 1

or

SELECT * FROM users LIMIT 10

In Redux Entity Manager, entityName corresponds to table name in FROM clause, and query to everything else. In fact, much like most RDBMSs, Redux Entity Manager will create an index for each query to avoid storing duplicate entities.

Please note that Redux Entity Manager only handles data in Redux store. It is your responsibility to write side effects, i.e. http requests. This is an intentional design decision that allows using

  • any side effects library (e.g. Redux Thunk, redux-observable, ngrx, etc...)
  • any architecture (REST, GraphQL, etc...)
  • any additional logic (pagination, cache invalidation, undo/redo, etc...)

Tutorials and Examples

Contributing

Improvements and bugfix PRs are welcome!

If you have an idea for a feature that would break API or tests, please open a discussion before submitting a PR.