redux-undoable
Version:
A reducer enhancer (or higher order reducer) that provides undo/redo functionality for Redux by replaying actions (rather than storing previous state)
126 lines (107 loc) • 10.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.default = function (reducer, config) {
var initialState = {
initial: null,
past: [],
present: reducer(undefined, {}),
future: []
};
var mergedConfig = _extends({}, defaultConfig, config);
return function () {
var state = arguments.length <= 0 || arguments[0] === undefined ? initialState : arguments[0];
var action = arguments[1];
var initial = state.initial;
var past = state.past;
var present = state.present;
var future = state.future;
if (mergedConfig.init.includes(action.type) && !state.present) {
return {
initial: initial,
past: past,
present: replay(initial, past, reducer),
future: future
};
}
switch (action.type) {
case UNDO:
{
return undo(initial, past, present, future, reducer);
}
case REDO:
{
return redo(initial, past, present, future, reducer);
}
default:
{
var newPresent = reducer(present, action);
if (present === newPresent) {
return state;
}
if (!mergedConfig.include.includes(action.type)) {
return {
initial: initial,
past: past,
present: newPresent,
future: future
};
}
return {
initial: initial,
past: [].concat(_toConsumableArray(past), [action]),
present: newPresent,
future: []
};
}
}
};
};
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var REDUX_INIT = '@@redux/INIT';
var UNDO = exports.UNDO = '@@redux-undoable/UNDO';
var REDO = exports.REDO = '@@redux-undoable/REDO';
var REPLAY_FINISHED = exports.REPLAY_FINISHED = '@@redux-undoable/REPLAY_FINISHED';
var replayFinished = function replayFinished() {
return {
type: REPLAY_FINISHED
};
};
var replay = function replay(initial, actions, reducer) {
return actions.map(function (action) {
// create a copy of the action with metadata to indicate that a replay is in progress
return _extends({}, action, { meta: { replay: true } });
}).concat(replayFinished()).reduce(function (state, action) {
return reducer(state, action);
}, initial);
};
var undo = function undo(initial, past, present, future, reducer) {
var action = past[past.length - 1];
var newPast = past.slice(0, past.length - 1);
var previous = replay(initial, newPast, reducer);
return {
initial: initial,
past: newPast,
present: previous,
future: [action].concat(_toConsumableArray(future))
};
};
var redo = function redo(initial, past, present, future, reducer) {
var action = future[0];
var newFuture = future.slice(1);
var newPresent = reducer(present, action);
return {
initial: initial,
past: [].concat(_toConsumableArray(past), [action]),
present: newPresent,
future: newFuture
};
};
var defaultConfig = {
init: [REDUX_INIT],
include: []
};
//# sourceMappingURL=data:application/json;base64,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LEtBQUssS0FBSyxNQUFMLEdBQWMsQ0FBbkIsQ0FBZjtBQUNBLE1BQU0sVUFBVSxLQUFLLEtBQUwsQ0FBVyxDQUFYLEVBQWMsS0FBSyxNQUFMLEdBQWMsQ0FBNUIsQ0FBaEI7QUFDQSxNQUFNLFdBQVcsT0FBTyxPQUFQLEVBQWdCLE9BQWhCLEVBQXlCLE9BQXpCLENBQWpCOztBQUVBLFNBQU87QUFDTCxvQkFESztBQUVMLFVBQU0sT0FGRDtBQUdMLGFBQVMsUUFISjtBQUlMLGFBQVUsTUFBViw0QkFBcUIsTUFBckI7QUFKSyxHQUFQO0FBTUQsQ0FYRDs7QUFhQSxJQUFNLE9BQU8sU0FBUCxJQUFPLENBQVMsT0FBVCxFQUFrQixJQUFsQixFQUF3QixPQUF4QixFQUFpQyxNQUFqQyxFQUF5QyxPQUF6QyxFQUFpRDtBQUM1RCxNQUFNLFNBQVMsT0FBTyxDQUFQLENBQWY7QUFDQSxNQUFNLFlBQVksT0FBTyxLQUFQLENBQWEsQ0FBYixDQUFsQjtBQUNBLE1BQU0sYUFBYSxRQUFRLE9BQVIsRUFBaUIsTUFBakIsQ0FBbkI7O0FBRUEsU0FBTztBQUNMLG9CQURLO0FBRUwsdUNBQVcsSUFBWCxJQUFpQixNQUFqQixFQUZLO0FBR0wsYUFBUyxVQUhKO0FBSUwsWUFBUTtBQUpILEdBQVA7QUFNRCxDQVhEOztBQWFBLElBQU0sZ0JBQWdCO0FBQ3BCLFFBQU0sQ0FBQyxVQUFELENBRGM7QUFFcEIsV0FBUztBQUZXLENBQXRCIiwiZmlsZSI6InVuZG9hYmxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgUkVEVVhfSU5JVCA9ICdAQHJlZHV4L0lOSVQnO1xuZXhwb3J0IGNvbnN0IFVORE8gPSAnQEByZWR1eC11bmRvYWJsZS9VTkRPJztcbmV4cG9ydCBjb25zdCBSRURPID0gJ0BAcmVkdXgtdW5kb2FibGUvUkVETyc7XG5leHBvcnQgY29uc3QgUkVQTEFZX0ZJTklTSEVEID0gJ0BAcmVkdXgtdW5kb2FibGUvUkVQTEFZX0ZJTklTSEVEJztcblxuY29uc3QgcmVwbGF5RmluaXNoZWQgPSAoKSA9PiB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogUkVQTEFZX0ZJTklTSEVEXG4gIH07XG59O1xuXG5jb25zdCByZXBsYXkgPSBmdW5jdGlvbihpbml0aWFsLCBhY3Rpb25zLCByZWR1Y2VyKSB7XG4gIHJldHVybiBhY3Rpb25zXG4gICAgLm1hcChhY3Rpb24gPT4ge1xuICAgICAgLy8gY3JlYXRlIGEgY29weSBvZiB0aGUgYWN0aW9uIHdpdGggbWV0YWRhdGEgdG8gaW5kaWNhdGUgdGhhdCBhIHJlcGxheSBpcyBpbiBwcm9ncmVzc1xuICAgICAgcmV0dXJuIHsgLi4uYWN0aW9uLCBtZXRhOiB7IHJlcGxheTogdHJ1ZSB9IH07XG4gICAgfSlcbiAgICAuY29uY2F0KHJlcGxheUZpbmlzaGVkKCkpXG4gICAgLnJlZHVjZSgoc3RhdGUsIGFjdGlvbikgPT4gcmVkdWNlcihzdGF0ZSwgYWN0aW9uKSwgaW5pdGlhbCk7XG59O1xuXG5jb25zdCB1bmRvID0gZnVuY3Rpb24oaW5pdGlhbCwgcGFzdCwgcHJlc2VudCwgZnV0dXJlLCByZWR1Y2VyKSB7XG4gIGNvbnN0IGFjdGlvbiA9IHBhc3RbcGFzdC5sZW5ndGggLSAxXTtcbiAgY29uc3QgbmV3UGFzdCA9IHBhc3Quc2xpY2UoMCwgcGFzdC5sZW5ndGggLSAxKTtcbiAgY29uc3QgcHJldmlvdXMgPSByZXBsYXkoaW5pdGlhbCwgbmV3UGFzdCwgcmVkdWNlcik7XG5cbiAgcmV0dXJuIHtcbiAgICBpbml0aWFsLFxuICAgIHBhc3Q6IG5ld1Bhc3QsXG4gICAgcHJlc2VudDogcHJldmlvdXMsXG4gICAgZnV0dXJlOiBbIGFjdGlvbiwgLi4uZnV0dXJlIF1cbiAgfTtcbn07XG5cbmNvbnN0IHJlZG8gPSBmdW5jdGlvbihpbml0aWFsLCBwYXN0LCBwcmVzZW50LCBmdXR1cmUsIHJlZHVjZXIpe1xuICBjb25zdCBhY3Rpb24gPSBmdXR1cmVbMF07XG4gIGNvbnN0IG5ld0Z1dHVyZSA9IGZ1dHVyZS5zbGljZSgxKTtcbiAgY29uc3QgbmV3UHJlc2VudCA9IHJlZHVjZXIocHJlc2VudCwgYWN0aW9uKTtcblxuICByZXR1cm4ge1xuICAgIGluaXRpYWwsXG4gICAgcGFzdDogWyAuLi5wYXN0LCBhY3Rpb24gXSxcbiAgICBwcmVzZW50OiBuZXdQcmVzZW50LFxuICAgIGZ1dHVyZTogbmV3RnV0dXJlXG4gIH07XG59O1xuXG5jb25zdCBkZWZhdWx0Q29uZmlnID0ge1xuICBpbml0OiBbUkVEVVhfSU5JVF0sXG4gIGluY2x1ZGU6IFtdXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihyZWR1Y2VyLCBjb25maWcpIHtcbiAgY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICAgIGluaXRpYWw6IG51bGwsXG4gICAgcGFzdDogW10sXG4gICAgcHJlc2VudDogcmVkdWNlcih1bmRlZmluZWQsIHt9KSxcbiAgICBmdXR1cmU6IFtdXG4gIH07XG5cbiAgY29uc3QgbWVyZ2VkQ29uZmlnID0geyAuLi5kZWZhdWx0Q29uZmlnLCAuLi5jb25maWcgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlID0gaW5pdGlhbFN0YXRlLCBhY3Rpb24pIHtcbiAgICBjb25zdCB7IGluaXRpYWwsIHBhc3QsIHByZXNlbnQsIGZ1dHVyZSB9ID0gc3RhdGU7XG5cbiAgICBpZiAobWVyZ2VkQ29uZmlnLmluaXQuaW5jbHVkZXMoYWN0aW9uLnR5cGUpICYmICFzdGF0ZS5wcmVzZW50KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbml0aWFsLFxuICAgICAgICBwYXN0LFxuICAgICAgICBwcmVzZW50OiByZXBsYXkoaW5pdGlhbCwgcGFzdCwgcmVkdWNlciksXG4gICAgICAgIGZ1dHVyZVxuICAgICAgfTtcbiAgICB9XG4gXG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgY2FzZSBVTkRPOiB7XG4gICAgICAgIHJldHVybiB1bmRvKGluaXRpYWwsIHBhc3QsIHByZXNlbnQsIGZ1dHVyZSwgcmVkdWNlcik7XG4gICAgICB9XG4gICAgICBjYXNlIFJFRE86IHtcbiAgICAgICAgcmV0dXJuIHJlZG8oaW5pdGlhbCwgcGFzdCwgcHJlc2VudCwgZnV0dXJlLCByZWR1Y2VyKTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgY29uc3QgbmV3UHJlc2VudCA9IHJlZHVjZXIocHJlc2VudCwgYWN0aW9uKTtcbiAgICAgICAgaWYgKHByZXNlbnQgPT09IG5ld1ByZXNlbnQpIHtcbiAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1lcmdlZENvbmZpZy5pbmNsdWRlLmluY2x1ZGVzKGFjdGlvbi50eXBlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbml0aWFsLFxuICAgICAgICAgICAgcGFzdCxcbiAgICAgICAgICAgIHByZXNlbnQ6IG5ld1ByZXNlbnQsXG4gICAgICAgICAgICBmdXR1cmVcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpbml0aWFsLFxuICAgICAgICAgIHBhc3Q6IFsgLi4ucGFzdCwgYWN0aW9uIF0sXG4gICAgICAgICAgcHJlc2VudDogbmV3UHJlc2VudCxcbiAgICAgICAgICBmdXR1cmU6IFtdXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuIl19
//# sourceMappingURL=undoable.js.map