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

v1.4.0

Published

Persist redux state

Downloads

451

Readme

Redux Phoenix

Restore redux state from previous sessions like a phoenix from ashes.

npm i --save redux-phoenix

CircleCI Maintainability Test Coverage

Basic usage

Basic usage requires adding a enhancer to a redux application:

// configureStore.js
import { createStore, compose } from 'redux';
import { autoRehydrate } from 'redux-phoenix';

const store = createStore(reducer, initialState, compose(
  applyMiddleware(...middlewares),
  autoRehydrate,
);

And modyfing client entry point:

// index.js
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import store from 'configureStore';
import persistStore from 'redux-phoenix';

persistStore(store).then(store => {
  render(
    <Provider store={store}>
      <App />
    </Provider>, document.getElementById('app')
  );
});

That's it. Now your redux state will be stored in localstorage.

API

persistStore(store, [config])

  • import persistStore from 'redux-phoenix'
  • arguments
    • store: redux store The store to be persisted.
    • config: object
      • key: string (default: redux) change storage default key.
      • whitelist: Array<string> (default: null) keys to persist, null means all keys will be persisted. It may be nested keys. For example: whitelist: [reducer.subfield] persist only { reducer: { subfield: valueFromState } } and omit all other keys.
      • blacklist: Array<string> (default: null) keys to ignore, null means no keys will be omitted. It may be nested keys and overwrite whitelisted keys.
      • storage: object (default: window.localStorage) a conforming storage engine.
      • expireDate: [number, string] (default: null) duration validity of the stored state. For example: expireDate: [2, 'hours'] restore state from storage only when it is not older than 2 hours.
      • serialize: function (default: JSON.stringify) a function which takes object with redux state and returns string which can be stored into storage.
      • deserialize: function (default: JSON.parse) a function which takes string from storage and returns object with redux state.
      • map: object (default: {}) a mapping transformation wich will be applied to state before saving.
      • disabled: boolean (default: false) disable persisting state.
      • throttle: number (default: 0) number of milisecond to wait between persisting the state, for values greater than 0 it uses throttled version.

autoRehydrate

  • import { autoRehydrate } from 'redux-phoenix'
  • This is a store enhancer that will automatically shallow merge the persisted state for each key.

REHYDRATE

  • import { REHYDRATE } from 'redux-phoenix'
  • Action type which will be dispatched on rehydration.

Storage Engines

  • localStorage (default)
  • sessionStorage
  • localForage
  • AsyncStorage
  • custom any conforming storage api implementing the following methods: setItem, getItem which returns value or a Promise resolved to value.

Whitelist and blacklist

Whitelisted keys are overwrited by blacklisted keys so is possible to omit some specific keys to not being stored.

For example given following state and configuration:

store.getState(); // { foo: { data: 'some data', errors: null,  isLoading: false }, bar: { data: 'some other data } }

persistStore(store, {
  whitelist: ['foo'],
  blacklist: ['foo.isLoading', 'foo.errors'],
});

will persist only object { foo: { data: 'some data' } } in storage.

Transformation

There is also a possibility to transform state before saving it into storage.

Example with transformation with strings

store.getState(); // { foo: { lastValidData: 'some data', actualData: 'some data with errors' } }

persistStore(store, {
  map: { 'foo.lastValidData': 'foo.actualData' },
});

this will persist object { foo: { lastValidData: 'some data', actualData: 'some data' } } so that restored state will always have the last valid value in state.

Example with transformation with function

store.getState(); // { foo: { lastValidData: 'some data', actualData: 'some data with errors' } }

persistStore(store, {
  map: {
    'foo.actualData': {
      lastValidData: (oldKey, value, state) => ({
        targetKey: 'foo.oldData',
        targetValue: { [oldKey]: value },
        sourceValue: state.foo.lastValidData,
      }),
    },
  },
});

this will persist object:

{
  foo: {
    lastValidData: 'some data',
    actualData: 'some data',
    oldData: {
      'foo.actualData': 'some data with errors'
    }
  }
}

so that is possible to modify state to much complicated form.

Throttle

When the throttle is defined, the state will not be saved at every action dispatched in the time set. It will take the state after the last action of this period of time. This can be useful to lower the charge of an external API.


persistStore(store, {
    throttle : 1000,
  }
); // The state will be save maximum one time / 1000 ms

Migrations

You can pass migrations that will be run just before rehydrating redux store. This allows to modify the old version of state that could be persisted previously, to the new version that is used currently. Note when you want to revert the migration that might be applied previously just omit the up method in the migration object.

const migrations = [
  {
    name: '001-initial-migration',
    up: state => ({ ...state, { newField: 'newFieldValue' } }),
    down: state => state,
  },
  {
    name: '002-missing-migration',
    up: state => ({ ...state, { anotherNewField: 'newValue' } }),
    down: state => _.omit(state, 'anotherNewField'),
  },
];

persistStore(store, { migrations }); // There will be applied missing migrations from 2 passed
const migrations = [
  {
    name: '001-initial-migration',
    up: state => ({ ...state, { newField: 'newFieldValue' } }),
    down: state => state,
  },
  {
    name: '002-reverted',
    down: state => state,
  },
];

persistStore(store, { migrations }); // There will be applied migration 001 (if not present) and reverted 002 (if present)