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

@goco/redux-undo

v0.9.99

Published

simple undo/redo functionality for redux state containers

Downloads

4

Readme

redux undo/redo

NPM version (>=0.4) Build Status Dependencies js-standard-style https://gratipay.com/omnidan/

simple undo/redo functionality for redux state containers

https://i.imgur.com/M2KR4uo.gif

Protip: You can use the redux-undo-boilerplate to quickly get started with redux-undo.

Note: Make sure to update your programs to the latest History API.

Installation

npm install --save redux-undo

API

import undoable from 'redux-undo';
undoable(reducer)
undoable(reducer, config)

Making your reducers undoable

redux-undo is a reducer enhancer, it provides the undoable function, which takes an existing reducer and a configuration object and enhances your existing reducer with undo functionality.

Note: If you were accessing state.counter before, you have to access state.counter.present after wrapping your reducer with undoable.

To install, firstly import redux-undo:

// Redux utility functions
import { combineReducers } from 'redux';
// redux-undo higher-order reducer
import undoable from 'redux-undo';

Then, add undoable to your reducer(s) like this:

combineReducers({
  counter: undoable(counter)
})

A configuration can be passed like this:

combineReducers({
  counter: undoable(counter, {
    limit: 10 // set a limit for the history
  })
})

History API

Wrapping your reducer with undoable makes the state look like this:

{
  past: [...pastStatesHere...],
  present: {...currentStateHere...},
  future: [...futureStatesHere...]
}

Now you can get your current state like this: state.present

And you can access all past states (e.g. to show a history) like this: state.past

Undo/Redo Actions

Firstly, import the undo/redo action creators:

import { ActionCreators } from 'redux-undo';

Then, you can use store.dispatch() and the undo/redo action creators to perform undo/redo operations on your state:

store.dispatch(ActionCreators.undo()) // undo the last action
store.dispatch(ActionCreators.redo()) // redo the last action

store.dispatch(ActionCreators.jumpToPast(index)) // jump to requested index in the past[] array
store.dispatch(ActionCreators.jumpToFuture(index)) // jump to requested index in the future[] array

Configuration

A configuration object can be passed to undoable() like this (values shown are default values):

undoable(reducer, {
  limit: false, // set to a number to turn on a limit for the history

  filter: () => true, // see `Filtering Actions` section

  undoType: ActionTypes.UNDO, // define a custom action type for this undo action
  redoType: ActionTypes.REDO, // define a custom action type for this redo action

  jumpToPastType: ActionTypes.JUMP_TO_PAST, // define custom action type for this jumpToPast action
  jumpToFutureType: ActionTypes.JUMP_TO_FUTURE, // define custom action type for this jumpToFuture action

  initialState: undefined, // initial state (e.g. for loading)
  initTypes: ['@@redux/INIT', '@@INIT'] // history will be (re)set upon init action type
  initialHistory: { // initial history (e.g. for loading)
    past: [],
    present: config.initialState,
    future: []
  },

  debug: false, // set to `true` to turn on debugging
})

Filtering Actions

If you don't want to include every action in the undo/redo history, you can pass a function to undoable like this:

undoable(reducer, function filterActions(action, currentState, previousState) {
  return action.type === SOME_ACTION; // only add to history if action is SOME_ACTION
})

// or you could do...

undoable(reducer, function filterState(action, currentState, previousState) {
  return currentState !== previousState; // only add to history if state changed
})

Or you can use the distinctState, includeAction and excludeAction helpers, which should be imported like this:

import undoable, { distinctState, includeAction, excludeAction } from 'redux-undo';

Now you can use the helper, which is pretty simple:

undoable(reducer, { filter: includeAction(SOME_ACTION) })
undoable(reducer, { filter: excludeAction(SOME_ACTION) })

// or you could do...

undoable(reducer, { filter: distinctState() })

... they even support Arrays:

undoable(reducer, { filter: includeAction([SOME_ACTION, SOME_OTHER_ACTION]) })
undoable(reducer, { filter: excludeAction([SOME_ACTION, SOME_OTHER_ACTION]) })

What is this magic? How does it work?

Have a read of the Implementing Undo History recipe in the Redux documents, which explains in detail how redux-undo works.

License

MIT, see LICENSE.md for more information.