UNPKG

rubico

Version:

[a]synchronous functional programming

182 lines (161 loc) 4.54 kB
/** * rubico v2.6.2 * https://github.com/a-synchronous/rubico * (c) 2019-2024 Richard Tong * rubico may be freely distributed under the MIT license. */ const isPromise = value => value != null && typeof value.then == 'function' const isArray = Array.isArray const memoizeCappedUnary = function (func, cap) { const cache = new Map(), memoized = function memoized(arg0) { if (cache.has(arg0)) { return cache.get(arg0) } const result = func(arg0) cache.set(arg0, result) if (cache.size > cap) { cache.clear() } return result } memoized.cache = cache return memoized } // a[0].b.c const pathDelimiters = /[.|[|\]]+/ const parsePropertyPath = function (pathString) { const pathStringLastIndex = pathString.length - 1, firstChar = pathString[0], lastChar = pathString[pathStringLastIndex], isFirstCharLeftBracket = firstChar == '[', isLastCharRightBracket = lastChar == ']' if (isFirstCharLeftBracket && isLastCharRightBracket) { return pathString.slice(1, pathStringLastIndex).split(pathDelimiters) } else if (isFirstCharLeftBracket) { return pathString.slice(1).split(pathDelimiters) } else if (isLastCharRightBracket) { return pathString.slice(0, pathStringLastIndex).split(pathDelimiters) } return pathString.split(pathDelimiters) } // memoized version of parsePropertyPath, max cache size 500 const memoizedCappedParsePropertyPath = memoizeCappedUnary(parsePropertyPath, 500) const propertyPathToArray = path => isArray(path) ? path : typeof path == 'string' ? memoizedCappedParsePropertyPath(path) : [path] const getByPath = function (value, path) { const propertyPathArray = propertyPathToArray(path), length = propertyPathArray.length let index = -1, result = value while (++index < length) { result = result[propertyPathArray[index]] if (result == null) { return undefined } } return result } const deleteByPath = function (object, path) { if (object == null) { return undefined } const pathArray = propertyPathToArray(path), lengthMinusOne = pathArray.length - 1 let index = -1, result = object while (++index < lengthMinusOne) { result = result[pathArray[index]] if (result == null) { return undefined } } const property = pathArray[index] if (result != null && property in result) { delete result[property] } return undefined } // objectCopyDeep(array Array) -> copied Array const objectCopyDeep = function (object) { const result = {} for (const key in object) { const item = object[key] if (isArray(item)) { result[key] = arrayCopyDeep(item) } else if (item != null && item.constructor == Object) { result[key] = objectCopyDeep(item) } else { result[key] = item } } return result } // arrayCopyDeep(array Array) -> copied Array const arrayCopyDeep = function (array) { const length = array.length, result = [] let index = -1 while (++index < length) { const item = array[index] if (isArray(item)) { result[index] = arrayCopyDeep(item) } else if (item != null && item.constructor == Object) { result[index] = objectCopyDeep(item) } else { result[index] = item } } return result } const copyDeep = function (value) { if (isArray(value)) { return arrayCopyDeep(value) } if (value == null) { return value } if (value.constructor == Object) { return objectCopyDeep(value) } return value } const __ = Symbol.for('placeholder') // argument resolver for curry2 const curry2ResolveArg0 = ( baseFunc, arg1, ) => function arg0Resolver(arg0) { return baseFunc(arg0, arg1) } // argument resolver for curry2 const curry2ResolveArg1 = ( baseFunc, arg0, ) => function arg1Resolver(arg1) { return baseFunc(arg0, arg1) } const curry2 = function (baseFunc, arg0, arg1) { return arg0 == __ ? curry2ResolveArg0(baseFunc, arg1) : curry2ResolveArg1(baseFunc, arg0) } // _omit(source Object, paths Array<string>) -> result Object const _omit = function (source, paths) { const pathsLength = paths.length, result = copyDeep(source) let pathsIndex = -1 while (++pathsIndex < pathsLength) { deleteByPath(result, paths[pathsIndex]) } return result } const omit = function (arg0, arg1) { if (arg1 == null) { return curry2(_omit, __, arg0) } if (isPromise(arg0)) { return arg0.then(curry2(_omit, __, arg1)) } return _omit(arg0, arg1) } export default omit