rambdax
Version:
Extended version of Rambda - a lightweight, faster alternative to Ramda
1,978 lines (1,589 loc) • 94.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.R = {}));
}(this, (function (exports) { 'use strict';
const _isArray = Array.isArray;
function type(input) {
const typeOf = typeof input;
if (input === null) {
return 'Null';
} else if (input === undefined) {
return 'Undefined';
} else if (typeOf === 'boolean') {
return 'Boolean';
} else if (typeOf === 'number') {
return Number.isNaN(input) ? 'NaN' : 'Number';
} else if (typeOf === 'string') {
return 'String';
} else if (_isArray(input)) {
return 'Array';
} else if (typeOf === 'symbol') {
return 'Symbol';
} else if (input instanceof RegExp) {
return 'RegExp';
}
const asStr = input && input.toString ? input.toString() : '';
if (['true', 'false'].includes(asStr)) return 'Boolean';
if (!Number.isNaN(Number(asStr))) return 'Number';
if (asStr.startsWith('async')) return 'Async';
if (asStr === '[object Promise]') return 'Promise';
if (typeOf === 'function') return 'Function';
if (input instanceof String) return 'String';
return 'Object';
}
function isTruthy(x) {
if (_isArray(x)) {
return x.length > 0;
}
if (type(x) === 'Object') {
return Object.keys(x).length > 0;
}
return Boolean(x);
}
function allFalse(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isTruthy(x())) {
return false;
}
} else if (isTruthy(x)) {
return false;
}
counter++;
}
return true;
}
function isFalsy(x) {
if (_isArray(x)) {
return x.length === 0;
}
if (type(x) === 'Object') {
return Object.keys(x).length === 0;
}
return !x;
}
function allTrue(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isFalsy(x())) {
return false;
}
} else if (isFalsy(x)) {
return false;
}
counter++;
}
return true;
}
function allType(targetType) {
return (...inputs) => {
let counter = 0;
while (counter < inputs.length) {
if (type(inputs[counter]) !== targetType) {
return false;
}
counter++;
}
return true;
};
}
function anyFalse(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isFalsy(x())) {
return true;
}
} else if (isFalsy(x)) {
return true;
}
counter++;
}
return false;
}
function anyTrue(...inputs) {
let counter = 0;
while (counter < inputs.length) {
const x = inputs[counter];
if (type(x) === 'Function') {
if (isTruthy(x())) {
return true;
}
} else if (isTruthy(x)) {
return true;
}
counter++;
}
return false;
}
function anyType(targetType) {
return (...inputs) => {
let counter = 0;
while (counter < inputs.length) {
if (type(inputs[counter]) === targetType) {
return true;
}
counter++;
}
return false;
};
}
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 _isInteger(n) {
return n << 0 === n;
}
var _isInteger$1 = Number.isInteger || _isInteger;
function curry(fn, args = []) {
return (..._args) => (rest => rest.length >= fn.length ? fn(...rest) : curry(fn, rest))([...args, ..._args]);
}
function assocFn(prop, newValue, obj) {
return Object.assign({}, obj, {
[prop]: newValue
});
}
const assoc = curry(assocFn);
function assocPathFn(path, newValue, input) {
const pathArrValue = typeof path === 'string' ? path.split('.').map(x => _isInteger(Number(x)) ? Number(x) : x) : path;
if (pathArrValue.length === 0) {
return newValue;
}
const index = pathArrValue[0];
if (pathArrValue.length > 1) {
const condition = typeof input !== 'object' || input === null || !input.hasOwnProperty(index);
const nextinput = condition ? _isInteger(pathArrValue[1]) ? [] : {} : input[index];
newValue = assocPathFn(Array.prototype.slice.call(pathArrValue, 1), newValue, nextinput);
}
if (_isInteger(index) && _isArray(input)) {
const arr = input.slice();
arr[index] = newValue;
return arr;
}
return assoc(index, newValue, input);
}
const assocPath = curry(assocPathFn);
function path(pathInput, obj) {
if (arguments.length === 1) return _obj => path(pathInput, _obj);
if (obj === null || obj === undefined) {
return undefined;
}
let willReturn = obj;
let counter = 0;
const pathArrValue = typeof pathInput === 'string' ? pathInput.split('.') : pathInput;
while (counter < pathArrValue.length) {
if (willReturn === null || willReturn === undefined) {
return undefined;
}
willReturn = willReturn[pathArrValue[counter]];
counter++;
}
return willReturn;
}
const ALLOWED_OPERATIONS = ['remove', 'add', 'update'];
function removeAtPath(path, obj) {
const p = typeof path === 'string' ? path.split('.') : path;
const len = p.length;
if (len === 0) return;
if (len === 1) return delete obj[p[0]];
if (len === 2) return delete obj[p[0]][p[1]];
if (len === 3) return delete obj[p[0]][p[1]][p[2]];
if (len === 4) return delete obj[p[0]][p[1]][p[2]][p[3]];
if (len === 5) return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]];
if (len === 6) {
return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]];
}
if (len === 7) {
return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]];
}
if (len === 8) {
return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]];
}
if (len === 9) {
return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]];
}
if (len === 10) {
return delete obj[p[0]][p[1]][p[2]][p[3]][p[4]][p[5]][p[6]][p[7]][p[8]][p[9]];
}
}
function applyDiff(rules, obj) {
if (arguments.length === 1) return _obj => applyDiff(rules, _obj);
let clone = _objectSpread2({}, obj);
rules.forEach(({
op,
path: path$1,
value
}) => {
if (!ALLOWED_OPERATIONS.includes(op)) return;
if (op === 'add' && path$1 && value !== undefined) {
if (path(path$1, obj)) return;
return clone = assocPath(path$1, value, clone);
}
if (op === 'remove') {
if (path(path$1, obj) === undefined) return;
return removeAtPath(path$1, clone);
}
if (op === 'update' && path$1 && value !== undefined) {
if (path(path$1, obj) === undefined) return;
return clone = assocPath(path$1, value, clone);
}
});
return clone;
}
function composeAsync(...inputArguments) {
return async function (startArgument) {
let argumentsToPass = startArgument;
while (inputArguments.length !== 0) {
const fn = inputArguments.pop();
const typeFn = type(fn);
if (typeFn === 'Async') {
argumentsToPass = await fn(argumentsToPass);
} else {
argumentsToPass = fn(argumentsToPass);
if (type(argumentsToPass) === 'Promise') {
argumentsToPass = await argumentsToPass;
}
}
}
return argumentsToPass;
};
}
function parseError(maybeError) {
const typeofError = maybeError.__proto__.toString();
if (!['Error', 'TypeError'].includes(typeofError)) return [];
return [typeofError, maybeError.message];
}
function parseDate(maybeDate) {
if (!maybeDate.toDateString) return [false];
return [true, maybeDate.getTime()];
}
function parseRegex(maybeRegex) {
if (maybeRegex.constructor !== RegExp) return [false];
return [true, maybeRegex.toString()];
}
function equals(a, b) {
if (arguments.length === 1) return _b => equals(a, _b);
const aType = type(a);
if (aType !== type(b)) return false;
if (aType === 'Function') {
return a.name === undefined ? false : a.name === b.name;
}
if (['NaN', 'Undefined', 'Null'].includes(aType)) return true;
if (aType === 'Number') {
if (Object.is(-0, a) !== Object.is(-0, b)) return false;
return a.toString() === b.toString();
}
if (['String', 'Boolean'].includes(aType)) {
return a.toString() === b.toString();
}
if (aType === 'Array') {
const aClone = Array.from(a);
const bClone = Array.from(b);
if (aClone.toString() !== bClone.toString()) {
return false;
}
let loopArrayFlag = true;
aClone.forEach((aCloneInstance, aCloneIndex) => {
if (loopArrayFlag) {
if (aCloneInstance !== bClone[aCloneIndex] && !equals(aCloneInstance, bClone[aCloneIndex])) {
loopArrayFlag = false;
}
}
});
return loopArrayFlag;
}
const aRegex = parseRegex(a);
const bRegex = parseRegex(b);
if (aRegex[0]) {
return bRegex[0] ? aRegex[1] === bRegex[1] : false;
} else if (bRegex[0]) return false;
const aDate = parseDate(a);
const bDate = parseDate(b);
if (aDate[0]) {
return bDate[0] ? aDate[1] === bDate[1] : false;
} else if (bDate[0]) return false;
const aError = parseError(a);
const bError = parseError(b);
if (aError[0]) {
return bError[0] ? aError[0] === bError[0] && aError[1] === bError[1] : false;
}
if (aType === 'Object') {
const aKeys = Object.keys(a);
if (aKeys.length !== Object.keys(b).length) {
return false;
}
let loopObjectFlag = true;
aKeys.forEach(aKeyInstance => {
if (loopObjectFlag) {
const aValue = a[aKeyInstance];
const bValue = b[aKeyInstance];
if (aValue !== bValue && !equals(aValue, bValue)) {
loopObjectFlag = false;
}
}
});
return loopObjectFlag;
}
return false;
}
function count(searchFor, list) {
if (arguments.length === 1) {
return _list => count(searchFor, _list);
}
if (!_isArray(list)) return 0;
return list.filter(x => equals(x, searchFor)).length;
}
function debounce(func, ms, immediate = false) {
let timeout;
return function (...input) {
const later = function () {
timeout = null;
if (!immediate) {
func.apply(null, input);
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, ms);
if (callNow) {
func.apply(null, input);
}
};
}
const DELAY = 'RAMBDAX_DELAY';
function delay(ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve(DELAY);
}, ms);
});
}
function includes(valueToFind, input) {
if (arguments.length === 1) return _input => includes(valueToFind, _input);
if (typeof input === 'string') {
return input.includes(valueToFind);
}
if (!input) {
throw new TypeError(`Cannot read property \'indexOf\' of ${input}`);
}
if (!_isArray(input)) return false;
let index = -1;
while (++index < input.length) {
if (equals(input[index], valueToFind)) {
return true;
}
}
return false;
}
function excludes(valueToFind, input) {
if (arguments.length === 1) return _input => excludes(valueToFind, _input);
return includes(valueToFind, input) === false;
}
function filterObject(fn, obj) {
const willReturn = {};
for (const prop in obj) {
if (fn(obj[prop], prop, obj)) {
willReturn[prop] = obj[prop];
}
}
return willReturn;
}
function filterArray(predicate, list, indexed = false) {
let index = 0;
const len = list.length;
const willReturn = [];
while (index < len) {
const predicateResult = indexed ? predicate(list[index], index) : predicate(list[index]);
if (predicateResult) {
willReturn.push(list[index]);
}
index++;
}
return willReturn;
}
function filter(predicate, iterable) {
if (arguments.length === 1) {
return _iterable => filter(predicate, _iterable);
}
if (!iterable) return [];
if (_isArray(iterable)) return filterArray(predicate, iterable);
return filterObject(predicate, iterable);
}
async function mapAsyncFn(fn, listOrObject) {
if (_isArray(listOrObject)) {
const willReturn = [];
let i = 0;
for (const a of listOrObject) {
willReturn.push(await fn(a, i++));
}
return willReturn;
}
const willReturn = {};
for (const prop in listOrObject) {
willReturn[prop] = await fn(listOrObject[prop], prop);
}
return willReturn;
}
function mapAsync(fn, listOrObject) {
if (arguments.length === 1) {
return async _listOrObject => mapAsyncFn(fn, _listOrObject);
}
return new Promise((resolve, reject) => {
mapAsyncFn(fn, listOrObject).then(resolve).catch(reject);
});
}
function filterAsyncFn(predicate, listOrObject) {
return new Promise((resolve, reject) => {
mapAsync(predicate, listOrObject).then(predicateResult => {
if (_isArray(predicateResult)) {
const filtered = listOrObject.filter((_, i) => predicateResult[i]);
return resolve(filtered);
}
const filtered = filter((_, prop) => predicateResult[prop], listOrObject);
return resolve(filtered);
}).catch(reject);
});
}
function filterAsync(predicate, listOrObject) {
if (arguments.length === 1) {
return async _listOrObject => filterAsyncFn(predicate, _listOrObject);
}
return new Promise((resolve, reject) => {
filterAsyncFn(predicate, listOrObject).then(resolve).catch(reject);
});
}
function filterIndexed(predicate, iterable) {
if (arguments.length === 1) return _iterable => filterIndexed(predicate, _iterable);
if (!iterable) return [];
if (_isArray(iterable)) return filterArray(predicate, iterable, true);
return filterObject(predicate, iterable);
}
const _keys = Object.keys;
function mapArray(fn, list, isIndexed = false) {
let index = 0;
const willReturn = Array(list.length);
while (index < list.length) {
willReturn[index] = isIndexed ? fn(list[index], index) : fn(list[index]);
index++;
}
return willReturn;
}
function mapObject(fn, obj) {
let index = 0;
const keys = _keys(obj);
const len = keys.length;
const willReturn = {};
while (index < len) {
const key = keys[index];
willReturn[key] = fn(obj[key], key, obj);
index++;
}
return willReturn;
}
function map(fn, list) {
if (arguments.length === 1) return _list => map(fn, _list);
if (list === undefined) return [];
if (_isArray(list)) return mapArray(fn, list);
return mapObject(fn, list);
}
function mapIndexed(fn, iterable) {
if (arguments.length === 1) {
return _iterable => mapIndexed(fn, _iterable);
}
if (iterable === undefined) return [];
if (_isArray(iterable)) return mapArray(fn, iterable, true);
return mapObject(fn, iterable);
}
function forEachIndexed(fn, iterable) {
if (arguments.length === 1) {
return _iterable => forEachIndexed(fn, _iterable);
}
mapIndexed(fn, iterable);
return iterable;
}
function merge(target, newProps) {
if (arguments.length === 1) return _newProps => merge(target, _newProps);
return Object.assign({}, target || {}, newProps || {});
}
function pick(propsToPick, input) {
if (arguments.length === 1) return _input => pick(propsToPick, _input);
if (input === null || input === undefined) {
return undefined;
}
const keys = typeof propsToPick === 'string' ? propsToPick.split(',') : propsToPick;
const willReturn = {};
let counter = 0;
while (counter < keys.length) {
if (keys[counter] in input) {
willReturn[keys[counter]] = input[keys[counter]];
}
counter++;
}
return willReturn;
}
let holder = {};
function getter(key) {
const typeKey = type(key);
if (typeKey === 'String') return holder[key];
if (typeKey === 'Array') return pick(key, holder);
return holder;
}
function setter(maybeKey, maybeValue) {
const typeKey = type(maybeKey);
const typeValue = type(maybeValue);
if (typeKey === 'String') {
if (typeValue === 'Function') {
return holder[maybeKey] = maybeValue(holder[maybeKey]);
}
return holder[maybeKey] = maybeValue;
}
if (typeKey !== 'Object') return;
holder = merge(holder, maybeKey);
}
function reset() {
holder = {};
}
function glue(input, glueChar) {
return input.split('\n').filter(x => x.trim().length > 0).map(x => x.trim()).join(glueChar === undefined ? ' ' : glueChar);
}
function createThenable(fn) {
return async function (...input) {
return fn(...input);
};
}
function ifElseAsync(condition, ifFn, elseFn) {
return (...inputs) => new Promise((resolve, reject) => {
const conditionPromise = createThenable(condition);
const ifFnPromise = createThenable(ifFn);
const elseFnPromise = createThenable(elseFn);
conditionPromise(...inputs).then(conditionResult => {
const promised = conditionResult === true ? ifFnPromise : elseFnPromise;
promised(...inputs).then(resolve).catch(reject);
}).catch(reject);
});
}
const getOccurances = input => input.match(/{{\s*.+?\s*}}/g);
const getOccuranceProp = occurance => occurance.replace(/{{\s*|\s*}}/g, '');
const replace = ({
inputHolder,
prop,
replacer
}) => {
const regexBase = `{{${prop}}}`;
const regex = new RegExp(regexBase, 'g');
return inputHolder.replace(regex, replacer);
};
function interpolate(input, templateInput) {
if (arguments.length === 1) {
return _templateInput => interpolate(input, _templateInput);
}
const occurances = getOccurances(input);
if (occurances === null) return input;
let inputHolder = input;
for (const occurance of occurances) {
const prop = getOccuranceProp(occurance);
inputHolder = replace({
inputHolder,
prop,
replacer: templateInput[prop]
});
}
return inputHolder;
}
function isFunction(fn) {
return ['Async', 'Function'].includes(type(fn));
}
function isPromise(x) {
return ['Async', 'Promise'].includes(type(x));
}
function isType(xType, x) {
if (arguments.length === 1) {
return xHolder => isType(xType, xHolder);
}
return type(x) === xType;
}
function all(predicate, list) {
if (arguments.length === 1) return _list => all(predicate, _list);
for (let i = 0; i < list.length; i++) {
if (!predicate(list[i])) return false;
}
return true;
}
function any(predicate, list) {
if (arguments.length === 1) return _list => any(predicate, _list);
let counter = 0;
while (counter < list.length) {
if (predicate(list[counter], counter)) {
return true;
}
counter++;
}
return false;
}
function baseSlice(array, start, end) {
let index = -1;
let {
length
} = array;
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : end - start >>> 0;
start >>>= 0;
const result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
function init(listOrString) {
if (typeof listOrString === 'string') return listOrString.slice(0, -1);
return listOrString.length ? baseSlice(listOrString, 0, -1) : [];
}
function test(pattern, str) {
if (arguments.length === 1) return _str => test(pattern, _str);
if (typeof pattern === 'string') {
throw new TypeError(`‘test’ requires a value of type RegExp as its first argument; received "${pattern}"`);
}
return str.search(pattern) !== -1;
}
function toLower(str) {
return str.toLowerCase();
}
function isPrototype(input) {
const currentPrototype = input.prototype;
const list = [Number, String, Boolean, Promise];
let toReturn = false;
let counter = -1;
while (++counter < list.length && !toReturn) {
if (currentPrototype === list[counter].prototype) toReturn = true;
}
return toReturn;
}
function prototypeToString(input) {
const currentPrototype = input.prototype;
const list = [Number, String, Boolean, Promise];
const translatedList = ['Number', 'String', 'Boolean', 'Promise'];
let found;
let counter = -1;
while (++counter < list.length) {
if (currentPrototype === list[counter].prototype) found = counter;
}
return translatedList[found];
}
const typesWithoutPrototype = ['any', 'promise', 'async', 'function'];
function fromPrototypeToString(rule) {
if (_isArray(rule) || rule === undefined || rule === null || rule.prototype === undefined || typesWithoutPrototype.includes(rule)) {
return {
rule,
parsed: false
};
}
if (String.prototype === rule.prototype) {
return {
rule: 'string',
parsed: true
};
}
if (Boolean.prototype === rule.prototype) {
return {
rule: 'boolean',
parsed: true
};
}
if (Number.prototype === rule.prototype) {
return {
rule: 'number',
parsed: true
};
}
return {
rule: type(rule.prototype).toLowerCase(),
parsed: true
};
}
function getRuleAndType(schema, requirementRaw) {
const ruleRaw = schema[requirementRaw];
const typeIs = type(ruleRaw);
const {
rule,
parsed
} = fromPrototypeToString(ruleRaw);
return {
rule: rule,
ruleType: parsed ? 'String' : typeIs
};
}
function isValid({
input,
schema
}) {
if (input === undefined || schema === undefined) return false;
let flag = true;
const boom = boomFlag => {
if (!boomFlag) {
flag = false;
}
};
for (const requirementRaw in schema) {
if (flag) {
const isOptional = requirementRaw.endsWith('?');
const requirement = isOptional ? init(requirementRaw) : requirementRaw;
const {
rule,
ruleType
} = getRuleAndType(schema, requirementRaw);
const inputProp = input[requirement];
const inputPropType = type(input[requirement]);
const ok = isOptional && inputProp !== undefined || !isOptional;
if (!ok || rule === 'any' && inputProp != null || rule === inputProp) continue;
if (ruleType === 'Object') {
const isValidResult = isValid({
input: inputProp,
schema: rule
});
boom(isValidResult);
} else if (ruleType === 'String') {
boom(toLower(inputPropType) === rule);
} else if (typeof rule === 'function') {
boom(rule(inputProp));
} else if (ruleType === 'Array' && inputPropType === 'String') {
boom(includes(inputProp, rule));
} else if (ruleType === 'Array' && rule.length === 1 && inputPropType === 'Array') {
const [currentRule] = rule;
const currentRuleType = type(currentRule);
boom(currentRuleType === 'String' || currentRuleType === 'Object' || isPrototype(currentRule));
if (currentRuleType === 'Object' && flag) {
const isValidResult = all(inputPropInstance => isValid({
input: inputPropInstance,
schema: currentRule
}), inputProp);
boom(isValidResult);
} else if (flag) {
const actualRule = currentRuleType === 'String' ? currentRule : prototypeToString(currentRule);
const isInvalidResult = any(inputPropInstance => type(inputPropInstance).toLowerCase() !== actualRule.toLowerCase(), inputProp);
boom(!isInvalidResult);
}
} else if (ruleType === 'RegExp' && inputPropType === 'String') {
boom(test(rule, inputProp));
} else {
boom(false);
}
}
}
return flag;
}
function forEach(fn, list) {
if (arguments.length === 1) return _list => forEach(fn, _list);
if (list === undefined) {
return;
}
if (_isArray(list)) {
let index = 0;
const len = list.length;
while (index < len) {
fn(list[index]);
index++;
}
} else {
let index = 0;
const keys = _keys(list);
const len = keys.length;
while (index < len) {
const key = keys[index];
fn(list[key], key, list);
index++;
}
}
return list;
}
async function isValidAsync({
schema,
input
}) {
const asyncSchema = {};
const simpleSchema = {};
forEach((rule, prop) => {
if (isPromise(rule)) {
asyncSchema[prop] = rule;
} else {
simpleSchema[prop] = rule;
}
}, schema);
if (Object.keys(asyncSchema).length === 0) return isValid({
input,
schema
});
if (!isValid({
input,
schema: simpleSchema
})) return false;
let toReturn = true;
for (const singleRuleProp in asyncSchema) {
if (toReturn) {
const validated = await asyncSchema[singleRuleProp](input[singleRuleProp]);
if (!validated) toReturn = false;
}
}
return toReturn;
}
const Const = x => ({
x,
map: fn => Const(x)
});
function view(lens, target) {
if (arguments.length === 1) return _target => view(lens, _target);
return lens(Const)(target).x;
}
function lensEqFn(lens, target, input) {
return equals(view(lens, input), target);
}
const lensEq = curry(lensEqFn);
function lensSatisfiesFn(predicate, lens, input) {
return Boolean(predicate(view(lens, input)));
}
const lensSatisfies = curry(lensSatisfiesFn);
async function mapFastAsyncFn(fn, arr) {
const promised = arr.map((a, i) => fn(a, i));
return Promise.all(promised);
}
function mapFastAsync(fn, arr) {
if (arguments.length === 1) {
return async holder => mapFastAsyncFn(fn, holder);
}
return new Promise((resolve, reject) => {
mapFastAsyncFn(fn, arr).then(resolve).catch(reject);
});
}
function splitEvery(sliceLength, listOrString) {
if (arguments.length === 1) {
return _listOrString => splitEvery(sliceLength, _listOrString);
}
if (sliceLength < 1) {
throw new Error('First argument to splitEvery must be a positive integer');
}
const willReturn = [];
let counter = 0;
while (counter < listOrString.length) {
willReturn.push(listOrString.slice(counter, counter += sliceLength));
}
return willReturn;
}
async function mapAsyncLimitFn(iterable, limit, list) {
if (list.length < limit) return mapFastAsync(iterable, list);
const slices = splitEvery(limit, list);
let toReturn = [];
for (const slice of slices) {
const iterableResult = await mapFastAsyncFn(iterable, slice);
toReturn = [...toReturn, ...iterableResult];
}
return toReturn;
}
function mapAsyncLimit(iterable, limit, list) {
if (arguments.length === 2) {
return async _list => mapAsyncLimitFn(iterable, limit, _list);
}
return new Promise((resolve, reject) => {
mapAsyncLimitFn(iterable, limit, list).then(resolve).catch(reject);
});
}
function mapKeys(changeKeyFn, obj) {
if (arguments.length === 1) return _obj => mapKeys(changeKeyFn, _obj);
const toReturn = {};
Object.keys(obj).forEach(prop => toReturn[changeKeyFn(prop)] = obj[prop]);
return toReturn;
}
function mergeAll(arr) {
let willReturn = {};
map(val => {
willReturn = merge(willReturn, val);
}, arr);
return willReturn;
}
function schemaToString(schema) {
if (type(schema) !== 'Object') {
return fromPrototypeToString(schema).rule;
}
return map(x => {
const {
rule,
parsed
} = fromPrototypeToString(x);
const xType = type(x);
if (xType === 'Function' && !parsed) return 'Function';
return parsed ? rule : xType;
}, schema);
}
function check(singleInput, schema) {
return isValid({
input: {
singleInput
},
schema: {
singleInput: schema
}
});
}
function ok(...inputs) {
return (...schemas) => {
let failedSchema;
const anyError = any((singleInput, i) => {
const schema = schemas[i] === undefined ? schemas[0] : schemas[i];
const checked = check(singleInput, schema);
if (!checked) {
failedSchema = JSON.stringify({
input: singleInput,
schema: schemaToString(schema)
});
}
return !checked;
}, inputs);
if (anyError) {
const errorMessage = inputs.length > 1 ? glue(`
Failed R.ok -
reason: ${failedSchema}
all inputs: ${JSON.stringify(inputs)}
all schemas: ${JSON.stringify(schemas.map(schemaToString))}
`, '\n') : `Failed R.ok - ${failedSchema}`;
throw new Error(errorMessage);
}
};
}
function mapToObject(fn, list) {
if (arguments.length === 1) {
return listHolder => mapToObject(fn, listHolder);
}
ok(type(fn), type(list))('Function', 'Array');
return mergeAll(map(fn, list));
}
async function mapToObjectAsyncFn(fn, list) {
let toReturn = {};
const innerIterable = async x => {
const intermediateResult = await fn(x);
if (intermediateResult === false) return;
toReturn = _objectSpread2(_objectSpread2({}, toReturn), intermediateResult);
};
await mapAsync(innerIterable, list);
return toReturn;
}
function mapToObjectAsync(fn, list) {
if (arguments.length === 1) {
return async _list => mapToObjectAsyncFn(fn, _list);
}
return new Promise((resolve, reject) => {
mapToObjectAsyncFn(fn, list).then(resolve).catch(reject);
});
}
function maybe(ifRule, whenIf, whenElse) {
const whenIfInput = ifRule && type(whenIf) === 'Function' ? whenIf() : whenIf;
const whenElseInput = !ifRule && type(whenElse) === 'Function' ? whenElse() : whenElse;
return ifRule ? whenIfInput : whenElseInput;
}
function compose(...fns) {
if (fns.length === 0) {
throw new Error('compose requires at least one argument');
}
return (...args) => {
const list = fns.slice();
if (list.length > 0) {
const fn = list.pop();
let result = fn(...args);
while (list.length > 0) {
result = list.pop()(result);
}
return result;
}
};
}
function replaceFn(pattern, replacer, str) {
return str.replace(pattern, replacer);
}
const replace$1 = curry(replaceFn);
function sort(sortFn, list) {
if (arguments.length === 1) return _list => sort(sortFn, _list);
const clone = list.slice();
return clone.sort(sortFn);
}
function take(howMany, listOrString) {
if (arguments.length === 1) return _listOrString => take(howMany, _listOrString);
if (howMany < 0) return listOrString.slice();
if (typeof listOrString === 'string') return listOrString.slice(0, howMany);
return baseSlice(listOrString, 0, howMany);
}
const cache = {};
const normalizeObject = obj => {
const sortFn = (a, b) => a > b ? 1 : -1;
const willReturn = {};
compose(map(prop => willReturn[prop] = obj[prop]), sort(sortFn))(Object.keys(obj));
return willReturn;
};
const stringify = a => {
if (type(a) === 'String') {
return a;
} else if (['Function', 'Async'].includes(type(a))) {
const compacted = replace$1(/\s{1,}/g, ' ', a.toString());
return replace$1(/\s/g, '_', take(15, compacted));
} else if (type(a) === 'Object') {
return JSON.stringify(normalizeObject(a));
}
return JSON.stringify(a);
};
const generateProp = (fn, ...inputArguments) => {
let propString = '';
inputArguments.forEach(inputArgument => {
propString += `${stringify(inputArgument)}_`;
});
return `${propString}${stringify(fn)}`;
};
function memoize(fn, ...inputArguments) {
if (arguments.length === 1) {
return (...inputArgumentsHolder) => memoize(fn, ...inputArgumentsHolder);
}
const prop = generateProp(fn, ...inputArguments);
if (prop in cache) return cache[prop];
if (type(fn) === 'Async') {
return new Promise(resolve => {
fn(...inputArguments).then(result => {
cache[prop] = result;
resolve(result);
});
});
}
const result = fn(...inputArguments);
cache[prop] = result;
return result;
}
function nextIndex(index, list) {
return index >= list.length - 1 ? 0 : index + 1;
}
function partialCurry(fn, input) {
return rest => {
if (type(fn) === 'Async') {
return new Promise((resolve, reject) => {
fn(merge(rest, input)).then(resolve).catch(reject);
});
}
return fn(merge(rest, input));
};
}
async function whenObject(predicate, input) {
const yes = {};
const no = {};
Object.entries(input).forEach(([prop, value]) => {
if (predicate(value, prop)) {
yes[prop] = value;
} else {
no[prop] = value;
}
});
return [yes, no];
}
async function partitionAsyncFn(predicate, input) {
if (!_isArray(input)) return whenObject(predicate, input);
const yes = [];
const no = [];
for (const i in input) {
const predicateResult = await predicate(input[i], Number(i));
if (predicateResult) {
yes.push(input[i]);
} else {
no.push(input[i]);
}
}
return [yes, no];
}
function partitionAsync(predicate, list) {
if (arguments.length === 1) {
return async _list => partitionAsyncFn(predicate, _list);
}
return new Promise((resolve, reject) => {
partitionAsyncFn(predicate, list).then(resolve).catch(reject);
});
}
function pass(...inputs) {
return (...schemas) => any((x, i) => {
const schema = schemas[i] === undefined ? schemas[0] : schemas[i];
return !check(x, schema);
}, inputs) === false;
}
function pipeAsync(...inputArguments) {
return async function (startArgument) {
let argumentsToPass = startArgument;
while (inputArguments.length !== 0) {
const fn = inputArguments.shift();
const typeFn = type(fn);
if (typeFn === 'Async') {
argumentsToPass = await fn(argumentsToPass);
} else {
argumentsToPass = fn(argumentsToPass);
if (type(argumentsToPass) === 'Promise') {
argumentsToPass = await argumentsToPass;
}
}
}
return argumentsToPass;
};
}
function pipe(...fns) {
if (fns.length === 0) throw new Error('pipe requires at least one argument');
return (...args) => {
const list = fns.slice();
if (list.length > 0) {
const fn = list.shift();
let result = fn(...args);
while (list.length > 0) {
result = list.shift()(result);
}
return result;
}
};
}
function piped(...inputs) {
const [input, ...fnList] = inputs;
return pipe(...fnList)(input);
}
async function pipedAsync(...inputs) {
const [input, ...fnList] = inputs;
let argumentsToPass = input;
while (fnList.length !== 0) {
const fn = fnList.shift();
const typeFn = type(fn);
if (typeFn === 'Async') {
argumentsToPass = await fn(argumentsToPass);
} else {
argumentsToPass = fn(argumentsToPass);
}
}
return argumentsToPass;
}
function prevIndex(index, list) {
return index === 0 ? list.length - 1 : index - 1;
}
function produce(rules, input) {
if (arguments.length === 1) {
return _input => produce(rules, _input);
}
return map(singleRule => type(singleRule) === 'Object' ? produce(singleRule, input) : singleRule(input), rules);
}
function promisify({
condition,
input,
prop
}) {
return new Promise((resolve, reject) => {
if (type(condition) !== 'Async') {
return resolve({
type: prop,
payload: condition(input)
});
}
condition(input).then(result => {
resolve({
type: prop,
payload: result
});
}).catch(err => reject(err));
});
}
function produceFn(conditions, input) {
let asyncConditionsFlag = false;
for (const prop in conditions) {
if (asyncConditionsFlag === false && type(conditions[prop]) === 'Async') {
asyncConditionsFlag = true;
}
}
if (asyncConditionsFlag === false) {
const willReturn = {};
for (const prop in conditions) {
willReturn[prop] = conditions[prop](input);
}
return Promise.resolve(willReturn);
}
const promised = [];
for (const prop in conditions) {
const condition = conditions[prop];
promised.push(promisify({
input,
condition,
prop
}));
}
return new Promise((resolve, reject) => {
Promise.all(promised).then(results => {
const willReturn = {};
map(result => willReturn[result.type] = result.payload, results);
resolve(willReturn);
}).catch(err => reject(err));
});
}
function produceAsync(conditions, input) {
if (arguments.length === 1) {
return async _input => produceFn(conditions, _input);
}
return new Promise((resolve, reject) => {
produceFn(conditions, input).then(resolve).catch(reject);
});
}
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function remove(inputs, text) {
if (arguments.length === 1) {
return textHolder => remove(inputs, textHolder);
}
if (type(text) !== 'String') {
throw new Error(`R.remove requires string not ${type(text)}`);
}
if (type(inputs) !== 'Array') {
return replace$1(inputs, '', text);
}
let textCopy = text;
inputs.forEach(singleInput => {
textCopy = replace$1(singleInput, '', textCopy).trim();
});
return textCopy;
}
function removeIndex(list, index) {
if (arguments.length === 1) return _index => removeIndex(list, _index);
if (index <= 0) return list.slice(1);
if (index >= list.length - 1) return list.slice(0, list.length - 1);
return [...list.slice(0, index), ...list.slice(index + 1)];
}
function omit(propsToOmit, obj) {
if (arguments.length === 1) return _obj => omit(propsToOmit, _obj);
if (obj === null || obj === undefined) {
return undefined;
}
const propsToOmitValue = typeof propsToOmit === 'string' ? propsToOmit.split(',') : propsToOmit;
const willReturn = {};
for (const key in obj) {
if (!propsToOmitValue.includes(key)) {
willReturn[key] = obj[key];
}
}
return willReturn;
}
function renameProps(conditions, inputObject) {
if (arguments.length === 1) {
return inputObjectHolder => renameProps(conditions, inputObjectHolder);
}
const renamed = {};
Object.keys(conditions).forEach(condition => {
if (Object.keys(inputObject).includes(condition)) {
renamed[conditions[condition]] = inputObject[condition];
}
});
return merge(renamed, omit(Object.keys(conditions), inputObject));
}
function replaceAllFn(patterns, replacer, input) {
ok(patterns, replacer, input)(Array, String, String);
let text = input;
patterns.forEach(singlePattern => {
text = text.replace(singlePattern, replacer);
});
return text;
}
const replaceAll = curry(replaceAllFn);
function shuffle(arrayRaw) {
const array = arrayRaw.concat();
let counter = array.length;
while (counter > 0) {
const index = Math.floor(Math.random() * counter);
counter--;
const temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
}
function sortBy(sortFn, list) {
if (arguments.length === 1) return _list => sortBy(sortFn, _list);
const clone = list.slice();
return clone.sort((a, b) => {
const aSortResult = sortFn(a);
const bSortResult = sortFn(b);
if (aSortResult === bSortResult) return 0;
return aSortResult < bSortResult ? -1 : 1;
});
}
function sortByPath(sortPath, list) {
if (arguments.length === 1) return _list => sortByPath(sortPath, _list);
return sortBy(path(sortPath), list);
}
function singleSort(a, b, sortPaths) {
let toReturn = 0;
sortPaths.forEach(singlePath => {
if (toReturn !== 0) return;
const aResult = path(singlePath, a);
const bResult = path(singlePath, b);
if ([aResult, bResult].includes(undefined)) return;
if (aResult === bResult) return;
toReturn = aResult > bResult ? 1 : -1;
});
return toReturn;
}
function sortByProps(sortPaths, list) {
if (arguments.length === 1) return _list => sortByProps(sortPaths, _list);
const clone = list.slice();
clone.sort((a, b) => singleSort(a, b, sortPaths));
return clone;
}
function sortObject(predicate, obj) {
if (arguments.length === 1) {
return _obj => sortObject(predicate, _obj);
}
const keys = Object.keys(obj);
const sortedKeys = sort((a, b) => predicate(a, b, obj[a], obj[b]), keys);
const toReturn = {};
sortedKeys.forEach(singleKey => {
toReturn[singleKey] = obj[singleKey];
});
return toReturn;
}
const NO_MATCH_FOUND = Symbol ? Symbol('NO_MATCH_FOUND') : undefined;
const getMatchingKeyValuePair = (cases, testValue, defaultValue) => {
let iterationValue;
for (let index = 0; index < cases.length; index++) {
iterationValue = cases[index].test(testValue);
if (iterationValue !== NO_MATCH_FOUND) {
return iterationValue;
}
}
return defaultValue;
};
const isEqual = (testValue, matchValue) => {
const willReturn = typeof testValue === 'function' ? testValue(matchValue) : equals(testValue, matchValue);
return willReturn;
};
const is = (testValue, matchResult = true) => ({
key: testValue,
test: matchValue => isEqual(testValue, matchValue) ? matchResult : NO_MATCH_FOUND
});
class Switchem {
constructor(defaultValue, cases, willMatch) {
if (cases === undefined && willMatch === undefined) {
this.cases = [];
this.defaultValue = undefined;
this.willMatch = defaultValue;
} else {
this.cases = cases;
this.defaultValue = defaultValue;
this.willMatch = willMatch;
}
return this;
}
default(defaultValue) {
const holder = new Switchem(defaultValue, this.cases, this.willMatch);
return holder.match(this.willMatch);
}
is(testValue, matchResult) {
return new Switchem(this.defaultValue, [...this.cases, is(testValue, matchResult)], this.willMatch);
}
match(matchValue) {
return getMatchingKeyValuePair(this.cases, matchValue, this.defaultValue);
}
}
function switcher(input) {
return new Switchem(input);
}
function takeUntil(predicate, list) {
const toReturn = [];
let stopFlag = false;
let counter = -1;
while (stopFlag === false && counter++ < list.length - 1) {
if (predicate(list[counter])) {
stopFlag = true;
} else {
toReturn.push(list[counter]);
}
}
return toReturn;
}
async function tapAsyncFn(fn, input) {
await fn(input);
return input;
}
function tapAsync(fn, input) {
if (arguments.length === 1) {
return async _input => tapAsyncFn(fn, _input);
}
return new Promise((resolve, reject) => {
tapAsyncFn(fn, input).then(resolve).catch(reject);
});
}
function throttle(fn, ms) {
let wait = false;
return function (...input) {
if (!wait) {
fn.apply(null, input);
wait = true;
setTimeout(() => {
wait = false;
}, ms);
}
};
}
function toDecimal(number, charsAfterDecimalPoint = 2) {
return Number(parseFloat(String(number)).toFixed(charsAfterDecimalPoint));
}
function tryCatchAsync(fn, fallback) {
return (...inputs) => new Promise(resolve => {
fn(...inputs).then(resolve).catch(err => {
if (!isFunction(fallback)) {
return resolve(fallback);
}
if (!isPromise(fallback)) {
return resolve(fallback(err, ...inputs));
}
fallback(err, ...inputs).then(resolve).catch(resolve);
});
});
}
function updateObject(rules, obj) {
if (arguments.length === 1) return _obj => updateObject(rules, _obj);
let clone = _objectSpread2({}, obj);
rules.forEach(([objectPath, newValue]) => {
clone = assocPath(objectPath, newValue, clone);
});
return clone;
}
function isFalsy$1(input) {
return input === undefined || input === null || Number.isNaN(input) === true;
}
function defaultTo(defaultArgument, input) {
if (arguments.length === 1) {
return _input => defaultTo(defaultArgument, _input);
}
return isFalsy$1(input) ? defaultArgument : input;
}
function viewOrFn(fallback, lens, input) {
return defaultTo(fallback, view(lens, input));
}
const viewOr = curry(viewOrFn);
function wait(fn) {
return new Promise(resolve => {
fn.then(result => resolve([result, undefined])).catch(e => resolve([undefined, e]));
});
}
function range(start, end) {
if (arguments.length === 1) return _end => range(start, _end);
if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))) {
throw new TypeError('Both arguments to range must be numbers');
}
if (end < start) return [];
const len = end - start;
const willReturn = Array(len);
for (let i = 0; i < len; i++) {
willReturn[i] = start + i;
}
return willReturn;
}
function waitFor(condition, howLong, loops = 10) {
const typeCondition = type(condition);
const passPromise = typeCondition === 'Async';
const passFunction = typeCondition === 'Function';
const interval = Math.floor(howLong / loops);
if (!(passPromise || passFunction)) {
throw new Error('R.waitFor');
}
return async (...inputs) => {
for (const _ of range(0, loops)) {
const resultCondition = await condition(...inputs);
if (resultCondition === false) {
await delay(interval);
} else {
return resultCondition;
}
}
return false;
};
}
function xnor(x, y) {
if (arguments.length === 1) {
return _y => xnor(x, _y);
}
return Boolean(x && y || !x && !y);
}
function add(a, b) {
if (arguments.length === 1) return _b => add(a, _b);
return Number(a) + Number(b);
}
function adjustFn(index, replaceFn, list) {
const actualIndex = index < 0 ? list.length + index : index;
if (index >= list.length || actualIndex < 0) return list;
const clone = list.slice();
clone[actualIndex] = replaceFn(clone[actualIndex]);
return clone;
}
const adjust = curry(adjustFn);
function allPass(predicates) {
return input => {
let counter = 0;
while (counter < predicates.length) {
if (!predicates[counter](input)) {
return false;
}
counter++;
}
return true;
};
}
function always(x) {
return () => x;
}
function and(a, b) {
if (arguments.length === 1) return _b => and(a, _b);
return a && b;
}
function or(a, b) {
if (arguments.length === 1) return _b => or(a, _b);
return a || b;
}
function anyPass(predicates) {
return input => {
let coun