UNPKG

rubico

Version:

[a]synchronous functional programming

182 lines (159 loc) 4.76 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 __ = 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) } const isArray = Array.isArray const objectValues = Object.values const SelfReferencingPromise = function (basePromise) { const promise = basePromise.then(res => [res, promise]) return promise } const promiseRace = Promise.race.bind(Promise) const asyncArraySome = async function ( array, predicate, index, promisesInFlight, ) { const length = array.length while (++index < length) { const predication = predicate(array[index]) if (isPromise(predication)) { promisesInFlight.add(SelfReferencingPromise(predication)) } else if (predication) { return true } } while (promisesInFlight.size > 0) { const [predication, promise] = await promiseRace(promisesInFlight) promisesInFlight.delete(promise) if (predication) { return true } } return false } const arraySome = function (array, predicate) { const length = array.length let index = -1 while (++index < length) { const predication = predicate(array[index]) if (isPromise(predication)) { return asyncArraySome( array, predicate, index, new Set([SelfReferencingPromise(predication)])) } if (predication) { return true } } return false } const asyncIteratorSome = async function ( iterator, predicate, promisesInFlight, maxConcurrency = 20, ) { let iteration = iterator.next() if (isPromise(iteration)) { iteration = await iteration } while (!iteration.done) { if (promisesInFlight.size >= maxConcurrency) { const [predication, promise] = await promiseRace(promisesInFlight) promisesInFlight.delete(promise) if (predication) { return true } } const predication = predicate(iteration.value) if (isPromise(predication)) { promisesInFlight.add(SelfReferencingPromise(predication)) } else if (predication) { return true } iteration = iterator.next() if (isPromise(iteration)) { iteration = await iteration } } while (promisesInFlight.size > 0) { const [predication, promise] = await promiseRace(promisesInFlight) promisesInFlight.delete(promise) if (predication) { return true } } return false } const iteratorSome = function (iterator, predicate) { for (const item of iterator) { const predication = predicate(item) if (isPromise(predication)) { return asyncIteratorSome( iterator, predicate, new Set([SelfReferencingPromise(predication)])) } if (predication) { return true } } return false } const reducerAnySync = predicate => function anyReducer(result, item) { return result ? true : predicate(item) } const reducerSome = predicate => function anyReducer(result, item) { return result === true ? result : isPromise(result) ? result.then(curry2(reducerAnySync(predicate), __, item)) : result ? true : predicate(item) } const symbolIterator = Symbol.iterator const symbolAsyncIterator = Symbol.asyncIterator // _some(collection Array|Iterable|AsyncIterable|{ reduce: function }|Object, predicate function) -> Promise|boolean const _some = function (collection, predicate) { if (isArray(collection)) { return arraySome(collection, predicate) } if (collection == null) { return predicate(collection) } if (typeof collection[symbolIterator] == 'function') { return iteratorSome(collection[symbolIterator](), predicate) } if (typeof collection[symbolAsyncIterator] == 'function') { return asyncIteratorSome( collection[symbolAsyncIterator](), predicate, new Set() ) } if (typeof collection.reduce == 'function') { return collection.reduce(reducerSome(predicate), false) } if (collection.constructor == Object) { return arraySome(objectValues(collection), predicate) } return predicate(collection) } const some = function (arg0, arg1) { if (typeof arg0 == 'function') { return curry2(_some, __, arg0) } return isPromise(arg0) ? arg0.then(curry2(_some, __, arg1)) : _some(arg0, arg1) } export default some