UNPKG

rubico

Version:

[a]synchronous functional programming

179 lines (153 loc) 4.67 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. */ (function (root, maxBy) { if (typeof module == 'object') (module.exports = maxBy) // CommonJS else if (typeof define == 'function') define(() => maxBy) // AMD else (root.maxBy = maxBy) // Browser }(typeof globalThis == 'object' ? globalThis : this, (function () { 'use strict' const isPromise = value => value != null && typeof value.then == 'function' const __ = Symbol.for('placeholder') // argument resolver for curry3 const curry3ResolveArg0 = ( baseFunc, arg1, arg2, ) => function arg0Resolver(arg0) { return baseFunc(arg0, arg1, arg2) } // argument resolver for curry3 const curry3ResolveArg1 = ( baseFunc, arg0, arg2, ) => function arg1Resolver(arg1) { return baseFunc(arg0, arg1, arg2) } // argument resolver for curry3 const curry3ResolveArg2 = ( baseFunc, arg0, arg1, ) => function arg2Resolver(arg2) { return baseFunc(arg0, arg1, arg2) } const curry3 = function (baseFunc, arg0, arg1, arg2) { if (arg0 == __) { return curry3ResolveArg0(baseFunc, arg1, arg2) } if (arg1 == __) { return curry3ResolveArg1(baseFunc, arg0, arg2) } return curry3ResolveArg2(baseFunc, arg0, arg1) } const isArray = Array.isArray const isObject = value => { if (value == null) { return false } const typeofValue = typeof value return (typeofValue == 'object') || (typeofValue == 'function') } 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 } // _get(object Object, path string, defaultValue function|any) const _get = function (object, path, defaultValue) { const result = object == null ? undefined : getByPath(object, path) return result === undefined ? typeof defaultValue == 'function' ? defaultValue(object) : defaultValue : result } const get = function (arg0, arg1, arg2) { if (typeof arg0 == 'string' || typeof arg0 == 'number' || isArray(arg0)) { return curry3(_get, __, arg0, arg1) } if (isPromise(arg0)) { return arg0.then(curry3(_get, __, arg1, arg2)) } return _get(arg0, arg1, arg2) } // 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) } const _maxBy = function (array, path) { const length = array.length const getter = get(path) let index = 0 let maxItem = array[index] while (++index < length) { const item = array[index] if (getter(item) > getter(maxItem)) { maxItem = item } } return maxItem } const maxBy = function (...args) { if (args.length > 1) { return _maxBy(...args) } return curry2(_maxBy, __, args[0]) } return maxBy }())))