source: frontend/node_modules/async/dist/async.mjs

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 195.6 KB
Line 
1/**
2 * Creates a continuation function with some arguments already applied.
3 *
4 * Useful as a shorthand when combined with other control flow functions. Any
5 * arguments passed to the returned function are added to the arguments
6 * originally passed to apply.
7 *
8 * @name apply
9 * @static
10 * @memberOf module:Utils
11 * @method
12 * @category Util
13 * @param {Function} fn - The function you want to eventually apply all
14 * arguments to. Invokes with (arguments...).
15 * @param {...*} arguments... - Any number of arguments to automatically apply
16 * when the continuation is called.
17 * @returns {Function} the partially-applied function
18 * @example
19 *
20 * // using apply
21 * async.parallel([
22 * async.apply(fs.writeFile, 'testfile1', 'test1'),
23 * async.apply(fs.writeFile, 'testfile2', 'test2')
24 * ]);
25 *
26 *
27 * // the same process without using apply
28 * async.parallel([
29 * function(callback) {
30 * fs.writeFile('testfile1', 'test1', callback);
31 * },
32 * function(callback) {
33 * fs.writeFile('testfile2', 'test2', callback);
34 * }
35 * ]);
36 *
37 * // It's possible to pass any number of additional arguments when calling the
38 * // continuation:
39 *
40 * node> var fn = async.apply(sys.puts, 'one');
41 * node> fn('two', 'three');
42 * one
43 * two
44 * three
45 */
46function apply(fn, ...args) {
47 return (...callArgs) => fn(...args,...callArgs);
48}
49
50function initialParams (fn) {
51 return function (...args/*, callback*/) {
52 var callback = args.pop();
53 return fn.call(this, args, callback);
54 };
55}
56
57/* istanbul ignore file */
58
59var hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;
60var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
61var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
62
63function fallback(fn) {
64 setTimeout(fn, 0);
65}
66
67function wrap(defer) {
68 return (fn, ...args) => defer(() => fn(...args));
69}
70
71var _defer$1;
72
73if (hasQueueMicrotask) {
74 _defer$1 = queueMicrotask;
75} else if (hasSetImmediate) {
76 _defer$1 = setImmediate;
77} else if (hasNextTick) {
78 _defer$1 = process.nextTick;
79} else {
80 _defer$1 = fallback;
81}
82
83var setImmediate$1 = wrap(_defer$1);
84
85/**
86 * Take a sync function and make it async, passing its return value to a
87 * callback. This is useful for plugging sync functions into a waterfall,
88 * series, or other async functions. Any arguments passed to the generated
89 * function will be passed to the wrapped function (except for the final
90 * callback argument). Errors thrown will be passed to the callback.
91 *
92 * If the function passed to `asyncify` returns a Promise, that promises's
93 * resolved/rejected state will be used to call the callback, rather than simply
94 * the synchronous return value.
95 *
96 * This also means you can asyncify ES2017 `async` functions.
97 *
98 * @name asyncify
99 * @static
100 * @memberOf module:Utils
101 * @method
102 * @alias wrapSync
103 * @category Util
104 * @param {Function} func - The synchronous function, or Promise-returning
105 * function to convert to an {@link AsyncFunction}.
106 * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
107 * invoked with `(args..., callback)`.
108 * @example
109 *
110 * // passing a regular synchronous function
111 * async.waterfall([
112 * async.apply(fs.readFile, filename, "utf8"),
113 * async.asyncify(JSON.parse),
114 * function (data, next) {
115 * // data is the result of parsing the text.
116 * // If there was a parsing error, it would have been caught.
117 * }
118 * ], callback);
119 *
120 * // passing a function returning a promise
121 * async.waterfall([
122 * async.apply(fs.readFile, filename, "utf8"),
123 * async.asyncify(function (contents) {
124 * return db.model.create(contents);
125 * }),
126 * function (model, next) {
127 * // `model` is the instantiated model object.
128 * // If there was an error, this function would be skipped.
129 * }
130 * ], callback);
131 *
132 * // es2017 example, though `asyncify` is not needed if your JS environment
133 * // supports async functions out of the box
134 * var q = async.queue(async.asyncify(async function(file) {
135 * var intermediateStep = await processFile(file);
136 * return await somePromise(intermediateStep)
137 * }));
138 *
139 * q.push(files);
140 */
141function asyncify(func) {
142 if (isAsync(func)) {
143 return function (...args/*, callback*/) {
144 const callback = args.pop();
145 const promise = func.apply(this, args);
146 return handlePromise(promise, callback)
147 }
148 }
149
150 return initialParams(function (args, callback) {
151 var result;
152 try {
153 result = func.apply(this, args);
154 } catch (e) {
155 return callback(e);
156 }
157 // if result is Promise object
158 if (result && typeof result.then === 'function') {
159 return handlePromise(result, callback)
160 } else {
161 callback(null, result);
162 }
163 });
164}
165
166function handlePromise(promise, callback) {
167 return promise.then(value => {
168 invokeCallback(callback, null, value);
169 }, err => {
170 invokeCallback(callback, err && (err instanceof Error || err.message) ? err : new Error(err));
171 });
172}
173
174function invokeCallback(callback, error, value) {
175 try {
176 callback(error, value);
177 } catch (err) {
178 setImmediate$1(e => { throw e }, err);
179 }
180}
181
182function isAsync(fn) {
183 return fn[Symbol.toStringTag] === 'AsyncFunction';
184}
185
186function isAsyncGenerator(fn) {
187 return fn[Symbol.toStringTag] === 'AsyncGenerator';
188}
189
190function isAsyncIterable(obj) {
191 return typeof obj[Symbol.asyncIterator] === 'function';
192}
193
194function wrapAsync(asyncFn) {
195 if (typeof asyncFn !== 'function') throw new Error('expected a function')
196 return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
197}
198
199// conditionally promisify a function.
200// only return a promise if a callback is omitted
201function awaitify (asyncFn, arity) {
202 if (!arity) arity = asyncFn.length;
203 if (!arity) throw new Error('arity is undefined')
204 function awaitable (...args) {
205 if (typeof args[arity - 1] === 'function') {
206 return asyncFn.apply(this, args)
207 }
208
209 return new Promise((resolve, reject) => {
210 args[arity - 1] = (err, ...cbArgs) => {
211 if (err) return reject(err)
212 resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
213 };
214 asyncFn.apply(this, args);
215 })
216 }
217
218 return awaitable
219}
220
221function applyEach$1 (eachfn) {
222 return function applyEach(fns, ...callArgs) {
223 const go = awaitify(function (callback) {
224 var that = this;
225 return eachfn(fns, (fn, cb) => {
226 wrapAsync(fn).apply(that, callArgs.concat(cb));
227 }, callback);
228 });
229 return go;
230 };
231}
232
233function _asyncMap(eachfn, arr, iteratee, callback) {
234 arr = arr || [];
235 var results = [];
236 var counter = 0;
237 var _iteratee = wrapAsync(iteratee);
238
239 return eachfn(arr, (value, _, iterCb) => {
240 var index = counter++;
241 _iteratee(value, (err, v) => {
242 results[index] = v;
243 iterCb(err);
244 });
245 }, err => {
246 callback(err, results);
247 });
248}
249
250function isArrayLike(value) {
251 return value &&
252 typeof value.length === 'number' &&
253 value.length >= 0 &&
254 value.length % 1 === 0;
255}
256
257// A temporary value used to identify if the loop should be broken.
258// See #1064, #1293
259const breakLoop = {};
260
261function once(fn) {
262 function wrapper (...args) {
263 if (fn === null) return;
264 var callFn = fn;
265 fn = null;
266 callFn.apply(this, args);
267 }
268 Object.assign(wrapper, fn);
269 return wrapper
270}
271
272function getIterator (coll) {
273 return coll[Symbol.iterator] && coll[Symbol.iterator]();
274}
275
276function createArrayIterator(coll) {
277 var i = -1;
278 var len = coll.length;
279 return function next() {
280 return ++i < len ? {value: coll[i], key: i} : null;
281 }
282}
283
284function createES2015Iterator(iterator) {
285 var i = -1;
286 return function next() {
287 var item = iterator.next();
288 if (item.done)
289 return null;
290 i++;
291 return {value: item.value, key: i};
292 }
293}
294
295function createObjectIterator(obj) {
296 var okeys = obj ? Object.keys(obj) : [];
297 var i = -1;
298 var len = okeys.length;
299 return function next() {
300 var key = okeys[++i];
301 if (key === '__proto__') {
302 return next();
303 }
304 return i < len ? {value: obj[key], key} : null;
305 };
306}
307
308function createIterator(coll) {
309 if (isArrayLike(coll)) {
310 return createArrayIterator(coll);
311 }
312
313 var iterator = getIterator(coll);
314 return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
315}
316
317function onlyOnce(fn) {
318 return function (...args) {
319 if (fn === null) throw new Error("Callback was already called.");
320 var callFn = fn;
321 fn = null;
322 callFn.apply(this, args);
323 };
324}
325
326// for async generators
327function asyncEachOfLimit(generator, limit, iteratee, callback) {
328 let done = false;
329 let canceled = false;
330 let awaiting = false;
331 let running = 0;
332 let idx = 0;
333
334 function replenish() {
335 //console.log('replenish')
336 if (running >= limit || awaiting || done) return
337 //console.log('replenish awaiting')
338 awaiting = true;
339 generator.next().then(({value, done: iterDone}) => {
340 //console.log('got value', value)
341 if (canceled || done) return
342 awaiting = false;
343 if (iterDone) {
344 done = true;
345 if (running <= 0) {
346 //console.log('done nextCb')
347 callback(null);
348 }
349 return;
350 }
351 running++;
352 iteratee(value, idx, iterateeCallback);
353 idx++;
354 replenish();
355 }).catch(handleError);
356 }
357
358 function iterateeCallback(err, result) {
359 //console.log('iterateeCallback')
360 running -= 1;
361 if (canceled) return
362 if (err) return handleError(err)
363
364 if (err === false) {
365 done = true;
366 canceled = true;
367 return
368 }
369
370 if (result === breakLoop || (done && running <= 0)) {
371 done = true;
372 //console.log('done iterCb')
373 return callback(null);
374 }
375 replenish();
376 }
377
378 function handleError(err) {
379 if (canceled) return
380 awaiting = false;
381 done = true;
382 callback(err);
383 }
384
385 replenish();
386}
387
388var eachOfLimit$2 = (limit) => {
389 return (obj, iteratee, callback) => {
390 callback = once(callback);
391 if (limit <= 0) {
392 throw new RangeError('concurrency limit cannot be less than 1')
393 }
394 if (!obj) {
395 return callback(null);
396 }
397 if (isAsyncGenerator(obj)) {
398 return asyncEachOfLimit(obj, limit, iteratee, callback)
399 }
400 if (isAsyncIterable(obj)) {
401 return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)
402 }
403 var nextElem = createIterator(obj);
404 var done = false;
405 var canceled = false;
406 var running = 0;
407 var looping = false;
408
409 function iterateeCallback(err, value) {
410 if (canceled) return
411 running -= 1;
412 if (err) {
413 done = true;
414 callback(err);
415 }
416 else if (err === false) {
417 done = true;
418 canceled = true;
419 }
420 else if (value === breakLoop || (done && running <= 0)) {
421 done = true;
422 return callback(null);
423 }
424 else if (!looping) {
425 replenish();
426 }
427 }
428
429 function replenish () {
430 looping = true;
431 while (running < limit && !done) {
432 var elem = nextElem();
433 if (elem === null) {
434 done = true;
435 if (running <= 0) {
436 callback(null);
437 }
438 return;
439 }
440 running += 1;
441 iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
442 }
443 looping = false;
444 }
445
446 replenish();
447 };
448};
449
450/**
451 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
452 * time.
453 *
454 * @name eachOfLimit
455 * @static
456 * @memberOf module:Collections
457 * @method
458 * @see [async.eachOf]{@link module:Collections.eachOf}
459 * @alias forEachOfLimit
460 * @category Collection
461 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
462 * @param {number} limit - The maximum number of async operations at a time.
463 * @param {AsyncFunction} iteratee - An async function to apply to each
464 * item in `coll`. The `key` is the item's key, or index in the case of an
465 * array.
466 * Invoked with (item, key, callback).
467 * @param {Function} [callback] - A callback which is called when all
468 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
469 * @returns {Promise} a promise, if a callback is omitted
470 */
471function eachOfLimit(coll, limit, iteratee, callback) {
472 return eachOfLimit$2(limit)(coll, wrapAsync(iteratee), callback);
473}
474
475var eachOfLimit$1 = awaitify(eachOfLimit, 4);
476
477// eachOf implementation optimized for array-likes
478function eachOfArrayLike(coll, iteratee, callback) {
479 callback = once(callback);
480 var index = 0,
481 completed = 0,
482 {length} = coll,
483 canceled = false;
484 if (length === 0) {
485 callback(null);
486 }
487
488 function iteratorCallback(err, value) {
489 if (err === false) {
490 canceled = true;
491 }
492 if (canceled === true) return
493 if (err) {
494 callback(err);
495 } else if ((++completed === length) || value === breakLoop) {
496 callback(null);
497 }
498 }
499
500 for (; index < length; index++) {
501 iteratee(coll[index], index, onlyOnce(iteratorCallback));
502 }
503}
504
505// a generic version of eachOf which can handle array, object, and iterator cases.
506function eachOfGeneric (coll, iteratee, callback) {
507 return eachOfLimit$1(coll, Infinity, iteratee, callback);
508}
509
510/**
511 * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
512 * to the iteratee.
513 *
514 * @name eachOf
515 * @static
516 * @memberOf module:Collections
517 * @method
518 * @alias forEachOf
519 * @category Collection
520 * @see [async.each]{@link module:Collections.each}
521 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
522 * @param {AsyncFunction} iteratee - A function to apply to each
523 * item in `coll`.
524 * The `key` is the item's key, or index in the case of an array.
525 * Invoked with (item, key, callback).
526 * @param {Function} [callback] - A callback which is called when all
527 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
528 * @returns {Promise} a promise, if a callback is omitted
529 * @example
530 *
531 * // dev.json is a file containing a valid json object config for dev environment
532 * // dev.json is a file containing a valid json object config for test environment
533 * // prod.json is a file containing a valid json object config for prod environment
534 * // invalid.json is a file with a malformed json object
535 *
536 * let configs = {}; //global variable
537 * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};
538 * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};
539 *
540 * // asynchronous function that reads a json file and parses the contents as json object
541 * function parseFile(file, key, callback) {
542 * fs.readFile(file, "utf8", function(err, data) {
543 * if (err) return calback(err);
544 * try {
545 * configs[key] = JSON.parse(data);
546 * } catch (e) {
547 * return callback(e);
548 * }
549 * callback();
550 * });
551 * }
552 *
553 * // Using callbacks
554 * async.forEachOf(validConfigFileMap, parseFile, function (err) {
555 * if (err) {
556 * console.error(err);
557 * } else {
558 * console.log(configs);
559 * // configs is now a map of JSON data, e.g.
560 * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
561 * }
562 * });
563 *
564 * //Error handing
565 * async.forEachOf(invalidConfigFileMap, parseFile, function (err) {
566 * if (err) {
567 * console.error(err);
568 * // JSON parse error exception
569 * } else {
570 * console.log(configs);
571 * }
572 * });
573 *
574 * // Using Promises
575 * async.forEachOf(validConfigFileMap, parseFile)
576 * .then( () => {
577 * console.log(configs);
578 * // configs is now a map of JSON data, e.g.
579 * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
580 * }).catch( err => {
581 * console.error(err);
582 * });
583 *
584 * //Error handing
585 * async.forEachOf(invalidConfigFileMap, parseFile)
586 * .then( () => {
587 * console.log(configs);
588 * }).catch( err => {
589 * console.error(err);
590 * // JSON parse error exception
591 * });
592 *
593 * // Using async/await
594 * async () => {
595 * try {
596 * let result = await async.forEachOf(validConfigFileMap, parseFile);
597 * console.log(configs);
598 * // configs is now a map of JSON data, e.g.
599 * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}
600 * }
601 * catch (err) {
602 * console.log(err);
603 * }
604 * }
605 *
606 * //Error handing
607 * async () => {
608 * try {
609 * let result = await async.forEachOf(invalidConfigFileMap, parseFile);
610 * console.log(configs);
611 * }
612 * catch (err) {
613 * console.log(err);
614 * // JSON parse error exception
615 * }
616 * }
617 *
618 */
619function eachOf(coll, iteratee, callback) {
620 var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
621 return eachOfImplementation(coll, wrapAsync(iteratee), callback);
622}
623
624var eachOf$1 = awaitify(eachOf, 3);
625
626/**
627 * Produces a new collection of values by mapping each value in `coll` through
628 * the `iteratee` function. The `iteratee` is called with an item from `coll`
629 * and a callback for when it has finished processing. Each of these callbacks
630 * takes 2 arguments: an `error`, and the transformed item from `coll`. If
631 * `iteratee` passes an error to its callback, the main `callback` (for the
632 * `map` function) is immediately called with the error.
633 *
634 * Note, that since this function applies the `iteratee` to each item in
635 * parallel, there is no guarantee that the `iteratee` functions will complete
636 * in order. However, the results array will be in the same order as the
637 * original `coll`.
638 *
639 * If `map` is passed an Object, the results will be an Array. The results
640 * will roughly be in the order of the original Objects' keys (but this can
641 * vary across JavaScript engines).
642 *
643 * @name map
644 * @static
645 * @memberOf module:Collections
646 * @method
647 * @category Collection
648 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
649 * @param {AsyncFunction} iteratee - An async function to apply to each item in
650 * `coll`.
651 * The iteratee should complete with the transformed item.
652 * Invoked with (item, callback).
653 * @param {Function} [callback] - A callback which is called when all `iteratee`
654 * functions have finished, or an error occurs. Results is an Array of the
655 * transformed items from the `coll`. Invoked with (err, results).
656 * @returns {Promise} a promise, if no callback is passed
657 * @example
658 *
659 * // file1.txt is a file that is 1000 bytes in size
660 * // file2.txt is a file that is 2000 bytes in size
661 * // file3.txt is a file that is 3000 bytes in size
662 * // file4.txt does not exist
663 *
664 * const fileList = ['file1.txt','file2.txt','file3.txt'];
665 * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
666 *
667 * // asynchronous function that returns the file size in bytes
668 * function getFileSizeInBytes(file, callback) {
669 * fs.stat(file, function(err, stat) {
670 * if (err) {
671 * return callback(err);
672 * }
673 * callback(null, stat.size);
674 * });
675 * }
676 *
677 * // Using callbacks
678 * async.map(fileList, getFileSizeInBytes, function(err, results) {
679 * if (err) {
680 * console.log(err);
681 * } else {
682 * console.log(results);
683 * // results is now an array of the file size in bytes for each file, e.g.
684 * // [ 1000, 2000, 3000]
685 * }
686 * });
687 *
688 * // Error Handling
689 * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {
690 * if (err) {
691 * console.log(err);
692 * // [ Error: ENOENT: no such file or directory ]
693 * } else {
694 * console.log(results);
695 * }
696 * });
697 *
698 * // Using Promises
699 * async.map(fileList, getFileSizeInBytes)
700 * .then( results => {
701 * console.log(results);
702 * // results is now an array of the file size in bytes for each file, e.g.
703 * // [ 1000, 2000, 3000]
704 * }).catch( err => {
705 * console.log(err);
706 * });
707 *
708 * // Error Handling
709 * async.map(withMissingFileList, getFileSizeInBytes)
710 * .then( results => {
711 * console.log(results);
712 * }).catch( err => {
713 * console.log(err);
714 * // [ Error: ENOENT: no such file or directory ]
715 * });
716 *
717 * // Using async/await
718 * async () => {
719 * try {
720 * let results = await async.map(fileList, getFileSizeInBytes);
721 * console.log(results);
722 * // results is now an array of the file size in bytes for each file, e.g.
723 * // [ 1000, 2000, 3000]
724 * }
725 * catch (err) {
726 * console.log(err);
727 * }
728 * }
729 *
730 * // Error Handling
731 * async () => {
732 * try {
733 * let results = await async.map(withMissingFileList, getFileSizeInBytes);
734 * console.log(results);
735 * }
736 * catch (err) {
737 * console.log(err);
738 * // [ Error: ENOENT: no such file or directory ]
739 * }
740 * }
741 *
742 */
743function map (coll, iteratee, callback) {
744 return _asyncMap(eachOf$1, coll, iteratee, callback)
745}
746var map$1 = awaitify(map, 3);
747
748/**
749 * Applies the provided arguments to each function in the array, calling
750 * `callback` after all functions have completed. If you only provide the first
751 * argument, `fns`, then it will return a function which lets you pass in the
752 * arguments as if it were a single function call. If more arguments are
753 * provided, `callback` is required while `args` is still optional. The results
754 * for each of the applied async functions are passed to the final callback
755 * as an array.
756 *
757 * @name applyEach
758 * @static
759 * @memberOf module:ControlFlow
760 * @method
761 * @category Control Flow
762 * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s
763 * to all call with the same arguments
764 * @param {...*} [args] - any number of separate arguments to pass to the
765 * function.
766 * @param {Function} [callback] - the final argument should be the callback,
767 * called when all functions have completed processing.
768 * @returns {AsyncFunction} - Returns a function that takes no args other than
769 * an optional callback, that is the result of applying the `args` to each
770 * of the functions.
771 * @example
772 *
773 * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')
774 *
775 * appliedFn((err, results) => {
776 * // results[0] is the results for `enableSearch`
777 * // results[1] is the results for `updateSchema`
778 * });
779 *
780 * // partial application example:
781 * async.each(
782 * buckets,
783 * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),
784 * callback
785 * );
786 */
787var applyEach = applyEach$1(map$1);
788
789/**
790 * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
791 *
792 * @name eachOfSeries
793 * @static
794 * @memberOf module:Collections
795 * @method
796 * @see [async.eachOf]{@link module:Collections.eachOf}
797 * @alias forEachOfSeries
798 * @category Collection
799 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
800 * @param {AsyncFunction} iteratee - An async function to apply to each item in
801 * `coll`.
802 * Invoked with (item, key, callback).
803 * @param {Function} [callback] - A callback which is called when all `iteratee`
804 * functions have finished, or an error occurs. Invoked with (err).
805 * @returns {Promise} a promise, if a callback is omitted
806 */
807function eachOfSeries(coll, iteratee, callback) {
808 return eachOfLimit$1(coll, 1, iteratee, callback)
809}
810var eachOfSeries$1 = awaitify(eachOfSeries, 3);
811
812/**
813 * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
814 *
815 * @name mapSeries
816 * @static
817 * @memberOf module:Collections
818 * @method
819 * @see [async.map]{@link module:Collections.map}
820 * @category Collection
821 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
822 * @param {AsyncFunction} iteratee - An async function to apply to each item in
823 * `coll`.
824 * The iteratee should complete with the transformed item.
825 * Invoked with (item, callback).
826 * @param {Function} [callback] - A callback which is called when all `iteratee`
827 * functions have finished, or an error occurs. Results is an array of the
828 * transformed items from the `coll`. Invoked with (err, results).
829 * @returns {Promise} a promise, if no callback is passed
830 */
831function mapSeries (coll, iteratee, callback) {
832 return _asyncMap(eachOfSeries$1, coll, iteratee, callback)
833}
834var mapSeries$1 = awaitify(mapSeries, 3);
835
836/**
837 * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
838 *
839 * @name applyEachSeries
840 * @static
841 * @memberOf module:ControlFlow
842 * @method
843 * @see [async.applyEach]{@link module:ControlFlow.applyEach}
844 * @category Control Flow
845 * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all
846 * call with the same arguments
847 * @param {...*} [args] - any number of separate arguments to pass to the
848 * function.
849 * @param {Function} [callback] - the final argument should be the callback,
850 * called when all functions have completed processing.
851 * @returns {AsyncFunction} - A function, that when called, is the result of
852 * appling the `args` to the list of functions. It takes no args, other than
853 * a callback.
854 */
855var applyEachSeries = applyEach$1(mapSeries$1);
856
857const PROMISE_SYMBOL = Symbol('promiseCallback');
858
859function promiseCallback () {
860 let resolve, reject;
861 function callback (err, ...args) {
862 if (err) return reject(err)
863 resolve(args.length > 1 ? args : args[0]);
864 }
865
866 callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
867 resolve = res,
868 reject = rej;
869 });
870
871 return callback
872}
873
874/**
875 * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
876 * their requirements. Each function can optionally depend on other functions
877 * being completed first, and each function is run as soon as its requirements
878 * are satisfied.
879 *
880 * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
881 * will stop. Further tasks will not execute (so any other functions depending
882 * on it will not run), and the main `callback` is immediately called with the
883 * error.
884 *
885 * {@link AsyncFunction}s also receive an object containing the results of functions which
886 * have completed so far as the first argument, if they have dependencies. If a
887 * task function has no dependencies, it will only be passed a callback.
888 *
889 * @name auto
890 * @static
891 * @memberOf module:ControlFlow
892 * @method
893 * @category Control Flow
894 * @param {Object} tasks - An object. Each of its properties is either a
895 * function or an array of requirements, with the {@link AsyncFunction} itself the last item
896 * in the array. The object's key of a property serves as the name of the task
897 * defined by that property, i.e. can be used when specifying requirements for
898 * other tasks. The function receives one or two arguments:
899 * * a `results` object, containing the results of the previously executed
900 * functions, only passed if the task has any dependencies,
901 * * a `callback(err, result)` function, which must be called when finished,
902 * passing an `error` (which can be `null`) and the result of the function's
903 * execution.
904 * @param {number} [concurrency=Infinity] - An optional `integer` for
905 * determining the maximum number of tasks that can be run in parallel. By
906 * default, as many as possible.
907 * @param {Function} [callback] - An optional callback which is called when all
908 * the tasks have been completed. It receives the `err` argument if any `tasks`
909 * pass an error to their callback. Results are always returned; however, if an
910 * error occurs, no further `tasks` will be performed, and the results object
911 * will only contain partial results. Invoked with (err, results).
912 * @returns {Promise} a promise, if a callback is not passed
913 * @example
914 *
915 * //Using Callbacks
916 * async.auto({
917 * get_data: function(callback) {
918 * // async code to get some data
919 * callback(null, 'data', 'converted to array');
920 * },
921 * make_folder: function(callback) {
922 * // async code to create a directory to store a file in
923 * // this is run at the same time as getting the data
924 * callback(null, 'folder');
925 * },
926 * write_file: ['get_data', 'make_folder', function(results, callback) {
927 * // once there is some data and the directory exists,
928 * // write the data to a file in the directory
929 * callback(null, 'filename');
930 * }],
931 * email_link: ['write_file', function(results, callback) {
932 * // once the file is written let's email a link to it...
933 * callback(null, {'file':results.write_file, 'email':'user@example.com'});
934 * }]
935 * }, function(err, results) {
936 * if (err) {
937 * console.log('err = ', err);
938 * }
939 * console.log('results = ', results);
940 * // results = {
941 * // get_data: ['data', 'converted to array']
942 * // make_folder; 'folder',
943 * // write_file: 'filename'
944 * // email_link: { file: 'filename', email: 'user@example.com' }
945 * // }
946 * });
947 *
948 * //Using Promises
949 * async.auto({
950 * get_data: function(callback) {
951 * console.log('in get_data');
952 * // async code to get some data
953 * callback(null, 'data', 'converted to array');
954 * },
955 * make_folder: function(callback) {
956 * console.log('in make_folder');
957 * // async code to create a directory to store a file in
958 * // this is run at the same time as getting the data
959 * callback(null, 'folder');
960 * },
961 * write_file: ['get_data', 'make_folder', function(results, callback) {
962 * // once there is some data and the directory exists,
963 * // write the data to a file in the directory
964 * callback(null, 'filename');
965 * }],
966 * email_link: ['write_file', function(results, callback) {
967 * // once the file is written let's email a link to it...
968 * callback(null, {'file':results.write_file, 'email':'user@example.com'});
969 * }]
970 * }).then(results => {
971 * console.log('results = ', results);
972 * // results = {
973 * // get_data: ['data', 'converted to array']
974 * // make_folder; 'folder',
975 * // write_file: 'filename'
976 * // email_link: { file: 'filename', email: 'user@example.com' }
977 * // }
978 * }).catch(err => {
979 * console.log('err = ', err);
980 * });
981 *
982 * //Using async/await
983 * async () => {
984 * try {
985 * let results = await async.auto({
986 * get_data: function(callback) {
987 * // async code to get some data
988 * callback(null, 'data', 'converted to array');
989 * },
990 * make_folder: function(callback) {
991 * // async code to create a directory to store a file in
992 * // this is run at the same time as getting the data
993 * callback(null, 'folder');
994 * },
995 * write_file: ['get_data', 'make_folder', function(results, callback) {
996 * // once there is some data and the directory exists,
997 * // write the data to a file in the directory
998 * callback(null, 'filename');
999 * }],
1000 * email_link: ['write_file', function(results, callback) {
1001 * // once the file is written let's email a link to it...
1002 * callback(null, {'file':results.write_file, 'email':'user@example.com'});
1003 * }]
1004 * });
1005 * console.log('results = ', results);
1006 * // results = {
1007 * // get_data: ['data', 'converted to array']
1008 * // make_folder; 'folder',
1009 * // write_file: 'filename'
1010 * // email_link: { file: 'filename', email: 'user@example.com' }
1011 * // }
1012 * }
1013 * catch (err) {
1014 * console.log(err);
1015 * }
1016 * }
1017 *
1018 */
1019function auto(tasks, concurrency, callback) {
1020 if (typeof concurrency !== 'number') {
1021 // concurrency is optional, shift the args.
1022 callback = concurrency;
1023 concurrency = null;
1024 }
1025 callback = once(callback || promiseCallback());
1026 var numTasks = Object.keys(tasks).length;
1027 if (!numTasks) {
1028 return callback(null);
1029 }
1030 if (!concurrency) {
1031 concurrency = numTasks;
1032 }
1033
1034 var results = {};
1035 var runningTasks = 0;
1036 var canceled = false;
1037 var hasError = false;
1038
1039 var listeners = Object.create(null);
1040
1041 var readyTasks = [];
1042
1043 // for cycle detection:
1044 var readyToCheck = []; // tasks that have been identified as reachable
1045 // without the possibility of returning to an ancestor task
1046 var uncheckedDependencies = {};
1047
1048 Object.keys(tasks).forEach(key => {
1049 var task = tasks[key];
1050 if (!Array.isArray(task)) {
1051 // no dependencies
1052 enqueueTask(key, [task]);
1053 readyToCheck.push(key);
1054 return;
1055 }
1056
1057 var dependencies = task.slice(0, task.length - 1);
1058 var remainingDependencies = dependencies.length;
1059 if (remainingDependencies === 0) {
1060 enqueueTask(key, task);
1061 readyToCheck.push(key);
1062 return;
1063 }
1064 uncheckedDependencies[key] = remainingDependencies;
1065
1066 dependencies.forEach(dependencyName => {
1067 if (!tasks[dependencyName]) {
1068 throw new Error('async.auto task `' + key +
1069 '` has a non-existent dependency `' +
1070 dependencyName + '` in ' +
1071 dependencies.join(', '));
1072 }
1073 addListener(dependencyName, () => {
1074 remainingDependencies--;
1075 if (remainingDependencies === 0) {
1076 enqueueTask(key, task);
1077 }
1078 });
1079 });
1080 });
1081
1082 checkForDeadlocks();
1083 processQueue();
1084
1085 function enqueueTask(key, task) {
1086 readyTasks.push(() => runTask(key, task));
1087 }
1088
1089 function processQueue() {
1090 if (canceled) return
1091 if (readyTasks.length === 0 && runningTasks === 0) {
1092 return callback(null, results);
1093 }
1094 while(readyTasks.length && runningTasks < concurrency) {
1095 var run = readyTasks.shift();
1096 run();
1097 }
1098
1099 }
1100
1101 function addListener(taskName, fn) {
1102 var taskListeners = listeners[taskName];
1103 if (!taskListeners) {
1104 taskListeners = listeners[taskName] = [];
1105 }
1106
1107 taskListeners.push(fn);
1108 }
1109
1110 function taskComplete(taskName) {
1111 var taskListeners = listeners[taskName] || [];
1112 taskListeners.forEach(fn => fn());
1113 processQueue();
1114 }
1115
1116
1117 function runTask(key, task) {
1118 if (hasError) return;
1119
1120 var taskCallback = onlyOnce((err, ...result) => {
1121 runningTasks--;
1122 if (err === false) {
1123 canceled = true;
1124 return
1125 }
1126 if (result.length < 2) {
1127 [result] = result;
1128 }
1129 if (err) {
1130 var safeResults = {};
1131 Object.keys(results).forEach(rkey => {
1132 safeResults[rkey] = results[rkey];
1133 });
1134 safeResults[key] = result;
1135 hasError = true;
1136 listeners = Object.create(null);
1137 if (canceled) return
1138 callback(err, safeResults);
1139 } else {
1140 results[key] = result;
1141 taskComplete(key);
1142 }
1143 });
1144
1145 runningTasks++;
1146 var taskFn = wrapAsync(task[task.length - 1]);
1147 if (task.length > 1) {
1148 taskFn(results, taskCallback);
1149 } else {
1150 taskFn(taskCallback);
1151 }
1152 }
1153
1154 function checkForDeadlocks() {
1155 // Kahn's algorithm
1156 // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
1157 // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
1158 var currentTask;
1159 var counter = 0;
1160 while (readyToCheck.length) {
1161 currentTask = readyToCheck.pop();
1162 counter++;
1163 getDependents(currentTask).forEach(dependent => {
1164 if (--uncheckedDependencies[dependent] === 0) {
1165 readyToCheck.push(dependent);
1166 }
1167 });
1168 }
1169
1170 if (counter !== numTasks) {
1171 throw new Error(
1172 'async.auto cannot execute tasks due to a recursive dependency'
1173 );
1174 }
1175 }
1176
1177 function getDependents(taskName) {
1178 var result = [];
1179 Object.keys(tasks).forEach(key => {
1180 const task = tasks[key];
1181 if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
1182 result.push(key);
1183 }
1184 });
1185 return result;
1186 }
1187
1188 return callback[PROMISE_SYMBOL]
1189}
1190
1191var FN_ARGS = /^(?:async\s)?(?:function)?\s*(?:\w+\s*)?\(([^)]+)\)(?:\s*{)/;
1192var ARROW_FN_ARGS = /^(?:async\s)?\s*(?:\(\s*)?((?:[^)=\s]\s*)*)(?:\)\s*)?=>/;
1193var FN_ARG_SPLIT = /,/;
1194var FN_ARG = /(=.+)?(\s*)$/;
1195
1196function stripComments(string) {
1197 let stripped = '';
1198 let index = 0;
1199 let endBlockComment = string.indexOf('*/');
1200 while (index < string.length) {
1201 if (string[index] === '/' && string[index+1] === '/') {
1202 // inline comment
1203 let endIndex = string.indexOf('\n', index);
1204 index = (endIndex === -1) ? string.length : endIndex;
1205 } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {
1206 // block comment
1207 let endIndex = string.indexOf('*/', index);
1208 if (endIndex !== -1) {
1209 index = endIndex + 2;
1210 endBlockComment = string.indexOf('*/', index);
1211 } else {
1212 stripped += string[index];
1213 index++;
1214 }
1215 } else {
1216 stripped += string[index];
1217 index++;
1218 }
1219 }
1220 return stripped;
1221}
1222
1223function parseParams(func) {
1224 const src = stripComments(func.toString());
1225 let match = src.match(FN_ARGS);
1226 if (!match) {
1227 match = src.match(ARROW_FN_ARGS);
1228 }
1229 if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)
1230 let [, args] = match;
1231 return args
1232 .replace(/\s/g, '')
1233 .split(FN_ARG_SPLIT)
1234 .map((arg) => arg.replace(FN_ARG, '').trim());
1235}
1236
1237/**
1238 * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
1239 * tasks are specified as parameters to the function, after the usual callback
1240 * parameter, with the parameter names matching the names of the tasks it
1241 * depends on. This can provide even more readable task graphs which can be
1242 * easier to maintain.
1243 *
1244 * If a final callback is specified, the task results are similarly injected,
1245 * specified as named parameters after the initial error parameter.
1246 *
1247 * The autoInject function is purely syntactic sugar and its semantics are
1248 * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
1249 *
1250 * @name autoInject
1251 * @static
1252 * @memberOf module:ControlFlow
1253 * @method
1254 * @see [async.auto]{@link module:ControlFlow.auto}
1255 * @category Control Flow
1256 * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
1257 * the form 'func([dependencies...], callback). The object's key of a property
1258 * serves as the name of the task defined by that property, i.e. can be used
1259 * when specifying requirements for other tasks.
1260 * * The `callback` parameter is a `callback(err, result)` which must be called
1261 * when finished, passing an `error` (which can be `null`) and the result of
1262 * the function's execution. The remaining parameters name other tasks on
1263 * which the task is dependent, and the results from those tasks are the
1264 * arguments of those parameters.
1265 * @param {Function} [callback] - An optional callback which is called when all
1266 * the tasks have been completed. It receives the `err` argument if any `tasks`
1267 * pass an error to their callback, and a `results` object with any completed
1268 * task results, similar to `auto`.
1269 * @returns {Promise} a promise, if no callback is passed
1270 * @example
1271 *
1272 * // The example from `auto` can be rewritten as follows:
1273 * async.autoInject({
1274 * get_data: function(callback) {
1275 * // async code to get some data
1276 * callback(null, 'data', 'converted to array');
1277 * },
1278 * make_folder: function(callback) {
1279 * // async code to create a directory to store a file in
1280 * // this is run at the same time as getting the data
1281 * callback(null, 'folder');
1282 * },
1283 * write_file: function(get_data, make_folder, callback) {
1284 * // once there is some data and the directory exists,
1285 * // write the data to a file in the directory
1286 * callback(null, 'filename');
1287 * },
1288 * email_link: function(write_file, callback) {
1289 * // once the file is written let's email a link to it...
1290 * // write_file contains the filename returned by write_file.
1291 * callback(null, {'file':write_file, 'email':'user@example.com'});
1292 * }
1293 * }, function(err, results) {
1294 * console.log('err = ', err);
1295 * console.log('email_link = ', results.email_link);
1296 * });
1297 *
1298 * // If you are using a JS minifier that mangles parameter names, `autoInject`
1299 * // will not work with plain functions, since the parameter names will be
1300 * // collapsed to a single letter identifier. To work around this, you can
1301 * // explicitly specify the names of the parameters your task function needs
1302 * // in an array, similar to Angular.js dependency injection.
1303 *
1304 * // This still has an advantage over plain `auto`, since the results a task
1305 * // depends on are still spread into arguments.
1306 * async.autoInject({
1307 * //...
1308 * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
1309 * callback(null, 'filename');
1310 * }],
1311 * email_link: ['write_file', function(write_file, callback) {
1312 * callback(null, {'file':write_file, 'email':'user@example.com'});
1313 * }]
1314 * //...
1315 * }, function(err, results) {
1316 * console.log('err = ', err);
1317 * console.log('email_link = ', results.email_link);
1318 * });
1319 */
1320function autoInject(tasks, callback) {
1321 var newTasks = {};
1322
1323 Object.keys(tasks).forEach(key => {
1324 var taskFn = tasks[key];
1325 var params;
1326 var fnIsAsync = isAsync(taskFn);
1327 var hasNoDeps =
1328 (!fnIsAsync && taskFn.length === 1) ||
1329 (fnIsAsync && taskFn.length === 0);
1330
1331 if (Array.isArray(taskFn)) {
1332 params = [...taskFn];
1333 taskFn = params.pop();
1334
1335 newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
1336 } else if (hasNoDeps) {
1337 // no dependencies, use the function as-is
1338 newTasks[key] = taskFn;
1339 } else {
1340 params = parseParams(taskFn);
1341 if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {
1342 throw new Error("autoInject task functions require explicit parameters.");
1343 }
1344
1345 // remove callback param
1346 if (!fnIsAsync) params.pop();
1347
1348 newTasks[key] = params.concat(newTask);
1349 }
1350
1351 function newTask(results, taskCb) {
1352 var newArgs = params.map(name => results[name]);
1353 newArgs.push(taskCb);
1354 wrapAsync(taskFn)(...newArgs);
1355 }
1356 });
1357
1358 return auto(newTasks, callback);
1359}
1360
1361// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
1362// used for queues. This implementation assumes that the node provided by the user can be modified
1363// to adjust the next and last properties. We implement only the minimal functionality
1364// for queue support.
1365class DLL {
1366 constructor() {
1367 this.head = this.tail = null;
1368 this.length = 0;
1369 }
1370
1371 removeLink(node) {
1372 if (node.prev) node.prev.next = node.next;
1373 else this.head = node.next;
1374 if (node.next) node.next.prev = node.prev;
1375 else this.tail = node.prev;
1376
1377 node.prev = node.next = null;
1378 this.length -= 1;
1379 return node;
1380 }
1381
1382 empty () {
1383 while(this.head) this.shift();
1384 return this;
1385 }
1386
1387 insertAfter(node, newNode) {
1388 newNode.prev = node;
1389 newNode.next = node.next;
1390 if (node.next) node.next.prev = newNode;
1391 else this.tail = newNode;
1392 node.next = newNode;
1393 this.length += 1;
1394 }
1395
1396 insertBefore(node, newNode) {
1397 newNode.prev = node.prev;
1398 newNode.next = node;
1399 if (node.prev) node.prev.next = newNode;
1400 else this.head = newNode;
1401 node.prev = newNode;
1402 this.length += 1;
1403 }
1404
1405 unshift(node) {
1406 if (this.head) this.insertBefore(this.head, node);
1407 else setInitial(this, node);
1408 }
1409
1410 push(node) {
1411 if (this.tail) this.insertAfter(this.tail, node);
1412 else setInitial(this, node);
1413 }
1414
1415 shift() {
1416 return this.head && this.removeLink(this.head);
1417 }
1418
1419 pop() {
1420 return this.tail && this.removeLink(this.tail);
1421 }
1422
1423 toArray() {
1424 return [...this]
1425 }
1426
1427 *[Symbol.iterator] () {
1428 var cur = this.head;
1429 while (cur) {
1430 yield cur.data;
1431 cur = cur.next;
1432 }
1433 }
1434
1435 remove (testFn) {
1436 var curr = this.head;
1437 while(curr) {
1438 var {next} = curr;
1439 if (testFn(curr)) {
1440 this.removeLink(curr);
1441 }
1442 curr = next;
1443 }
1444 return this;
1445 }
1446}
1447
1448function setInitial(dll, node) {
1449 dll.length = 1;
1450 dll.head = dll.tail = node;
1451}
1452
1453function queue$1(worker, concurrency, payload) {
1454 if (concurrency == null) {
1455 concurrency = 1;
1456 }
1457 else if(concurrency === 0) {
1458 throw new RangeError('Concurrency must not be zero');
1459 }
1460
1461 var _worker = wrapAsync(worker);
1462 var numRunning = 0;
1463 var workersList = [];
1464 const events = {
1465 error: [],
1466 drain: [],
1467 saturated: [],
1468 unsaturated: [],
1469 empty: []
1470 };
1471
1472 function on (event, handler) {
1473 events[event].push(handler);
1474 }
1475
1476 function once (event, handler) {
1477 const handleAndRemove = (...args) => {
1478 off(event, handleAndRemove);
1479 handler(...args);
1480 };
1481 events[event].push(handleAndRemove);
1482 }
1483
1484 function off (event, handler) {
1485 if (!event) return Object.keys(events).forEach(ev => events[ev] = [])
1486 if (!handler) return events[event] = []
1487 events[event] = events[event].filter(ev => ev !== handler);
1488 }
1489
1490 function trigger (event, ...args) {
1491 events[event].forEach(handler => handler(...args));
1492 }
1493
1494 var processingScheduled = false;
1495 function _insert(data, insertAtFront, rejectOnError, callback) {
1496 if (callback != null && typeof callback !== 'function') {
1497 throw new Error('task callback must be a function');
1498 }
1499 q.started = true;
1500
1501 var res, rej;
1502 function promiseCallback (err, ...args) {
1503 // we don't care about the error, let the global error handler
1504 // deal with it
1505 if (err) return rejectOnError ? rej(err) : res()
1506 if (args.length <= 1) return res(args[0])
1507 res(args);
1508 }
1509
1510 var item = q._createTaskItem(
1511 data,
1512 rejectOnError ? promiseCallback :
1513 (callback || promiseCallback)
1514 );
1515
1516 if (insertAtFront) {
1517 q._tasks.unshift(item);
1518 } else {
1519 q._tasks.push(item);
1520 }
1521
1522 if (!processingScheduled) {
1523 processingScheduled = true;
1524 setImmediate$1(() => {
1525 processingScheduled = false;
1526 q.process();
1527 });
1528 }
1529
1530 if (rejectOnError || !callback) {
1531 return new Promise((resolve, reject) => {
1532 res = resolve;
1533 rej = reject;
1534 })
1535 }
1536 }
1537
1538 function _createCB(tasks) {
1539 return function (err, ...args) {
1540 numRunning -= 1;
1541
1542 for (var i = 0, l = tasks.length; i < l; i++) {
1543 var task = tasks[i];
1544
1545 var index = workersList.indexOf(task);
1546 if (index === 0) {
1547 workersList.shift();
1548 } else if (index > 0) {
1549 workersList.splice(index, 1);
1550 }
1551
1552 task.callback(err, ...args);
1553
1554 if (err != null) {
1555 trigger('error', err, task.data);
1556 }
1557 }
1558
1559 if (numRunning <= (q.concurrency - q.buffer) ) {
1560 trigger('unsaturated');
1561 }
1562
1563 if (q.idle()) {
1564 trigger('drain');
1565 }
1566 q.process();
1567 };
1568 }
1569
1570 function _maybeDrain(data) {
1571 if (data.length === 0 && q.idle()) {
1572 // call drain immediately if there are no tasks
1573 setImmediate$1(() => trigger('drain'));
1574 return true
1575 }
1576 return false
1577 }
1578
1579 const eventMethod = (name) => (handler) => {
1580 if (!handler) {
1581 return new Promise((resolve, reject) => {
1582 once(name, (err, data) => {
1583 if (err) return reject(err)
1584 resolve(data);
1585 });
1586 })
1587 }
1588 off(name);
1589 on(name, handler);
1590
1591 };
1592
1593 var isProcessing = false;
1594 var q = {
1595 _tasks: new DLL(),
1596 _createTaskItem (data, callback) {
1597 return {
1598 data,
1599 callback
1600 };
1601 },
1602 *[Symbol.iterator] () {
1603 yield* q._tasks[Symbol.iterator]();
1604 },
1605 concurrency,
1606 payload,
1607 buffer: concurrency / 4,
1608 started: false,
1609 paused: false,
1610 push (data, callback) {
1611 if (Array.isArray(data)) {
1612 if (_maybeDrain(data)) return
1613 return data.map(datum => _insert(datum, false, false, callback))
1614 }
1615 return _insert(data, false, false, callback);
1616 },
1617 pushAsync (data, callback) {
1618 if (Array.isArray(data)) {
1619 if (_maybeDrain(data)) return
1620 return data.map(datum => _insert(datum, false, true, callback))
1621 }
1622 return _insert(data, false, true, callback);
1623 },
1624 kill () {
1625 off();
1626 q._tasks.empty();
1627 },
1628 unshift (data, callback) {
1629 if (Array.isArray(data)) {
1630 if (_maybeDrain(data)) return
1631 return data.map(datum => _insert(datum, true, false, callback))
1632 }
1633 return _insert(data, true, false, callback);
1634 },
1635 unshiftAsync (data, callback) {
1636 if (Array.isArray(data)) {
1637 if (_maybeDrain(data)) return
1638 return data.map(datum => _insert(datum, true, true, callback))
1639 }
1640 return _insert(data, true, true, callback);
1641 },
1642 remove (testFn) {
1643 q._tasks.remove(testFn);
1644 },
1645 process () {
1646 // Avoid trying to start too many processing operations. This can occur
1647 // when callbacks resolve synchronously (#1267).
1648 if (isProcessing) {
1649 return;
1650 }
1651 isProcessing = true;
1652 while(!q.paused && numRunning < q.concurrency && q._tasks.length){
1653 var tasks = [], data = [];
1654 var l = q._tasks.length;
1655 if (q.payload) l = Math.min(l, q.payload);
1656 for (var i = 0; i < l; i++) {
1657 var node = q._tasks.shift();
1658 tasks.push(node);
1659 workersList.push(node);
1660 data.push(node.data);
1661 }
1662
1663 numRunning += 1;
1664
1665 if (q._tasks.length === 0) {
1666 trigger('empty');
1667 }
1668
1669 if (numRunning === q.concurrency) {
1670 trigger('saturated');
1671 }
1672
1673 var cb = onlyOnce(_createCB(tasks));
1674 _worker(data, cb);
1675 }
1676 isProcessing = false;
1677 },
1678 length () {
1679 return q._tasks.length;
1680 },
1681 running () {
1682 return numRunning;
1683 },
1684 workersList () {
1685 return workersList;
1686 },
1687 idle() {
1688 return q._tasks.length + numRunning === 0;
1689 },
1690 pause () {
1691 q.paused = true;
1692 },
1693 resume () {
1694 if (q.paused === false) { return; }
1695 q.paused = false;
1696 setImmediate$1(q.process);
1697 }
1698 };
1699 // define these as fixed properties, so people get useful errors when updating
1700 Object.defineProperties(q, {
1701 saturated: {
1702 writable: false,
1703 value: eventMethod('saturated')
1704 },
1705 unsaturated: {
1706 writable: false,
1707 value: eventMethod('unsaturated')
1708 },
1709 empty: {
1710 writable: false,
1711 value: eventMethod('empty')
1712 },
1713 drain: {
1714 writable: false,
1715 value: eventMethod('drain')
1716 },
1717 error: {
1718 writable: false,
1719 value: eventMethod('error')
1720 },
1721 });
1722 return q;
1723}
1724
1725/**
1726 * Creates a `cargo` object with the specified payload. Tasks added to the
1727 * cargo will be processed altogether (up to the `payload` limit). If the
1728 * `worker` is in progress, the task is queued until it becomes available. Once
1729 * the `worker` has completed some tasks, each callback of those tasks is
1730 * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
1731 * for how `cargo` and `queue` work.
1732 *
1733 * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
1734 * at a time, cargo passes an array of tasks to a single worker, repeating
1735 * when the worker is finished.
1736 *
1737 * @name cargo
1738 * @static
1739 * @memberOf module:ControlFlow
1740 * @method
1741 * @see [async.queue]{@link module:ControlFlow.queue}
1742 * @category Control Flow
1743 * @param {AsyncFunction} worker - An asynchronous function for processing an array
1744 * of queued tasks. Invoked with `(tasks, callback)`.
1745 * @param {number} [payload=Infinity] - An optional `integer` for determining
1746 * how many tasks should be processed per round; if omitted, the default is
1747 * unlimited.
1748 * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can
1749 * attached as certain properties to listen for specific events during the
1750 * lifecycle of the cargo and inner queue.
1751 * @example
1752 *
1753 * // create a cargo object with payload 2
1754 * var cargo = async.cargo(function(tasks, callback) {
1755 * for (var i=0; i<tasks.length; i++) {
1756 * console.log('hello ' + tasks[i].name);
1757 * }
1758 * callback();
1759 * }, 2);
1760 *
1761 * // add some items
1762 * cargo.push({name: 'foo'}, function(err) {
1763 * console.log('finished processing foo');
1764 * });
1765 * cargo.push({name: 'bar'}, function(err) {
1766 * console.log('finished processing bar');
1767 * });
1768 * await cargo.push({name: 'baz'});
1769 * console.log('finished processing baz');
1770 */
1771function cargo$1(worker, payload) {
1772 return queue$1(worker, 1, payload);
1773}
1774
1775/**
1776 * Creates a `cargoQueue` object with the specified payload. Tasks added to the
1777 * cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.
1778 * If the all `workers` are in progress, the task is queued until one becomes available. Once
1779 * a `worker` has completed some tasks, each callback of those tasks is
1780 * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
1781 * for how `cargo` and `queue` work.
1782 *
1783 * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
1784 * at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,
1785 * the cargoQueue passes an array of tasks to multiple parallel workers.
1786 *
1787 * @name cargoQueue
1788 * @static
1789 * @memberOf module:ControlFlow
1790 * @method
1791 * @see [async.queue]{@link module:ControlFlow.queue}
1792 * @see [async.cargo]{@link module:ControlFLow.cargo}
1793 * @category Control Flow
1794 * @param {AsyncFunction} worker - An asynchronous function for processing an array
1795 * of queued tasks. Invoked with `(tasks, callback)`.
1796 * @param {number} [concurrency=1] - An `integer` for determining how many
1797 * `worker` functions should be run in parallel. If omitted, the concurrency
1798 * defaults to `1`. If the concurrency is `0`, an error is thrown.
1799 * @param {number} [payload=Infinity] - An optional `integer` for determining
1800 * how many tasks should be processed per round; if omitted, the default is
1801 * unlimited.
1802 * @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can
1803 * attached as certain properties to listen for specific events during the
1804 * lifecycle of the cargoQueue and inner queue.
1805 * @example
1806 *
1807 * // create a cargoQueue object with payload 2 and concurrency 2
1808 * var cargoQueue = async.cargoQueue(function(tasks, callback) {
1809 * for (var i=0; i<tasks.length; i++) {
1810 * console.log('hello ' + tasks[i].name);
1811 * }
1812 * callback();
1813 * }, 2, 2);
1814 *
1815 * // add some items
1816 * cargoQueue.push({name: 'foo'}, function(err) {
1817 * console.log('finished processing foo');
1818 * });
1819 * cargoQueue.push({name: 'bar'}, function(err) {
1820 * console.log('finished processing bar');
1821 * });
1822 * cargoQueue.push({name: 'baz'}, function(err) {
1823 * console.log('finished processing baz');
1824 * });
1825 * cargoQueue.push({name: 'boo'}, function(err) {
1826 * console.log('finished processing boo');
1827 * });
1828 */
1829function cargo(worker, concurrency, payload) {
1830 return queue$1(worker, concurrency, payload);
1831}
1832
1833/**
1834 * Reduces `coll` into a single value using an async `iteratee` to return each
1835 * successive step. `memo` is the initial state of the reduction. This function
1836 * only operates in series.
1837 *
1838 * For performance reasons, it may make sense to split a call to this function
1839 * into a parallel map, and then use the normal `Array.prototype.reduce` on the
1840 * results. This function is for situations where each step in the reduction
1841 * needs to be async; if you can get the data before reducing it, then it's
1842 * probably a good idea to do so.
1843 *
1844 * @name reduce
1845 * @static
1846 * @memberOf module:Collections
1847 * @method
1848 * @alias inject
1849 * @alias foldl
1850 * @category Collection
1851 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1852 * @param {*} memo - The initial state of the reduction.
1853 * @param {AsyncFunction} iteratee - A function applied to each item in the
1854 * array to produce the next step in the reduction.
1855 * The `iteratee` should complete with the next state of the reduction.
1856 * If the iteratee completes with an error, the reduction is stopped and the
1857 * main `callback` is immediately called with the error.
1858 * Invoked with (memo, item, callback).
1859 * @param {Function} [callback] - A callback which is called after all the
1860 * `iteratee` functions have finished. Result is the reduced value. Invoked with
1861 * (err, result).
1862 * @returns {Promise} a promise, if no callback is passed
1863 * @example
1864 *
1865 * // file1.txt is a file that is 1000 bytes in size
1866 * // file2.txt is a file that is 2000 bytes in size
1867 * // file3.txt is a file that is 3000 bytes in size
1868 * // file4.txt does not exist
1869 *
1870 * const fileList = ['file1.txt','file2.txt','file3.txt'];
1871 * const withMissingFileList = ['file1.txt','file2.txt','file3.txt', 'file4.txt'];
1872 *
1873 * // asynchronous function that computes the file size in bytes
1874 * // file size is added to the memoized value, then returned
1875 * function getFileSizeInBytes(memo, file, callback) {
1876 * fs.stat(file, function(err, stat) {
1877 * if (err) {
1878 * return callback(err);
1879 * }
1880 * callback(null, memo + stat.size);
1881 * });
1882 * }
1883 *
1884 * // Using callbacks
1885 * async.reduce(fileList, 0, getFileSizeInBytes, function(err, result) {
1886 * if (err) {
1887 * console.log(err);
1888 * } else {
1889 * console.log(result);
1890 * // 6000
1891 * // which is the sum of the file sizes of the three files
1892 * }
1893 * });
1894 *
1895 * // Error Handling
1896 * async.reduce(withMissingFileList, 0, getFileSizeInBytes, function(err, result) {
1897 * if (err) {
1898 * console.log(err);
1899 * // [ Error: ENOENT: no such file or directory ]
1900 * } else {
1901 * console.log(result);
1902 * }
1903 * });
1904 *
1905 * // Using Promises
1906 * async.reduce(fileList, 0, getFileSizeInBytes)
1907 * .then( result => {
1908 * console.log(result);
1909 * // 6000
1910 * // which is the sum of the file sizes of the three files
1911 * }).catch( err => {
1912 * console.log(err);
1913 * });
1914 *
1915 * // Error Handling
1916 * async.reduce(withMissingFileList, 0, getFileSizeInBytes)
1917 * .then( result => {
1918 * console.log(result);
1919 * }).catch( err => {
1920 * console.log(err);
1921 * // [ Error: ENOENT: no such file or directory ]
1922 * });
1923 *
1924 * // Using async/await
1925 * async () => {
1926 * try {
1927 * let result = await async.reduce(fileList, 0, getFileSizeInBytes);
1928 * console.log(result);
1929 * // 6000
1930 * // which is the sum of the file sizes of the three files
1931 * }
1932 * catch (err) {
1933 * console.log(err);
1934 * }
1935 * }
1936 *
1937 * // Error Handling
1938 * async () => {
1939 * try {
1940 * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);
1941 * console.log(result);
1942 * }
1943 * catch (err) {
1944 * console.log(err);
1945 * // [ Error: ENOENT: no such file or directory ]
1946 * }
1947 * }
1948 *
1949 */
1950function reduce(coll, memo, iteratee, callback) {
1951 callback = once(callback);
1952 var _iteratee = wrapAsync(iteratee);
1953 return eachOfSeries$1(coll, (x, i, iterCb) => {
1954 _iteratee(memo, x, (err, v) => {
1955 memo = v;
1956 iterCb(err);
1957 });
1958 }, err => callback(err, memo));
1959}
1960var reduce$1 = awaitify(reduce, 4);
1961
1962/**
1963 * Version of the compose function that is more natural to read. Each function
1964 * consumes the return value of the previous function. It is the equivalent of
1965 * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
1966 *
1967 * Each function is executed with the `this` binding of the composed function.
1968 *
1969 * @name seq
1970 * @static
1971 * @memberOf module:ControlFlow
1972 * @method
1973 * @see [async.compose]{@link module:ControlFlow.compose}
1974 * @category Control Flow
1975 * @param {...AsyncFunction} functions - the asynchronous functions to compose
1976 * @returns {Function} a function that composes the `functions` in order
1977 * @example
1978 *
1979 * // Requires lodash (or underscore), express3 and dresende's orm2.
1980 * // Part of an app, that fetches cats of the logged user.
1981 * // This example uses `seq` function to avoid overnesting and error
1982 * // handling clutter.
1983 * app.get('/cats', function(request, response) {
1984 * var User = request.models.User;
1985 * async.seq(
1986 * User.get.bind(User), // 'User.get' has signature (id, callback(err, data))
1987 * function(user, fn) {
1988 * user.getCats(fn); // 'getCats' has signature (callback(err, data))
1989 * }
1990 * )(req.session.user_id, function (err, cats) {
1991 * if (err) {
1992 * console.error(err);
1993 * response.json({ status: 'error', message: err.message });
1994 * } else {
1995 * response.json({ status: 'ok', message: 'Cats found', data: cats });
1996 * }
1997 * });
1998 * });
1999 */
2000function seq(...functions) {
2001 var _functions = functions.map(wrapAsync);
2002 return function (...args) {
2003 var that = this;
2004
2005 var cb = args[args.length - 1];
2006 if (typeof cb == 'function') {
2007 args.pop();
2008 } else {
2009 cb = promiseCallback();
2010 }
2011
2012 reduce$1(_functions, args, (newargs, fn, iterCb) => {
2013 fn.apply(that, newargs.concat((err, ...nextargs) => {
2014 iterCb(err, nextargs);
2015 }));
2016 },
2017 (err, results) => cb(err, ...results));
2018
2019 return cb[PROMISE_SYMBOL]
2020 };
2021}
2022
2023/**
2024 * Creates a function which is a composition of the passed asynchronous
2025 * functions. Each function consumes the return value of the function that
2026 * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
2027 * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
2028 *
2029 * If the last argument to the composed function is not a function, a promise
2030 * is returned when you call it.
2031 *
2032 * Each function is executed with the `this` binding of the composed function.
2033 *
2034 * @name compose
2035 * @static
2036 * @memberOf module:ControlFlow
2037 * @method
2038 * @category Control Flow
2039 * @param {...AsyncFunction} functions - the asynchronous functions to compose
2040 * @returns {Function} an asynchronous function that is the composed
2041 * asynchronous `functions`
2042 * @example
2043 *
2044 * function add1(n, callback) {
2045 * setTimeout(function () {
2046 * callback(null, n + 1);
2047 * }, 10);
2048 * }
2049 *
2050 * function mul3(n, callback) {
2051 * setTimeout(function () {
2052 * callback(null, n * 3);
2053 * }, 10);
2054 * }
2055 *
2056 * var add1mul3 = async.compose(mul3, add1);
2057 * add1mul3(4, function (err, result) {
2058 * // result now equals 15
2059 * });
2060 */
2061function compose(...args) {
2062 return seq(...args.reverse());
2063}
2064
2065/**
2066 * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
2067 *
2068 * @name mapLimit
2069 * @static
2070 * @memberOf module:Collections
2071 * @method
2072 * @see [async.map]{@link module:Collections.map}
2073 * @category Collection
2074 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2075 * @param {number} limit - The maximum number of async operations at a time.
2076 * @param {AsyncFunction} iteratee - An async function to apply to each item in
2077 * `coll`.
2078 * The iteratee should complete with the transformed item.
2079 * Invoked with (item, callback).
2080 * @param {Function} [callback] - A callback which is called when all `iteratee`
2081 * functions have finished, or an error occurs. Results is an array of the
2082 * transformed items from the `coll`. Invoked with (err, results).
2083 * @returns {Promise} a promise, if no callback is passed
2084 */
2085function mapLimit (coll, limit, iteratee, callback) {
2086 return _asyncMap(eachOfLimit$2(limit), coll, iteratee, callback)
2087}
2088var mapLimit$1 = awaitify(mapLimit, 4);
2089
2090/**
2091 * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
2092 *
2093 * @name concatLimit
2094 * @static
2095 * @memberOf module:Collections
2096 * @method
2097 * @see [async.concat]{@link module:Collections.concat}
2098 * @category Collection
2099 * @alias flatMapLimit
2100 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2101 * @param {number} limit - The maximum number of async operations at a time.
2102 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
2103 * which should use an array as its result. Invoked with (item, callback).
2104 * @param {Function} [callback] - A callback which is called after all the
2105 * `iteratee` functions have finished, or an error occurs. Results is an array
2106 * containing the concatenated results of the `iteratee` function. Invoked with
2107 * (err, results).
2108 * @returns A Promise, if no callback is passed
2109 */
2110function concatLimit(coll, limit, iteratee, callback) {
2111 var _iteratee = wrapAsync(iteratee);
2112 return mapLimit$1(coll, limit, (val, iterCb) => {
2113 _iteratee(val, (err, ...args) => {
2114 if (err) return iterCb(err);
2115 return iterCb(err, args);
2116 });
2117 }, (err, mapResults) => {
2118 var result = [];
2119 for (var i = 0; i < mapResults.length; i++) {
2120 if (mapResults[i]) {
2121 result = result.concat(...mapResults[i]);
2122 }
2123 }
2124
2125 return callback(err, result);
2126 });
2127}
2128var concatLimit$1 = awaitify(concatLimit, 4);
2129
2130/**
2131 * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
2132 * the concatenated list. The `iteratee`s are called in parallel, and the
2133 * results are concatenated as they return. The results array will be returned in
2134 * the original order of `coll` passed to the `iteratee` function.
2135 *
2136 * @name concat
2137 * @static
2138 * @memberOf module:Collections
2139 * @method
2140 * @category Collection
2141 * @alias flatMap
2142 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2143 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
2144 * which should use an array as its result. Invoked with (item, callback).
2145 * @param {Function} [callback] - A callback which is called after all the
2146 * `iteratee` functions have finished, or an error occurs. Results is an array
2147 * containing the concatenated results of the `iteratee` function. Invoked with
2148 * (err, results).
2149 * @returns A Promise, if no callback is passed
2150 * @example
2151 *
2152 * // dir1 is a directory that contains file1.txt, file2.txt
2153 * // dir2 is a directory that contains file3.txt, file4.txt
2154 * // dir3 is a directory that contains file5.txt
2155 * // dir4 does not exist
2156 *
2157 * let directoryList = ['dir1','dir2','dir3'];
2158 * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];
2159 *
2160 * // Using callbacks
2161 * async.concat(directoryList, fs.readdir, function(err, results) {
2162 * if (err) {
2163 * console.log(err);
2164 * } else {
2165 * console.log(results);
2166 * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
2167 * }
2168 * });
2169 *
2170 * // Error Handling
2171 * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {
2172 * if (err) {
2173 * console.log(err);
2174 * // [ Error: ENOENT: no such file or directory ]
2175 * // since dir4 does not exist
2176 * } else {
2177 * console.log(results);
2178 * }
2179 * });
2180 *
2181 * // Using Promises
2182 * async.concat(directoryList, fs.readdir)
2183 * .then(results => {
2184 * console.log(results);
2185 * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
2186 * }).catch(err => {
2187 * console.log(err);
2188 * });
2189 *
2190 * // Error Handling
2191 * async.concat(withMissingDirectoryList, fs.readdir)
2192 * .then(results => {
2193 * console.log(results);
2194 * }).catch(err => {
2195 * console.log(err);
2196 * // [ Error: ENOENT: no such file or directory ]
2197 * // since dir4 does not exist
2198 * });
2199 *
2200 * // Using async/await
2201 * async () => {
2202 * try {
2203 * let results = await async.concat(directoryList, fs.readdir);
2204 * console.log(results);
2205 * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]
2206 * } catch (err) {
2207 * console.log(err);
2208 * }
2209 * }
2210 *
2211 * // Error Handling
2212 * async () => {
2213 * try {
2214 * let results = await async.concat(withMissingDirectoryList, fs.readdir);
2215 * console.log(results);
2216 * } catch (err) {
2217 * console.log(err);
2218 * // [ Error: ENOENT: no such file or directory ]
2219 * // since dir4 does not exist
2220 * }
2221 * }
2222 *
2223 */
2224function concat(coll, iteratee, callback) {
2225 return concatLimit$1(coll, Infinity, iteratee, callback)
2226}
2227var concat$1 = awaitify(concat, 3);
2228
2229/**
2230 * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
2231 *
2232 * @name concatSeries
2233 * @static
2234 * @memberOf module:Collections
2235 * @method
2236 * @see [async.concat]{@link module:Collections.concat}
2237 * @category Collection
2238 * @alias flatMapSeries
2239 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2240 * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
2241 * The iteratee should complete with an array an array of results.
2242 * Invoked with (item, callback).
2243 * @param {Function} [callback] - A callback which is called after all the
2244 * `iteratee` functions have finished, or an error occurs. Results is an array
2245 * containing the concatenated results of the `iteratee` function. Invoked with
2246 * (err, results).
2247 * @returns A Promise, if no callback is passed
2248 */
2249function concatSeries(coll, iteratee, callback) {
2250 return concatLimit$1(coll, 1, iteratee, callback)
2251}
2252var concatSeries$1 = awaitify(concatSeries, 3);
2253
2254/**
2255 * Returns a function that when called, calls-back with the values provided.
2256 * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
2257 * [`auto`]{@link module:ControlFlow.auto}.
2258 *
2259 * @name constant
2260 * @static
2261 * @memberOf module:Utils
2262 * @method
2263 * @category Util
2264 * @param {...*} arguments... - Any number of arguments to automatically invoke
2265 * callback with.
2266 * @returns {AsyncFunction} Returns a function that when invoked, automatically
2267 * invokes the callback with the previous given arguments.
2268 * @example
2269 *
2270 * async.waterfall([
2271 * async.constant(42),
2272 * function (value, next) {
2273 * // value === 42
2274 * },
2275 * //...
2276 * ], callback);
2277 *
2278 * async.waterfall([
2279 * async.constant(filename, "utf8"),
2280 * fs.readFile,
2281 * function (fileData, next) {
2282 * //...
2283 * }
2284 * //...
2285 * ], callback);
2286 *
2287 * async.auto({
2288 * hostname: async.constant("https://server.net/"),
2289 * port: findFreePort,
2290 * launchServer: ["hostname", "port", function (options, cb) {
2291 * startServer(options, cb);
2292 * }],
2293 * //...
2294 * }, callback);
2295 */
2296function constant$1(...args) {
2297 return function (...ignoredArgs/*, callback*/) {
2298 var callback = ignoredArgs.pop();
2299 return callback(null, ...args);
2300 };
2301}
2302
2303function _createTester(check, getResult) {
2304 return (eachfn, arr, _iteratee, cb) => {
2305 var testPassed = false;
2306 var testResult;
2307 const iteratee = wrapAsync(_iteratee);
2308 eachfn(arr, (value, _, callback) => {
2309 iteratee(value, (err, result) => {
2310 if (err || err === false) return callback(err);
2311
2312 if (check(result) && !testResult) {
2313 testPassed = true;
2314 testResult = getResult(true, value);
2315 return callback(null, breakLoop);
2316 }
2317 callback();
2318 });
2319 }, err => {
2320 if (err) return cb(err);
2321 cb(null, testPassed ? testResult : getResult(false));
2322 });
2323 };
2324}
2325
2326/**
2327 * Returns the first value in `coll` that passes an async truth test. The
2328 * `iteratee` is applied in parallel, meaning the first iteratee to return
2329 * `true` will fire the detect `callback` with that result. That means the
2330 * result might not be the first item in the original `coll` (in terms of order)
2331 * that passes the test.
2332
2333 * If order within the original `coll` is important, then look at
2334 * [`detectSeries`]{@link module:Collections.detectSeries}.
2335 *
2336 * @name detect
2337 * @static
2338 * @memberOf module:Collections
2339 * @method
2340 * @alias find
2341 * @category Collections
2342 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2343 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2344 * The iteratee must complete with a boolean value as its result.
2345 * Invoked with (item, callback).
2346 * @param {Function} [callback] - A callback which is called as soon as any
2347 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2348 * Result will be the first item in the array that passes the truth test
2349 * (iteratee) or the value `undefined` if none passed. Invoked with
2350 * (err, result).
2351 * @returns {Promise} a promise, if a callback is omitted
2352 * @example
2353 *
2354 * // dir1 is a directory that contains file1.txt, file2.txt
2355 * // dir2 is a directory that contains file3.txt, file4.txt
2356 * // dir3 is a directory that contains file5.txt
2357 *
2358 * // asynchronous function that checks if a file exists
2359 * function fileExists(file, callback) {
2360 * fs.access(file, fs.constants.F_OK, (err) => {
2361 * callback(null, !err);
2362 * });
2363 * }
2364 *
2365 * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,
2366 * function(err, result) {
2367 * console.log(result);
2368 * // dir1/file1.txt
2369 * // result now equals the first file in the list that exists
2370 * }
2371 *);
2372 *
2373 * // Using Promises
2374 * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)
2375 * .then(result => {
2376 * console.log(result);
2377 * // dir1/file1.txt
2378 * // result now equals the first file in the list that exists
2379 * }).catch(err => {
2380 * console.log(err);
2381 * });
2382 *
2383 * // Using async/await
2384 * async () => {
2385 * try {
2386 * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);
2387 * console.log(result);
2388 * // dir1/file1.txt
2389 * // result now equals the file in the list that exists
2390 * }
2391 * catch (err) {
2392 * console.log(err);
2393 * }
2394 * }
2395 *
2396 */
2397function detect(coll, iteratee, callback) {
2398 return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)
2399}
2400var detect$1 = awaitify(detect, 3);
2401
2402/**
2403 * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
2404 * time.
2405 *
2406 * @name detectLimit
2407 * @static
2408 * @memberOf module:Collections
2409 * @method
2410 * @see [async.detect]{@link module:Collections.detect}
2411 * @alias findLimit
2412 * @category Collections
2413 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2414 * @param {number} limit - The maximum number of async operations at a time.
2415 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2416 * The iteratee must complete with a boolean value as its result.
2417 * Invoked with (item, callback).
2418 * @param {Function} [callback] - A callback which is called as soon as any
2419 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2420 * Result will be the first item in the array that passes the truth test
2421 * (iteratee) or the value `undefined` if none passed. Invoked with
2422 * (err, result).
2423 * @returns {Promise} a promise, if a callback is omitted
2424 */
2425function detectLimit(coll, limit, iteratee, callback) {
2426 return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(limit), coll, iteratee, callback)
2427}
2428var detectLimit$1 = awaitify(detectLimit, 4);
2429
2430/**
2431 * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
2432 *
2433 * @name detectSeries
2434 * @static
2435 * @memberOf module:Collections
2436 * @method
2437 * @see [async.detect]{@link module:Collections.detect}
2438 * @alias findSeries
2439 * @category Collections
2440 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2441 * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2442 * The iteratee must complete with a boolean value as its result.
2443 * Invoked with (item, callback).
2444 * @param {Function} [callback] - A callback which is called as soon as any
2445 * iteratee returns `true`, or after all the `iteratee` functions have finished.
2446 * Result will be the first item in the array that passes the truth test
2447 * (iteratee) or the value `undefined` if none passed. Invoked with
2448 * (err, result).
2449 * @returns {Promise} a promise, if a callback is omitted
2450 */
2451function detectSeries(coll, iteratee, callback) {
2452 return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(1), coll, iteratee, callback)
2453}
2454
2455var detectSeries$1 = awaitify(detectSeries, 3);
2456
2457function consoleFunc(name) {
2458 return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {
2459 /* istanbul ignore else */
2460 if (typeof console === 'object') {
2461 /* istanbul ignore else */
2462 if (err) {
2463 /* istanbul ignore else */
2464 if (console.error) {
2465 console.error(err);
2466 }
2467 } else if (console[name]) { /* istanbul ignore else */
2468 resultArgs.forEach(x => console[name](x));
2469 }
2470 }
2471 })
2472}
2473
2474/**
2475 * Logs the result of an [`async` function]{@link AsyncFunction} to the
2476 * `console` using `console.dir` to display the properties of the resulting object.
2477 * Only works in Node.js or in browsers that support `console.dir` and
2478 * `console.error` (such as FF and Chrome).
2479 * If multiple arguments are returned from the async function,
2480 * `console.dir` is called on each argument in order.
2481 *
2482 * @name dir
2483 * @static
2484 * @memberOf module:Utils
2485 * @method
2486 * @category Util
2487 * @param {AsyncFunction} function - The function you want to eventually apply
2488 * all arguments to.
2489 * @param {...*} arguments... - Any number of arguments to apply to the function.
2490 * @example
2491 *
2492 * // in a module
2493 * var hello = function(name, callback) {
2494 * setTimeout(function() {
2495 * callback(null, {hello: name});
2496 * }, 1000);
2497 * };
2498 *
2499 * // in the node repl
2500 * node> async.dir(hello, 'world');
2501 * {hello: 'world'}
2502 */
2503var dir = consoleFunc('dir');
2504
2505/**
2506 * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
2507 * the order of operations, the arguments `test` and `iteratee` are switched.
2508 *
2509 * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
2510 *
2511 * @name doWhilst
2512 * @static
2513 * @memberOf module:ControlFlow
2514 * @method
2515 * @see [async.whilst]{@link module:ControlFlow.whilst}
2516 * @category Control Flow
2517 * @param {AsyncFunction} iteratee - A function which is called each time `test`
2518 * passes. Invoked with (callback).
2519 * @param {AsyncFunction} test - asynchronous truth test to perform after each
2520 * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
2521 * non-error args from the previous callback of `iteratee`.
2522 * @param {Function} [callback] - A callback which is called after the test
2523 * function has failed and repeated execution of `iteratee` has stopped.
2524 * `callback` will be passed an error and any arguments passed to the final
2525 * `iteratee`'s callback. Invoked with (err, [results]);
2526 * @returns {Promise} a promise, if no callback is passed
2527 */
2528function doWhilst(iteratee, test, callback) {
2529 callback = onlyOnce(callback);
2530 var _fn = wrapAsync(iteratee);
2531 var _test = wrapAsync(test);
2532 var results;
2533
2534 function next(err, ...args) {
2535 if (err) return callback(err);
2536 if (err === false) return;
2537 results = args;
2538 _test(...args, check);
2539 }
2540
2541 function check(err, truth) {
2542 if (err) return callback(err);
2543 if (err === false) return;
2544 if (!truth) return callback(null, ...results);
2545 _fn(next);
2546 }
2547
2548 return check(null, true);
2549}
2550
2551var doWhilst$1 = awaitify(doWhilst, 3);
2552
2553/**
2554 * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
2555 * argument ordering differs from `until`.
2556 *
2557 * @name doUntil
2558 * @static
2559 * @memberOf module:ControlFlow
2560 * @method
2561 * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
2562 * @category Control Flow
2563 * @param {AsyncFunction} iteratee - An async function which is called each time
2564 * `test` fails. Invoked with (callback).
2565 * @param {AsyncFunction} test - asynchronous truth test to perform after each
2566 * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
2567 * non-error args from the previous callback of `iteratee`
2568 * @param {Function} [callback] - A callback which is called after the test
2569 * function has passed and repeated execution of `iteratee` has stopped. `callback`
2570 * will be passed an error and any arguments passed to the final `iteratee`'s
2571 * callback. Invoked with (err, [results]);
2572 * @returns {Promise} a promise, if no callback is passed
2573 */
2574function doUntil(iteratee, test, callback) {
2575 const _test = wrapAsync(test);
2576 return doWhilst$1(iteratee, (...args) => {
2577 const cb = args.pop();
2578 _test(...args, (err, truth) => cb (err, !truth));
2579 }, callback);
2580}
2581
2582function _withoutIndex(iteratee) {
2583 return (value, index, callback) => iteratee(value, callback);
2584}
2585
2586/**
2587 * Applies the function `iteratee` to each item in `coll`, in parallel.
2588 * The `iteratee` is called with an item from the list, and a callback for when
2589 * it has finished. If the `iteratee` passes an error to its `callback`, the
2590 * main `callback` (for the `each` function) is immediately called with the
2591 * error.
2592 *
2593 * Note, that since this function applies `iteratee` to each item in parallel,
2594 * there is no guarantee that the iteratee functions will complete in order.
2595 *
2596 * @name each
2597 * @static
2598 * @memberOf module:Collections
2599 * @method
2600 * @alias forEach
2601 * @category Collection
2602 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2603 * @param {AsyncFunction} iteratee - An async function to apply to
2604 * each item in `coll`. Invoked with (item, callback).
2605 * The array index is not passed to the iteratee.
2606 * If you need the index, use `eachOf`.
2607 * @param {Function} [callback] - A callback which is called when all
2608 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2609 * @returns {Promise} a promise, if a callback is omitted
2610 * @example
2611 *
2612 * // dir1 is a directory that contains file1.txt, file2.txt
2613 * // dir2 is a directory that contains file3.txt, file4.txt
2614 * // dir3 is a directory that contains file5.txt
2615 * // dir4 does not exist
2616 *
2617 * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];
2618 * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];
2619 *
2620 * // asynchronous function that deletes a file
2621 * const deleteFile = function(file, callback) {
2622 * fs.unlink(file, callback);
2623 * };
2624 *
2625 * // Using callbacks
2626 * async.each(fileList, deleteFile, function(err) {
2627 * if( err ) {
2628 * console.log(err);
2629 * } else {
2630 * console.log('All files have been deleted successfully');
2631 * }
2632 * });
2633 *
2634 * // Error Handling
2635 * async.each(withMissingFileList, deleteFile, function(err){
2636 * console.log(err);
2637 * // [ Error: ENOENT: no such file or directory ]
2638 * // since dir4/file2.txt does not exist
2639 * // dir1/file1.txt could have been deleted
2640 * });
2641 *
2642 * // Using Promises
2643 * async.each(fileList, deleteFile)
2644 * .then( () => {
2645 * console.log('All files have been deleted successfully');
2646 * }).catch( err => {
2647 * console.log(err);
2648 * });
2649 *
2650 * // Error Handling
2651 * async.each(fileList, deleteFile)
2652 * .then( () => {
2653 * console.log('All files have been deleted successfully');
2654 * }).catch( err => {
2655 * console.log(err);
2656 * // [ Error: ENOENT: no such file or directory ]
2657 * // since dir4/file2.txt does not exist
2658 * // dir1/file1.txt could have been deleted
2659 * });
2660 *
2661 * // Using async/await
2662 * async () => {
2663 * try {
2664 * await async.each(files, deleteFile);
2665 * }
2666 * catch (err) {
2667 * console.log(err);
2668 * }
2669 * }
2670 *
2671 * // Error Handling
2672 * async () => {
2673 * try {
2674 * await async.each(withMissingFileList, deleteFile);
2675 * }
2676 * catch (err) {
2677 * console.log(err);
2678 * // [ Error: ENOENT: no such file or directory ]
2679 * // since dir4/file2.txt does not exist
2680 * // dir1/file1.txt could have been deleted
2681 * }
2682 * }
2683 *
2684 */
2685function eachLimit$2(coll, iteratee, callback) {
2686 return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);
2687}
2688
2689var each = awaitify(eachLimit$2, 3);
2690
2691/**
2692 * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
2693 *
2694 * @name eachLimit
2695 * @static
2696 * @memberOf module:Collections
2697 * @method
2698 * @see [async.each]{@link module:Collections.each}
2699 * @alias forEachLimit
2700 * @category Collection
2701 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2702 * @param {number} limit - The maximum number of async operations at a time.
2703 * @param {AsyncFunction} iteratee - An async function to apply to each item in
2704 * `coll`.
2705 * The array index is not passed to the iteratee.
2706 * If you need the index, use `eachOfLimit`.
2707 * Invoked with (item, callback).
2708 * @param {Function} [callback] - A callback which is called when all
2709 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2710 * @returns {Promise} a promise, if a callback is omitted
2711 */
2712function eachLimit(coll, limit, iteratee, callback) {
2713 return eachOfLimit$2(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
2714}
2715var eachLimit$1 = awaitify(eachLimit, 4);
2716
2717/**
2718 * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
2719 *
2720 * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
2721 * in series and therefore the iteratee functions will complete in order.
2722
2723 * @name eachSeries
2724 * @static
2725 * @memberOf module:Collections
2726 * @method
2727 * @see [async.each]{@link module:Collections.each}
2728 * @alias forEachSeries
2729 * @category Collection
2730 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2731 * @param {AsyncFunction} iteratee - An async function to apply to each
2732 * item in `coll`.
2733 * The array index is not passed to the iteratee.
2734 * If you need the index, use `eachOfSeries`.
2735 * Invoked with (item, callback).
2736 * @param {Function} [callback] - A callback which is called when all
2737 * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2738 * @returns {Promise} a promise, if a callback is omitted
2739 */
2740function eachSeries(coll, iteratee, callback) {
2741 return eachLimit$1(coll, 1, iteratee, callback)
2742}
2743var eachSeries$1 = awaitify(eachSeries, 3);
2744
2745/**
2746 * Wrap an async function and ensure it calls its callback on a later tick of
2747 * the event loop. If the function already calls its callback on a next tick,
2748 * no extra deferral is added. This is useful for preventing stack overflows
2749 * (`RangeError: Maximum call stack size exceeded`) and generally keeping
2750 * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
2751 * contained. ES2017 `async` functions are returned as-is -- they are immune
2752 * to Zalgo's corrupting influences, as they always resolve on a later tick.
2753 *
2754 * @name ensureAsync
2755 * @static
2756 * @memberOf module:Utils
2757 * @method
2758 * @category Util
2759 * @param {AsyncFunction} fn - an async function, one that expects a node-style
2760 * callback as its last argument.
2761 * @returns {AsyncFunction} Returns a wrapped function with the exact same call
2762 * signature as the function passed in.
2763 * @example
2764 *
2765 * function sometimesAsync(arg, callback) {
2766 * if (cache[arg]) {
2767 * return callback(null, cache[arg]); // this would be synchronous!!
2768 * } else {
2769 * doSomeIO(arg, callback); // this IO would be asynchronous
2770 * }
2771 * }
2772 *
2773 * // this has a risk of stack overflows if many results are cached in a row
2774 * async.mapSeries(args, sometimesAsync, done);
2775 *
2776 * // this will defer sometimesAsync's callback if necessary,
2777 * // preventing stack overflows
2778 * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
2779 */
2780function ensureAsync(fn) {
2781 if (isAsync(fn)) return fn;
2782 return function (...args/*, callback*/) {
2783 var callback = args.pop();
2784 var sync = true;
2785 args.push((...innerArgs) => {
2786 if (sync) {
2787 setImmediate$1(() => callback(...innerArgs));
2788 } else {
2789 callback(...innerArgs);
2790 }
2791 });
2792 fn.apply(this, args);
2793 sync = false;
2794 };
2795}
2796
2797/**
2798 * Returns `true` if every element in `coll` satisfies an async test. If any
2799 * iteratee call returns `false`, the main `callback` is immediately called.
2800 *
2801 * @name every
2802 * @static
2803 * @memberOf module:Collections
2804 * @method
2805 * @alias all
2806 * @category Collection
2807 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2808 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2809 * in the collection in parallel.
2810 * The iteratee must complete with a boolean result value.
2811 * Invoked with (item, callback).
2812 * @param {Function} [callback] - A callback which is called after all the
2813 * `iteratee` functions have finished. Result will be either `true` or `false`
2814 * depending on the values of the async tests. Invoked with (err, result).
2815 * @returns {Promise} a promise, if no callback provided
2816 * @example
2817 *
2818 * // dir1 is a directory that contains file1.txt, file2.txt
2819 * // dir2 is a directory that contains file3.txt, file4.txt
2820 * // dir3 is a directory that contains file5.txt
2821 * // dir4 does not exist
2822 *
2823 * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];
2824 * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];
2825 *
2826 * // asynchronous function that checks if a file exists
2827 * function fileExists(file, callback) {
2828 * fs.access(file, fs.constants.F_OK, (err) => {
2829 * callback(null, !err);
2830 * });
2831 * }
2832 *
2833 * // Using callbacks
2834 * async.every(fileList, fileExists, function(err, result) {
2835 * console.log(result);
2836 * // true
2837 * // result is true since every file exists
2838 * });
2839 *
2840 * async.every(withMissingFileList, fileExists, function(err, result) {
2841 * console.log(result);
2842 * // false
2843 * // result is false since NOT every file exists
2844 * });
2845 *
2846 * // Using Promises
2847 * async.every(fileList, fileExists)
2848 * .then( result => {
2849 * console.log(result);
2850 * // true
2851 * // result is true since every file exists
2852 * }).catch( err => {
2853 * console.log(err);
2854 * });
2855 *
2856 * async.every(withMissingFileList, fileExists)
2857 * .then( result => {
2858 * console.log(result);
2859 * // false
2860 * // result is false since NOT every file exists
2861 * }).catch( err => {
2862 * console.log(err);
2863 * });
2864 *
2865 * // Using async/await
2866 * async () => {
2867 * try {
2868 * let result = await async.every(fileList, fileExists);
2869 * console.log(result);
2870 * // true
2871 * // result is true since every file exists
2872 * }
2873 * catch (err) {
2874 * console.log(err);
2875 * }
2876 * }
2877 *
2878 * async () => {
2879 * try {
2880 * let result = await async.every(withMissingFileList, fileExists);
2881 * console.log(result);
2882 * // false
2883 * // result is false since NOT every file exists
2884 * }
2885 * catch (err) {
2886 * console.log(err);
2887 * }
2888 * }
2889 *
2890 */
2891function every(coll, iteratee, callback) {
2892 return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)
2893}
2894var every$1 = awaitify(every, 3);
2895
2896/**
2897 * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
2898 *
2899 * @name everyLimit
2900 * @static
2901 * @memberOf module:Collections
2902 * @method
2903 * @see [async.every]{@link module:Collections.every}
2904 * @alias allLimit
2905 * @category Collection
2906 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2907 * @param {number} limit - The maximum number of async operations at a time.
2908 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2909 * in the collection in parallel.
2910 * The iteratee must complete with a boolean result value.
2911 * Invoked with (item, callback).
2912 * @param {Function} [callback] - A callback which is called after all the
2913 * `iteratee` functions have finished. Result will be either `true` or `false`
2914 * depending on the values of the async tests. Invoked with (err, result).
2915 * @returns {Promise} a promise, if no callback provided
2916 */
2917function everyLimit(coll, limit, iteratee, callback) {
2918 return _createTester(bool => !bool, res => !res)(eachOfLimit$2(limit), coll, iteratee, callback)
2919}
2920var everyLimit$1 = awaitify(everyLimit, 4);
2921
2922/**
2923 * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
2924 *
2925 * @name everySeries
2926 * @static
2927 * @memberOf module:Collections
2928 * @method
2929 * @see [async.every]{@link module:Collections.every}
2930 * @alias allSeries
2931 * @category Collection
2932 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2933 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2934 * in the collection in series.
2935 * The iteratee must complete with a boolean result value.
2936 * Invoked with (item, callback).
2937 * @param {Function} [callback] - A callback which is called after all the
2938 * `iteratee` functions have finished. Result will be either `true` or `false`
2939 * depending on the values of the async tests. Invoked with (err, result).
2940 * @returns {Promise} a promise, if no callback provided
2941 */
2942function everySeries(coll, iteratee, callback) {
2943 return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)
2944}
2945var everySeries$1 = awaitify(everySeries, 3);
2946
2947function filterArray(eachfn, arr, iteratee, callback) {
2948 var truthValues = new Array(arr.length);
2949 eachfn(arr, (x, index, iterCb) => {
2950 iteratee(x, (err, v) => {
2951 truthValues[index] = !!v;
2952 iterCb(err);
2953 });
2954 }, err => {
2955 if (err) return callback(err);
2956 var results = [];
2957 for (var i = 0; i < arr.length; i++) {
2958 if (truthValues[i]) results.push(arr[i]);
2959 }
2960 callback(null, results);
2961 });
2962}
2963
2964function filterGeneric(eachfn, coll, iteratee, callback) {
2965 var results = [];
2966 eachfn(coll, (x, index, iterCb) => {
2967 iteratee(x, (err, v) => {
2968 if (err) return iterCb(err);
2969 if (v) {
2970 results.push({index, value: x});
2971 }
2972 iterCb(err);
2973 });
2974 }, err => {
2975 if (err) return callback(err);
2976 callback(null, results
2977 .sort((a, b) => a.index - b.index)
2978 .map(v => v.value));
2979 });
2980}
2981
2982function _filter(eachfn, coll, iteratee, callback) {
2983 var filter = isArrayLike(coll) ? filterArray : filterGeneric;
2984 return filter(eachfn, coll, wrapAsync(iteratee), callback);
2985}
2986
2987/**
2988 * Returns a new array of all the values in `coll` which pass an async truth
2989 * test. This operation is performed in parallel, but the results array will be
2990 * in the same order as the original.
2991 *
2992 * @name filter
2993 * @static
2994 * @memberOf module:Collections
2995 * @method
2996 * @alias select
2997 * @category Collection
2998 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2999 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3000 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3001 * with a boolean argument once it has completed. Invoked with (item, callback).
3002 * @param {Function} [callback] - A callback which is called after all the
3003 * `iteratee` functions have finished. Invoked with (err, results).
3004 * @returns {Promise} a promise, if no callback provided
3005 * @example
3006 *
3007 * // dir1 is a directory that contains file1.txt, file2.txt
3008 * // dir2 is a directory that contains file3.txt, file4.txt
3009 * // dir3 is a directory that contains file5.txt
3010 *
3011 * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
3012 *
3013 * // asynchronous function that checks if a file exists
3014 * function fileExists(file, callback) {
3015 * fs.access(file, fs.constants.F_OK, (err) => {
3016 * callback(null, !err);
3017 * });
3018 * }
3019 *
3020 * // Using callbacks
3021 * async.filter(files, fileExists, function(err, results) {
3022 * if(err) {
3023 * console.log(err);
3024 * } else {
3025 * console.log(results);
3026 * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
3027 * // results is now an array of the existing files
3028 * }
3029 * });
3030 *
3031 * // Using Promises
3032 * async.filter(files, fileExists)
3033 * .then(results => {
3034 * console.log(results);
3035 * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
3036 * // results is now an array of the existing files
3037 * }).catch(err => {
3038 * console.log(err);
3039 * });
3040 *
3041 * // Using async/await
3042 * async () => {
3043 * try {
3044 * let results = await async.filter(files, fileExists);
3045 * console.log(results);
3046 * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]
3047 * // results is now an array of the existing files
3048 * }
3049 * catch (err) {
3050 * console.log(err);
3051 * }
3052 * }
3053 *
3054 */
3055function filter (coll, iteratee, callback) {
3056 return _filter(eachOf$1, coll, iteratee, callback)
3057}
3058var filter$1 = awaitify(filter, 3);
3059
3060/**
3061 * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
3062 * time.
3063 *
3064 * @name filterLimit
3065 * @static
3066 * @memberOf module:Collections
3067 * @method
3068 * @see [async.filter]{@link module:Collections.filter}
3069 * @alias selectLimit
3070 * @category Collection
3071 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3072 * @param {number} limit - The maximum number of async operations at a time.
3073 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3074 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3075 * with a boolean argument once it has completed. Invoked with (item, callback).
3076 * @param {Function} [callback] - A callback which is called after all the
3077 * `iteratee` functions have finished. Invoked with (err, results).
3078 * @returns {Promise} a promise, if no callback provided
3079 */
3080function filterLimit (coll, limit, iteratee, callback) {
3081 return _filter(eachOfLimit$2(limit), coll, iteratee, callback)
3082}
3083var filterLimit$1 = awaitify(filterLimit, 4);
3084
3085/**
3086 * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
3087 *
3088 * @name filterSeries
3089 * @static
3090 * @memberOf module:Collections
3091 * @method
3092 * @see [async.filter]{@link module:Collections.filter}
3093 * @alias selectSeries
3094 * @category Collection
3095 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3096 * @param {Function} iteratee - A truth test to apply to each item in `coll`.
3097 * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
3098 * with a boolean argument once it has completed. Invoked with (item, callback).
3099 * @param {Function} [callback] - A callback which is called after all the
3100 * `iteratee` functions have finished. Invoked with (err, results)
3101 * @returns {Promise} a promise, if no callback provided
3102 */
3103function filterSeries (coll, iteratee, callback) {
3104 return _filter(eachOfSeries$1, coll, iteratee, callback)
3105}
3106var filterSeries$1 = awaitify(filterSeries, 3);
3107
3108/**
3109 * Calls the asynchronous function `fn` with a callback parameter that allows it
3110 * to call itself again, in series, indefinitely.
3111
3112 * If an error is passed to the callback then `errback` is called with the
3113 * error, and execution stops, otherwise it will never be called.
3114 *
3115 * @name forever
3116 * @static
3117 * @memberOf module:ControlFlow
3118 * @method
3119 * @category Control Flow
3120 * @param {AsyncFunction} fn - an async function to call repeatedly.
3121 * Invoked with (next).
3122 * @param {Function} [errback] - when `fn` passes an error to it's callback,
3123 * this function will be called, and execution stops. Invoked with (err).
3124 * @returns {Promise} a promise that rejects if an error occurs and an errback
3125 * is not passed
3126 * @example
3127 *
3128 * async.forever(
3129 * function(next) {
3130 * // next is suitable for passing to things that need a callback(err [, whatever]);
3131 * // it will result in this function being called again.
3132 * },
3133 * function(err) {
3134 * // if next is called with a value in its first parameter, it will appear
3135 * // in here as 'err', and execution will stop.
3136 * }
3137 * );
3138 */
3139function forever(fn, errback) {
3140 var done = onlyOnce(errback);
3141 var task = wrapAsync(ensureAsync(fn));
3142
3143 function next(err) {
3144 if (err) return done(err);
3145 if (err === false) return;
3146 task(next);
3147 }
3148 return next();
3149}
3150var forever$1 = awaitify(forever, 2);
3151
3152/**
3153 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
3154 *
3155 * @name groupByLimit
3156 * @static
3157 * @memberOf module:Collections
3158 * @method
3159 * @see [async.groupBy]{@link module:Collections.groupBy}
3160 * @category Collection
3161 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3162 * @param {number} limit - The maximum number of async operations at a time.
3163 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3164 * `coll`.
3165 * The iteratee should complete with a `key` to group the value under.
3166 * Invoked with (value, callback).
3167 * @param {Function} [callback] - A callback which is called when all `iteratee`
3168 * functions have finished, or an error occurs. Result is an `Object` whoses
3169 * properties are arrays of values which returned the corresponding key.
3170 * @returns {Promise} a promise, if no callback is passed
3171 */
3172function groupByLimit(coll, limit, iteratee, callback) {
3173 var _iteratee = wrapAsync(iteratee);
3174 return mapLimit$1(coll, limit, (val, iterCb) => {
3175 _iteratee(val, (err, key) => {
3176 if (err) return iterCb(err);
3177 return iterCb(err, {key, val});
3178 });
3179 }, (err, mapResults) => {
3180 var result = {};
3181 // from MDN, handle object having an `hasOwnProperty` prop
3182 var {hasOwnProperty} = Object.prototype;
3183
3184 for (var i = 0; i < mapResults.length; i++) {
3185 if (mapResults[i]) {
3186 var {key} = mapResults[i];
3187 var {val} = mapResults[i];
3188
3189 if (hasOwnProperty.call(result, key)) {
3190 result[key].push(val);
3191 } else {
3192 result[key] = [val];
3193 }
3194 }
3195 }
3196
3197 return callback(err, result);
3198 });
3199}
3200
3201var groupByLimit$1 = awaitify(groupByLimit, 4);
3202
3203/**
3204 * Returns a new object, where each value corresponds to an array of items, from
3205 * `coll`, that returned the corresponding key. That is, the keys of the object
3206 * correspond to the values passed to the `iteratee` callback.
3207 *
3208 * Note: Since this function applies the `iteratee` to each item in parallel,
3209 * there is no guarantee that the `iteratee` functions will complete in order.
3210 * However, the values for each key in the `result` will be in the same order as
3211 * the original `coll`. For Objects, the values will roughly be in the order of
3212 * the original Objects' keys (but this can vary across JavaScript engines).
3213 *
3214 * @name groupBy
3215 * @static
3216 * @memberOf module:Collections
3217 * @method
3218 * @category Collection
3219 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3220 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3221 * `coll`.
3222 * The iteratee should complete with a `key` to group the value under.
3223 * Invoked with (value, callback).
3224 * @param {Function} [callback] - A callback which is called when all `iteratee`
3225 * functions have finished, or an error occurs. Result is an `Object` whoses
3226 * properties are arrays of values which returned the corresponding key.
3227 * @returns {Promise} a promise, if no callback is passed
3228 * @example
3229 *
3230 * // dir1 is a directory that contains file1.txt, file2.txt
3231 * // dir2 is a directory that contains file3.txt, file4.txt
3232 * // dir3 is a directory that contains file5.txt
3233 * // dir4 does not exist
3234 *
3235 * const files = ['dir1/file1.txt','dir2','dir4']
3236 *
3237 * // asynchronous function that detects file type as none, file, or directory
3238 * function detectFile(file, callback) {
3239 * fs.stat(file, function(err, stat) {
3240 * if (err) {
3241 * return callback(null, 'none');
3242 * }
3243 * callback(null, stat.isDirectory() ? 'directory' : 'file');
3244 * });
3245 * }
3246 *
3247 * //Using callbacks
3248 * async.groupBy(files, detectFile, function(err, result) {
3249 * if(err) {
3250 * console.log(err);
3251 * } else {
3252 * console.log(result);
3253 * // {
3254 * // file: [ 'dir1/file1.txt' ],
3255 * // none: [ 'dir4' ],
3256 * // directory: [ 'dir2']
3257 * // }
3258 * // result is object containing the files grouped by type
3259 * }
3260 * });
3261 *
3262 * // Using Promises
3263 * async.groupBy(files, detectFile)
3264 * .then( result => {
3265 * console.log(result);
3266 * // {
3267 * // file: [ 'dir1/file1.txt' ],
3268 * // none: [ 'dir4' ],
3269 * // directory: [ 'dir2']
3270 * // }
3271 * // result is object containing the files grouped by type
3272 * }).catch( err => {
3273 * console.log(err);
3274 * });
3275 *
3276 * // Using async/await
3277 * async () => {
3278 * try {
3279 * let result = await async.groupBy(files, detectFile);
3280 * console.log(result);
3281 * // {
3282 * // file: [ 'dir1/file1.txt' ],
3283 * // none: [ 'dir4' ],
3284 * // directory: [ 'dir2']
3285 * // }
3286 * // result is object containing the files grouped by type
3287 * }
3288 * catch (err) {
3289 * console.log(err);
3290 * }
3291 * }
3292 *
3293 */
3294function groupBy (coll, iteratee, callback) {
3295 return groupByLimit$1(coll, Infinity, iteratee, callback)
3296}
3297
3298/**
3299 * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
3300 *
3301 * @name groupBySeries
3302 * @static
3303 * @memberOf module:Collections
3304 * @method
3305 * @see [async.groupBy]{@link module:Collections.groupBy}
3306 * @category Collection
3307 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3308 * @param {AsyncFunction} iteratee - An async function to apply to each item in
3309 * `coll`.
3310 * The iteratee should complete with a `key` to group the value under.
3311 * Invoked with (value, callback).
3312 * @param {Function} [callback] - A callback which is called when all `iteratee`
3313 * functions have finished, or an error occurs. Result is an `Object` whose
3314 * properties are arrays of values which returned the corresponding key.
3315 * @returns {Promise} a promise, if no callback is passed
3316 */
3317function groupBySeries (coll, iteratee, callback) {
3318 return groupByLimit$1(coll, 1, iteratee, callback)
3319}
3320
3321/**
3322 * Logs the result of an `async` function to the `console`. Only works in
3323 * Node.js or in browsers that support `console.log` and `console.error` (such
3324 * as FF and Chrome). If multiple arguments are returned from the async
3325 * function, `console.log` is called on each argument in order.
3326 *
3327 * @name log
3328 * @static
3329 * @memberOf module:Utils
3330 * @method
3331 * @category Util
3332 * @param {AsyncFunction} function - The function you want to eventually apply
3333 * all arguments to.
3334 * @param {...*} arguments... - Any number of arguments to apply to the function.
3335 * @example
3336 *
3337 * // in a module
3338 * var hello = function(name, callback) {
3339 * setTimeout(function() {
3340 * callback(null, 'hello ' + name);
3341 * }, 1000);
3342 * };
3343 *
3344 * // in the node repl
3345 * node> async.log(hello, 'world');
3346 * 'hello world'
3347 */
3348var log = consoleFunc('log');
3349
3350/**
3351 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
3352 * time.
3353 *
3354 * @name mapValuesLimit
3355 * @static
3356 * @memberOf module:Collections
3357 * @method
3358 * @see [async.mapValues]{@link module:Collections.mapValues}
3359 * @category Collection
3360 * @param {Object} obj - A collection to iterate over.
3361 * @param {number} limit - The maximum number of async operations at a time.
3362 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3363 * in `coll`.
3364 * The iteratee should complete with the transformed value as its result.
3365 * Invoked with (value, key, callback).
3366 * @param {Function} [callback] - A callback which is called when all `iteratee`
3367 * functions have finished, or an error occurs. `result` is a new object consisting
3368 * of each key from `obj`, with each transformed value on the right-hand side.
3369 * Invoked with (err, result).
3370 * @returns {Promise} a promise, if no callback is passed
3371 */
3372function mapValuesLimit(obj, limit, iteratee, callback) {
3373 callback = once(callback);
3374 var newObj = {};
3375 var _iteratee = wrapAsync(iteratee);
3376 return eachOfLimit$2(limit)(obj, (val, key, next) => {
3377 _iteratee(val, key, (err, result) => {
3378 if (err) return next(err);
3379 newObj[key] = result;
3380 next(err);
3381 });
3382 }, err => callback(err, newObj));
3383}
3384
3385var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);
3386
3387/**
3388 * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
3389 *
3390 * Produces a new Object by mapping each value of `obj` through the `iteratee`
3391 * function. The `iteratee` is called each `value` and `key` from `obj` and a
3392 * callback for when it has finished processing. Each of these callbacks takes
3393 * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
3394 * passes an error to its callback, the main `callback` (for the `mapValues`
3395 * function) is immediately called with the error.
3396 *
3397 * Note, the order of the keys in the result is not guaranteed. The keys will
3398 * be roughly in the order they complete, (but this is very engine-specific)
3399 *
3400 * @name mapValues
3401 * @static
3402 * @memberOf module:Collections
3403 * @method
3404 * @category Collection
3405 * @param {Object} obj - A collection to iterate over.
3406 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3407 * in `coll`.
3408 * The iteratee should complete with the transformed value as its result.
3409 * Invoked with (value, key, callback).
3410 * @param {Function} [callback] - A callback which is called when all `iteratee`
3411 * functions have finished, or an error occurs. `result` is a new object consisting
3412 * of each key from `obj`, with each transformed value on the right-hand side.
3413 * Invoked with (err, result).
3414 * @returns {Promise} a promise, if no callback is passed
3415 * @example
3416 *
3417 * // file1.txt is a file that is 1000 bytes in size
3418 * // file2.txt is a file that is 2000 bytes in size
3419 * // file3.txt is a file that is 3000 bytes in size
3420 * // file4.txt does not exist
3421 *
3422 * const fileMap = {
3423 * f1: 'file1.txt',
3424 * f2: 'file2.txt',
3425 * f3: 'file3.txt'
3426 * };
3427 *
3428 * const withMissingFileMap = {
3429 * f1: 'file1.txt',
3430 * f2: 'file2.txt',
3431 * f3: 'file4.txt'
3432 * };
3433 *
3434 * // asynchronous function that returns the file size in bytes
3435 * function getFileSizeInBytes(file, key, callback) {
3436 * fs.stat(file, function(err, stat) {
3437 * if (err) {
3438 * return callback(err);
3439 * }
3440 * callback(null, stat.size);
3441 * });
3442 * }
3443 *
3444 * // Using callbacks
3445 * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {
3446 * if (err) {
3447 * console.log(err);
3448 * } else {
3449 * console.log(result);
3450 * // result is now a map of file size in bytes for each file, e.g.
3451 * // {
3452 * // f1: 1000,
3453 * // f2: 2000,
3454 * // f3: 3000
3455 * // }
3456 * }
3457 * });
3458 *
3459 * // Error handling
3460 * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {
3461 * if (err) {
3462 * console.log(err);
3463 * // [ Error: ENOENT: no such file or directory ]
3464 * } else {
3465 * console.log(result);
3466 * }
3467 * });
3468 *
3469 * // Using Promises
3470 * async.mapValues(fileMap, getFileSizeInBytes)
3471 * .then( result => {
3472 * console.log(result);
3473 * // result is now a map of file size in bytes for each file, e.g.
3474 * // {
3475 * // f1: 1000,
3476 * // f2: 2000,
3477 * // f3: 3000
3478 * // }
3479 * }).catch (err => {
3480 * console.log(err);
3481 * });
3482 *
3483 * // Error Handling
3484 * async.mapValues(withMissingFileMap, getFileSizeInBytes)
3485 * .then( result => {
3486 * console.log(result);
3487 * }).catch (err => {
3488 * console.log(err);
3489 * // [ Error: ENOENT: no such file or directory ]
3490 * });
3491 *
3492 * // Using async/await
3493 * async () => {
3494 * try {
3495 * let result = await async.mapValues(fileMap, getFileSizeInBytes);
3496 * console.log(result);
3497 * // result is now a map of file size in bytes for each file, e.g.
3498 * // {
3499 * // f1: 1000,
3500 * // f2: 2000,
3501 * // f3: 3000
3502 * // }
3503 * }
3504 * catch (err) {
3505 * console.log(err);
3506 * }
3507 * }
3508 *
3509 * // Error Handling
3510 * async () => {
3511 * try {
3512 * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);
3513 * console.log(result);
3514 * }
3515 * catch (err) {
3516 * console.log(err);
3517 * // [ Error: ENOENT: no such file or directory ]
3518 * }
3519 * }
3520 *
3521 */
3522function mapValues(obj, iteratee, callback) {
3523 return mapValuesLimit$1(obj, Infinity, iteratee, callback)
3524}
3525
3526/**
3527 * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
3528 *
3529 * @name mapValuesSeries
3530 * @static
3531 * @memberOf module:Collections
3532 * @method
3533 * @see [async.mapValues]{@link module:Collections.mapValues}
3534 * @category Collection
3535 * @param {Object} obj - A collection to iterate over.
3536 * @param {AsyncFunction} iteratee - A function to apply to each value and key
3537 * in `coll`.
3538 * The iteratee should complete with the transformed value as its result.
3539 * Invoked with (value, key, callback).
3540 * @param {Function} [callback] - A callback which is called when all `iteratee`
3541 * functions have finished, or an error occurs. `result` is a new object consisting
3542 * of each key from `obj`, with each transformed value on the right-hand side.
3543 * Invoked with (err, result).
3544 * @returns {Promise} a promise, if no callback is passed
3545 */
3546function mapValuesSeries(obj, iteratee, callback) {
3547 return mapValuesLimit$1(obj, 1, iteratee, callback)
3548}
3549
3550/**
3551 * Caches the results of an async function. When creating a hash to store
3552 * function results against, the callback is omitted from the hash and an
3553 * optional hash function can be used.
3554 *
3555 * **Note: if the async function errs, the result will not be cached and
3556 * subsequent calls will call the wrapped function.**
3557 *
3558 * If no hash function is specified, the first argument is used as a hash key,
3559 * which may work reasonably if it is a string or a data type that converts to a
3560 * distinct string. Note that objects and arrays will not behave reasonably.
3561 * Neither will cases where the other arguments are significant. In such cases,
3562 * specify your own hash function.
3563 *
3564 * The cache of results is exposed as the `memo` property of the function
3565 * returned by `memoize`.
3566 *
3567 * @name memoize
3568 * @static
3569 * @memberOf module:Utils
3570 * @method
3571 * @category Util
3572 * @param {AsyncFunction} fn - The async function to proxy and cache results from.
3573 * @param {Function} hasher - An optional function for generating a custom hash
3574 * for storing results. It has all the arguments applied to it apart from the
3575 * callback, and must be synchronous.
3576 * @returns {AsyncFunction} a memoized version of `fn`
3577 * @example
3578 *
3579 * var slow_fn = function(name, callback) {
3580 * // do something
3581 * callback(null, result);
3582 * };
3583 * var fn = async.memoize(slow_fn);
3584 *
3585 * // fn can now be used as if it were slow_fn
3586 * fn('some name', function() {
3587 * // callback
3588 * });
3589 */
3590function memoize(fn, hasher = v => v) {
3591 var memo = Object.create(null);
3592 var queues = Object.create(null);
3593 var _fn = wrapAsync(fn);
3594 var memoized = initialParams((args, callback) => {
3595 var key = hasher(...args);
3596 if (key in memo) {
3597 setImmediate$1(() => callback(null, ...memo[key]));
3598 } else if (key in queues) {
3599 queues[key].push(callback);
3600 } else {
3601 queues[key] = [callback];
3602 _fn(...args, (err, ...resultArgs) => {
3603 // #1465 don't memoize if an error occurred
3604 if (!err) {
3605 memo[key] = resultArgs;
3606 }
3607 var q = queues[key];
3608 delete queues[key];
3609 for (var i = 0, l = q.length; i < l; i++) {
3610 q[i](err, ...resultArgs);
3611 }
3612 });
3613 }
3614 });
3615 memoized.memo = memo;
3616 memoized.unmemoized = fn;
3617 return memoized;
3618}
3619
3620/* istanbul ignore file */
3621
3622/**
3623 * Calls `callback` on a later loop around the event loop. In Node.js this just
3624 * calls `process.nextTick`. In the browser it will use `setImmediate` if
3625 * available, otherwise `setTimeout(callback, 0)`, which means other higher
3626 * priority events may precede the execution of `callback`.
3627 *
3628 * This is used internally for browser-compatibility purposes.
3629 *
3630 * @name nextTick
3631 * @static
3632 * @memberOf module:Utils
3633 * @method
3634 * @see [async.setImmediate]{@link module:Utils.setImmediate}
3635 * @category Util
3636 * @param {Function} callback - The function to call on a later loop around
3637 * the event loop. Invoked with (args...).
3638 * @param {...*} args... - any number of additional arguments to pass to the
3639 * callback on the next tick.
3640 * @example
3641 *
3642 * var call_order = [];
3643 * async.nextTick(function() {
3644 * call_order.push('two');
3645 * // call_order now equals ['one','two']
3646 * });
3647 * call_order.push('one');
3648 *
3649 * async.setImmediate(function (a, b, c) {
3650 * // a, b, and c equal 1, 2, and 3
3651 * }, 1, 2, 3);
3652 */
3653var _defer;
3654
3655if (hasNextTick) {
3656 _defer = process.nextTick;
3657} else if (hasSetImmediate) {
3658 _defer = setImmediate;
3659} else {
3660 _defer = fallback;
3661}
3662
3663var nextTick = wrap(_defer);
3664
3665var _parallel = awaitify((eachfn, tasks, callback) => {
3666 var results = isArrayLike(tasks) ? [] : {};
3667
3668 eachfn(tasks, (task, key, taskCb) => {
3669 wrapAsync(task)((err, ...result) => {
3670 if (result.length < 2) {
3671 [result] = result;
3672 }
3673 results[key] = result;
3674 taskCb(err);
3675 });
3676 }, err => callback(err, results));
3677}, 3);
3678
3679/**
3680 * Run the `tasks` collection of functions in parallel, without waiting until
3681 * the previous function has completed. If any of the functions pass an error to
3682 * its callback, the main `callback` is immediately called with the value of the
3683 * error. Once the `tasks` have completed, the results are passed to the final
3684 * `callback` as an array.
3685 *
3686 * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
3687 * parallel execution of code. If your tasks do not use any timers or perform
3688 * any I/O, they will actually be executed in series. Any synchronous setup
3689 * sections for each task will happen one after the other. JavaScript remains
3690 * single-threaded.
3691 *
3692 * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
3693 * execution of other tasks when a task fails.
3694 *
3695 * It is also possible to use an object instead of an array. Each property will
3696 * be run as a function and the results will be passed to the final `callback`
3697 * as an object instead of an array. This can be a more readable way of handling
3698 * results from {@link async.parallel}.
3699 *
3700 * @name parallel
3701 * @static
3702 * @memberOf module:ControlFlow
3703 * @method
3704 * @category Control Flow
3705 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
3706 * [async functions]{@link AsyncFunction} to run.
3707 * Each async function can complete with any number of optional `result` values.
3708 * @param {Function} [callback] - An optional callback to run once all the
3709 * functions have completed successfully. This function gets a results array
3710 * (or object) containing all the result arguments passed to the task callbacks.
3711 * Invoked with (err, results).
3712 * @returns {Promise} a promise, if a callback is not passed
3713 *
3714 * @example
3715 *
3716 * //Using Callbacks
3717 * async.parallel([
3718 * function(callback) {
3719 * setTimeout(function() {
3720 * callback(null, 'one');
3721 * }, 200);
3722 * },
3723 * function(callback) {
3724 * setTimeout(function() {
3725 * callback(null, 'two');
3726 * }, 100);
3727 * }
3728 * ], function(err, results) {
3729 * console.log(results);
3730 * // results is equal to ['one','two'] even though
3731 * // the second function had a shorter timeout.
3732 * });
3733 *
3734 * // an example using an object instead of an array
3735 * async.parallel({
3736 * one: function(callback) {
3737 * setTimeout(function() {
3738 * callback(null, 1);
3739 * }, 200);
3740 * },
3741 * two: function(callback) {
3742 * setTimeout(function() {
3743 * callback(null, 2);
3744 * }, 100);
3745 * }
3746 * }, function(err, results) {
3747 * console.log(results);
3748 * // results is equal to: { one: 1, two: 2 }
3749 * });
3750 *
3751 * //Using Promises
3752 * async.parallel([
3753 * function(callback) {
3754 * setTimeout(function() {
3755 * callback(null, 'one');
3756 * }, 200);
3757 * },
3758 * function(callback) {
3759 * setTimeout(function() {
3760 * callback(null, 'two');
3761 * }, 100);
3762 * }
3763 * ]).then(results => {
3764 * console.log(results);
3765 * // results is equal to ['one','two'] even though
3766 * // the second function had a shorter timeout.
3767 * }).catch(err => {
3768 * console.log(err);
3769 * });
3770 *
3771 * // an example using an object instead of an array
3772 * async.parallel({
3773 * one: function(callback) {
3774 * setTimeout(function() {
3775 * callback(null, 1);
3776 * }, 200);
3777 * },
3778 * two: function(callback) {
3779 * setTimeout(function() {
3780 * callback(null, 2);
3781 * }, 100);
3782 * }
3783 * }).then(results => {
3784 * console.log(results);
3785 * // results is equal to: { one: 1, two: 2 }
3786 * }).catch(err => {
3787 * console.log(err);
3788 * });
3789 *
3790 * //Using async/await
3791 * async () => {
3792 * try {
3793 * let results = await async.parallel([
3794 * function(callback) {
3795 * setTimeout(function() {
3796 * callback(null, 'one');
3797 * }, 200);
3798 * },
3799 * function(callback) {
3800 * setTimeout(function() {
3801 * callback(null, 'two');
3802 * }, 100);
3803 * }
3804 * ]);
3805 * console.log(results);
3806 * // results is equal to ['one','two'] even though
3807 * // the second function had a shorter timeout.
3808 * }
3809 * catch (err) {
3810 * console.log(err);
3811 * }
3812 * }
3813 *
3814 * // an example using an object instead of an array
3815 * async () => {
3816 * try {
3817 * let results = await async.parallel({
3818 * one: function(callback) {
3819 * setTimeout(function() {
3820 * callback(null, 1);
3821 * }, 200);
3822 * },
3823 * two: function(callback) {
3824 * setTimeout(function() {
3825 * callback(null, 2);
3826 * }, 100);
3827 * }
3828 * });
3829 * console.log(results);
3830 * // results is equal to: { one: 1, two: 2 }
3831 * }
3832 * catch (err) {
3833 * console.log(err);
3834 * }
3835 * }
3836 *
3837 */
3838function parallel(tasks, callback) {
3839 return _parallel(eachOf$1, tasks, callback);
3840}
3841
3842/**
3843 * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
3844 * time.
3845 *
3846 * @name parallelLimit
3847 * @static
3848 * @memberOf module:ControlFlow
3849 * @method
3850 * @see [async.parallel]{@link module:ControlFlow.parallel}
3851 * @category Control Flow
3852 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
3853 * [async functions]{@link AsyncFunction} to run.
3854 * Each async function can complete with any number of optional `result` values.
3855 * @param {number} limit - The maximum number of async operations at a time.
3856 * @param {Function} [callback] - An optional callback to run once all the
3857 * functions have completed successfully. This function gets a results array
3858 * (or object) containing all the result arguments passed to the task callbacks.
3859 * Invoked with (err, results).
3860 * @returns {Promise} a promise, if a callback is not passed
3861 */
3862function parallelLimit(tasks, limit, callback) {
3863 return _parallel(eachOfLimit$2(limit), tasks, callback);
3864}
3865
3866/**
3867 * A queue of tasks for the worker function to complete.
3868 * @typedef {Iterable} QueueObject
3869 * @memberOf module:ControlFlow
3870 * @property {Function} length - a function returning the number of items
3871 * waiting to be processed. Invoke with `queue.length()`.
3872 * @property {boolean} started - a boolean indicating whether or not any
3873 * items have been pushed and processed by the queue.
3874 * @property {Function} running - a function returning the number of items
3875 * currently being processed. Invoke with `queue.running()`.
3876 * @property {Function} workersList - a function returning the array of items
3877 * currently being processed. Invoke with `queue.workersList()`.
3878 * @property {Function} idle - a function returning false if there are items
3879 * waiting or being processed, or true if not. Invoke with `queue.idle()`.
3880 * @property {number} concurrency - an integer for determining how many `worker`
3881 * functions should be run in parallel. This property can be changed after a
3882 * `queue` is created to alter the concurrency on-the-fly.
3883 * @property {number} payload - an integer that specifies how many items are
3884 * passed to the worker function at a time. only applies if this is a
3885 * [cargo]{@link module:ControlFlow.cargo} object
3886 * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`
3887 * once the `worker` has finished processing the task. Instead of a single task,
3888 * a `tasks` array can be submitted. The respective callback is used for every
3889 * task in the list. Invoke with `queue.push(task, [callback])`,
3890 * @property {AsyncFunction} unshift - add a new task to the front of the `queue`.
3891 * Invoke with `queue.unshift(task, [callback])`.
3892 * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns
3893 * a promise that rejects if an error occurs.
3894 * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns
3895 * a promise that rejects if an error occurs.
3896 * @property {Function} remove - remove items from the queue that match a test
3897 * function. The test function will be passed an object with a `data` property,
3898 * and a `priority` property, if this is a
3899 * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
3900 * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
3901 * `function ({data, priority}) {}` and returns a Boolean.
3902 * @property {Function} saturated - a function that sets a callback that is
3903 * called when the number of running workers hits the `concurrency` limit, and
3904 * further tasks will be queued. If the callback is omitted, `q.saturated()`
3905 * returns a promise for the next occurrence.
3906 * @property {Function} unsaturated - a function that sets a callback that is
3907 * called when the number of running workers is less than the `concurrency` &
3908 * `buffer` limits, and further tasks will not be queued. If the callback is
3909 * omitted, `q.unsaturated()` returns a promise for the next occurrence.
3910 * @property {number} buffer - A minimum threshold buffer in order to say that
3911 * the `queue` is `unsaturated`.
3912 * @property {Function} empty - a function that sets a callback that is called
3913 * when the last item from the `queue` is given to a `worker`. If the callback
3914 * is omitted, `q.empty()` returns a promise for the next occurrence.
3915 * @property {Function} drain - a function that sets a callback that is called
3916 * when the last item from the `queue` has returned from the `worker`. If the
3917 * callback is omitted, `q.drain()` returns a promise for the next occurrence.
3918 * @property {Function} error - a function that sets a callback that is called
3919 * when a task errors. Has the signature `function(error, task)`. If the
3920 * callback is omitted, `error()` returns a promise that rejects on the next
3921 * error.
3922 * @property {boolean} paused - a boolean for determining whether the queue is
3923 * in a paused state.
3924 * @property {Function} pause - a function that pauses the processing of tasks
3925 * until `resume()` is called. Invoke with `queue.pause()`.
3926 * @property {Function} resume - a function that resumes the processing of
3927 * queued tasks when the queue is paused. Invoke with `queue.resume()`.
3928 * @property {Function} kill - a function that removes the `drain` callback and
3929 * empties remaining tasks from the queue forcing it to go idle. No more tasks
3930 * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
3931 *
3932 * @example
3933 * const q = async.queue(worker, 2)
3934 * q.push(item1)
3935 * q.push(item2)
3936 * q.push(item3)
3937 * // queues are iterable, spread into an array to inspect
3938 * const items = [...q] // [item1, item2, item3]
3939 * // or use for of
3940 * for (let item of q) {
3941 * console.log(item)
3942 * }
3943 *
3944 * q.drain(() => {
3945 * console.log('all done')
3946 * })
3947 * // or
3948 * await q.drain()
3949 */
3950
3951/**
3952 * Creates a `queue` object with the specified `concurrency`. Tasks added to the
3953 * `queue` are processed in parallel (up to the `concurrency` limit). If all
3954 * `worker`s are in progress, the task is queued until one becomes available.
3955 * Once a `worker` completes a `task`, that `task`'s callback is called.
3956 *
3957 * @name queue
3958 * @static
3959 * @memberOf module:ControlFlow
3960 * @method
3961 * @category Control Flow
3962 * @param {AsyncFunction} worker - An async function for processing a queued task.
3963 * If you want to handle errors from an individual task, pass a callback to
3964 * `q.push()`. Invoked with (task, callback).
3965 * @param {number} [concurrency=1] - An `integer` for determining how many
3966 * `worker` functions should be run in parallel. If omitted, the concurrency
3967 * defaults to `1`. If the concurrency is `0`, an error is thrown.
3968 * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be
3969 * attached as certain properties to listen for specific events during the
3970 * lifecycle of the queue.
3971 * @example
3972 *
3973 * // create a queue object with concurrency 2
3974 * var q = async.queue(function(task, callback) {
3975 * console.log('hello ' + task.name);
3976 * callback();
3977 * }, 2);
3978 *
3979 * // assign a callback
3980 * q.drain(function() {
3981 * console.log('all items have been processed');
3982 * });
3983 * // or await the end
3984 * await q.drain()
3985 *
3986 * // assign an error callback
3987 * q.error(function(err, task) {
3988 * console.error('task experienced an error');
3989 * });
3990 *
3991 * // add some items to the queue
3992 * q.push({name: 'foo'}, function(err) {
3993 * console.log('finished processing foo');
3994 * });
3995 * // callback is optional
3996 * q.push({name: 'bar'});
3997 *
3998 * // add some items to the queue (batch-wise)
3999 * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
4000 * console.log('finished processing item');
4001 * });
4002 *
4003 * // add some items to the front of the queue
4004 * q.unshift({name: 'bar'}, function (err) {
4005 * console.log('finished processing bar');
4006 * });
4007 */
4008function queue (worker, concurrency) {
4009 var _worker = wrapAsync(worker);
4010 return queue$1((items, cb) => {
4011 _worker(items[0], cb);
4012 }, concurrency, 1);
4013}
4014
4015// Binary min-heap implementation used for priority queue.
4016// Implementation is stable, i.e. push time is considered for equal priorities
4017class Heap {
4018 constructor() {
4019 this.heap = [];
4020 this.pushCount = Number.MIN_SAFE_INTEGER;
4021 }
4022
4023 get length() {
4024 return this.heap.length;
4025 }
4026
4027 empty () {
4028 this.heap = [];
4029 return this;
4030 }
4031
4032 percUp(index) {
4033 let p;
4034
4035 while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {
4036 let t = this.heap[index];
4037 this.heap[index] = this.heap[p];
4038 this.heap[p] = t;
4039
4040 index = p;
4041 }
4042 }
4043
4044 percDown(index) {
4045 let l;
4046
4047 while ((l=leftChi(index)) < this.heap.length) {
4048 if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {
4049 l = l+1;
4050 }
4051
4052 if (smaller(this.heap[index], this.heap[l])) {
4053 break;
4054 }
4055
4056 let t = this.heap[index];
4057 this.heap[index] = this.heap[l];
4058 this.heap[l] = t;
4059
4060 index = l;
4061 }
4062 }
4063
4064 push(node) {
4065 node.pushCount = ++this.pushCount;
4066 this.heap.push(node);
4067 this.percUp(this.heap.length-1);
4068 }
4069
4070 unshift(node) {
4071 return this.heap.push(node);
4072 }
4073
4074 shift() {
4075 let [top] = this.heap;
4076
4077 this.heap[0] = this.heap[this.heap.length-1];
4078 this.heap.pop();
4079 this.percDown(0);
4080
4081 return top;
4082 }
4083
4084 toArray() {
4085 return [...this];
4086 }
4087
4088 *[Symbol.iterator] () {
4089 for (let i = 0; i < this.heap.length; i++) {
4090 yield this.heap[i].data;
4091 }
4092 }
4093
4094 remove (testFn) {
4095 let j = 0;
4096 for (let i = 0; i < this.heap.length; i++) {
4097 if (!testFn(this.heap[i])) {
4098 this.heap[j] = this.heap[i];
4099 j++;
4100 }
4101 }
4102
4103 this.heap.splice(j);
4104
4105 for (let i = parent(this.heap.length-1); i >= 0; i--) {
4106 this.percDown(i);
4107 }
4108
4109 return this;
4110 }
4111}
4112
4113function leftChi(i) {
4114 return (i<<1)+1;
4115}
4116
4117function parent(i) {
4118 return ((i+1)>>1)-1;
4119}
4120
4121function smaller(x, y) {
4122 if (x.priority !== y.priority) {
4123 return x.priority < y.priority;
4124 }
4125 else {
4126 return x.pushCount < y.pushCount;
4127 }
4128}
4129
4130/**
4131 * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
4132 * completed in ascending priority order.
4133 *
4134 * @name priorityQueue
4135 * @static
4136 * @memberOf module:ControlFlow
4137 * @method
4138 * @see [async.queue]{@link module:ControlFlow.queue}
4139 * @category Control Flow
4140 * @param {AsyncFunction} worker - An async function for processing a queued task.
4141 * If you want to handle errors from an individual task, pass a callback to
4142 * `q.push()`.
4143 * Invoked with (task, callback).
4144 * @param {number} concurrency - An `integer` for determining how many `worker`
4145 * functions should be run in parallel. If omitted, the concurrency defaults to
4146 * `1`. If the concurrency is `0`, an error is thrown.
4147 * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are three
4148 * differences between `queue` and `priorityQueue` objects:
4149 * * `push(task, priority, [callback])` - `priority` should be a number. If an
4150 * array of `tasks` is given, all tasks will be assigned the same priority.
4151 * * `pushAsync(task, priority, [callback])` - the same as `priorityQueue.push`,
4152 * except this returns a promise that rejects if an error occurs.
4153 * * The `unshift` and `unshiftAsync` methods were removed.
4154 */
4155function priorityQueue(worker, concurrency) {
4156 // Start with a normal queue
4157 var q = queue(worker, concurrency);
4158
4159 var {
4160 push,
4161 pushAsync
4162 } = q;
4163
4164 q._tasks = new Heap();
4165 q._createTaskItem = ({data, priority}, callback) => {
4166 return {
4167 data,
4168 priority,
4169 callback
4170 };
4171 };
4172
4173 function createDataItems(tasks, priority) {
4174 if (!Array.isArray(tasks)) {
4175 return {data: tasks, priority};
4176 }
4177 return tasks.map(data => { return {data, priority}; });
4178 }
4179
4180 // Override push to accept second parameter representing priority
4181 q.push = function(data, priority = 0, callback) {
4182 return push(createDataItems(data, priority), callback);
4183 };
4184
4185 q.pushAsync = function(data, priority = 0, callback) {
4186 return pushAsync(createDataItems(data, priority), callback);
4187 };
4188
4189 // Remove unshift functions
4190 delete q.unshift;
4191 delete q.unshiftAsync;
4192
4193 return q;
4194}
4195
4196/**
4197 * Runs the `tasks` array of functions in parallel, without waiting until the
4198 * previous function has completed. Once any of the `tasks` complete or pass an
4199 * error to its callback, the main `callback` is immediately called. It's
4200 * equivalent to `Promise.race()`.
4201 *
4202 * @name race
4203 * @static
4204 * @memberOf module:ControlFlow
4205 * @method
4206 * @category Control Flow
4207 * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
4208 * to run. Each function can complete with an optional `result` value.
4209 * @param {Function} callback - A callback to run once any of the functions have
4210 * completed. This function gets an error or result from the first function that
4211 * completed. Invoked with (err, result).
4212 * @returns {Promise} a promise, if a callback is omitted
4213 * @example
4214 *
4215 * async.race([
4216 * function(callback) {
4217 * setTimeout(function() {
4218 * callback(null, 'one');
4219 * }, 200);
4220 * },
4221 * function(callback) {
4222 * setTimeout(function() {
4223 * callback(null, 'two');
4224 * }, 100);
4225 * }
4226 * ],
4227 * // main callback
4228 * function(err, result) {
4229 * // the result will be equal to 'two' as it finishes earlier
4230 * });
4231 */
4232function race(tasks, callback) {
4233 callback = once(callback);
4234 if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
4235 if (!tasks.length) return callback();
4236 for (var i = 0, l = tasks.length; i < l; i++) {
4237 wrapAsync(tasks[i])(callback);
4238 }
4239}
4240
4241var race$1 = awaitify(race, 2);
4242
4243/**
4244 * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
4245 *
4246 * @name reduceRight
4247 * @static
4248 * @memberOf module:Collections
4249 * @method
4250 * @see [async.reduce]{@link module:Collections.reduce}
4251 * @alias foldr
4252 * @category Collection
4253 * @param {Array} array - A collection to iterate over.
4254 * @param {*} memo - The initial state of the reduction.
4255 * @param {AsyncFunction} iteratee - A function applied to each item in the
4256 * array to produce the next step in the reduction.
4257 * The `iteratee` should complete with the next state of the reduction.
4258 * If the iteratee completes with an error, the reduction is stopped and the
4259 * main `callback` is immediately called with the error.
4260 * Invoked with (memo, item, callback).
4261 * @param {Function} [callback] - A callback which is called after all the
4262 * `iteratee` functions have finished. Result is the reduced value. Invoked with
4263 * (err, result).
4264 * @returns {Promise} a promise, if no callback is passed
4265 */
4266function reduceRight (array, memo, iteratee, callback) {
4267 var reversed = [...array].reverse();
4268 return reduce$1(reversed, memo, iteratee, callback);
4269}
4270
4271/**
4272 * Wraps the async function in another function that always completes with a
4273 * result object, even when it errors.
4274 *
4275 * The result object has either the property `error` or `value`.
4276 *
4277 * @name reflect
4278 * @static
4279 * @memberOf module:Utils
4280 * @method
4281 * @category Util
4282 * @param {AsyncFunction} fn - The async function you want to wrap
4283 * @returns {Function} - A function that always passes null to it's callback as
4284 * the error. The second argument to the callback will be an `object` with
4285 * either an `error` or a `value` property.
4286 * @example
4287 *
4288 * async.parallel([
4289 * async.reflect(function(callback) {
4290 * // do some stuff ...
4291 * callback(null, 'one');
4292 * }),
4293 * async.reflect(function(callback) {
4294 * // do some more stuff but error ...
4295 * callback('bad stuff happened');
4296 * }),
4297 * async.reflect(function(callback) {
4298 * // do some more stuff ...
4299 * callback(null, 'two');
4300 * })
4301 * ],
4302 * // optional callback
4303 * function(err, results) {
4304 * // values
4305 * // results[0].value = 'one'
4306 * // results[1].error = 'bad stuff happened'
4307 * // results[2].value = 'two'
4308 * });
4309 */
4310function reflect(fn) {
4311 var _fn = wrapAsync(fn);
4312 return initialParams(function reflectOn(args, reflectCallback) {
4313 args.push((error, ...cbArgs) => {
4314 let retVal = {};
4315 if (error) {
4316 retVal.error = error;
4317 }
4318 if (cbArgs.length > 0){
4319 var value = cbArgs;
4320 if (cbArgs.length <= 1) {
4321 [value] = cbArgs;
4322 }
4323 retVal.value = value;
4324 }
4325 reflectCallback(null, retVal);
4326 });
4327
4328 return _fn.apply(this, args);
4329 });
4330}
4331
4332/**
4333 * A helper function that wraps an array or an object of functions with `reflect`.
4334 *
4335 * @name reflectAll
4336 * @static
4337 * @memberOf module:Utils
4338 * @method
4339 * @see [async.reflect]{@link module:Utils.reflect}
4340 * @category Util
4341 * @param {Array|Object|Iterable} tasks - The collection of
4342 * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
4343 * @returns {Array} Returns an array of async functions, each wrapped in
4344 * `async.reflect`
4345 * @example
4346 *
4347 * let tasks = [
4348 * function(callback) {
4349 * setTimeout(function() {
4350 * callback(null, 'one');
4351 * }, 200);
4352 * },
4353 * function(callback) {
4354 * // do some more stuff but error ...
4355 * callback(new Error('bad stuff happened'));
4356 * },
4357 * function(callback) {
4358 * setTimeout(function() {
4359 * callback(null, 'two');
4360 * }, 100);
4361 * }
4362 * ];
4363 *
4364 * async.parallel(async.reflectAll(tasks),
4365 * // optional callback
4366 * function(err, results) {
4367 * // values
4368 * // results[0].value = 'one'
4369 * // results[1].error = Error('bad stuff happened')
4370 * // results[2].value = 'two'
4371 * });
4372 *
4373 * // an example using an object instead of an array
4374 * let tasks = {
4375 * one: function(callback) {
4376 * setTimeout(function() {
4377 * callback(null, 'one');
4378 * }, 200);
4379 * },
4380 * two: function(callback) {
4381 * callback('two');
4382 * },
4383 * three: function(callback) {
4384 * setTimeout(function() {
4385 * callback(null, 'three');
4386 * }, 100);
4387 * }
4388 * };
4389 *
4390 * async.parallel(async.reflectAll(tasks),
4391 * // optional callback
4392 * function(err, results) {
4393 * // values
4394 * // results.one.value = 'one'
4395 * // results.two.error = 'two'
4396 * // results.three.value = 'three'
4397 * });
4398 */
4399function reflectAll(tasks) {
4400 var results;
4401 if (Array.isArray(tasks)) {
4402 results = tasks.map(reflect);
4403 } else {
4404 results = {};
4405 Object.keys(tasks).forEach(key => {
4406 results[key] = reflect.call(this, tasks[key]);
4407 });
4408 }
4409 return results;
4410}
4411
4412function reject$2(eachfn, arr, _iteratee, callback) {
4413 const iteratee = wrapAsync(_iteratee);
4414 return _filter(eachfn, arr, (value, cb) => {
4415 iteratee(value, (err, v) => {
4416 cb(err, !v);
4417 });
4418 }, callback);
4419}
4420
4421/**
4422 * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
4423 *
4424 * @name reject
4425 * @static
4426 * @memberOf module:Collections
4427 * @method
4428 * @see [async.filter]{@link module:Collections.filter}
4429 * @category Collection
4430 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4431 * @param {Function} iteratee - An async truth test to apply to each item in
4432 * `coll`.
4433 * The should complete with a boolean value as its `result`.
4434 * Invoked with (item, callback).
4435 * @param {Function} [callback] - A callback which is called after all the
4436 * `iteratee` functions have finished. Invoked with (err, results).
4437 * @returns {Promise} a promise, if no callback is passed
4438 * @example
4439 *
4440 * // dir1 is a directory that contains file1.txt, file2.txt
4441 * // dir2 is a directory that contains file3.txt, file4.txt
4442 * // dir3 is a directory that contains file5.txt
4443 *
4444 * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];
4445 *
4446 * // asynchronous function that checks if a file exists
4447 * function fileExists(file, callback) {
4448 * fs.access(file, fs.constants.F_OK, (err) => {
4449 * callback(null, !err);
4450 * });
4451 * }
4452 *
4453 * // Using callbacks
4454 * async.reject(fileList, fileExists, function(err, results) {
4455 * // [ 'dir3/file6.txt' ]
4456 * // results now equals an array of the non-existing files
4457 * });
4458 *
4459 * // Using Promises
4460 * async.reject(fileList, fileExists)
4461 * .then( results => {
4462 * console.log(results);
4463 * // [ 'dir3/file6.txt' ]
4464 * // results now equals an array of the non-existing files
4465 * }).catch( err => {
4466 * console.log(err);
4467 * });
4468 *
4469 * // Using async/await
4470 * async () => {
4471 * try {
4472 * let results = await async.reject(fileList, fileExists);
4473 * console.log(results);
4474 * // [ 'dir3/file6.txt' ]
4475 * // results now equals an array of the non-existing files
4476 * }
4477 * catch (err) {
4478 * console.log(err);
4479 * }
4480 * }
4481 *
4482 */
4483function reject (coll, iteratee, callback) {
4484 return reject$2(eachOf$1, coll, iteratee, callback)
4485}
4486var reject$1 = awaitify(reject, 3);
4487
4488/**
4489 * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
4490 * time.
4491 *
4492 * @name rejectLimit
4493 * @static
4494 * @memberOf module:Collections
4495 * @method
4496 * @see [async.reject]{@link module:Collections.reject}
4497 * @category Collection
4498 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4499 * @param {number} limit - The maximum number of async operations at a time.
4500 * @param {Function} iteratee - An async truth test to apply to each item in
4501 * `coll`.
4502 * The should complete with a boolean value as its `result`.
4503 * Invoked with (item, callback).
4504 * @param {Function} [callback] - A callback which is called after all the
4505 * `iteratee` functions have finished. Invoked with (err, results).
4506 * @returns {Promise} a promise, if no callback is passed
4507 */
4508function rejectLimit (coll, limit, iteratee, callback) {
4509 return reject$2(eachOfLimit$2(limit), coll, iteratee, callback)
4510}
4511var rejectLimit$1 = awaitify(rejectLimit, 4);
4512
4513/**
4514 * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
4515 *
4516 * @name rejectSeries
4517 * @static
4518 * @memberOf module:Collections
4519 * @method
4520 * @see [async.reject]{@link module:Collections.reject}
4521 * @category Collection
4522 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4523 * @param {Function} iteratee - An async truth test to apply to each item in
4524 * `coll`.
4525 * The should complete with a boolean value as its `result`.
4526 * Invoked with (item, callback).
4527 * @param {Function} [callback] - A callback which is called after all the
4528 * `iteratee` functions have finished. Invoked with (err, results).
4529 * @returns {Promise} a promise, if no callback is passed
4530 */
4531function rejectSeries (coll, iteratee, callback) {
4532 return reject$2(eachOfSeries$1, coll, iteratee, callback)
4533}
4534var rejectSeries$1 = awaitify(rejectSeries, 3);
4535
4536function constant(value) {
4537 return function () {
4538 return value;
4539 }
4540}
4541
4542/**
4543 * Attempts to get a successful response from `task` no more than `times` times
4544 * before returning an error. If the task is successful, the `callback` will be
4545 * passed the result of the successful task. If all attempts fail, the callback
4546 * will be passed the error and result (if any) of the final attempt.
4547 *
4548 * @name retry
4549 * @static
4550 * @memberOf module:ControlFlow
4551 * @method
4552 * @category Control Flow
4553 * @see [async.retryable]{@link module:ControlFlow.retryable}
4554 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
4555 * object with `times` and `interval` or a number.
4556 * * `times` - The number of attempts to make before giving up. The default
4557 * is `5`.
4558 * * `interval` - The time to wait between retries, in milliseconds. The
4559 * default is `0`. The interval may also be specified as a function of the
4560 * retry count (see example).
4561 * * `errorFilter` - An optional synchronous function that is invoked on
4562 * erroneous result. If it returns `true` the retry attempts will continue;
4563 * if the function returns `false` the retry flow is aborted with the current
4564 * attempt's error and result being returned to the final callback.
4565 * Invoked with (err).
4566 * * If `opts` is a number, the number specifies the number of times to retry,
4567 * with the default interval of `0`.
4568 * @param {AsyncFunction} task - An async function to retry.
4569 * Invoked with (callback).
4570 * @param {Function} [callback] - An optional callback which is called when the
4571 * task has succeeded, or after the final failed attempt. It receives the `err`
4572 * and `result` arguments of the last attempt at completing the `task`. Invoked
4573 * with (err, results).
4574 * @returns {Promise} a promise if no callback provided
4575 *
4576 * @example
4577 *
4578 * // The `retry` function can be used as a stand-alone control flow by passing
4579 * // a callback, as shown below:
4580 *
4581 * // try calling apiMethod 3 times
4582 * async.retry(3, apiMethod, function(err, result) {
4583 * // do something with the result
4584 * });
4585 *
4586 * // try calling apiMethod 3 times, waiting 200 ms between each retry
4587 * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
4588 * // do something with the result
4589 * });
4590 *
4591 * // try calling apiMethod 10 times with exponential backoff
4592 * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
4593 * async.retry({
4594 * times: 10,
4595 * interval: function(retryCount) {
4596 * return 50 * Math.pow(2, retryCount);
4597 * }
4598 * }, apiMethod, function(err, result) {
4599 * // do something with the result
4600 * });
4601 *
4602 * // try calling apiMethod the default 5 times no delay between each retry
4603 * async.retry(apiMethod, function(err, result) {
4604 * // do something with the result
4605 * });
4606 *
4607 * // try calling apiMethod only when error condition satisfies, all other
4608 * // errors will abort the retry control flow and return to final callback
4609 * async.retry({
4610 * errorFilter: function(err) {
4611 * return err.message === 'Temporary error'; // only retry on a specific error
4612 * }
4613 * }, apiMethod, function(err, result) {
4614 * // do something with the result
4615 * });
4616 *
4617 * // to retry individual methods that are not as reliable within other
4618 * // control flow functions, use the `retryable` wrapper:
4619 * async.auto({
4620 * users: api.getUsers.bind(api),
4621 * payments: async.retryable(3, api.getPayments.bind(api))
4622 * }, function(err, results) {
4623 * // do something with the results
4624 * });
4625 *
4626 */
4627const DEFAULT_TIMES = 5;
4628const DEFAULT_INTERVAL = 0;
4629
4630function retry(opts, task, callback) {
4631 var options = {
4632 times: DEFAULT_TIMES,
4633 intervalFunc: constant(DEFAULT_INTERVAL)
4634 };
4635
4636 if (arguments.length < 3 && typeof opts === 'function') {
4637 callback = task || promiseCallback();
4638 task = opts;
4639 } else {
4640 parseTimes(options, opts);
4641 callback = callback || promiseCallback();
4642 }
4643
4644 if (typeof task !== 'function') {
4645 throw new Error("Invalid arguments for async.retry");
4646 }
4647
4648 var _task = wrapAsync(task);
4649
4650 var attempt = 1;
4651 function retryAttempt() {
4652 _task((err, ...args) => {
4653 if (err === false) return
4654 if (err && attempt++ < options.times &&
4655 (typeof options.errorFilter != 'function' ||
4656 options.errorFilter(err))) {
4657 setTimeout(retryAttempt, options.intervalFunc(attempt - 1));
4658 } else {
4659 callback(err, ...args);
4660 }
4661 });
4662 }
4663
4664 retryAttempt();
4665 return callback[PROMISE_SYMBOL]
4666}
4667
4668function parseTimes(acc, t) {
4669 if (typeof t === 'object') {
4670 acc.times = +t.times || DEFAULT_TIMES;
4671
4672 acc.intervalFunc = typeof t.interval === 'function' ?
4673 t.interval :
4674 constant(+t.interval || DEFAULT_INTERVAL);
4675
4676 acc.errorFilter = t.errorFilter;
4677 } else if (typeof t === 'number' || typeof t === 'string') {
4678 acc.times = +t || DEFAULT_TIMES;
4679 } else {
4680 throw new Error("Invalid arguments for async.retry");
4681 }
4682}
4683
4684/**
4685 * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method
4686 * wraps a task and makes it retryable, rather than immediately calling it
4687 * with retries.
4688 *
4689 * @name retryable
4690 * @static
4691 * @memberOf module:ControlFlow
4692 * @method
4693 * @see [async.retry]{@link module:ControlFlow.retry}
4694 * @category Control Flow
4695 * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
4696 * options, exactly the same as from `retry`, except for a `opts.arity` that
4697 * is the arity of the `task` function, defaulting to `task.length`
4698 * @param {AsyncFunction} task - the asynchronous function to wrap.
4699 * This function will be passed any arguments passed to the returned wrapper.
4700 * Invoked with (...args, callback).
4701 * @returns {AsyncFunction} The wrapped function, which when invoked, will
4702 * retry on an error, based on the parameters specified in `opts`.
4703 * This function will accept the same parameters as `task`.
4704 * @example
4705 *
4706 * async.auto({
4707 * dep1: async.retryable(3, getFromFlakyService),
4708 * process: ["dep1", async.retryable(3, function (results, cb) {
4709 * maybeProcessData(results.dep1, cb);
4710 * })]
4711 * }, callback);
4712 */
4713function retryable (opts, task) {
4714 if (!task) {
4715 task = opts;
4716 opts = null;
4717 }
4718 let arity = (opts && opts.arity) || task.length;
4719 if (isAsync(task)) {
4720 arity += 1;
4721 }
4722 var _task = wrapAsync(task);
4723 return initialParams((args, callback) => {
4724 if (args.length < arity - 1 || callback == null) {
4725 args.push(callback);
4726 callback = promiseCallback();
4727 }
4728 function taskFn(cb) {
4729 _task(...args, cb);
4730 }
4731
4732 if (opts) retry(opts, taskFn, callback);
4733 else retry(taskFn, callback);
4734
4735 return callback[PROMISE_SYMBOL]
4736 });
4737}
4738
4739/**
4740 * Run the functions in the `tasks` collection in series, each one running once
4741 * the previous function has completed. If any functions in the series pass an
4742 * error to its callback, no more functions are run, and `callback` is
4743 * immediately called with the value of the error. Otherwise, `callback`
4744 * receives an array of results when `tasks` have completed.
4745 *
4746 * It is also possible to use an object instead of an array. Each property will
4747 * be run as a function, and the results will be passed to the final `callback`
4748 * as an object instead of an array. This can be a more readable way of handling
4749 * results from {@link async.series}.
4750 *
4751 * **Note** that while many implementations preserve the order of object
4752 * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
4753 * explicitly states that
4754 *
4755 * > The mechanics and order of enumerating the properties is not specified.
4756 *
4757 * So if you rely on the order in which your series of functions are executed,
4758 * and want this to work on all platforms, consider using an array.
4759 *
4760 * @name series
4761 * @static
4762 * @memberOf module:ControlFlow
4763 * @method
4764 * @category Control Flow
4765 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing
4766 * [async functions]{@link AsyncFunction} to run in series.
4767 * Each function can complete with any number of optional `result` values.
4768 * @param {Function} [callback] - An optional callback to run once all the
4769 * functions have completed. This function gets a results array (or object)
4770 * containing all the result arguments passed to the `task` callbacks. Invoked
4771 * with (err, result).
4772 * @return {Promise} a promise, if no callback is passed
4773 * @example
4774 *
4775 * //Using Callbacks
4776 * async.series([
4777 * function(callback) {
4778 * setTimeout(function() {
4779 * // do some async task
4780 * callback(null, 'one');
4781 * }, 200);
4782 * },
4783 * function(callback) {
4784 * setTimeout(function() {
4785 * // then do another async task
4786 * callback(null, 'two');
4787 * }, 100);
4788 * }
4789 * ], function(err, results) {
4790 * console.log(results);
4791 * // results is equal to ['one','two']
4792 * });
4793 *
4794 * // an example using objects instead of arrays
4795 * async.series({
4796 * one: function(callback) {
4797 * setTimeout(function() {
4798 * // do some async task
4799 * callback(null, 1);
4800 * }, 200);
4801 * },
4802 * two: function(callback) {
4803 * setTimeout(function() {
4804 * // then do another async task
4805 * callback(null, 2);
4806 * }, 100);
4807 * }
4808 * }, function(err, results) {
4809 * console.log(results);
4810 * // results is equal to: { one: 1, two: 2 }
4811 * });
4812 *
4813 * //Using Promises
4814 * async.series([
4815 * function(callback) {
4816 * setTimeout(function() {
4817 * callback(null, 'one');
4818 * }, 200);
4819 * },
4820 * function(callback) {
4821 * setTimeout(function() {
4822 * callback(null, 'two');
4823 * }, 100);
4824 * }
4825 * ]).then(results => {
4826 * console.log(results);
4827 * // results is equal to ['one','two']
4828 * }).catch(err => {
4829 * console.log(err);
4830 * });
4831 *
4832 * // an example using an object instead of an array
4833 * async.series({
4834 * one: function(callback) {
4835 * setTimeout(function() {
4836 * // do some async task
4837 * callback(null, 1);
4838 * }, 200);
4839 * },
4840 * two: function(callback) {
4841 * setTimeout(function() {
4842 * // then do another async task
4843 * callback(null, 2);
4844 * }, 100);
4845 * }
4846 * }).then(results => {
4847 * console.log(results);
4848 * // results is equal to: { one: 1, two: 2 }
4849 * }).catch(err => {
4850 * console.log(err);
4851 * });
4852 *
4853 * //Using async/await
4854 * async () => {
4855 * try {
4856 * let results = await async.series([
4857 * function(callback) {
4858 * setTimeout(function() {
4859 * // do some async task
4860 * callback(null, 'one');
4861 * }, 200);
4862 * },
4863 * function(callback) {
4864 * setTimeout(function() {
4865 * // then do another async task
4866 * callback(null, 'two');
4867 * }, 100);
4868 * }
4869 * ]);
4870 * console.log(results);
4871 * // results is equal to ['one','two']
4872 * }
4873 * catch (err) {
4874 * console.log(err);
4875 * }
4876 * }
4877 *
4878 * // an example using an object instead of an array
4879 * async () => {
4880 * try {
4881 * let results = await async.parallel({
4882 * one: function(callback) {
4883 * setTimeout(function() {
4884 * // do some async task
4885 * callback(null, 1);
4886 * }, 200);
4887 * },
4888 * two: function(callback) {
4889 * setTimeout(function() {
4890 * // then do another async task
4891 * callback(null, 2);
4892 * }, 100);
4893 * }
4894 * });
4895 * console.log(results);
4896 * // results is equal to: { one: 1, two: 2 }
4897 * }
4898 * catch (err) {
4899 * console.log(err);
4900 * }
4901 * }
4902 *
4903 */
4904function series(tasks, callback) {
4905 return _parallel(eachOfSeries$1, tasks, callback);
4906}
4907
4908/**
4909 * Returns `true` if at least one element in the `coll` satisfies an async test.
4910 * If any iteratee call returns `true`, the main `callback` is immediately
4911 * called.
4912 *
4913 * @name some
4914 * @static
4915 * @memberOf module:Collections
4916 * @method
4917 * @alias any
4918 * @category Collection
4919 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4920 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4921 * in the collections in parallel.
4922 * The iteratee should complete with a boolean `result` value.
4923 * Invoked with (item, callback).
4924 * @param {Function} [callback] - A callback which is called as soon as any
4925 * iteratee returns `true`, or after all the iteratee functions have finished.
4926 * Result will be either `true` or `false` depending on the values of the async
4927 * tests. Invoked with (err, result).
4928 * @returns {Promise} a promise, if no callback provided
4929 * @example
4930 *
4931 * // dir1 is a directory that contains file1.txt, file2.txt
4932 * // dir2 is a directory that contains file3.txt, file4.txt
4933 * // dir3 is a directory that contains file5.txt
4934 * // dir4 does not exist
4935 *
4936 * // asynchronous function that checks if a file exists
4937 * function fileExists(file, callback) {
4938 * fs.access(file, fs.constants.F_OK, (err) => {
4939 * callback(null, !err);
4940 * });
4941 * }
4942 *
4943 * // Using callbacks
4944 * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,
4945 * function(err, result) {
4946 * console.log(result);
4947 * // true
4948 * // result is true since some file in the list exists
4949 * }
4950 *);
4951 *
4952 * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,
4953 * function(err, result) {
4954 * console.log(result);
4955 * // false
4956 * // result is false since none of the files exists
4957 * }
4958 *);
4959 *
4960 * // Using Promises
4961 * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)
4962 * .then( result => {
4963 * console.log(result);
4964 * // true
4965 * // result is true since some file in the list exists
4966 * }).catch( err => {
4967 * console.log(err);
4968 * });
4969 *
4970 * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)
4971 * .then( result => {
4972 * console.log(result);
4973 * // false
4974 * // result is false since none of the files exists
4975 * }).catch( err => {
4976 * console.log(err);
4977 * });
4978 *
4979 * // Using async/await
4980 * async () => {
4981 * try {
4982 * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);
4983 * console.log(result);
4984 * // true
4985 * // result is true since some file in the list exists
4986 * }
4987 * catch (err) {
4988 * console.log(err);
4989 * }
4990 * }
4991 *
4992 * async () => {
4993 * try {
4994 * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);
4995 * console.log(result);
4996 * // false
4997 * // result is false since none of the files exists
4998 * }
4999 * catch (err) {
5000 * console.log(err);
5001 * }
5002 * }
5003 *
5004 */
5005function some(coll, iteratee, callback) {
5006 return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)
5007}
5008var some$1 = awaitify(some, 3);
5009
5010/**
5011 * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
5012 *
5013 * @name someLimit
5014 * @static
5015 * @memberOf module:Collections
5016 * @method
5017 * @see [async.some]{@link module:Collections.some}
5018 * @alias anyLimit
5019 * @category Collection
5020 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
5021 * @param {number} limit - The maximum number of async operations at a time.
5022 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
5023 * in the collections in parallel.
5024 * The iteratee should complete with a boolean `result` value.
5025 * Invoked with (item, callback).
5026 * @param {Function} [callback] - A callback which is called as soon as any
5027 * iteratee returns `true`, or after all the iteratee functions have finished.
5028 * Result will be either `true` or `false` depending on the values of the async
5029 * tests. Invoked with (err, result).
5030 * @returns {Promise} a promise, if no callback provided
5031 */
5032function someLimit(coll, limit, iteratee, callback) {
5033 return _createTester(Boolean, res => res)(eachOfLimit$2(limit), coll, iteratee, callback)
5034}
5035var someLimit$1 = awaitify(someLimit, 4);
5036
5037/**
5038 * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
5039 *
5040 * @name someSeries
5041 * @static
5042 * @memberOf module:Collections
5043 * @method
5044 * @see [async.some]{@link module:Collections.some}
5045 * @alias anySeries
5046 * @category Collection
5047 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
5048 * @param {AsyncFunction} iteratee - An async truth test to apply to each item
5049 * in the collections in series.
5050 * The iteratee should complete with a boolean `result` value.
5051 * Invoked with (item, callback).
5052 * @param {Function} [callback] - A callback which is called as soon as any
5053 * iteratee returns `true`, or after all the iteratee functions have finished.
5054 * Result will be either `true` or `false` depending on the values of the async
5055 * tests. Invoked with (err, result).
5056 * @returns {Promise} a promise, if no callback provided
5057 */
5058function someSeries(coll, iteratee, callback) {
5059 return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)
5060}
5061var someSeries$1 = awaitify(someSeries, 3);
5062
5063/**
5064 * Sorts a list by the results of running each `coll` value through an async
5065 * `iteratee`.
5066 *
5067 * @name sortBy
5068 * @static
5069 * @memberOf module:Collections
5070 * @method
5071 * @category Collection
5072 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
5073 * @param {AsyncFunction} iteratee - An async function to apply to each item in
5074 * `coll`.
5075 * The iteratee should complete with a value to use as the sort criteria as
5076 * its `result`.
5077 * Invoked with (item, callback).
5078 * @param {Function} callback - A callback which is called after all the
5079 * `iteratee` functions have finished, or an error occurs. Results is the items
5080 * from the original `coll` sorted by the values returned by the `iteratee`
5081 * calls. Invoked with (err, results).
5082 * @returns {Promise} a promise, if no callback passed
5083 * @example
5084 *
5085 * // bigfile.txt is a file that is 251100 bytes in size
5086 * // mediumfile.txt is a file that is 11000 bytes in size
5087 * // smallfile.txt is a file that is 121 bytes in size
5088 *
5089 * // asynchronous function that returns the file size in bytes
5090 * function getFileSizeInBytes(file, callback) {
5091 * fs.stat(file, function(err, stat) {
5092 * if (err) {
5093 * return callback(err);
5094 * }
5095 * callback(null, stat.size);
5096 * });
5097 * }
5098 *
5099 * // Using callbacks
5100 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,
5101 * function(err, results) {
5102 * if (err) {
5103 * console.log(err);
5104 * } else {
5105 * console.log(results);
5106 * // results is now the original array of files sorted by
5107 * // file size (ascending by default), e.g.
5108 * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
5109 * }
5110 * }
5111 * );
5112 *
5113 * // By modifying the callback parameter the
5114 * // sorting order can be influenced:
5115 *
5116 * // ascending order
5117 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {
5118 * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
5119 * if (getFileSizeErr) return callback(getFileSizeErr);
5120 * callback(null, fileSize);
5121 * });
5122 * }, function(err, results) {
5123 * if (err) {
5124 * console.log(err);
5125 * } else {
5126 * console.log(results);
5127 * // results is now the original array of files sorted by
5128 * // file size (ascending by default), e.g.
5129 * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
5130 * }
5131 * }
5132 * );
5133 *
5134 * // descending order
5135 * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {
5136 * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {
5137 * if (getFileSizeErr) {
5138 * return callback(getFileSizeErr);
5139 * }
5140 * callback(null, fileSize * -1);
5141 * });
5142 * }, function(err, results) {
5143 * if (err) {
5144 * console.log(err);
5145 * } else {
5146 * console.log(results);
5147 * // results is now the original array of files sorted by
5148 * // file size (ascending by default), e.g.
5149 * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']
5150 * }
5151 * }
5152 * );
5153 *
5154 * // Error handling
5155 * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,
5156 * function(err, results) {
5157 * if (err) {
5158 * console.log(err);
5159 * // [ Error: ENOENT: no such file or directory ]
5160 * } else {
5161 * console.log(results);
5162 * }
5163 * }
5164 * );
5165 *
5166 * // Using Promises
5167 * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)
5168 * .then( results => {
5169 * console.log(results);
5170 * // results is now the original array of files sorted by
5171 * // file size (ascending by default), e.g.
5172 * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
5173 * }).catch( err => {
5174 * console.log(err);
5175 * });
5176 *
5177 * // Error handling
5178 * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)
5179 * .then( results => {
5180 * console.log(results);
5181 * }).catch( err => {
5182 * console.log(err);
5183 * // [ Error: ENOENT: no such file or directory ]
5184 * });
5185 *
5186 * // Using async/await
5187 * (async () => {
5188 * try {
5189 * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
5190 * console.log(results);
5191 * // results is now the original array of files sorted by
5192 * // file size (ascending by default), e.g.
5193 * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']
5194 * }
5195 * catch (err) {
5196 * console.log(err);
5197 * }
5198 * })();
5199 *
5200 * // Error handling
5201 * async () => {
5202 * try {
5203 * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);
5204 * console.log(results);
5205 * }
5206 * catch (err) {
5207 * console.log(err);
5208 * // [ Error: ENOENT: no such file or directory ]
5209 * }
5210 * }
5211 *
5212 */
5213function sortBy (coll, iteratee, callback) {
5214 var _iteratee = wrapAsync(iteratee);
5215 return map$1(coll, (x, iterCb) => {
5216 _iteratee(x, (err, criteria) => {
5217 if (err) return iterCb(err);
5218 iterCb(err, {value: x, criteria});
5219 });
5220 }, (err, results) => {
5221 if (err) return callback(err);
5222 callback(null, results.sort(comparator).map(v => v.value));
5223 });
5224
5225 function comparator(left, right) {
5226 var a = left.criteria, b = right.criteria;
5227 return a < b ? -1 : a > b ? 1 : 0;
5228 }
5229}
5230var sortBy$1 = awaitify(sortBy, 3);
5231
5232/**
5233 * Sets a time limit on an asynchronous function. If the function does not call
5234 * its callback within the specified milliseconds, it will be called with a
5235 * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
5236 *
5237 * @name timeout
5238 * @static
5239 * @memberOf module:Utils
5240 * @method
5241 * @category Util
5242 * @param {AsyncFunction} asyncFn - The async function to limit in time.
5243 * @param {number} milliseconds - The specified time limit.
5244 * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
5245 * to timeout Error for more information..
5246 * @returns {AsyncFunction} Returns a wrapped function that can be used with any
5247 * of the control flow functions.
5248 * Invoke this function with the same parameters as you would `asyncFunc`.
5249 * @example
5250 *
5251 * function myFunction(foo, callback) {
5252 * doAsyncTask(foo, function(err, data) {
5253 * // handle errors
5254 * if (err) return callback(err);
5255 *
5256 * // do some stuff ...
5257 *
5258 * // return processed data
5259 * return callback(null, data);
5260 * });
5261 * }
5262 *
5263 * var wrapped = async.timeout(myFunction, 1000);
5264 *
5265 * // call `wrapped` as you would `myFunction`
5266 * wrapped({ bar: 'bar' }, function(err, data) {
5267 * // if `myFunction` takes < 1000 ms to execute, `err`
5268 * // and `data` will have their expected values
5269 *
5270 * // else `err` will be an Error with the code 'ETIMEDOUT'
5271 * });
5272 */
5273function timeout(asyncFn, milliseconds, info) {
5274 var fn = wrapAsync(asyncFn);
5275
5276 return initialParams((args, callback) => {
5277 var timedOut = false;
5278 var timer;
5279
5280 function timeoutCallback() {
5281 var name = asyncFn.name || 'anonymous';
5282 var error = new Error('Callback function "' + name + '" timed out.');
5283 error.code = 'ETIMEDOUT';
5284 if (info) {
5285 error.info = info;
5286 }
5287 timedOut = true;
5288 callback(error);
5289 }
5290
5291 args.push((...cbArgs) => {
5292 if (!timedOut) {
5293 callback(...cbArgs);
5294 clearTimeout(timer);
5295 }
5296 });
5297
5298 // setup timer and call original function
5299 timer = setTimeout(timeoutCallback, milliseconds);
5300 fn(...args);
5301 });
5302}
5303
5304function range(size) {
5305 var result = Array(size);
5306 while (size--) {
5307 result[size] = size;
5308 }
5309 return result;
5310}
5311
5312/**
5313 * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
5314 * time.
5315 *
5316 * @name timesLimit
5317 * @static
5318 * @memberOf module:ControlFlow
5319 * @method
5320 * @see [async.times]{@link module:ControlFlow.times}
5321 * @category Control Flow
5322 * @param {number} count - The number of times to run the function.
5323 * @param {number} limit - The maximum number of async operations at a time.
5324 * @param {AsyncFunction} iteratee - The async function to call `n` times.
5325 * Invoked with the iteration index and a callback: (n, next).
5326 * @param {Function} callback - see [async.map]{@link module:Collections.map}.
5327 * @returns {Promise} a promise, if no callback is provided
5328 */
5329function timesLimit(count, limit, iteratee, callback) {
5330 var _iteratee = wrapAsync(iteratee);
5331 return mapLimit$1(range(count), limit, _iteratee, callback);
5332}
5333
5334/**
5335 * Calls the `iteratee` function `n` times, and accumulates results in the same
5336 * manner you would use with [map]{@link module:Collections.map}.
5337 *
5338 * @name times
5339 * @static
5340 * @memberOf module:ControlFlow
5341 * @method
5342 * @see [async.map]{@link module:Collections.map}
5343 * @category Control Flow
5344 * @param {number} n - The number of times to run the function.
5345 * @param {AsyncFunction} iteratee - The async function to call `n` times.
5346 * Invoked with the iteration index and a callback: (n, next).
5347 * @param {Function} callback - see {@link module:Collections.map}.
5348 * @returns {Promise} a promise, if no callback is provided
5349 * @example
5350 *
5351 * // Pretend this is some complicated async factory
5352 * var createUser = function(id, callback) {
5353 * callback(null, {
5354 * id: 'user' + id
5355 * });
5356 * };
5357 *
5358 * // generate 5 users
5359 * async.times(5, function(n, next) {
5360 * createUser(n, function(err, user) {
5361 * next(err, user);
5362 * });
5363 * }, function(err, users) {
5364 * // we should now have 5 users
5365 * });
5366 */
5367function times (n, iteratee, callback) {
5368 return timesLimit(n, Infinity, iteratee, callback)
5369}
5370
5371/**
5372 * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
5373 *
5374 * @name timesSeries
5375 * @static
5376 * @memberOf module:ControlFlow
5377 * @method
5378 * @see [async.times]{@link module:ControlFlow.times}
5379 * @category Control Flow
5380 * @param {number} n - The number of times to run the function.
5381 * @param {AsyncFunction} iteratee - The async function to call `n` times.
5382 * Invoked with the iteration index and a callback: (n, next).
5383 * @param {Function} callback - see {@link module:Collections.map}.
5384 * @returns {Promise} a promise, if no callback is provided
5385 */
5386function timesSeries (n, iteratee, callback) {
5387 return timesLimit(n, 1, iteratee, callback)
5388}
5389
5390/**
5391 * A relative of `reduce`. Takes an Object or Array, and iterates over each
5392 * element in parallel, each step potentially mutating an `accumulator` value.
5393 * The type of the accumulator defaults to the type of collection passed in.
5394 *
5395 * @name transform
5396 * @static
5397 * @memberOf module:Collections
5398 * @method
5399 * @category Collection
5400 * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
5401 * @param {*} [accumulator] - The initial state of the transform. If omitted,
5402 * it will default to an empty Object or Array, depending on the type of `coll`
5403 * @param {AsyncFunction} iteratee - A function applied to each item in the
5404 * collection that potentially modifies the accumulator.
5405 * Invoked with (accumulator, item, key, callback).
5406 * @param {Function} [callback] - A callback which is called after all the
5407 * `iteratee` functions have finished. Result is the transformed accumulator.
5408 * Invoked with (err, result).
5409 * @returns {Promise} a promise, if no callback provided
5410 * @example
5411 *
5412 * // file1.txt is a file that is 1000 bytes in size
5413 * // file2.txt is a file that is 2000 bytes in size
5414 * // file3.txt is a file that is 3000 bytes in size
5415 *
5416 * // helper function that returns human-readable size format from bytes
5417 * function formatBytes(bytes, decimals = 2) {
5418 * // implementation not included for brevity
5419 * return humanReadbleFilesize;
5420 * }
5421 *
5422 * const fileList = ['file1.txt','file2.txt','file3.txt'];
5423 *
5424 * // asynchronous function that returns the file size, transformed to human-readable format
5425 * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
5426 * function transformFileSize(acc, value, key, callback) {
5427 * fs.stat(value, function(err, stat) {
5428 * if (err) {
5429 * return callback(err);
5430 * }
5431 * acc[key] = formatBytes(stat.size);
5432 * callback(null);
5433 * });
5434 * }
5435 *
5436 * // Using callbacks
5437 * async.transform(fileList, transformFileSize, function(err, result) {
5438 * if(err) {
5439 * console.log(err);
5440 * } else {
5441 * console.log(result);
5442 * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
5443 * }
5444 * });
5445 *
5446 * // Using Promises
5447 * async.transform(fileList, transformFileSize)
5448 * .then(result => {
5449 * console.log(result);
5450 * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
5451 * }).catch(err => {
5452 * console.log(err);
5453 * });
5454 *
5455 * // Using async/await
5456 * (async () => {
5457 * try {
5458 * let result = await async.transform(fileList, transformFileSize);
5459 * console.log(result);
5460 * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]
5461 * }
5462 * catch (err) {
5463 * console.log(err);
5464 * }
5465 * })();
5466 *
5467 * @example
5468 *
5469 * // file1.txt is a file that is 1000 bytes in size
5470 * // file2.txt is a file that is 2000 bytes in size
5471 * // file3.txt is a file that is 3000 bytes in size
5472 *
5473 * // helper function that returns human-readable size format from bytes
5474 * function formatBytes(bytes, decimals = 2) {
5475 * // implementation not included for brevity
5476 * return humanReadbleFilesize;
5477 * }
5478 *
5479 * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };
5480 *
5481 * // asynchronous function that returns the file size, transformed to human-readable format
5482 * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.
5483 * function transformFileSize(acc, value, key, callback) {
5484 * fs.stat(value, function(err, stat) {
5485 * if (err) {
5486 * return callback(err);
5487 * }
5488 * acc[key] = formatBytes(stat.size);
5489 * callback(null);
5490 * });
5491 * }
5492 *
5493 * // Using callbacks
5494 * async.transform(fileMap, transformFileSize, function(err, result) {
5495 * if(err) {
5496 * console.log(err);
5497 * } else {
5498 * console.log(result);
5499 * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
5500 * }
5501 * });
5502 *
5503 * // Using Promises
5504 * async.transform(fileMap, transformFileSize)
5505 * .then(result => {
5506 * console.log(result);
5507 * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
5508 * }).catch(err => {
5509 * console.log(err);
5510 * });
5511 *
5512 * // Using async/await
5513 * async () => {
5514 * try {
5515 * let result = await async.transform(fileMap, transformFileSize);
5516 * console.log(result);
5517 * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }
5518 * }
5519 * catch (err) {
5520 * console.log(err);
5521 * }
5522 * }
5523 *
5524 */
5525function transform (coll, accumulator, iteratee, callback) {
5526 if (arguments.length <= 3 && typeof accumulator === 'function') {
5527 callback = iteratee;
5528 iteratee = accumulator;
5529 accumulator = Array.isArray(coll) ? [] : {};
5530 }
5531 callback = once(callback || promiseCallback());
5532 var _iteratee = wrapAsync(iteratee);
5533
5534 eachOf$1(coll, (v, k, cb) => {
5535 _iteratee(accumulator, v, k, cb);
5536 }, err => callback(err, accumulator));
5537 return callback[PROMISE_SYMBOL]
5538}
5539
5540/**
5541 * It runs each task in series but stops whenever any of the functions were
5542 * successful. If one of the tasks were successful, the `callback` will be
5543 * passed the result of the successful task. If all tasks fail, the callback
5544 * will be passed the error and result (if any) of the final attempt.
5545 *
5546 * @name tryEach
5547 * @static
5548 * @memberOf module:ControlFlow
5549 * @method
5550 * @category Control Flow
5551 * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to
5552 * run, each function is passed a `callback(err, result)` it must call on
5553 * completion with an error `err` (which can be `null`) and an optional `result`
5554 * value.
5555 * @param {Function} [callback] - An optional callback which is called when one
5556 * of the tasks has succeeded, or all have failed. It receives the `err` and
5557 * `result` arguments of the last attempt at completing the `task`. Invoked with
5558 * (err, results).
5559 * @returns {Promise} a promise, if no callback is passed
5560 * @example
5561 * async.tryEach([
5562 * function getDataFromFirstWebsite(callback) {
5563 * // Try getting the data from the first website
5564 * callback(err, data);
5565 * },
5566 * function getDataFromSecondWebsite(callback) {
5567 * // First website failed,
5568 * // Try getting the data from the backup website
5569 * callback(err, data);
5570 * }
5571 * ],
5572 * // optional callback
5573 * function(err, results) {
5574 * Now do something with the data.
5575 * });
5576 *
5577 */
5578function tryEach(tasks, callback) {
5579 var error = null;
5580 var result;
5581 return eachSeries$1(tasks, (task, taskCb) => {
5582 wrapAsync(task)((err, ...args) => {
5583 if (err === false) return taskCb(err);
5584
5585 if (args.length < 2) {
5586 [result] = args;
5587 } else {
5588 result = args;
5589 }
5590 error = err;
5591 taskCb(err ? null : {});
5592 });
5593 }, () => callback(error, result));
5594}
5595
5596var tryEach$1 = awaitify(tryEach);
5597
5598/**
5599 * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
5600 * unmemoized form. Handy for testing.
5601 *
5602 * @name unmemoize
5603 * @static
5604 * @memberOf module:Utils
5605 * @method
5606 * @see [async.memoize]{@link module:Utils.memoize}
5607 * @category Util
5608 * @param {AsyncFunction} fn - the memoized function
5609 * @returns {AsyncFunction} a function that calls the original unmemoized function
5610 */
5611function unmemoize(fn) {
5612 return (...args) => {
5613 return (fn.unmemoized || fn)(...args);
5614 };
5615}
5616
5617/**
5618 * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
5619 * stopped, or an error occurs.
5620 *
5621 * @name whilst
5622 * @static
5623 * @memberOf module:ControlFlow
5624 * @method
5625 * @category Control Flow
5626 * @param {AsyncFunction} test - asynchronous truth test to perform before each
5627 * execution of `iteratee`. Invoked with (callback).
5628 * @param {AsyncFunction} iteratee - An async function which is called each time
5629 * `test` passes. Invoked with (callback).
5630 * @param {Function} [callback] - A callback which is called after the test
5631 * function has failed and repeated execution of `iteratee` has stopped. `callback`
5632 * will be passed an error and any arguments passed to the final `iteratee`'s
5633 * callback. Invoked with (err, [results]);
5634 * @returns {Promise} a promise, if no callback is passed
5635 * @example
5636 *
5637 * var count = 0;
5638 * async.whilst(
5639 * function test(cb) { cb(null, count < 5); },
5640 * function iter(callback) {
5641 * count++;
5642 * setTimeout(function() {
5643 * callback(null, count);
5644 * }, 1000);
5645 * },
5646 * function (err, n) {
5647 * // 5 seconds have passed, n = 5
5648 * }
5649 * );
5650 */
5651function whilst(test, iteratee, callback) {
5652 callback = onlyOnce(callback);
5653 var _fn = wrapAsync(iteratee);
5654 var _test = wrapAsync(test);
5655 var results = [];
5656
5657 function next(err, ...rest) {
5658 if (err) return callback(err);
5659 results = rest;
5660 if (err === false) return;
5661 _test(check);
5662 }
5663
5664 function check(err, truth) {
5665 if (err) return callback(err);
5666 if (err === false) return;
5667 if (!truth) return callback(null, ...results);
5668 _fn(next);
5669 }
5670
5671 return _test(check);
5672}
5673var whilst$1 = awaitify(whilst, 3);
5674
5675/**
5676 * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
5677 * stopped, or an error occurs. `callback` will be passed an error and any
5678 * arguments passed to the final `iteratee`'s callback.
5679 *
5680 * The inverse of [whilst]{@link module:ControlFlow.whilst}.
5681 *
5682 * @name until
5683 * @static
5684 * @memberOf module:ControlFlow
5685 * @method
5686 * @see [async.whilst]{@link module:ControlFlow.whilst}
5687 * @category Control Flow
5688 * @param {AsyncFunction} test - asynchronous truth test to perform before each
5689 * execution of `iteratee`. Invoked with (callback).
5690 * @param {AsyncFunction} iteratee - An async function which is called each time
5691 * `test` fails. Invoked with (callback).
5692 * @param {Function} [callback] - A callback which is called after the test
5693 * function has passed and repeated execution of `iteratee` has stopped. `callback`
5694 * will be passed an error and any arguments passed to the final `iteratee`'s
5695 * callback. Invoked with (err, [results]);
5696 * @returns {Promise} a promise, if a callback is not passed
5697 *
5698 * @example
5699 * const results = []
5700 * let finished = false
5701 * async.until(function test(cb) {
5702 * cb(null, finished)
5703 * }, function iter(next) {
5704 * fetchPage(url, (err, body) => {
5705 * if (err) return next(err)
5706 * results = results.concat(body.objects)
5707 * finished = !!body.next
5708 * next(err)
5709 * })
5710 * }, function done (err) {
5711 * // all pages have been fetched
5712 * })
5713 */
5714function until(test, iteratee, callback) {
5715 const _test = wrapAsync(test);
5716 return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);
5717}
5718
5719/**
5720 * Runs the `tasks` array of functions in series, each passing their results to
5721 * the next in the array. However, if any of the `tasks` pass an error to their
5722 * own callback, the next function is not executed, and the main `callback` is
5723 * immediately called with the error.
5724 *
5725 * @name waterfall
5726 * @static
5727 * @memberOf module:ControlFlow
5728 * @method
5729 * @category Control Flow
5730 * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
5731 * to run.
5732 * Each function should complete with any number of `result` values.
5733 * The `result` values will be passed as arguments, in order, to the next task.
5734 * @param {Function} [callback] - An optional callback to run once all the
5735 * functions have completed. This will be passed the results of the last task's
5736 * callback. Invoked with (err, [results]).
5737 * @returns {Promise} a promise, if a callback is omitted
5738 * @example
5739 *
5740 * async.waterfall([
5741 * function(callback) {
5742 * callback(null, 'one', 'two');
5743 * },
5744 * function(arg1, arg2, callback) {
5745 * // arg1 now equals 'one' and arg2 now equals 'two'
5746 * callback(null, 'three');
5747 * },
5748 * function(arg1, callback) {
5749 * // arg1 now equals 'three'
5750 * callback(null, 'done');
5751 * }
5752 * ], function (err, result) {
5753 * // result now equals 'done'
5754 * });
5755 *
5756 * // Or, with named functions:
5757 * async.waterfall([
5758 * myFirstFunction,
5759 * mySecondFunction,
5760 * myLastFunction,
5761 * ], function (err, result) {
5762 * // result now equals 'done'
5763 * });
5764 * function myFirstFunction(callback) {
5765 * callback(null, 'one', 'two');
5766 * }
5767 * function mySecondFunction(arg1, arg2, callback) {
5768 * // arg1 now equals 'one' and arg2 now equals 'two'
5769 * callback(null, 'three');
5770 * }
5771 * function myLastFunction(arg1, callback) {
5772 * // arg1 now equals 'three'
5773 * callback(null, 'done');
5774 * }
5775 */
5776function waterfall (tasks, callback) {
5777 callback = once(callback);
5778 if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
5779 if (!tasks.length) return callback();
5780 var taskIndex = 0;
5781
5782 function nextTask(args) {
5783 var task = wrapAsync(tasks[taskIndex++]);
5784 task(...args, onlyOnce(next));
5785 }
5786
5787 function next(err, ...args) {
5788 if (err === false) return
5789 if (err || taskIndex === tasks.length) {
5790 return callback(err, ...args);
5791 }
5792 nextTask(args);
5793 }
5794
5795 nextTask([]);
5796}
5797
5798var waterfall$1 = awaitify(waterfall);
5799
5800/**
5801 * An "async function" in the context of Async is an asynchronous function with
5802 * a variable number of parameters, with the final parameter being a callback.
5803 * (`function (arg1, arg2, ..., callback) {}`)
5804 * The final callback is of the form `callback(err, results...)`, which must be
5805 * called once the function is completed. The callback should be called with a
5806 * Error as its first argument to signal that an error occurred.
5807 * Otherwise, if no error occurred, it should be called with `null` as the first
5808 * argument, and any additional `result` arguments that may apply, to signal
5809 * successful completion.
5810 * The callback must be called exactly once, ideally on a later tick of the
5811 * JavaScript event loop.
5812 *
5813 * This type of function is also referred to as a "Node-style async function",
5814 * or a "continuation passing-style function" (CPS). Most of the methods of this
5815 * library are themselves CPS/Node-style async functions, or functions that
5816 * return CPS/Node-style async functions.
5817 *
5818 * Wherever we accept a Node-style async function, we also directly accept an
5819 * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
5820 * In this case, the `async` function will not be passed a final callback
5821 * argument, and any thrown error will be used as the `err` argument of the
5822 * implicit callback, and the return value will be used as the `result` value.
5823 * (i.e. a `rejected` of the returned Promise becomes the `err` callback
5824 * argument, and a `resolved` value becomes the `result`.)
5825 *
5826 * Note, due to JavaScript limitations, we can only detect native `async`
5827 * functions and not transpilied implementations.
5828 * Your environment must have `async`/`await` support for this to work.
5829 * (e.g. Node > v7.6, or a recent version of a modern browser).
5830 * If you are using `async` functions through a transpiler (e.g. Babel), you
5831 * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
5832 * because the `async function` will be compiled to an ordinary function that
5833 * returns a promise.
5834 *
5835 * @typedef {Function} AsyncFunction
5836 * @static
5837 */
5838
5839
5840var index = {
5841 apply,
5842 applyEach,
5843 applyEachSeries,
5844 asyncify,
5845 auto,
5846 autoInject,
5847 cargo: cargo$1,
5848 cargoQueue: cargo,
5849 compose,
5850 concat: concat$1,
5851 concatLimit: concatLimit$1,
5852 concatSeries: concatSeries$1,
5853 constant: constant$1,
5854 detect: detect$1,
5855 detectLimit: detectLimit$1,
5856 detectSeries: detectSeries$1,
5857 dir,
5858 doUntil,
5859 doWhilst: doWhilst$1,
5860 each,
5861 eachLimit: eachLimit$1,
5862 eachOf: eachOf$1,
5863 eachOfLimit: eachOfLimit$1,
5864 eachOfSeries: eachOfSeries$1,
5865 eachSeries: eachSeries$1,
5866 ensureAsync,
5867 every: every$1,
5868 everyLimit: everyLimit$1,
5869 everySeries: everySeries$1,
5870 filter: filter$1,
5871 filterLimit: filterLimit$1,
5872 filterSeries: filterSeries$1,
5873 forever: forever$1,
5874 groupBy,
5875 groupByLimit: groupByLimit$1,
5876 groupBySeries,
5877 log,
5878 map: map$1,
5879 mapLimit: mapLimit$1,
5880 mapSeries: mapSeries$1,
5881 mapValues,
5882 mapValuesLimit: mapValuesLimit$1,
5883 mapValuesSeries,
5884 memoize,
5885 nextTick,
5886 parallel,
5887 parallelLimit,
5888 priorityQueue,
5889 queue,
5890 race: race$1,
5891 reduce: reduce$1,
5892 reduceRight,
5893 reflect,
5894 reflectAll,
5895 reject: reject$1,
5896 rejectLimit: rejectLimit$1,
5897 rejectSeries: rejectSeries$1,
5898 retry,
5899 retryable,
5900 seq,
5901 series,
5902 setImmediate: setImmediate$1,
5903 some: some$1,
5904 someLimit: someLimit$1,
5905 someSeries: someSeries$1,
5906 sortBy: sortBy$1,
5907 timeout,
5908 times,
5909 timesLimit,
5910 timesSeries,
5911 transform,
5912 tryEach: tryEach$1,
5913 unmemoize,
5914 until,
5915 waterfall: waterfall$1,
5916 whilst: whilst$1,
5917
5918 // aliases
5919 all: every$1,
5920 allLimit: everyLimit$1,
5921 allSeries: everySeries$1,
5922 any: some$1,
5923 anyLimit: someLimit$1,
5924 anySeries: someSeries$1,
5925 find: detect$1,
5926 findLimit: detectLimit$1,
5927 findSeries: detectSeries$1,
5928 flatMap: concat$1,
5929 flatMapLimit: concatLimit$1,
5930 flatMapSeries: concatSeries$1,
5931 forEach: each,
5932 forEachSeries: eachSeries$1,
5933 forEachLimit: eachLimit$1,
5934 forEachOf: eachOf$1,
5935 forEachOfSeries: eachOfSeries$1,
5936 forEachOfLimit: eachOfLimit$1,
5937 inject: reduce$1,
5938 foldl: reduce$1,
5939 foldr: reduceRight,
5940 select: filter$1,
5941 selectLimit: filterLimit$1,
5942 selectSeries: filterSeries$1,
5943 wrapSync: asyncify,
5944 during: whilst$1,
5945 doDuring: doWhilst$1
5946};
5947
5948export { every$1 as all, everyLimit$1 as allLimit, everySeries$1 as allSeries, some$1 as any, someLimit$1 as anyLimit, someSeries$1 as anySeries, apply, applyEach, applyEachSeries, asyncify, auto, autoInject, cargo$1 as cargo, cargo as cargoQueue, compose, concat$1 as concat, concatLimit$1 as concatLimit, concatSeries$1 as concatSeries, constant$1 as constant, index as default, detect$1 as detect, detectLimit$1 as detectLimit, detectSeries$1 as detectSeries, dir, doWhilst$1 as doDuring, doUntil, doWhilst$1 as doWhilst, whilst$1 as during, each, eachLimit$1 as eachLimit, eachOf$1 as eachOf, eachOfLimit$1 as eachOfLimit, eachOfSeries$1 as eachOfSeries, eachSeries$1 as eachSeries, ensureAsync, every$1 as every, everyLimit$1 as everyLimit, everySeries$1 as everySeries, filter$1 as filter, filterLimit$1 as filterLimit, filterSeries$1 as filterSeries, detect$1 as find, detectLimit$1 as findLimit, detectSeries$1 as findSeries, concat$1 as flatMap, concatLimit$1 as flatMapLimit, concatSeries$1 as flatMapSeries, reduce$1 as foldl, reduceRight as foldr, each as forEach, eachLimit$1 as forEachLimit, eachOf$1 as forEachOf, eachOfLimit$1 as forEachOfLimit, eachOfSeries$1 as forEachOfSeries, eachSeries$1 as forEachSeries, forever$1 as forever, groupBy, groupByLimit$1 as groupByLimit, groupBySeries, reduce$1 as inject, log, map$1 as map, mapLimit$1 as mapLimit, mapSeries$1 as mapSeries, mapValues, mapValuesLimit$1 as mapValuesLimit, mapValuesSeries, memoize, nextTick, parallel, parallelLimit, priorityQueue, queue, race$1 as race, reduce$1 as reduce, reduceRight, reflect, reflectAll, reject$1 as reject, rejectLimit$1 as rejectLimit, rejectSeries$1 as rejectSeries, retry, retryable, filter$1 as select, filterLimit$1 as selectLimit, filterSeries$1 as selectSeries, seq, series, setImmediate$1 as setImmediate, some$1 as some, someLimit$1 as someLimit, someSeries$1 as someSeries, sortBy$1 as sortBy, timeout, times, timesLimit, timesSeries, transform, tryEach$1 as tryEach, unmemoize, until, waterfall$1 as waterfall, whilst$1 as whilst, asyncify as wrapSync };
Note: See TracBrowser for help on using the repository browser.