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 🙏

© 2025 – Pkg Stats / Ryan Hefner

redux-parts

v0.4.0

Published

It\`s just a try to create a tool for helps you create and manage your reducer and actions.

Readme

redux-parts

It`s just a try to create a tool for helps you create and manage your reducer and actions.

Redux-parts is a small library, with no dependies. It has small and very human friendly API.

Here we go a simple example:

import {Creator} from 'redux-parts';

const part = {
 initial_state: {
  text: 'Hello'
 },
 
 reducer: {
  addText(state, action) {
   return {
    ...state,
    text: `${state.text} ${action.payload}`
   }
  }
 }
}

const {actions, reducer} = Creator(part);

const state = reducer(undefined, actions.addText('World!'))

state.text === 'Hello World!'

Goals

  • Helps to organize code (reducer, actions and etc)
  • Easy
    • create and support
    • combine and extend
    • build deep state
    • testing
  • Remove
    • action type constant
    • switch-case from reducer

Example app

Example code


Table of contents


Install

npm i -S redux-parts

BasicTerms

Here describes basic terms, which helps you to start.

  • Part - is the smallest bit of your code. Is`s just a simple object with few properties. Parts may be simple or complex.
    • SimplePart - looks like mixins. Simple parts allows you write many little pieces and just merge them in complex part. Interface:
interface ISimplePart {
  reducer: Dictionary<Functions>;
  actions?: Dictionary<Functions>;
  initial_state?: any;
}
  • ComplexPart - is a little bit difficult than simple part. With complex part you can build a deep state, with sub states. Also you can mixin simple parts into your complex part. It`s easy, see code examples or example app. Interface:
interface IComplexPart {
  reducer?: Dictionary<Functions>;
  actions?: Dictionary<Functions>;
  initial_state?: any;
  
  simple_parts?: ISimplePart[];
  complex_parts?: Dictionary<IComplexPart>;
}

API

Creator

After you have created a part, you can create actions and reducer just pass part to Creator:

import {Creator} from 'redux-parts';

const part = // part code here

const {actions, reducer} = Creator(part);
  • actions - object with action creators, with pre-set types.

Redux-parts use flux-standard-action for create actions.

  • reducer - pure function. This function you can pass to createStore function.

What is it a "part"? See it below.


Part

"Part" is just javascript object, with such properties:


reducer

type | simple part | complex part --- | --- | --- Dictionary<Functions> | required | optional

It is an object with pure functions. From these functions will build final reducer function. For example:

const counter_part = {
 reducer: {
  add(state, action) {
   return {
    ...state,
    value: state.value + action.payload
   }
  }
 }
}

const {actions, reducer} = Creator(counter_part);

let state = {value: 0};

const add_action = actions.add(5);
state = reducer(state, add_action);

expect(add_action).to.deep.equal({type: 'add', payload: 5})
expect(state).to.deep.equal({value: 5})

As you can see, redux-parts automatically create default action creators, with the same name. First argument such action creators, will be payload in action object, other arguments will be ignore.

initial_state

type | simple part | complex part --- | --- | --- Dictionary<any> | optional | optional

In example above, we must set initial state into state variable. But in redux nobody will create initial state for us.

Now with this property we can create reducer function with initial state:

const counter_part = {
 initial_state: {
  value: 0
 },
 reducer: {
  add(state, action) {
   return {
    ...state,
    value: state.value + action.payload
   }
  }
 }
}

const {actions, reducer} = Creator(counter_part);

// No value here anymore
let state;
state = reducer(state, actions.add(5));

expect(state).to.deep.equal({value: 5})

actions

type | simple part | complex part --- | --- | --- Dictionary<Functions> | optional | optional

Sometimes default action creators, which was created automatically from reducer property, can be not enough.

Maybe you wanna pass more than one argument or doing something with your arguments in action creator function.

All that you will return from action creator, will be in the payload action property.

Name of function in actions must be equal with name of function in reducer:

const counter_part = {
 initial_state: {
  value: 0
 },
 
 actions: {
  add(firts, second) {
   return first + second;
  }
 },
 
 reducer: {
  add(state, action) {
   return {
    ...state,
    value: state.value + action.payload
   }
  }
 }
}

const {actions, reducer} = Creator(counter_part);

let state;

const add_action = actions.add(5, 10);
state = reducer(state, add_action);

expect(add_action).to.deep.equal({type: 'add', payload: 15})
expect(state).to.deep.equal({value: 15})

simple_parts

type | simple part | complex part --- | --- | --- Array<SimplePart> | no | optional

For example we have some logic, which we wanna add to different part. We can create a SimpleParts and just add it to our part.

Because the counter part from above examples is a SimplePart, we can use it(the last one) in our example:

// simple part
 const counter_part = ...;
 
 const part = {
  simple_parts: [
   counter_part
  ]
 }
 
const {actions, reducer} = Creator(part);

let state;

const add_action = actions.add(5, 10);
state = reducer(state, add_action);

// The same tests from example above
expect(add_action).to.deep.equal({type: 'add', payload: 15})
expect(state).to.deep.equal({value: 15})

As we can see, our part with "simple_parts" property works exactly, how just counter part, it happens because "simple_parts" is just array of mixins, nothing more.

complex_parts

type | simple part | complex part --- | --- | --- Dictionary<ComplexPart> | no | optional

Sometimes your state may have a sub state and that state have another sub state and etc. For easy combine and use sub state, we have a "complex_parts" property.

For example we wanna have a two independent counter in our app. We can take the "counter_part" from examples above and use it(the last one):

const counter_part = ...;

const part = {
 complex_parts: {
  counter_1: counter_part,
  counter_2: counter_part
 }
};

const {actions, reducer} = Creator(part);

let state;

const counter_1_add_action = actions.counter_1.add(5, 10);
const counter_2_add_action = actions.counter_2.add(40, 10);

state = reducer(state, counter_1_add_action);
state = reducer(state, counter_2_add_action);

expect(state).to.deep.equal({
 counter_1: {
  value: 15
 },
 counter_2: {
  value: 50
 }
})

Keys from "complex_parts" property will be a name for sub actions and will use in action types.

We can create a part with "complex_parts" property and use this part in another part in "complex_parts" property, thereby create any depth of state.

SimplePart

Simple part may include only these three properties:

  • reducer {Object} required
  • initial_state {Object}
  • actions {Object}

Simple part - is the smallest possible part. It is like mixin. You can create many simple parts and combine them in ComplexPart. Also can be a root part, if you have really small application) For example - simple part for load data:

const LoadDataPart = {
 reducer: {
 
  loadData(state, action) {
   return {
    ...state,
    is_pending: true
   }
  },
  
  loadDataSuccess(state, action) {
   return {
    ...state,
    data: action.payload.data,
    is_pending: false
   }
  }
  
 }

ComplexPart

Complex part - is the heart of library. With Complex part you can build big and deep state very easily and declarative style. Complex part has many usage examples and many of them described above, but if after reading this article you have a problem with use Complex part, please take a look examples code and/or app.