:recycle: higher order reducer to add undo/redo functionality to redux state containers

Overview

redux undo/redo

NPM version (>=1.0) NPM Downloads Coverage Status Dependencies js-standard-style GitHub license

simple undo/redo functionality for redux state containers

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

Protip: Check out the todos-with-undo example or the redux-undo-boilerplate to quickly get started with redux-undo.

Switching from 0.x to 1.0: Make sure to update your programs to the latest History API.

Help wanted: We are looking for volunteers to maintain this project, if you are interested, feel free to contact me at [email protected]


This README is about the new 1.0 branch of redux-undo, if you are using or plan on using 0.6, check out the 0.6 branch


Note on Imports

If you use Redux Undo in CommonJS environment, don’t forget to add .default to your import.

- var ReduxUndo = require('redux-undo')
+ var ReduxUndo = require('redux-undo').default

If your environment support es modules just go by:

import ReduxUndo from 'redux-undo';

We are also supporting UMD build:

var ReduxUndo = window.ReduxUndo.default;

once again .default is required.

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 (higher-order reducer). 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.present.counter 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 size of the history
  })
})

Apply redux-undo magic to specific slice of your state.

When you expose an undo redo history action to your app users, you will not want those action to apply on your whole redux state. Lets see this with naive document editor state.

const rootReducer = combineReducers({
  ui: uiReducer,
  document: documentReducer,
})

wrapping the documentReducer with undoable higher order reducer

const rootReducer = combineReducers({
  ui: uiReducer,
  document: undoable(documentReducer),
})

will provide only the document mountpoint of your state with an history.

an even more advanced usage would be to have many different mountpoint of your redux state, managed under redux-undo.

const rootReducer = combineReducers({
  ui: uiReducer,
  document: undoable(documentReducer, {
    undoType: 'DOCUMENT_UNDO',
    redoType: 'DOCUMENT_REDO',
    // here you will want to configure specific redux-undo action type  
  }),
  anotherDocument: undoable(documentReducer, {
    undoType: 'ANOTHERDOCUMENT_UNDO',
    redoType: 'ANOTHERDOCUMENT_REDO',
    // here you will want to configure specific redux-undo action type  
  }),
})

Don't forget to configure specific redux-undo action type for each of your mount point if you don't want to see your different history to undo/redo in sync.

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

Note: Your reducer still receives the current state, a.k.a. state.present. Therefore, you would not have to update an existing reducer to add undo functionality.

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.jump(-2)) // undo 2 steps
store.dispatch(ActionCreators.jump(5)) // redo 5 steps

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

store.dispatch(ActionCreators.clearHistory()) // Remove all items from past[] and future[] arrays

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`
  groupBy: () => null, // see `Grouping Actions`

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

  jumpType: ActionTypes.JUMP, // define custom action type for this jump 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

  clearHistoryType: ActionTypes.CLEAR_HISTORY, // define custom action type for this clearHistory action
  // you can also pass an array of strings to define several action types that would clear the history
  // beware: those actions will not be passed down to the wrapped reducers

  initTypes: ['@@redux-undo/INIT'], // history will be (re)set upon init action type
  // beware: those actions will not be passed down to the wrapped reducers

  debug: false, // set to `true` to turn on debugging
  ignoreInitialState: false, // prevent user from undoing to the beginning, ex: client-side hydration

  neverSkipReducer: false, // prevent undoable from skipping the reducer on undo/redo and clearHistoryType actions
  syncFilter: false // set to `true` to synchronize the `_latestUnfiltered` state with `present` when an excluded action is dispatched
})

Note: If you want to use just the initTypes functionality, but not import the whole redux-undo library, use redux-recycle!

Initial State and History

You can use your redux store to set an initial history for your undoable reducers:

import { createStore } from 'redux';

const initialHistory = {
  past: [0, 1, 2, 3],
  present: 4,
  future: [5, 6, 7]
}

// Alternatively use the helper:
// import { newHistory } from 'redux-undo';
// const initialHistory = newHistory([0, 1, 2, 3], 4, [5, 6, 7]);

const store = createStore(undoable(counter), initialHistory);

Or just set the current state like you're used to with Redux. Redux-undo will create the history for you:

import { createStore } from 'redux';

const store = createStore(undoable(counter), {foo: 'bar'});

// will make the state look like this:
{
  past: [],
  present: {foo: 'bar'},
  future: []
}

Grouping Actions

If you want to group your actions together into single undo/redo steps, you can add a groupBy function to undoable. redux-undo provides groupByActionTypes as a basic groupBy function:

import undoable, { groupByActionTypes } from 'redux-undo';

undoable(reducer, { groupBy: groupByActionTypes(SOME_ACTION) })
// or with arrays
undoable(reducer, { groupBy: groupByActionTypes([SOME_ACTION]) })

In these cases, consecutive SOME_ACTION actions will be considered a single step in the undo/redo history.

Custom groupBy Function

If you want to implement custom grouping behaviour, pass in your own function with the signature (action, currentState, previousHistory). If the return value is not null, then the new state will be grouped by that return value. If the next state is grouped into the same group as the previous state, then the two states will be grouped together in one step.

If the return value is null, then redux-undo will not group the next state with the previous state.

The groupByActionTypes function essentially returns the following:

  • If a grouped action type (SOME_ACTION), the action type of the action (SOME_ACTION).
  • If not a grouped action type (any other action type), null.

When groupBy groups a state change, the associated group will be saved alongside past, present, and future so that it may be referenced by the next state change.

After an undo/redo/jump occurs, the current group gets reset to null so that the undo/redo history is remembered.

Filtering Actions

If you don't want to include every action in the undo/redo history, you can add a filter function to undoable. This is useful for, for example, excluding actions that were not triggered by the user.

redux-undo provides you with the includeAction and excludeAction helpers for basic filtering. They should be imported like this:

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

Now you can use the helper functions:

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

// they even support Arrays:

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

Note: Since beta4, only actions resulting in a new state are recorded. This means the (now deprecated) distinctState() filter is auto-applied.

Custom Filters

If you want to create your own filter, pass in a function with the signature (action, currentState, previousHistory). For example:

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

// The entire `history` state is available to your filter, so you can make
// decisions based on past or future states:

undoable(reducer, {
  filter: function filterState(action, currentState, previousHistory) {
    let { past, present, future } = previousHistory;
    return future.length === 0; // only add to history if future is empty
  }
})

Combining Filters

You can also use our helper to combine filters.

import undoable, {combineFilters} from 'redux-undo'

function isActionSelfExcluded(action) {
  return action.wouldLikeToBeInHistory
}

function areWeRecording(action, state) {
  return state.recording
}

undoable(reducer, {
  filter: combineFilters(isActionSelfExcluded, areWeRecording)
})

Ignoring Actions

When implementing a filter function, it only prevents the old state from being stored in the history. filter does not prevent the present state from being updated.

If you want to ignore an action completely, as in, not even update the present state, you can make use of redux-ignore.

It can be used like this:

import { ignoreActions } from 'redux-ignore'

ignoreActions(
  undoable(reducer),
  [IGNORED_ACTION, ANOTHER_IGNORED_ACTION]
)

// or define your own function:

ignoreActions(
  undoable(reducer),
  (action) => action.type === SOME_ACTION // only add to history if action is SOME_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.

Gitter Chat / Support

If you have a question or just want to discuss something with other redux-undo users/maintainers, chat with the community on gitter.im/omnidan/redux-undo

Also, look at the documentation over at redux-undo.js.org.

License

MIT, see LICENSE.md for more information.

Issues
  • History updated with filtered action

    History updated with filtered action

    I found that filtered action after unfiltered one change history too. Here is debug output: action SET_FEATURES is only allowed (not filtered)

    %credux-undo font-style: italic action SET_FEATURES 
    prev history Object { past: Array[1], present: Object, future: Array[0] } 
    action Object { type: "SET_FEATURES", features: Array[2] } 
    next history Object { past: Array[2], present: Object, future: Array[0] } 
    inserting Object { list: Array[2], selected: Array[0], hovered: null } 
     new free:  8 
     inserted new state into history 
    
    %credux-undo font-style: italic action SET_HOVERED 
    prev history Object { past: Array[2], present: Object, future: Array[0] } 
    action Object { type: "SET_HOVERED", feature: Object } 
    next history Object { past: Array[3], present: Object, future: Array[0], wasFiltered: true } 
    inserting Object { list: Array[2], selected: Array[0], hovered: Object } 
     new free:  7 
     filter prevented action, not storing it 
    
    %credux-undo font-style: italic action SET_HOVERED 
    prev history Object { past: Array[3], present: Object, future: Array[0], wasFiltered: true } 
    action Object { type: "SET_HOVERED", feature: Object } 
    next history Object { past: Array[3], present: Object, future: Array[0], wasFiltered: true } 
    inserting Object { list: Array[2], selected: Array[0], hovered: Object } 
     new free:  6 
     filter prevented action, not storing it 
    
    %credux-undo font-style: italic action SET_HOVERED 
    prev history Object { past: Array[3], present: Object, future: Array[0], wasFiltered: true } 
    action Object { type: "SET_HOVERED", feature: null } 
    next history Object { past: Array[3], present: Object, future: Array[0], wasFiltered: true } 
    inserting Object { list: Array[2], selected: Array[0], hovered: Object } 
     new free:  6 
     filter prevented action, not storing it 
    

    As you can see in first SET_HOVERED action changed the history (past array increased to 3 items), however output says: filter prevented action, not storing it. Just updated to beta9, issue is still there.

    bug 
    opened by xiceph 42
  • how to implement multiple undoable states

    how to implement multiple undoable states

    I have multiple documents on one page in my redux store:

    store = {
      docs: [
        { doc1 }, { doc2 }, { docN }
      ]
    }
    

    I want to undo each document independently of one another. If user focus is on doc1 and he presses ctrl+z, only doc1 should be undone, not all changes of all docs.

    How can I achieve this with redux undo?

    opened by aeneasr 32
  • use symbols for history

    use symbols for history

    When you set something as undoable, the structure of the state changes and you need to reflect it somewhere else in the code. This should be changed with Symbols.

    enhancement 
    opened by omnidan 31
  • Build error related to babel

    Build error related to babel

    v0.6.0

    error: bundling failed: "TransformError: [app_folder]/node_modules/redux-undo/lib/index.js: [BABEL] [app_folder]/node_modules/redux-undo/lib/index.js: Using removed Babel 5 option: [app_folder]/node_modules/redux-undo/.babelrc.stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets"

    v0.6.1

    error: bundling failed: "TransformError: [app_folder]/node_modules/redux-undo/lib/index.js: Couldn't find preset \"es2015\" relative to directory \"[app_folder]/node_modules/redux-undo\""

    v1.0.0-beta9-9-6

    error: bundling failed: "TransformError: [app]/node_modules/redux-undo/lib/index.js: Unknown plugin \"add-module-exports\" specified in \"[app]/node_modules/redux-undo/.babelrc\" at 0, attempted to resolve relative to \"[app]/node_modules/redux-undo\""

    opened by beornborn 22
  • Actions that didn't change the state shouldn't be written in history

    Actions that didn't change the state shouldn't be written in history

    Or maybe this should be configurable.. I guess?

    You can reproduce the problem in https://github.com/rackt/redux/pull/777:

    1. Add a couple of todos
    2. Switch visibility filter to "Active"
    3. Press "undo"

    Expected: todo is removed. Actual: nothing happens until you press it again.

    Reason: currently even the actions that did not result in state modification are written to history. Proposed solution: don't write actions to the history if state === previousState.

    enhancement 
    opened by gaearon 22
  • more useful & cleaner debugging

    more useful & cleaner debugging

    Yeah, it was real mess with a lot of actions going around (especially when redux-devtools replays everything). So I've grouped relevant things together and got rid of the historyToString because it just generated bunch of [object Object] strings which you cannot really investigate in any way.

    I think that eventually it might be better to just use https://www.npmjs.com/package/debug which is rather wide spread and people can configure what debugging message they want to see.

    opened by FredyC 19
  • Get  Cannot read property 'length' of undefined

    Get Cannot read property 'length' of undefined

    i try to implement redux-undo to my app so my reducers is like

    const combine = combineReducers({ designer, activities:undoable(activities), activitySelectedIndex, activitySelectedId, activityTypes, componentSelectedIndex, router: routerReducer })

    and also :

    function mapDispachToProps(dispatch){ return bindActionCreators(Object.assign({},actionCreators,UndoActionCreators), dispatch); }

    but i get this error : Uncaught TypeError: Cannot read property 'length' of undefined at lengthWithoutFuture (reducer.js:25) at insert (reducer.js:33) at reducer.js:307 at combination (combineReducers.js:132) at dispatch (createStore.js:179) at createStore (createStore.js:253) at applyMiddleware.js:38 at createStore (createStore.js:65) at Object.<anonymous> (Routes.js:27) at __webpack_require__ (bootstrap df649ed…:555)

    opened by MBehtemam 18
  • Initial history does not work

    Initial history does not work

    I tried these:

      let reducerA = (state = "none", action) => {
        return state;
      };
      let reducerB = Redux.combineReducers({
        reducerA,
      }); 
      let store = Redux.createStore(undoable(reducerB, {
        initialState: {
          reducerA: "some"
        },  
        initialHistory: {
          past: [{reducerA: "past"}],
          present: {reducerA: "some (from history)"},
          future: [{reducerA: "future"}]
        }   
      }));
      debugger;
    
    
      let store2 = Redux.createStore(undoable(reducerA, {
        initialState: "some",
        initialHistory: {
          past: ["past"],
          present: "some (from history)",
          future: ["future"]
        }   
      }));
      debugger;
    

    But the current state is "none" in both cases and the history is empty. In the second case if I don't set state = "none" initially the current state becomes undefined.

    bug 
    opened by neojski 17
  • Console Group Rework

    Console Group Rework

    Address #66 by grouping arguments together and calling console.group once all the arguments are available.

    enhancement 
    opened by pl12133 16
  • treating multiple

    treating multiple "identical" actions as one undo step

    This is a follow up of #115 and #139.

    Here is the context I am working with: there are actions that happen in series, and the whole series should create one undo. Example of action series are: onChange on a text field (happens for every character typed) and changing a object position by dragging.

    I implemented a filter which remembers the last action, compares the last action and the current action, and if action type and action parameters match (only the values change), the filter returns false so that no new undo state is created. I was counting on the fact that even if an action is filtered, the current state is updated. At the end of a series, the current state would contain the last value (of the text field or of the position). The first action of the series pushes to history the state before the action series, and the first action not in the series pushes to history the state after the series, with the last value.

    #139, with the use of _latestUnfiltered, defeats my naive strategy. The _latestUnfiltered contains the state after the first action of the series, the latest action that was not filtered. Pushing _latestUnfiltered to history instead of the current state replaces the current state at the end of the series with the state after the first action of the series.

    I do not understand the need for #139, but at least in my case, it is counter-productive and maybe should be put behind a config switch ?

    Note: I have (almost?) resolved my situation with a dirty hack: in my filter, I detect the existence of a _latestUnfiltered and I set it to the current state. I tried deleting _latestUnfiltered but everything fails then.

    opened by jcdufourd 16
  • Bump path-parse from 1.0.6 to 1.0.7

    Bump path-parse from 1.0.6 to 1.0.7

    Bumps path-parse from 1.0.6 to 1.0.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump browserslist from 4.8.2 to 4.16.6

    Bump browserslist from 4.8.2 to 4.16.6

    Bumps browserslist from 4.8.2 to 4.16.6.

    Changelog

    Sourced from browserslist's changelog.

    4.16.6

    • Fixed npm-shrinkwrap.json support in --update-db (by Geoff Newman).

    4.16.5

    • Fixed unsafe RegExp (by Yeting Li).

    4.16.4

    • Fixed unsafe RegExp.
    • Added artifactory support to --update-db (by Ittai Baratz).

    4.16.3

    • Fixed --update-db.

    4.16.2

    4.16.1

    • Fixed Chrome 4 with mobileToDesktop (by Aron Woost).

    4.16

    • Add browserslist config query.

    4.15

    • Add TypeScript types (by Dmitry Semigradsky).

    4.14.7

    • Fixed Yarn Workspaces support to --update-db (by Fausto Núñez Alberro).
    • Added browser changes to --update-db (by @​AleksandrSl).
    • Added color output to --update-db.
    • Updated package.funding to have link to our Open Collective.

    4.14.6

    • Fixed Yarn support in --update-db (by Ivan Storck).
    • Fixed npm 7 support in --update-db.

    4.14.5

    • Fixed last 2 electron versions query (by Sergey Melyukov).

    4.14.4

    • Fixed Unknown version 59 of op_mob error.

    4.14.3

    • Update Firefox ESR.

    4.14.2

    • Fixed --update-db on Windows (by James Ross).
    • Improved --update-db output.

    4.14.1

    • Added --update-db explanation (by Justin Zelinsky).

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump hosted-git-info from 2.7.1 to 2.8.9

    Bump hosted-git-info from 2.7.1 to 2.8.9

    Bumps hosted-git-info from 2.7.1 to 2.8.9.

    Changelog

    Sourced from hosted-git-info's changelog.

    2.8.9 (2021-04-07)

    Bug Fixes

    2.8.8 (2020-02-29)

    Bug Fixes

    • #61 & #65 addressing issues w/ url.URL implmentation which regressed node 6 support (5038b18), closes #66

    2.8.7 (2020-02-26)

    Bug Fixes

    • Do not attempt to use url.URL when unavailable (2d0bb66), closes #61 #62
    • Do not pass scp-style URLs to the WhatWG url.URL (f2cdfcf), closes #60

    2.8.6 (2020-02-25)

    2.8.5 (2019-10-07)

    Bug Fixes

    • updated pathmatch for gitlab (e8325b5), closes #51
    • updated pathmatch for gitlab (ffe056f)

    2.8.4 (2019-08-12)

    ... (truncated)

    Commits
    • 8d4b369 chore(release): 2.8.9
    • 29adfe5 fix: backport regex fix from #76
    • afeaefd chore(release): 2.8.8
    • 5038b18 fix: #61 & #65 addressing issues w/ url.URL implmentation which regressed nod...
    • 7440afa chore(release): 2.8.7
    • 2d0bb66 fix: Do not attempt to use url.URL when unavailable
    • f2cdfcf fix: Do not pass scp-style URLs to the WhatWG url.URL
    • e1b83df chore(release): 2.8.6
    • ff259a6 Ensure passwords in hosted Git URLs are correctly escaped
    • 624fd6f chore(release): 2.8.5
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by nlf, a new releaser for hosted-git-info since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump lodash from 4.17.15 to 4.17.21

    Bump lodash from 4.17.15 to 4.17.21

    Bumps lodash from 4.17.15 to 4.17.21.

    Commits
    • f299b52 Bump to v4.17.21
    • c4847eb Improve performance of toNumber, trim and trimEnd on large input strings
    • 3469357 Prevent command injection through _.template's variable option
    • ded9bc6 Bump to v4.17.20.
    • 63150ef Documentation fixes.
    • 00f0f62 test.js: Remove trailing comma.
    • 846e434 Temporarily use a custom fork of lodash-cli.
    • 5d046f3 Re-enable Travis tests on 4.17 branch.
    • aa816b3 Remove /npm-package.
    • d7fbc52 Bump to v4.17.19
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by bnjmnt4n, a new releaser for lodash since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump ssri from 6.0.1 to 6.0.2

    Bump ssri from 6.0.1 to 6.0.2

    Bumps ssri from 6.0.1 to 6.0.2.

    Changelog

    Sourced from ssri's changelog.

    6.0.2 (2021-04-07)

    Bug Fixes

    • backport regex change from 8.0.1 (b30dfdb), closes #19

    Commits
    Maintainer changes

    This version was pushed to npm by nlf, a new releaser for ssri since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump y18n from 4.0.0 to 4.0.1

    Bump y18n from 4.0.0 to 4.0.1

    Bumps y18n from 4.0.0 to 4.0.1.

    Changelog

    Sourced from y18n's changelog.

    Change Log

    All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

    5.0.5 (2020-10-25)

    Bug Fixes

    5.0.4 (2020-10-16)

    Bug Fixes

    • exports: node 13.0 and 13.1 require the dotted object form with a string fallback (#105) (4f85d80)

    5.0.3 (2020-10-16)

    Bug Fixes

    • exports: node 13.0-13.6 require a string fallback (#103) (e39921e)

    5.0.2 (2020-10-01)

    Bug Fixes

    5.0.1 (2020-09-05)

    Bug Fixes

    5.0.0 (2020-09-05)

    ⚠ BREAKING CHANGES

    • exports maps are now used, which modifies import behavior.
    • drops Node 6 and 4. begin following Node.js LTS schedule (#89)

    Features

    ... (truncated)

    Commits
    Maintainer changes

    This version was pushed to npm by oss-bot, a new releaser for y18n since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump elliptic from 6.5.2 to 6.5.4

    Bump elliptic from 6.5.2 to 6.5.4

    Bumps elliptic from 6.5.2 to 6.5.4.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Is it possible to have an async function as a filter?

    Is it possible to have an async function as a filter?

    I tried to use an async function with setTimeout in order to add to history only after the state stops changing. Instead of saving every single change of state I wanted to save only when half a second has passed after the user's last action without a new action being executed. Is that possible?

    opened by romarybi 0
  • Support ESM

    Support ESM

    I'm submitting a ...

    • [ ] Bug report
    • [x] Feature request
    • [ ] Docs update
    • [ ] Support request => Please do not submit support requests here, see note at the top of this template.

    What is the current behavior/state of the project?

    The project does not support esm build

    What is the desired behavior?

    Support esm module export

    If this is a feature request, what is the use case for changing the behavior?

    I'm using this code in an angular 10 application which now emit a compilation warning for modules that are not exported as ESM... :-(

    Please tell us about your environment:

    • Library version: 1.0.1
    • Redux version: 4.0.5
    • Browser: all
    • Language: Angular 11 with typescript 4.0.5

    Other information

    See here: https://angular.io/guide/build#configuring-commonjs-dependencies

    opened by HarelM 0
  • Bump ini from 1.3.5 to 1.3.7

    Bump ini from 1.3.5 to 1.3.7

    Bumps ini from 1.3.5 to 1.3.7.

    Commits
    • c74c8af 1.3.7
    • 024b8b5 update deps, add linting
    • 032fbaf Use Object.create(null) to avoid default object property hazards
    • 2da9039 1.3.6
    • cfea636 better git push script, before publish instead of after
    • 56d2805 do not allow invalid hazardous string as section name
    • See full diff in compare view
    Maintainer changes

    This version was pushed to npm by isaacs, a new releaser for ini since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
Releases(beta9)
  • beta9(Jul 28, 2016)

  • beta8(May 3, 2016)

    • improved insertion behaviour: now the state is stored to past on the next action that happens (except if the previous action was filtered) - this fixes #86
    • jspm support :metal: - just run:
    jspm install redux-undo=github:omnidan/[email protected]
    

    to install redux-undo from latest master

    Source code(tar.gz)
    Source code(zip)
  • beta7(Apr 15, 2016)

    • Improved debug logs - #68 by @pl12133
    • Added basic example for throttling - #78 by @peteruithoven
    • Added combineFilters() helper - #80 by @Bear-Foot
    • Support UMD builds - #82 by @weslleyaraujo

    Thanks a lot to all contributors - you are awesome! :grin:

    Source code(tar.gz)
    Source code(zip)
  • beta6(Mar 31, 2016)

  • beta5(Mar 31, 2016)

  • beta4(Mar 24, 2016)

    Welcome to the redux-undo team, @pl12133 and @tiemevanveen - and thanks for all contributions!

    • remove redundant dependencies
    • implement CLEAR_HISTORY action (thanks @pl12133)
    • add gitter link to README.md
    • more tests and some fixes (thanks to @pl12133 and @tiemevanveen)
    • allow initialization of state from redux createStore (thanks to @tiemevanveen)
    • clarify debug messages (thanks to @pl12133)
    • make beta default (in README.md), add link to 0.6 README

    Full list of changes/commits

    Source code(tar.gz)
    Source code(zip)
  • beta3(Feb 24, 2016)

    • Upgraded dependencies
     babel-eslint             ^4.1.8  →  ^5.0.0
     eslint                    ^1.10  →    ^2.2
     eslint-config-standard   ^4.4.0  →  ^5.1.0
     eslint-plugin-react     ^3.16.1  →  ^4.1.0
    
    • New build chain (global installation of build tools not needed anymore :metal:)
    Source code(tar.gz)
    Source code(zip)
  • v0.6.1(Feb 22, 2016)

  • beta2(Jan 31, 2016)

  • beta1(Jan 31, 2016)

    • Fixed custom filter syntax in README.md (closes #26)
    • Removed deprecated history property (closes #29)
    • Upgraded dependencies (1.0-beta1 comes with babel 6!)
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Dec 15, 2015)

    • small refinements in README.md
    • added unit tests, closed #5 (thank you, @pl12133 :smile:)
    • implemented jump to future/past with index, closed #13 (thank you too, @leomelin :smiley:)
    • all issues closed now :metal:
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Dec 15, 2015)

  • v0.4.2(Sep 26, 2015)

  • v0.4.1(Sep 25, 2015)

  • v0.4.0(Sep 25, 2015)

    • new filter function: filter(action, currentState, previousState)
    • distinctState() helper
    • this release fixes #10

    BREAKING CHANGE: .currentState is now .present

    Source code(tar.gz)
    Source code(zip)
  • v0.2.5(Sep 21, 2015)

    • introduce undoType and redoType in config
    • if specified, use that as the action type for undo/redo instead of the default action types: @@redux-undo/UNDO and @@redux-undo/REDO
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Sep 21, 2015)

    • redux-undo is an enhanced reducer / higher order reducer (undoable) instead of a store enhancer now
    • this makes so many things so much cleaner, have a read of #1 and #2
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Sep 21, 2015)

    • structured history like an UndoList in elm (this fixes issue #6 and makes undo/redo cleaner in general)
    • improved debugging of history changes: https://i.imgur.com/UZySpDY.png
    • removed index and initialIndex as it's not needed anymore
    • introduced initialState and new initialHistory
    Source code(tar.gz)
    Source code(zip)
Owner
Daniel Bugl
Co-Founder @TouchLay — @reactjs member — redux, redux-undo, node-emoji maintainer — /r/npm moderator — Developer, Web Enthusiast
Daniel Bugl
React with Redux, action, dispatch, reducer, store setup and guide

This Project has Snippets for react with redux steup, process and how to implemenntation details src->components->HomeButtons has old approach src->co

Mohib Khan 1 Nov 22, 2021
redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.

redux-immutable redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state. When Redux creat

Gajus Kuizinas 1.9k Nov 18, 2021
Skeleton React App configured with Redux store along with redux-thunk, redux persist and form validation using formik and yup

Getting Started with React-Redux App Some Configrations Needed You guys need to modify the baseUrl (path to your server) in the server.js file that is

Usama Sarfraz 10 Aug 23, 2021
A chart monitor for Redux DevTools https://www.npmjs.com/package/redux-devtools-chart-monitor

Redux DevTools Chart Monitor This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and

Redux 298 Nov 13, 2021
Official React bindings for Redux

React Redux Official React bindings for Redux. Performant and flexible. Installation Using Create React App The recommended way to start new apps with

Redux 21.6k Dec 2, 2021
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

Redux 12.2k Nov 23, 2021
Ruthlessly simple bindings to keep react-router and redux in sync

Project Deprecated This project is no longer maintained. For your Redux <-> Router syncing needs with React Router 4+, please see one of these librari

React Community 7.9k Nov 25, 2021
The official, opinionated, batteries-included toolset for efficient Redux development

Redux Toolkit The official, opinionated, batteries-included toolset for efficient Redux development (Formerly known as "Redux Starter Kit") Installati

Redux 6.8k Dec 2, 2021
Thunk middleware for Redux

Redux Thunk Thunk middleware for Redux. npm install redux-thunk yarn add redux-thunk Note on 2.x Update Most tutorials today assume that you're using

Redux 16.8k Nov 24, 2021
Logger for Redux

Logger for Redux Now maintained by LogRocket! LogRocket is a production Redux logging tool that lets you replay problems as if they happened in your o

null 5.6k Nov 21, 2021
Selector library for Redux

Reselect Simple “selector” library for Redux (and others) inspired by getters in NuclearJS, subscriptions in re-frame and this proposal from speedskat

Redux 18.4k Nov 26, 2021
An alternative side effect model for Redux apps

redux-saga redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like acce

Redux-Saga 21.9k Nov 24, 2021
Declarative Side Effects for Redux

Redux Data FX Declarative Side Effects for Redux. It helps you keep your business logic and effectful code separate. The idea is simple: in addition o

Matthieu Béteille 53 Jun 30, 2021
RxJS middleware for action side effects in Redux using "Epics"

RxJS-based middleware for Redux. Compose and cancel async actions to create side effects and more. https://redux-observable.js.org Install This has pe

redux-observable 7.8k Nov 29, 2021
Analytics middleware for Redux

redux-analytics Analytics middleware for Redux. $ npm install --save redux-analytics Want to customise your metadata further? Check out redux-tap. Usa

Mark Dalgleish 491 Nov 12, 2021
Redux bindings for client-side search

redux-search Higher-order Redux library for searching collections of objects. Search algorithms powered by js-worker-search. Check out the live demo a

Brian Vaughn 1.4k Nov 17, 2021
A mock store for testing Redux async action creators and middleware.

redux-mock-store A mock store for testing Redux async action creators and middleware. The mock store will create an array of dispatched actions which

Redux 2.4k Nov 28, 2021
An i18n solution for React/Redux and React Native projects

redux-react-i18n An i18n solution with plural forms support for Redux/React Workers of all countries, unite! Supported languages list with expected co

Dmitry Erzunov 63 Sep 30, 2021
Helper to create less verbose action types for Redux

Action Typer Helper to create slightly less verbose redux action types. Uses ES6 Proxies! Highly Performant: Proxy is only run once at startup. Includ

Alister Norris 57 Nov 21, 2021