Skip to content

Instantly share code, notes, and snippets.

@wolverineks
Last active November 12, 2017 23:38
Show Gist options
  • Save wolverineks/cfaa356c8dcb82c34584c0623bfdbaf7 to your computer and use it in GitHub Desktop.
Save wolverineks/cfaa356c8dcb82c34584c0623bfdbaf7 to your computer and use it in GitHub Desktop.
redux-keto example
const keto = require('redux-keto')
const buildReducer = keto.buildReducer
const maxCount = (state = 0, action) =>
action.type === 'CHANGE_MAX_COUNT'
? action.payload
: state
const counter = (state = 0, action, next) =>
Math.min(next.maxCount, action.type === 'INCREMENT' ? state + action.payload : state)
const rootReducer = buildReducer({ maxCount, counter })
state = rootReducer(undefined, {type: 'init'})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'CHANGE_MAX_COUNT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'CHANGE_MAX_COUNT', payload: 0})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"redux-keto":[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
// Special property that only our wrappers will have:
var wrapperMagic = 'redux-keto wrapper';
/**
* Makes a collection of lazy getters for a key-value state slice.
* The actual wrapper object inherits from this prototype.
*/
function makeWrapperProto (keys, makeReducer, makeNext) {
var wrapperProto = Object.create(null);
var loop = function () {
var key = list[i];
var reducer = makeReducer(key);
Object.defineProperty(wrapperProto, key, {
configurable: true,
enumerable: true,
get: function get () {
var wrapper = this;
var stash = wrapper[wrapperMagic];
// If we are already running, this is a problem!
if (stash.running[key]) {
var e = new ReferenceError(
("Reducer '" + key + "' depends on its own result")
);
e.name = 'ReduxKetoCircularReferenceError';
throw e
}
stash.running[key] = true;
// Evaluate the reducer:
try {
var out = reducer(
stash.state[key],
stash.action,
makeNext(stash.next, wrapper, key),
makeNext(stash.prev, stash.state, key)
);
if (out === undefined) {
throw new TypeError(("Reducer '" + key + "' returned undefined"))
}
Object.defineProperty(wrapper, key, {
configurable: true,
enumerable: true,
writable: false,
value: out
});
return out
} finally {
stash.running[key] = false;
}
}
});
};
for (var i = 0, list = keys; i < list.length; i += 1) loop();
return wrapperProto
}
/**
* Makes a lazy wrapper object for a key-value state slice.
*/
function makeWrapper (wrapperProto, state, action, next, prev) {
var wrapper = Object.create(wrapperProto);
Object.defineProperty(wrapper, wrapperMagic, {
configurable: true,
enumerable: false,
writable: false,
value: { state: state, action: action, next: next, prev: prev, running: {} }
});
return wrapper
}
/**
* Flattens a lazy key-value wrapper into a plain-old object
* with the current state as its properties.
*/
function flattenWrapper (state, wrapper) {
if ( state === void 0 ) state = {};
// If it's not a wrapper, we are done:
if (wrapper === null || wrapper[wrapperMagic] == null) { return wrapper }
// Diff the old and new states:
var keys = Object.keys(Object.getPrototypeOf(wrapper));
var unchanged = Object.keys(state).length === keys.length;
for (var i = 0, list = keys; i < list.length; i += 1) {
var key = list[i];
Object.defineProperty(wrapper, key, {
configurable: false,
enumerable: true,
writable: false,
value: flattenWrapper(state[key], wrapper[key])
});
if (wrapper[key] !== state[key]) {
unchanged = false;
}
}
// If nothing changed, just return the previous state:
if (unchanged) { return state }
delete wrapper[wrapperMagic];
return wrapper
}
function makeNextDefault (next, children, id) {
return next !== void 0 ? next : children
}
/**
* Combines several reducers into one.
*/
function buildReducer (reducerMap, makeNext) {
if ( makeNext === void 0 ) makeNext = makeNextDefault;
// Validate argument types:
if (typeof reducerMap !== 'object' || reducerMap === null) {
throw new TypeError('The reducer map must be an object.')
}
var keys = Object.keys(reducerMap);
for (var i = 0, list = keys; i < list.length; i += 1) {
var key = list[i];
if (typeof reducerMap[key] !== 'function') {
throw new TypeError('Reducers must be functions.')
}
}
// Build the wrapper:
var wrapperProto = makeWrapperProto(keys, function (key) { return reducerMap[key]; }, makeNext);
// Build the default state:
var defaultState = {};
for (var i$1 = 0, list$1 = keys; i$1 < list$1.length; i$1 += 1) {
var key$1 = list$1[i$1];
defaultState[key$1] = reducerMap[key$1].defaultState;
}
function builtReducer (state, action, next, prev) {
if ( state === void 0 ) state = defaultState;
var wrapper = makeWrapper(wrapperProto, state, action, next, prev);
// If we are the topmost fat reducer, flatten the wrappers:
return next === void 0 ? flattenWrapper(state, wrapper) : wrapper
}
builtReducer.defaultState = defaultState;
return builtReducer
}
function filterActionsDefault (action, next) {
return action
}
function filterNextDefault (next) {
return next
}
/**
* Filters the next and actions going into a fat reducer.
*/
function filterReducer (
reducer,
filterAction,
filterNext
) {
if ( filterAction === void 0 ) filterAction = filterActionsDefault;
if ( filterNext === void 0 ) filterNext = filterNextDefault;
var defaultState = reducer.defaultState;
function filteredReducer (state, action, next, prev) {
if ( state === void 0 ) state = defaultState;
var innerAction = filterAction(action, next);
var innerNext = filterNext(next);
var innerPrev = filterNext(prev);
if (!innerAction) { return state }
var wrapper = reducer(state, innerAction, innerNext, innerPrev);
// If we are the topmost fat reducer, flatten the wrappers:
return next === void 0 ? flattenWrapper(state, wrapper) : wrapper
}
filteredReducer.defaultState = defaultState;
return filteredReducer
}
function makeNextDefault$1 (next, children, id) {
return {
id: id,
root: next !== void 0 ? next : children,
get self () {
return children[id]
}
}
}
var defaultState = {};
/**
* Applies a reducer to each item of a list.
* Each reducer manages its own state slice on behalf of the list item.
*/
function mapReducer (reducer, listIds, makeNext) {
if ( makeNext === void 0 ) makeNext = makeNextDefault$1;
function mapReducer (state, action, next, prev) {
if ( state === void 0 ) state = defaultState;
var ids = listIds(next);
// Try to recycle our wrapper prototype, if possible:
var wrapperProto =
state === defaultState || ids !== listIds(prev)
? makeWrapperProto(ids, function (id) { return reducer; }, makeNext)
: Object.getPrototypeOf(state);
var wrapper = makeWrapper(wrapperProto, state, action, next, prev);
// If we are the topmost fat reducer, flatten the wrappers:
return next === void 0 ? flattenWrapper(state, wrapper) : wrapper
}
mapReducer.defaultState = defaultState;
return mapReducer
}
/**
* Creates a memoized reducer for derived values.
* The first aguments are argument filters,
* which take the next and return an argument to pass to the derivation.
* The reducer will only run if some of its arguments are not equal ('===').
*/
function memoizeReducer () {
var arguments$1 = arguments;
var i = arguments.length - 1;
var reducer = arguments[i];
var filters = [];
while (i-- > 0) { filters[i] = arguments$1[i]; }
// Type-check the arguments:
if (typeof reducer !== 'function') {
throw new TypeError('The reducer must be a function')
}
for (var i$1 = 0, list = filters; i$1 < list.length; i$1 += 1) {
var filter = list[i$1];
if (typeof filter !== 'function') {
throw new TypeError('Each argument filter must be a function')
}
}
return function memoizedReducer (
state,
action,
next,
prev
) {
if ( state === void 0 ) state = reducer.defaultState;
var clean = state !== undefined;
var args = [];
for (var i = 0; i < filters.length; ++i) {
args[i] = filters[i](next);
if (clean && args[i] !== filters[i](prev)) { clean = false; }
}
return clean ? state : reducer.apply(void 0, args)
}
}
exports.buildReducer = buildReducer;
exports.filterReducer = filterReducer;
exports.mapReducer = mapReducer;
exports.memoizeReducer = memoizeReducer;
},{}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsInJlZHV4LWtldG8iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbi8vIFNwZWNpYWwgcHJvcGVydHkgdGhhdCBvbmx5IG91ciB3cmFwcGVycyB3aWxsIGhhdmU6XG52YXIgd3JhcHBlck1hZ2ljID0gJ3JlZHV4LWtldG8gd3JhcHBlcic7XG5cbi8qKlxuICogTWFrZXMgYSBjb2xsZWN0aW9uIG9mIGxhenkgZ2V0dGVycyBmb3IgYSBrZXktdmFsdWUgc3RhdGUgc2xpY2UuXG4gKiBUaGUgYWN0dWFsIHdyYXBwZXIgb2JqZWN0IGluaGVyaXRzIGZyb20gdGhpcyBwcm90b3R5cGUuXG4gKi9cbmZ1bmN0aW9uIG1ha2VXcmFwcGVyUHJvdG8gKGtleXMsIG1ha2VSZWR1Y2VyLCBtYWtlTmV4dCkge1xuICB2YXIgd3JhcHBlclByb3RvID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdmFyIGxvb3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGtleSA9IGxpc3RbaV07XG5cbiAgICB2YXIgcmVkdWNlciA9IG1ha2VSZWR1Y2VyKGtleSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlclByb3RvLCBrZXksIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCAoKSB7XG4gICAgICAgIHZhciB3cmFwcGVyID0gdGhpcztcbiAgICAgICAgdmFyIHN0YXNoID0gd3JhcHBlclt3cmFwcGVyTWFnaWNdO1xuXG4gICAgICAgIC8vIElmIHdlIGFyZSBhbHJlYWR5IHJ1bm5pbmcsIHRoaXMgaXMgYSBwcm9ibGVtIVxuICAgICAgICBpZiAoc3Rhc2gucnVubmluZ1trZXldKSB7XG4gICAgICAgICAgdmFyIGUgPSBuZXcgUmVmZXJlbmNlRXJyb3IoXG4gICAgICAgICAgICAoXCJSZWR1Y2VyICdcIiArIGtleSArIFwiJyBkZXBlbmRzIG9uIGl0cyBvd24gcmVzdWx0XCIpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBlLm5hbWUgPSAnUmVkdXhLZXRvQ2lyY3VsYXJSZWZlcmVuY2VFcnJvcic7XG4gICAgICAgICAgdGhyb3cgZVxuICAgICAgICB9XG4gICAgICAgIHN0YXNoLnJ1bm5pbmdba2V5XSA9IHRydWU7XG5cbiAgICAgICAgLy8gRXZhbHVhdGUgdGhlIHJlZHVjZXI6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFyIG91dCA9IHJlZHVjZXIoXG4gICAgICAgICAgICBzdGFzaC5zdGF0ZVtrZXldLFxuICAgICAgICAgICAgc3Rhc2guYWN0aW9uLFxuICAgICAgICAgICAgbWFrZU5leHQoc3Rhc2gubmV4dCwgd3JhcHBlciwga2V5KSxcbiAgICAgICAgICAgIG1ha2VOZXh0KHN0YXNoLnByZXYsIHN0YXNoLnN0YXRlLCBrZXkpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAob3V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKFwiUmVkdWNlciAnXCIgKyBrZXkgKyBcIicgcmV0dXJuZWQgdW5kZWZpbmVkXCIpKVxuICAgICAgICAgIH1cbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlciwga2V5LCB7XG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG91dFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBvdXRcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBzdGFzaC5ydW5uaW5nW2tleV0gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwLCBsaXN0ID0ga2V5czsgaSA8IGxpc3QubGVuZ3RoOyBpICs9IDEpIGxvb3AoKTtcblxuICByZXR1cm4gd3JhcHBlclByb3RvXG59XG5cbi8qKlxuICogTWFrZXMgYSBsYXp5IHdyYXBwZXIgb2JqZWN0IGZvciBhIGtleS12YWx1ZSBzdGF0ZSBzbGljZS5cbiAqL1xuZnVuY3Rpb24gbWFrZVdyYXBwZXIgKHdyYXBwZXJQcm90bywgc3RhdGUsIGFjdGlvbiwgbmV4dCwgcHJldikge1xuICB2YXIgd3JhcHBlciA9IE9iamVjdC5jcmVhdGUod3JhcHBlclByb3RvKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdyYXBwZXIsIHdyYXBwZXJNYWdpYywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IHsgc3RhdGU6IHN0YXRlLCBhY3Rpb246IGFjdGlvbiwgbmV4dDogbmV4dCwgcHJldjogcHJldiwgcnVubmluZzoge30gfVxuICB9KTtcblxuICByZXR1cm4gd3JhcHBlclxufVxuXG4vKipcbiAqIEZsYXR0ZW5zIGEgbGF6eSBrZXktdmFsdWUgd3JhcHBlciBpbnRvIGEgcGxhaW4tb2xkIG9iamVjdFxuICogd2l0aCB0aGUgY3VycmVudCBzdGF0ZSBhcyBpdHMgcHJvcGVydGllcy5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbldyYXBwZXIgKHN0YXRlLCB3cmFwcGVyKSB7XG4gIGlmICggc3RhdGUgPT09IHZvaWQgMCApIHN0YXRlID0ge307XG5cbiAgLy8gSWYgaXQncyBub3QgYSB3cmFwcGVyLCB3ZSBhcmUgZG9uZTpcbiAgaWYgKHdyYXBwZXIgPT09IG51bGwgfHwgd3JhcHBlclt3cmFwcGVyTWFnaWNdID09IG51bGwpIHsgcmV0dXJuIHdyYXBwZXIgfVxuXG4gIC8vIERpZmYgdGhlIG9sZCBhbmQgbmV3IHN0YXRlczpcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhPYmplY3QuZ2V0UHJvdG90eXBlT2Yod3JhcHBlcikpO1xuICB2YXIgdW5jaGFuZ2VkID0gT2JqZWN0LmtleXMoc3RhdGUpLmxlbmd0aCA9PT0ga2V5cy5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwLCBsaXN0ID0ga2V5czsgaSA8IGxpc3QubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB2YXIga2V5ID0gbGlzdFtpXTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVyLCBrZXksIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IGZsYXR0ZW5XcmFwcGVyKHN0YXRlW2tleV0sIHdyYXBwZXJba2V5XSlcbiAgICB9KTtcbiAgICBpZiAod3JhcHBlcltrZXldICE9PSBzdGF0ZVtrZXldKSB7XG4gICAgICB1bmNoYW5nZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBJZiBub3RoaW5nIGNoYW5nZWQsIGp1c3QgcmV0dXJuIHRoZSBwcmV2aW91cyBzdGF0ZTpcbiAgaWYgKHVuY2hhbmdlZCkgeyByZXR1cm4gc3RhdGUgfVxuXG4gIGRlbGV0ZSB3cmFwcGVyW3dyYXBwZXJNYWdpY107XG4gIHJldHVybiB3cmFwcGVyXG59XG5cbmZ1bmN0aW9uIG1ha2VOZXh0RGVmYXVsdCAobmV4dCwgY2hpbGRyZW4sIGlkKSB7XG4gIHJldHVybiBuZXh0ICE9PSB2b2lkIDAgPyBuZXh0IDogY2hpbGRyZW5cbn1cblxuLyoqXG4gKiBDb21iaW5lcyBzZXZlcmFsIHJlZHVjZXJzIGludG8gb25lLlxuICovXG5mdW5jdGlvbiBidWlsZFJlZHVjZXIgKHJlZHVjZXJNYXAsIG1ha2VOZXh0KSB7XG4gIGlmICggbWFrZU5leHQgPT09IHZvaWQgMCApIG1ha2VOZXh0ID0gbWFrZU5leHREZWZhdWx0O1xuXG4gIC8vIFZhbGlkYXRlIGFyZ3VtZW50IHR5cGVzOlxuICBpZiAodHlwZW9mIHJlZHVjZXJNYXAgIT09ICdvYmplY3QnIHx8IHJlZHVjZXJNYXAgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgcmVkdWNlciBtYXAgbXVzdCBiZSBhbiBvYmplY3QuJylcbiAgfVxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHJlZHVjZXJNYXApO1xuICBmb3IgKHZhciBpID0gMCwgbGlzdCA9IGtleXM7IGkgPCBsaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgdmFyIGtleSA9IGxpc3RbaV07XG5cbiAgICBpZiAodHlwZW9mIHJlZHVjZXJNYXBba2V5XSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVkdWNlcnMgbXVzdCBiZSBmdW5jdGlvbnMuJylcbiAgICB9XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgd3JhcHBlcjpcbiAgdmFyIHdyYXBwZXJQcm90byA9IG1ha2VXcmFwcGVyUHJvdG8oa2V5cywgZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gcmVkdWNlck1hcFtrZXldOyB9LCBtYWtlTmV4dCk7XG5cbiAgLy8gQnVpbGQgdGhlIGRlZmF1bHQgc3RhdGU6XG4gIHZhciBkZWZhdWx0U3RhdGUgPSB7fTtcbiAgZm9yICh2YXIgaSQxID0gMCwgbGlzdCQxID0ga2V5czsgaSQxIDwgbGlzdCQxLmxlbmd0aDsgaSQxICs9IDEpIHtcbiAgICB2YXIga2V5JDEgPSBsaXN0JDFbaSQxXTtcblxuICAgIGRlZmF1bHRTdGF0ZVtrZXkkMV0gPSByZWR1Y2VyTWFwW2tleSQxXS5kZWZhdWx0U3RhdGU7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsdFJlZHVjZXIgKHN0YXRlLCBhY3Rpb24sIG5leHQsIHByZXYpIHtcbiAgICBpZiAoIHN0YXRlID09PSB2b2lkIDAgKSBzdGF0ZSA9IGRlZmF1bHRTdGF0ZTtcblxuICAgIHZhciB3cmFwcGVyID0gbWFrZVdyYXBwZXIod3JhcHBlclByb3RvLCBzdGF0ZSwgYWN0aW9uLCBuZXh0LCBwcmV2KTtcblxuICAgIC8vIElmIHdlIGFyZSB0aGUgdG9wbW9zdCBmYXQgcmVkdWNlciwgZmxhdHRlbiB0aGUgd3JhcHBlcnM6XG4gICAgcmV0dXJuIG5leHQgPT09IHZvaWQgMCA/IGZsYXR0ZW5XcmFwcGVyKHN0YXRlLCB3cmFwcGVyKSA6IHdyYXBwZXJcbiAgfVxuICBidWlsdFJlZHVjZXIuZGVmYXVsdFN0YXRlID0gZGVmYXVsdFN0YXRlO1xuXG4gIHJldHVybiBidWlsdFJlZHVjZXJcbn1cblxuZnVuY3Rpb24gZmlsdGVyQWN0aW9uc0RlZmF1bHQgKGFjdGlvbiwgbmV4dCkge1xuICByZXR1cm4gYWN0aW9uXG59XG5cbmZ1bmN0aW9uIGZpbHRlck5leHREZWZhdWx0IChuZXh0KSB7XG4gIHJldHVybiBuZXh0XG59XG5cbi8qKlxuICogRmlsdGVycyB0aGUgbmV4dCBhbmQgYWN0aW9ucyBnb2luZyBpbnRvIGEgZmF0IHJlZHVjZXIuXG4gKi9cbmZ1bmN0aW9uIGZpbHRlclJlZHVjZXIgKFxuICByZWR1Y2VyLFxuICBmaWx0ZXJBY3Rpb24sXG4gIGZpbHRlck5leHRcbikge1xuICBpZiAoIGZpbHRlckFjdGlvbiA9PT0gdm9pZCAwICkgZmlsdGVyQWN0aW9uID0gZmlsdGVyQWN0aW9uc0RlZmF1bHQ7XG4gIGlmICggZmlsdGVyTmV4dCA9PT0gdm9pZCAwICkgZmlsdGVyTmV4dCA9IGZpbHRlck5leHREZWZhdWx0O1xuXG4gIHZhciBkZWZhdWx0U3RhdGUgPSByZWR1Y2VyLmRlZmF1bHRTdGF0ZTtcblxuICBmdW5jdGlvbiBmaWx0ZXJlZFJlZHVjZXIgKHN0YXRlLCBhY3Rpb24sIG5leHQsIHByZXYpIHtcbiAgICBpZiAoIHN0YXRlID09PSB2b2lkIDAgKSBzdGF0ZSA9IGRlZmF1bHRTdGF0ZTtcblxuICAgIHZhciBpbm5lckFjdGlvbiA9IGZpbHRlckFjdGlvbihhY3Rpb24sIG5leHQpO1xuICAgIHZhciBpbm5lck5leHQgPSBmaWx0ZXJOZXh0KG5leHQpO1xuICAgIHZhciBpbm5lclByZXYgPSBmaWx0ZXJOZXh0KHByZXYpO1xuXG4gICAgaWYgKCFpbm5lckFjdGlvbikgeyByZXR1cm4gc3RhdGUgfVxuXG4gICAgdmFyIHdyYXBwZXIgPSByZWR1Y2VyKHN0YXRlLCBpbm5lckFjdGlvbiwgaW5uZXJOZXh0LCBpbm5lclByZXYpO1xuXG4gICAgLy8gSWYgd2UgYXJlIHRoZSB0b3Btb3N0IGZhdCByZWR1Y2VyLCBmbGF0dGVuIHRoZSB3cmFwcGVyczpcbiAgICByZXR1cm4gbmV4dCA9PT0gdm9pZCAwID8gZmxhdHRlbldyYXBwZXIoc3RhdGUsIHdyYXBwZXIpIDogd3JhcHBlclxuICB9XG4gIGZpbHRlcmVkUmVkdWNlci5kZWZhdWx0U3RhdGUgPSBkZWZhdWx0U3RhdGU7XG5cbiAgcmV0dXJuIGZpbHRlcmVkUmVkdWNlclxufVxuXG5mdW5jdGlvbiBtYWtlTmV4dERlZmF1bHQkMSAobmV4dCwgY2hpbGRyZW4sIGlkKSB7XG4gIHJldHVybiB7XG4gICAgaWQ6IGlkLFxuICAgIHJvb3Q6IG5leHQgIT09IHZvaWQgMCA/IG5leHQgOiBjaGlsZHJlbixcbiAgICBnZXQgc2VsZiAoKSB7XG4gICAgICByZXR1cm4gY2hpbGRyZW5baWRdXG4gICAgfVxuICB9XG59XG5cbnZhciBkZWZhdWx0U3RhdGUgPSB7fTtcblxuLyoqXG4gKiBBcHBsaWVzIGEgcmVkdWNlciB0byBlYWNoIGl0ZW0gb2YgYSBsaXN0LlxuICogRWFjaCByZWR1Y2VyIG1hbmFnZXMgaXRzIG93biBzdGF0ZSBzbGljZSBvbiBiZWhhbGYgb2YgdGhlIGxpc3QgaXRlbS5cbiAqL1xuZnVuY3Rpb24gbWFwUmVkdWNlciAocmVkdWNlciwgbGlzdElkcywgbWFrZU5leHQpIHtcbiAgaWYgKCBtYWtlTmV4dCA9PT0gdm9pZCAwICkgbWFrZU5leHQgPSBtYWtlTmV4dERlZmF1bHQkMTtcblxuICBmdW5jdGlvbiBtYXBSZWR1Y2VyIChzdGF0ZSwgYWN0aW9uLCBuZXh0LCBwcmV2KSB7XG4gICAgaWYgKCBzdGF0ZSA9PT0gdm9pZCAwICkgc3RhdGUgPSBkZWZhdWx0U3RhdGU7XG5cbiAgICB2YXIgaWRzID0gbGlzdElkcyhuZXh0KTtcblxuICAgIC8vIFRyeSB0byByZWN5Y2xlIG91ciB3cmFwcGVyIHByb3RvdHlwZSwgaWYgcG9zc2libGU6XG4gICAgdmFyIHdyYXBwZXJQcm90byA9XG4gICAgICBzdGF0ZSA9PT0gZGVmYXVsdFN0YXRlIHx8IGlkcyAhPT0gbGlzdElkcyhwcmV2KVxuICAgICAgICA/IG1ha2VXcmFwcGVyUHJvdG8oaWRzLCBmdW5jdGlvbiAoaWQpIHsgcmV0dXJuIHJlZHVjZXI7IH0sIG1ha2VOZXh0KVxuICAgICAgICA6IE9iamVjdC5nZXRQcm90b3R5cGVPZihzdGF0ZSk7XG5cbiAgICB2YXIgd3JhcHBlciA9IG1ha2VXcmFwcGVyKHdyYXBwZXJQcm90bywgc3RhdGUsIGFjdGlvbiwgbmV4dCwgcHJldik7XG5cbiAgICAvLyBJZiB3ZSBhcmUgdGhlIHRvcG1vc3QgZmF0IHJlZHVjZXIsIGZsYXR0ZW4gdGhlIHdyYXBwZXJzOlxuICAgIHJldHVybiBuZXh0ID09PSB2b2lkIDAgPyBmbGF0dGVuV3JhcHBlcihzdGF0ZSwgd3JhcHBlcikgOiB3cmFwcGVyXG4gIH1cbiAgbWFwUmVkdWNlci5kZWZhdWx0U3RhdGUgPSBkZWZhdWx0U3RhdGU7XG5cbiAgcmV0dXJuIG1hcFJlZHVjZXJcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWVtb2l6ZWQgcmVkdWNlciBmb3IgZGVyaXZlZCB2YWx1ZXMuXG4gKiBUaGUgZmlyc3QgYWd1bWVudHMgYXJlIGFyZ3VtZW50IGZpbHRlcnMsXG4gKiB3aGljaCB0YWtlIHRoZSBuZXh0IGFuZCByZXR1cm4gYW4gYXJndW1lbnQgdG8gcGFzcyB0byB0aGUgZGVyaXZhdGlvbi5cbiAqIFRoZSByZWR1Y2VyIHdpbGwgb25seSBydW4gaWYgc29tZSBvZiBpdHMgYXJndW1lbnRzIGFyZSBub3QgZXF1YWwgKCc9PT0nKS5cbiAqL1xuZnVuY3Rpb24gbWVtb2l6ZVJlZHVjZXIgKCkge1xuICB2YXIgYXJndW1lbnRzJDEgPSBhcmd1bWVudHM7XG5cbiAgdmFyIGkgPSBhcmd1bWVudHMubGVuZ3RoIC0gMTtcbiAgdmFyIHJlZHVjZXIgPSBhcmd1bWVudHNbaV07XG4gIHZhciBmaWx0ZXJzID0gW107XG4gIHdoaWxlIChpLS0gPiAwKSB7IGZpbHRlcnNbaV0gPSBhcmd1bWVudHMkMVtpXTsgfVxuXG4gIC8vIFR5cGUtY2hlY2sgdGhlIGFyZ3VtZW50czpcbiAgaWYgKHR5cGVvZiByZWR1Y2VyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHJlZHVjZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJylcbiAgfVxuICBmb3IgKHZhciBpJDEgPSAwLCBsaXN0ID0gZmlsdGVyczsgaSQxIDwgbGlzdC5sZW5ndGg7IGkkMSArPSAxKSB7XG4gICAgdmFyIGZpbHRlciA9IGxpc3RbaSQxXTtcblxuICAgIGlmICh0eXBlb2YgZmlsdGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFYWNoIGFyZ3VtZW50IGZpbHRlciBtdXN0IGJlIGEgZnVuY3Rpb24nKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBtZW1vaXplZFJlZHVjZXIgKFxuICAgIHN0YXRlLFxuICAgIGFjdGlvbixcbiAgICBuZXh0LFxuICAgIHByZXZcbiAgKSB7XG4gICAgaWYgKCBzdGF0ZSA9PT0gdm9pZCAwICkgc3RhdGUgPSByZWR1Y2VyLmRlZmF1bHRTdGF0ZTtcblxuICAgIHZhciBjbGVhbiA9IHN0YXRlICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbHRlcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGFyZ3NbaV0gPSBmaWx0ZXJzW2ldKG5leHQpO1xuICAgICAgaWYgKGNsZWFuICYmIGFyZ3NbaV0gIT09IGZpbHRlcnNbaV0ocHJldikpIHsgY2xlYW4gPSBmYWxzZTsgfVxuICAgIH1cblxuICAgIHJldHVybiBjbGVhbiA/IHN0YXRlIDogcmVkdWNlci5hcHBseSh2b2lkIDAsIGFyZ3MpXG4gIH1cbn1cblxuZXhwb3J0cy5idWlsZFJlZHVjZXIgPSBidWlsZFJlZHVjZXI7XG5leHBvcnRzLmZpbHRlclJlZHVjZXIgPSBmaWx0ZXJSZWR1Y2VyO1xuZXhwb3J0cy5tYXBSZWR1Y2VyID0gbWFwUmVkdWNlcjtcbmV4cG9ydHMubWVtb2l6ZVJlZHVjZXIgPSBtZW1vaXplUmVkdWNlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlZHV4LWtldG8uanMubWFwXG4iXX0=
const keto = require('redux-keto')
const buildReducer = keto.buildReducer
const maxCount = (state = 0, action) =>
action.type === 'CHANGE_MAX_COUNT'
? action.payload
: state
const counter = (state = 0, action, next) =>
Math.min(next.maxCount, action.type === 'INCREMENT' ? state + action.payload : state)
const rootReducer = buildReducer({ maxCount, counter })
state = rootReducer(undefined, {type: 'init'})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'CHANGE_MAX_COUNT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
state = rootReducer(state, {type: 'CHANGE_MAX_COUNT', payload: 0})
console.log(state)
state = rootReducer(state, {type: 'INCREMENT', payload: 1})
console.log(state)
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"redux-keto": "0.3.2"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment