rubico
Version:
[a]synchronous functional programming
104 lines (88 loc) • 2.37 kB
JavaScript
/**
* 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 promiseAll = Promise.all.bind(Promise)
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 catcherApply = function (catcher, err, args) {
return catcher(err, ...args)
}
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
}
// _tryCatch(tryer function, catcher function, args Array) -> Promise
const _tryCatch = function (tryer, catcher, args) {
try {
const result = tryer(...args)
return isPromise(result)
? result.catch(curry3(catcherApply, catcher, __, args))
: result
} catch (error) {
return catcher(error, ...args)
}
}
const tryCatch = function (...args) {
if (args.length > 2) {
const catcher = args.pop(),
tryer = args.pop()
if (areAnyValuesPromises(args)) {
return promiseAll(args)
.then(curry3(_tryCatch, tryer, catcher, __))
}
return _tryCatch(tryer, catcher, args)
}
const tryer = args[0],
catcher = args[1]
return function tryCatcher(...args) {
return _tryCatch(tryer, catcher, args)
}
}
export default tryCatch