diff --git a/src/instrument.js b/src/instrument.js index 3c292395..f488b126 100644 --- a/src/instrument.js +++ b/src/instrument.js @@ -5,7 +5,8 @@ export const ActionTypes = { COMMIT: 'COMMIT', SWEEP: 'SWEEP', TOGGLE_ACTION: 'TOGGLE_ACTION', - JUMP_TO_STATE: 'JUMP_TO_STATE' + JUMP_TO_STATE: 'JUMP_TO_STATE', + IMPORT_STATE: 'IMPORT_STATE' }; /** @@ -38,6 +39,10 @@ export const ActionCreators = { jumpToState(index) { return { type: ActionTypes.JUMP_TO_STATE, index }; + }, + + importState(nextLiftedState) { + return { type: ActionTypes.IMPORT_STATE, nextLiftedState }; } }; @@ -186,6 +191,16 @@ function liftReducerWith(reducer, initialCommittedState, monitorReducer) { ); computedStates = [...computedStates, nextEntry]; break; + case ActionTypes.IMPORT_STATE: + ({ + stagedActions, + skippedActions, + computedStates, + currentStateIndex, + timestamps, + monitorState + } = liftedAction.nextLiftedState); + break; case '@@redux/INIT': // Always recompute states on hot reload and init. shouldRecomputeStates = true; @@ -266,7 +281,7 @@ function unliftStore(liftedStore, liftReducer) { } /** - * Redux History store enhancer. + * Redux instrumentation store enhancer. */ export default function instrument(monitorReducer = () => null) { return createStore => (reducer, initialState) => { diff --git a/test/instrument.spec.js b/test/instrument.spec.js index 34577b04..e5e61a72 100644 --- a/test/instrument.spec.js +++ b/test/instrument.spec.js @@ -215,4 +215,40 @@ describe('instrument', () => { monitoredInstrumentedStore.dispatch(ActionCreators.jumpToState(3)); expect(reducerCalls).toBe(4); }); + + describe('Import State', () => { + let monitoredStore; + let monitoredLiftedStore; + let exportedState; + + beforeEach(() => { + monitoredStore = instrument()(createStore)(counter); + monitoredLiftedStore = monitoredStore.liftedStore; + // Set up state to export + monitoredStore.dispatch({ type: 'INCREMENT' }); + monitoredStore.dispatch({ type: 'INCREMENT' }); + monitoredStore.dispatch({ type: 'INCREMENT' }); + + exportedState = monitoredLiftedStore.getState(); + }); + + it('should replay all the steps when a state is imported', () => { + let importMonitoredStore = instrument()(createStore)(counter); + let importMonitoredLiftedStore = importMonitoredStore.liftedStore; + // Import exported state + importMonitoredLiftedStore.dispatch(ActionCreators.importState(exportedState)); + expect(importMonitoredLiftedStore.getState()).toEqual(exportedState); + }); + + it('should replace the existing action log with the one imported', () => { + let importMonitoredStore = instrument()(createStore)(counter); + let importMonitoredLiftedStore = importMonitoredStore.liftedStore; + + importMonitoredStore.dispatch({ type: 'DECREMENT' }); + importMonitoredStore.dispatch({ type: 'DECREMENT' }); + + importMonitoredLiftedStore.dispatch(ActionCreators.importState(exportedState)); + expect(importMonitoredLiftedStore.getState()).toEqual(exportedState); + }); + }); });