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-stack

v1.0.1

Published

[![npm](https://img.shields.io/npm/v/redux-stack.svg?maxAge=2592000?style=plastic)]() [![Build Status](https://travis-ci.org/jondot/redux-stack.svg?branch=master)](https://travis-ci.org/jondot/redux-stack)

Downloads

59

Readme

Redux stack

npm Build Status

Redux Stack is a library that helps you build modular, structured, and cleaner redux apps.

As the Redux ecosystem grows, libraries integrate by offering their own middleware, or enhancers, or even custom compose and createStore functions. When each library require a different way, or a "non standard" way to integrate with your Redux store, reducers, and middleware, it's inevitable that something will break, or at least for the code base to be rigid and not modular enough to scale.

Redux Stack introduces a concept of initializers. Small pieces of integration code, per library, that "declares" how it integrates. Redux Stack will mesh these together to create your personalized store builder.

Quick Start

Create an initializers folder, and drop an initializer there. An initializer is the main abstraction around Redux Stack, and it's responsibility is to declare, for each integration, how to configure the store. To see how the redux DevTools initializer looks like, for example, check out this file. We'll come back to initializers in a bit.

To create your store, you only need to pull the initializers and configure with redux-stack:

import { createStore, combineReducers } from 'redux'
import { buildStack } from 'redux-stack'
import stack from './initializers'

const { reducers, enhancer } = buildStack(stack)
const store = createStore(combineReducers(reducers), {}, enhancer)

export default store

Initializers

An initializer in Redux Stack, is a simple Javascript module that exports the following shape:

export default {
  reducers: {}
  enhancers: []
  composers: []
}

The reducers, enhancers (applyMiddleware is one example of an enhancer), and composers fields all contain one or more of the standard redux reducer, enhancer and composer.

To learn how to make your own initializer, take a look at the example initializers in the examples folder, which cover trivial and more complex configuration.

Towards Redux Initializers and Presets

One goal is to have an extensive, pre-made set of initializers as part of redux-stack so people don't need to write them. For every well-known library you'll have a ready-made initializer that takes care of its configuration and integration into your Redux app.

So if you build a new initializer for a redux library, please feel free to submit!

Another goal is to provide presets, which are sets of initializers, or complete stacks for you to use. This idea is inspired from babel presets. So you could even do something like this:

import { createStore, combineReducers } from 'redux'
import { buildStack } from 'redux-stack'
import stack from 'stack-react-native'

const { reducers, enhancer } = buildStack(stack)
const store = createStore(combineReducers(reducers), {}, enhancer)

export default store

Example Store Setup

Here's how Redux Stack improves the way your code base feels, and supports modularity.

Before

import users from '@/modules/users/state'
import settings from '@/modules/settings/state'
import intro from '@/modules/intro/state'
import { NavigationReducer, createNavigationEnabledStore } from '@exponent/ex-navigation'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import { createStore, applyMiddleware, combineReducers, compose } from 'redux'
import { persistStore, autoRehydrate } from 'redux-persist'
import immutableTransform from 'redux-persist-transform-immutable'
import {AsyncStorage} from 'react-native'
const devtools = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const reducers = {
  users,
  settings,
  intro,
}
const rootReducer = combineReducers({navigation: NavigationReducer, ...reducers})


const logger = createLogger({
  collapsed: true,
  // only log in development mode
  predicate: () => __DEV__,
  // transform immutable state to plain objects
  stateTransformer: state => removeNavigation(fromJS(state).toJS()),
  // transform immutable action payloads to plain objects
  actionTransformer: action =>
    action && action.payload && action.payload.toJS
      ? {...action, payload: action.payload.toJS()}
      : action
})

let middleware = [
  thunk,
  logger
]

const createStoreWithNavigation = createNavigationEnabledStore({
  createStore,
  navigationStateKey: 'navigation',
})

const initialState = {}

const store = createStoreWithNavigation(
  rootReducer,
  initialState,
  compose(
    autoRehydrate(),
    devtools(
      applyMiddleware(...middleware)
    )
  )
)

persistStore(store, {
  storage: AsyncStorage,
  blacklist: ['navigation'],
  transforms: [immutableTransform()]
})

export default store

The setup code is convoluted. In addition imports and library usage are separated and out of mind. It also means that if you ever want to change, or remove components you'll have to hunt them out and hope you didn't break your app; we see a lot of importance for how your order your integration.

After

import { createStore, combineReducers } from 'redux'
import { buildStack } from 'redux-stack'
import stack from '@/initializers'

const initialState = {}
const { reducers, enhancer } = buildStack(stack)
const store = createStore(combineReducers(reducers), initialState, enhancer)

export default store

Where we have a new initializers folder:

initializers/
├── devtools.js
├── ex-navigation.js
├── index.js
├── middleware.js
├── reducers.js
├── redux-logger.js
└── redux-persist.js

The setup code is a no brainer. It is clean and reasonable and probably will look the same for every new app you make, so you can even extract that out into an npm module.

The initializers realm is separate and modular. You can remove and add any initializer you like and be certain nothing will break. If you built your app in a modular fashion, every module can "contribute" an initializer which sets itself app, and no drama happens - no other code to change or module to wreck by mistake.

Contributing

Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).

Thanks:

To all Contributors - you make this happen, thanks!

Copyright

Copyright (c) 2016 Dotan Nahum @jondot. See LICENSE for further details.