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

obrigado-redux-utils

v3.0.17

Published

<div> <a href="https://badge.fury.io/js/obrigado-redux-utils"> <img src="https://badge.fury.io/js/obrigado-redux-utils.svg"> </a> </div> obrigado-redux-utils is a small library designed to automatically generate Redux store, actions and reducers.

Downloads

30

Readme

Obrigado-Redux utils

It uses Immutable.js Records and lists to ensure store immutability.

Can be easily set up with redux-persist.

TypeScript types are included.

Setup with Redux

The first step is to create an object which will define your future store's initial state.

Next import ReduxHelper class and pass previously defined object to the constructor. Call createReducers() method to create an object containing automatically generated reducers.

Use ES6 spread operator and combineReducers function from Redux to create rootReducer. You can add your own reducers there as well.

Finally, create your store with createStore from redux and pass your root reducer to the createReduxHelper() method.

import {ReduxBuilder, ReduxStoreStateTemplate} from 'obrigado-redux-utils'
import {createStore, combineReducers} from 'redux'

const data = {
    user: {
        name: {
            firstName: 'Jhon',
            lastName: 'Ivanov'
        },
        age: 25,
        bd:new Date()
    },
    posts: {
        data: ['one', 'two']
    },
    isBool:true
}
// Use this type inside selectors
export type ReduxStoreState = ReduxStoreStateTemplate<typeof data>
const builder = new ReduxBuilder(data)
const reducer= builder.createReducer()

export const store = createStore(reducer)
// @ts-ignore


export const ReduxHelper = builder.createReduxHelper(store)

Now you can import ReduxHelper anywhere in your app and call the following methods on your store:

  • setIn
  • mergeIn
  • mergeDeepIn
  • updateIn
  • reset

Setup with redux-persist

If you want to use redux-persist with this package, obrigado-redux-utils already comes with a built-in method for this purpose.

Simply use createPersistsReducers() method instead of createReducers().

You will need to pass in storage engine, a list of whitelisted reducers.

Optionally, you can also pass an object with your custom reducers.

import {ReduxBuilder, PersistTransform, persistsReconciler, ReduxStoreStateTemplate} from 'obrigado-redux-utils'
import {createStore, combineReducers} from 'redux'
import {persistStore, persistReducer} from 'redux-persist'
import storage from 'redux-persist/lib/storage'

// defaults to localStorage for web
const persistConfig = {
    key: 'root',
    storage,
    transforms: [PersistTransform({
        whitelist: [
            {user:['name','age']},
            'isBool'
        ]
    })],
    stateReconciler: persistsReconciler

}

const data = {
    user: {
        name: {
            firstName: 'Jhon',
            lastName: 'Ivanov'
        },
        age: 25,
        bd:new Date()
    },
    posts: {
        data: ['one', 'two']
    },
    isBool:true
}
// Use this type inside selectors
export type ReduxStoreState =  ReduxStoreStateTemplate<typeof data> 
const builder = new ReduxBuilder(data)
const reducer= builder.createReducer()
// @ts-ignore
const persistedReducer = persistReducer(persistConfig, reducer)

export const store = createStore(persistedReducer)
// @ts-ignore
export const persistor = persistStore(store)


export const ReduxHelper = builder.createReduxHelper(store)

ReduxeHelper's methods

setIn (path, payload)

Path is an array of strings or numbers (for Lists) to the value you want to update. Use seIn to fully replace data at given path

mergeIn (path, payload)

Path is an array of strings or numbers (for Lists) to the value you want to update.

Uses mergeIn from Immutable.js to merge payload with store. Payload can be a plain JS object, an array or an Immutable structure.

import { ReduxHelper } from 'path/to/ReduxHelper'

ReduxHelper.mergeIn(['user', 'name'], {firstName:'Jane'}) // will change firstName from John to Jane
ReduxHelper.mergeIn(['posts', 'data'], ['three']) // will result in posts.data = ['one', 'two', 'three']

mergeDeepIn (path, payload)

Uses mergeDeepIn from Immutable.js to merge payload with store. Arguments work in the same way as in the previous method.

ReduxHelper.mergeDeepIn(['user', 'name'], {
  name: {
    firstName: 'Sam'
  },
  age: 34
})

When merging plain JS objects with the store and changing several fields in one merge like in the example above, it is recommended to use mergeDeepIn().

This method will change only specified fields and leave others unchanged, unlike mergeIn() that will remove unspecified fields on that level. Meaning that if in this example we had used mergeIn() instead, it would have removed lastName field completely.

updateIn (path, updater)

Uses updateIn method from Immutable js to update store values.

Path works the same way as in two previous methods. Updater parameter allows you to pass in a function to do something with the values that you got from specified path.

ReduxHelper.updateIn(['user', 'name', 'firstName'], value => value.toUpperCase())
// this will change the value of firstName to upper case

reset (key)

This method simply resets your store back to its initial state based on the type value. Key is a string that specifies what part of the store you want to reset.

ReduxHelper.reset('user') // will reset user to initial state

setInAction, mergeInAction, mergeDeepInAction, updateIn, resetAction

These methods only create action object, that can be dispatched to store. They can be very useful in sagas. ##Selectors Lib transforms all incoming objects too immutable records and lists. Lib provides generic type ReduxStoreStateTemplate, that helps to access redux store state.

  const user=useSelector((state:ReduxStoreState)=>state.user)

Sagas

You can easily create rootSaga and SagaHelper which helps you to run sagas from components.

Root saga

  1. Import all modules with sagas into object:
import * as module1 from './sagas/module1'
import * as module2 from './sagas/module2'
const sagaModules = {module1,module2}
  1. Call createRootSaga , that's all!
import { createRootSaga} from 'obrigado-redux-utils'
...
sagaMiddleware.run(createRootSaga(sagaModules))

createRootSaga generates action handler for each saga in format [RUN_sagaName in upperCase]

Saga helper

SagaHelper is created in way similar to creating rootSaga

import { createSagaHelper} from 'obrigado-redux-utils'
...
export const store = createStore(rootReducer, composeEnhancers(applyMiddleware(sagaMiddleware)))
//@ts-ignore current version of redux-saga has wrong type mapping and reuires 2 args
sagaMiddleware.run(createRootSaga(sagaModules))
export const SagaHelper = createSagaHelper(sagaModules, store)

Calling sagas

import {SagaHelper} from './store'
function Component(){
     useEffect(() => {
        SagaHelper.run(["module1","loadData"],{page:1}).then(
                (data)=>console.log(data))
        .catch((e)=>console.warn(e))
        return () => {};
      });
}

Saga for handling such call can look like this:

export function* loadData(params:{page:number}){
    let res= yield appCall(params.page)
    if (!res) throw new Error("Empty result")
    return res;
}