196 lines
5.4 KiB
JavaScript
196 lines
5.4 KiB
JavaScript
'use strict';
|
|
|
|
function _defineProperty(obj, key, value) {
|
|
if (key in obj) {
|
|
Object.defineProperty(obj, key, {
|
|
value: value,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
function ownKeys(object, enumerableOnly) {
|
|
var keys = Object.keys(object);
|
|
|
|
if (Object.getOwnPropertySymbols) {
|
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
});
|
|
keys.push.apply(keys, symbols);
|
|
}
|
|
|
|
return keys;
|
|
}
|
|
|
|
function _objectSpread2(target) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
|
|
if (i % 2) {
|
|
ownKeys(Object(source), true).forEach(function (key) {
|
|
_defineProperty(target, key, source[key]);
|
|
});
|
|
} else if (Object.getOwnPropertyDescriptors) {
|
|
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
} else {
|
|
ownKeys(Object(source)).forEach(function (key) {
|
|
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
});
|
|
}
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
function compose() {
|
|
for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
fns[_key] = arguments[_key];
|
|
}
|
|
|
|
return function (x) {
|
|
return fns.reduceRight(function (y, f) {
|
|
return f(y);
|
|
}, x);
|
|
};
|
|
}
|
|
|
|
function curry(fn) {
|
|
return function curried() {
|
|
var _this = this;
|
|
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
args[_key2] = arguments[_key2];
|
|
}
|
|
|
|
return args.length >= fn.length ? fn.apply(this, args) : function () {
|
|
for (var _len3 = arguments.length, nextArgs = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
nextArgs[_key3] = arguments[_key3];
|
|
}
|
|
|
|
return curried.apply(_this, [].concat(args, nextArgs));
|
|
};
|
|
};
|
|
}
|
|
|
|
function isObject(value) {
|
|
return {}.toString.call(value).includes('Object');
|
|
}
|
|
|
|
function isEmpty(obj) {
|
|
return !Object.keys(obj).length;
|
|
}
|
|
|
|
function isFunction(value) {
|
|
return typeof value === 'function';
|
|
}
|
|
|
|
function hasOwnProperty(object, property) {
|
|
return Object.prototype.hasOwnProperty.call(object, property);
|
|
}
|
|
|
|
function validateChanges(initial, changes) {
|
|
if (!isObject(changes)) errorHandler('changeType');
|
|
if (Object.keys(changes).some(function (field) {
|
|
return !hasOwnProperty(initial, field);
|
|
})) errorHandler('changeField');
|
|
return changes;
|
|
}
|
|
|
|
function validateSelector(selector) {
|
|
if (!isFunction(selector)) errorHandler('selectorType');
|
|
}
|
|
|
|
function validateHandler(handler) {
|
|
if (!(isFunction(handler) || isObject(handler))) errorHandler('handlerType');
|
|
if (isObject(handler) && Object.values(handler).some(function (_handler) {
|
|
return !isFunction(_handler);
|
|
})) errorHandler('handlersType');
|
|
}
|
|
|
|
function validateInitial(initial) {
|
|
if (!initial) errorHandler('initialIsRequired');
|
|
if (!isObject(initial)) errorHandler('initialType');
|
|
if (isEmpty(initial)) errorHandler('initialContent');
|
|
}
|
|
|
|
function throwError(errorMessages, type) {
|
|
throw new Error(errorMessages[type] || errorMessages["default"]);
|
|
}
|
|
|
|
var errorMessages = {
|
|
initialIsRequired: 'initial state is required',
|
|
initialType: 'initial state should be an object',
|
|
initialContent: 'initial state shouldn\'t be an empty object',
|
|
handlerType: 'handler should be an object or a function',
|
|
handlersType: 'all handlers should be a functions',
|
|
selectorType: 'selector should be a function',
|
|
changeType: 'provided value of changes should be an object',
|
|
changeField: 'it seams you want to change a field in the state which is not specified in the "initial" state',
|
|
"default": 'an unknown error accured in `state-local` package'
|
|
};
|
|
var errorHandler = curry(throwError)(errorMessages);
|
|
var validators = {
|
|
changes: validateChanges,
|
|
selector: validateSelector,
|
|
handler: validateHandler,
|
|
initial: validateInitial
|
|
};
|
|
|
|
function create(initial) {
|
|
var handler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
validators.initial(initial);
|
|
validators.handler(handler);
|
|
var state = {
|
|
current: initial
|
|
};
|
|
var didUpdate = curry(didStateUpdate)(state, handler);
|
|
var update = curry(updateState)(state);
|
|
var validate = curry(validators.changes)(initial);
|
|
var getChanges = curry(extractChanges)(state);
|
|
|
|
function getState() {
|
|
var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function (state) {
|
|
return state;
|
|
};
|
|
validators.selector(selector);
|
|
return selector(state.current);
|
|
}
|
|
|
|
function setState(causedChanges) {
|
|
compose(didUpdate, update, validate, getChanges)(causedChanges);
|
|
}
|
|
|
|
return [getState, setState];
|
|
}
|
|
|
|
function extractChanges(state, causedChanges) {
|
|
return isFunction(causedChanges) ? causedChanges(state.current) : causedChanges;
|
|
}
|
|
|
|
function updateState(state, changes) {
|
|
state.current = _objectSpread2(_objectSpread2({}, state.current), changes);
|
|
return changes;
|
|
}
|
|
|
|
function didStateUpdate(state, handler, changes) {
|
|
isFunction(handler) ? handler(state.current) : Object.keys(changes).forEach(function (field) {
|
|
var _handler$field;
|
|
|
|
return (_handler$field = handler[field]) === null || _handler$field === void 0 ? void 0 : _handler$field.call(handler, state.current[field]);
|
|
});
|
|
return changes;
|
|
}
|
|
|
|
var index = {
|
|
create: create
|
|
};
|
|
|
|
module.exports = index;
|