Skip to content

Instantly share code, notes, and snippets.

@morten-olsen
Created September 12, 2019 10:54
Show Gist options
  • Save morten-olsen/931be2b5d9008b0d52a88975768c94f3 to your computer and use it in GitHub Desktop.
Save morten-olsen/931be2b5d9008b0d52a88975768c94f3 to your computer and use it in GitHub Desktop.
let steps = [];
let index = 0;
const middleware = () => (next) => (action) => {
const result = next(action);
const stepIndex = index++;
Promise.resolve(action).then((resolvedAction) => {
steps[stepIndex] = resolvedAction;
});
return result;
}
const higherOrderReducer = (reducer) => {
let playbackStep = 0;
let playback = false;
let returnState = undefined;
(state, action) => {
switch (action.type) {
case '@@FOO/START_PLAYBACK':
// REWIND TO INITIAL STEP
playback = true;
playbackStep = 0;
returnState = state;
return reducer(undefined, { type: '@@FOO/INIT'});
case '@@FOO/NEXT_STEP':
// STEPS ONE STEP FORWARD
return reducer(state, steps[playbackStep++]);
case '@@FOO/GO_TO_STATE':
playback = false;
return reducer(returnState, { type: '@@FOO/INIT'});
case '@@FOO/END_PLAYBACK':
playback = false;
steps = steps.slice(0, playbackStep);
return reducer(state);
default:
if (!playback) { // If playback we don't allow state changes
return reducer(state, action);
}
return state;
}
}
};
const store = createStore(
higherOrderReducer(/* yourReducer */),
applyMiddleware(
/* Other middlewares */
middleware,
)
);
// Start playback from the beginning
store.dispaptch({ type: '@@FOO/START_PLAYBACK' });
// Move forward in the playback
store.dispaptch({ type: '@@FOO/NEXT_STEP' });
// Go back to the state before starting playback
store.dispaptch({ type: '@@FOO/GO_TO_STATE' });
// Makes current state the new working state
store.dispaptch({ type: '@@FOO/END_PLAYBACK ' });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment