// @NOTE catches uncaught promises, errors, exceptions, handles like a boss
// const log = require('fliplog')
// log.registerCatch()
// --- utils - for use as-a-snippet ---
const isArray = Array.isArray
const isNill = x => x === null || x === undefined
const isReal = x => !isNill(x) && !Number.isNaN(x)
const flatten = x => [].concat(...x)
const hasLength = x => x && isArray(x) && x.length !== 0
function castArgumentsToArray() {
const len = arguments.length
const args = new Array(len)
for (let i = 0; i < args.length; i++) args[i] = arguments[i]
return args
}
// function flip(fn) {
// return function() {
// return fn.apply(this, castArgumentsToArray(...arguments).reverse())
// }
// }
function flip2(fn: Function) {
return function(...argumentz: any[]) {
const args = argumentz.reverse()
const one = args[1]
const zero = args[0]
let flipped = [one, zero]
// if (!isNill(one) && !isNill(zero)) flipped = [one, zero]
// else if (isNill(one)) flipped = [zero, one]
// else flipped = [one, zero]
flipped = flipped
return fn.apply(this, flipped)
}
}
// --- logic ---
function wrapRequest(fn: Function, ...args: any[]) {
// @NOTE uses scoped `fn` here
// return function to call with arguments, unless we pass in arguments
function promiseFactory(this: any) {
// setup easy functions to make the promis sexier
let response = []
const update = (error = null, res = null) => {
response = flatten([error, res])
return Promise.resolve(response)
}
const updateSuccess = flip2(update)
const updateError = update
// @NOTE important that try catch is inside of the promise
return new Promise((resolve, reject) => {
try {
const result = fn.apply(this, arguments)
return resolve(result)
} catch (error) {
return reject(error)
}
})
.catch(error => updateError(error))
.then(res => updateSuccess(res))
}
if (isReal(args) && hasLength(args)) return promiseFactory.apply(this, args)
else return promiseFactory
}
// const wrapThenLog = async(fn, arg) => {
// try {
// const wrapper = wrapRequest(fn)
// const result = await wrapper(arg)
// const [error, response] = result
// console.log({[fn.name]: [error, response]})
// }
// catch (e) {
// console.log(e)
// }
// }
export { wrapRequest as asyncWrap }
export default wrapRequest