Skip to content

Instantly share code, notes, and snippets.

@markerikson
Created January 23, 2018 02:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save markerikson/9951faf2fa8f04f9a197784d47ee9ad3 to your computer and use it in GitHub Desktop.
Save markerikson/9951faf2fa8f04f9a197784d47ee9ad3 to your computer and use it in GitHub Desktop.
Redux random number middleware with resumable state
import {createStore, applyMiddleware} from"redux";
import {randomMiddleware, higherOrderRandomReducer} from "./reduxRandomMiddleware";
function randomInt(prng, lowest, highest) {
return lowest + Math.floor(prng() * (highest - lowest + 1));
}
function counterReducer(state = 0, action) {
switch(action.type) {
case "INCREMENT" : {
const amount = randomInt(action.meta.prng, 1, 20);
console.log("Incrementing by: " + amount);
return state + amount;
}
default : return state;
}
}
const middlewareEnhancer = applyMiddleware(randomMiddleware);
const wrappedReducer = higherOrderRandomReducer(counterReducer);
const store = createStore(wrappedReducer, middlewareEnhancer);
const originalState = store.dispatch({type : "GET_PRNG_STATE"});
for(let i = 0; i < 5; i++) {
store.dispatch({type : "INCREMENT"});
}
store.dispatch({type : "SET_PRNG_STATE", meta : {rngState : originalState}});
for(let i = 0; i < 5; i++) {
store.dispatch({type : "INCREMENT"});
}
import seedrandom from "seedrandom";
export const randomMiddleware = store => {
let prng = seedrandom(null, {state : true});
return next => action => {
switch(action.type) {
case "SET_PRNG_SEED" : {
const {seed = null} = action.payload;
prng = seedrandom(seed, {state : true});
return;
}
case "SET_PRNG_STATE" : {
const {rngState} = action.meta;
prng = seedrandom(null, {state : rngState});
return;
}
case "GET_PRNG_STATE" : {
return prng.state();
}
case "GET_RANDOM_NUMBER" : {
return prng();
}
case "RESET_PRNG" : {
prng = seedrandom(null, {state : true});
return;
}
}
const {meta = {}} = action;
const rngState = prng.state();
const newMeta = {...meta, rngState};
const newAction = {...action, meta : newMeta};
const result = next(newAction);
const newRngState = newAction.meta.rngState || rngState;
prng = seedrandom(null, {state : newRngState});
return action;
}
}
function higherOrderRandomReducer(reducer) {
return function (state, action) {
if(action.meta && action.meta.rngState) {
action.meta.prng = seedrandom(null, {state : action.meta.rngState});
}
const actualResult = reducer(state, action);
if(action.meta && action.meta.prng) {
const rngState = action.meta.prng.state();
action.meta.rngState = rngState;
}
return actualResult;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment