UNPKG

rubico

Version:

[a]synchronous functional programming

183 lines (160 loc) 4.68 kB
/** * Rubico v2.8.2 * https://rubico.land/ * * © Richard Yufei Tong, King of Software * Rubico may be freely distributed under the CFOSS 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, promises, ) { const length = array.length while (++index < length) { const predication = predicate(array[index]) if (isPromise(predication)) { promises.add(SelfReferencingPromise(predication)) } else if (predication) { return true } } while (promises.size > 0) { const [predication, promise] = await promiseRace(promises) promises.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, promises, maxConcurrency = 20, ) { let iteration = iterator.next() if (isPromise(iteration)) { iteration = await iteration } while (!iteration.done) { if (promises.size >= maxConcurrency) { const [predication, promise] = await promiseRace(promises) promises.delete(promise) if (predication) { return true } } const predication = predicate(iteration.value) if (isPromise(predication)) { promises.add(SelfReferencingPromise(predication)) } else if (predication) { return true } iteration = iterator.next() if (isPromise(iteration)) { iteration = await iteration } } while (promises.size > 0) { const [predication, promise] = await promiseRace(promises) promises.delete(promise) if (predication) { return true } } return false } const iteratorSome = function (iterator, predicate) { for (const element of iterator) { const predication = predicate(element) if (isPromise(predication)) { return asyncIteratorSome( iterator, predicate, new Set([SelfReferencingPromise(predication)])) } if (predication) { return true } } return false } const reducerAnySync = predicate => function anyReducer(result, element) { return result ? true : predicate(element) } const reducerSome = predicate => function anyReducer(result, element) { return result === true ? result : isPromise(result) ? result.then(curry2(reducerAnySync(predicate), __, element)) : result ? true : predicate(element) } 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