UNPKG

1.85 kBPlain TextView Raw
1// Import
2import { isError } from 'https://unpkg.com/typechecker@^7.17.0/edition-deno/index.ts'
3
4// Handle success case
5function onSuccess(value: any) {
6 // Reject if an error was returned
7 if (isError(value)) return Promise.reject(value)
8 // Success case, so return the value
9 return value
10}
11
12/**
13 * Ambidextrously execute the method with the passed arguments.
14 * If method.length > args.length, then ambi provides the method with a completion callback as the last expected argument.
15 * @param method A method, that can either resolve synchronously, via a promise, or via a callback.
16 * @param args The arguments to provide the function.
17 * @returns The determined result.
18 */
19export default function ambi<Result>(
20 method: Function,
21 ...args: any
22): Promise<Result> {
23 /*
24 Different ways functions can be called:
25 ambi(function(a,next){next(null, a)}, a)
26 > method.length > args.length
27 > next will be provided automatically
28 ambi(function(a){return a}, a)
29 > method.length = args.length
30 > no argument changes by ambi
31 ambi(function(a){return a}, a, b)
32 > method.length < args.length
33 > no argument changes by ambi
34 */
35 try {
36 // Inject a completion callback
37 if (method.length > args.length) {
38 return new Promise(function (resolve, reject) {
39 const xargs = args
40 .slice()
41 // add the difference as undefined values
42 .concat(new Array(method.length - args.length - 1))
43 // add the completion callback
44 .concat([
45 function ambiCallback(err?: Error, ...args: any) {
46 if (err) return reject(err)
47 if (args.length === 1) return resolve(args[0])
48 return resolve(args)
49 },
50 ])
51 method(...xargs)
52 }).then(onSuccess)
53 }
54 // Execute without a completion callback
55 else {
56 return Promise.resolve(method(...args)).then(onSuccess)
57 }
58 } catch (err) {
59 return Promise.reject(err)
60 }
61}