UNPKG

rubico

Version:

[a]synchronous functional programming

231 lines (198 loc) 5.48 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, or) { if (typeof module == 'object') (module.exports = or) // CommonJS else if (typeof define == 'function') define(() => or) // AMD else (root.or = or) // Browser }(typeof globalThis == 'object' ? globalThis : this, (function () { 'use strict' const promiseAll = Promise.all.bind(Promise) const isPromise = value => value != null && typeof value.then == 'function' const isArray = Array.isArray const areAnyValuesPromises = function (values) { if (isArray(values)) { const length = values.length let index = -1 while (++index < length) { const value = values[index] if (isPromise(value)) { return true } } return false } for (const key in values) { const value = values[key] if (isPromise(value)) { return true } } return false } 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) } // 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) } // argument resolver for curryArgs2 const curryArgs2ResolveArgs0 = ( baseFunc, arg1, arg2, ) => function args0Resolver(...args) { return baseFunc(args, arg1) } // argument resolver for curryArgs2 const curryArgs2ResolveArgs1 = ( baseFunc, arg0, arg2, ) => function arg1Resolver(...args) { return baseFunc(arg0, args) } const curryArgs2 = function (baseFunc, arg0, arg1) { if (arg0 == __) { return curryArgs2ResolveArgs0(baseFunc, arg1) } return curryArgs2ResolveArgs1(baseFunc, arg0) } const thunkConditional = ( conditionalExpression, thunkOnTruthy, thunkOnFalsy, ) => conditionalExpression ? thunkOnTruthy() : thunkOnFalsy() const areAllValuesNonfunctions = function (values) { if (isArray(values)) { const length = values.length let index = -1 while (++index < length) { if (typeof values[index] == 'function') { return false } } return true } for (const key in values) { if (typeof values[key] == 'function') { return false } } return true } const thunkify2 = (func, arg0, arg1) => function thunk() { return func(arg0, arg1) } const thunkify3 = (func, arg0, arg1, arg2) => function thunk() { return func(arg0, arg1, arg2) } const always = value => function getter() { return value } const areAnyNonfunctionsTruthy = function (predicates, index) { const length = predicates.length while (++index < length) { const predicate = predicates[index] if (isPromise(predicate)) { return predicate.then(curry3( thunkConditional, __, always(true), thunkify2(areAnyNonfunctionsTruthy, predicates, index), )) } if (predicate) { return true } } return false } const asyncAreAnyPredicatesTruthy = async function (args, predicates, index) { const length = predicates.length while (++index < length) { let predicate = predicates[index] if (typeof predicate == 'function') { predicate = predicate(...args) } if (isPromise(predicate)) { predicate = await predicate } if (predicate) { return true } } return false } // areAnyPredicatesTruthy(args Array, predicates Array<function>) -> Promise|boolean const areAnyPredicatesTruthy = function (args, predicates) { const length = predicates.length let index = -1 while (++index < length) { let predicate = predicates[index] if (typeof predicate == 'function') { predicate = predicate(...args) } if (isPromise(predicate)) { return predicate.then(curry3( thunkConditional, __, always(true), thunkify3(asyncAreAnyPredicatesTruthy, args, predicates, index), )) } if (predicate) { return true } } return false } const or = function (...args) { const predicatesOrValues = args.pop() if (areAllValuesNonfunctions(predicatesOrValues)) { return areAnyNonfunctionsTruthy(predicatesOrValues, -1) } if (args.length == 0) { return curryArgs2(areAnyPredicatesTruthy, __, predicatesOrValues) } if (areAnyValuesPromises(args)) { return promiseAll(args) .then(curry2(areAnyPredicatesTruthy, __, predicatesOrValues)) } return areAnyPredicatesTruthy(args, predicatesOrValues) } return or }())))