Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / run-async / index.js
1 'use strict';
2
3 function isPromise(obj) {
4   return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
5 }
6
7 /**
8  * Return a function that will run a function asynchronously or synchronously
9  *
10  * example:
11  * runAsync(wrappedFunction, callback)(...args);
12  *
13  * @param   {Function} func  Function to run
14  * @param   {Function} cb    Callback function passed the `func` returned value
15  * @return  {Function(arguments)} Arguments to pass to `func`. This function will in turn
16  *                                return a Promise (Node >= 0.12) or call the callbacks.
17  */
18
19 var runAsync = module.exports = function (func, cb) {
20   cb = cb || function () {};
21
22   return function () {
23
24     var args = arguments;
25
26     var promise = new Promise(function (resolve, reject) {
27       var resolved = false;
28       const wrappedResolve = function (value) {
29         if (resolved) {
30           console.warn('Run-async promise already resolved.')
31         }
32         resolved = true;
33         resolve(value);
34       }
35
36       var rejected = false;
37       const wrappedReject = function (value) {
38         if (rejected) {
39           console.warn('Run-async promise already rejected.')
40         }
41         rejected = true;
42         reject(value);
43       }
44
45       var usingCallback = false;
46       var callbackConflict = false;
47       var contextEnded = false;
48
49       var answer = func.apply({
50         async: function () {
51           if (contextEnded) {
52             console.warn('Run-async async() called outside a valid run-async context, callback will be ignored.');
53             return function() {};
54           }
55           if (callbackConflict) {
56             console.warn('Run-async wrapped function (async) returned a promise.\nCalls to async() callback can have unexpected results.');
57           }
58           usingCallback = true;
59           return function (err, value) {
60             if (err) {
61               wrappedReject(err);
62             } else {
63               wrappedResolve(value);
64             }
65           };
66         }
67       }, Array.prototype.slice.call(args));
68
69       if (usingCallback) {
70         if (isPromise(answer)) {
71           console.warn('Run-async wrapped function (sync) returned a promise but async() callback must be executed to resolve.');
72         }
73       } else {
74         if (isPromise(answer)) {
75           callbackConflict = true;
76           answer.then(wrappedResolve, wrappedReject);
77         } else {
78           wrappedResolve(answer);
79         }
80       }
81       contextEnded = true;
82     });
83
84     promise.then(cb.bind(null, null), cb);
85
86     return promise;
87   }
88 };
89
90 runAsync.cb = function (func, cb) {
91   return runAsync(function () {
92     var args = Array.prototype.slice.call(arguments);
93     if (args.length === func.length - 1) {
94       args.push(this.async());
95     }
96     return func.apply(this, args);
97   }, cb);
98 };