summaryrefslogtreecommitdiff
path: root/build/async.js
diff options
context:
space:
mode:
Diffstat (limited to 'build/async.js')
-rw-r--r--build/async.js1838
1 files changed, 919 insertions, 919 deletions
diff --git a/build/async.js b/build/async.js
index 84513d7..e5d60e3 100644
--- a/build/async.js
+++ b/build/async.js
@@ -1,10 +1,31 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
- factory((global.async = {}));
+ (factory((global.async = {})));
}(this, function (exports) { 'use strict';
/**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply$1(func, thisArg, args) {
+ var length = args ? args.length : 0;
+ switch (length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
+ }
+ return func.apply(thisArg, args);
+ }
+
+ /**
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
@@ -34,27 +55,6 @@
return !!value && (type == 'object' || type == 'function');
}
- /**
- * A faster alternative to `Function#apply`, this function invokes `func`
- * with the `this` binding of `thisArg` and the arguments of `args`.
- *
- * @private
- * @param {Function} func The function to invoke.
- * @param {*} thisArg The `this` binding of `func`.
- * @param {...*} [args] The arguments to invoke `func` with.
- * @returns {*} Returns the result of `func`.
- */
- function apply$1(func, thisArg, args) {
- var length = args ? args.length : 0;
- switch (length) {
- case 0: return func.call(thisArg);
- case 1: return func.call(thisArg, args[0]);
- case 2: return func.call(thisArg, args[0], args[1]);
- case 3: return func.call(thisArg, args[0], args[1], args[2]);
- }
- return func.apply(thisArg, args);
- }
-
var funcTag = '[object Function]';
var genTag = '[object GeneratorFunction]';
/** Used for built-in method references. */
@@ -241,77 +241,23 @@
};
}
- function asyncify(func) {
- return rest(function (args) {
- var callback = args.pop();
- var result;
- try {
- result = func.apply(this, args);
- } catch (e) {
- return callback(e);
- }
- // if result is Promise object
- if (isObject(result) && typeof result.then === 'function') {
- result.then(function (value) {
- callback(null, value);
- })['catch'](function (err) {
- callback(err.message ? err : new Error(err));
- });
+ function applyEach$1(eachfn) {
+ return rest(function (fns, args) {
+ var go = rest(function (args) {
+ var that = this;
+ var callback = args.pop();
+ return eachfn(fns, function (fn, _, cb) {
+ fn.apply(that, args.concat([cb]));
+ }, callback);
+ });
+ if (args.length) {
+ return go.apply(this, args);
} else {
- callback(null, result);
+ return go;
}
});
}
- /**
- * A specialized version of `_.map` for arrays without support for iteratee
- * shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns the new mapped array.
- */
- function arrayMap(array, iteratee) {
- var index = -1,
- length = array.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iteratee(array[index], index, array);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.property` without support for deep paths.
- *
- * @private
- * @param {string} key The key of the property to get.
- * @returns {Function} Returns the new function.
- */
- function baseProperty(key) {
- return function(object) {
- return object == null ? undefined : object[key];
- };
- }
-
- function _filter(eachfn, arr, iterator, callback) {
- var results = [];
- eachfn(arr, function (x, index, callback) {
- iterator(x, function (v) {
- if (v) {
- results.push({ index: index, value: x });
- }
- callback();
- });
- }, function () {
- callback(arrayMap(results.sort(function (a, b) {
- return a.index - b.index;
- }), baseProperty('value')));
- });
- }
-
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT$1 = 'Expected a function';
@@ -388,6 +334,19 @@
}
/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+ function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+ }
+
+ /**
* Gets the "length" property value of `object`.
*
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
@@ -799,6 +758,36 @@
};
}
+ function eachOf(object, iterator, callback) {
+ callback = once(callback || noop);
+ object = object || [];
+
+ var iter = keyIterator(object);
+ var key,
+ completed = 0;
+
+ while ((key = iter()) != null) {
+ completed += 1;
+ iterator(object[key], key, onlyOnce(done));
+ }
+
+ if (completed === 0) callback(null);
+
+ function done(err) {
+ completed--;
+ if (err) {
+ callback(err);
+ }
+ // Check key is null in case iterator isn't exhausted
+ // and done resolved synchronously.
+ else if (key === null && completed <= 0) {
+ callback(null);
+ }
+ }
+ }
+
+ var applyEach = applyEach$1(eachOf);
+
var _setImmediate = typeof setImmediate === 'function' && setImmediate;
var _delay;
@@ -849,137 +838,126 @@
iterate();
}
- function doSeries(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOfSeries, obj, iterator, callback);
- };
- }
+ var applyEachSeries = applyEach$1(eachOfSeries);
- var filterSeries = doSeries(_filter);
+ var apply = rest(function (fn, args) {
+ return rest(function (callArgs) {
+ return fn.apply(null, args.concat(callArgs));
+ });
+ });
- function _eachOfLimit(limit) {
- return function (obj, iterator, callback) {
- callback = once(callback || noop);
- obj = obj || [];
- var nextKey = keyIterator(obj);
- if (limit <= 0) {
- return callback(null);
+ function asyncify(func) {
+ return rest(function (args) {
+ var callback = args.pop();
+ var result;
+ try {
+ result = func.apply(this, args);
+ } catch (e) {
+ return callback(e);
}
- var done = false;
- var running = 0;
- var errored = false;
-
- (function replenish() {
- if (done && running <= 0) {
- return callback(null);
- }
-
- while (running < limit && !errored) {
- var key = nextKey();
- if (key === null) {
- done = true;
- if (running <= 0) {
- callback(null);
- }
- return;
- }
- running += 1;
- iterator(obj[key], key, onlyOnce(function (err) {
- running -= 1;
- if (err) {
- callback(err);
- errored = true;
- } else {
- replenish();
- }
- }));
- }
- })();
- };
- }
-
- function doParallelLimit(fn) {
- return function (obj, limit, iterator, callback) {
- return fn(_eachOfLimit(limit), obj, iterator, callback);
- };
- }
-
- var filterLimit = doParallelLimit(_filter);
-
- function eachOf(object, iterator, callback) {
- callback = once(callback || noop);
- object = object || [];
-
- var iter = keyIterator(object);
- var key,
- completed = 0;
-
- while ((key = iter()) != null) {
- completed += 1;
- iterator(object[key], key, onlyOnce(done));
- }
-
- if (completed === 0) callback(null);
-
- function done(err) {
- completed--;
- if (err) {
- callback(err);
+ // if result is Promise object
+ if (isObject(result) && typeof result.then === 'function') {
+ result.then(function (value) {
+ callback(null, value);
+ })['catch'](function (err) {
+ callback(err.message ? err : new Error(err));
+ });
+ } else {
+ callback(null, result);
}
- // Check key is null in case iterator isn't exhausted
- // and done resolved synchronously.
- else if (key === null && completed <= 0) {
- callback(null);
- }
- }
- }
-
- function doParallel(fn) {
- return function (obj, iterator, callback) {
- return fn(eachOf, obj, iterator, callback);
- };
- }
-
- var filter = doParallel(_filter);
-
- function reduce(arr, memo, iterator, cb) {
- eachOfSeries(arr, function (x, i, cb) {
- iterator(memo, x, function (err, v) {
- memo = v;
- cb(err);
- });
- }, function (err) {
- cb(err, memo);
});
}
- var slice = Array.prototype.slice;
+ /**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array.length;
- function reduceRight(arr, memo, iterator, cb) {
- var reversed = slice.call(arr).reverse();
- reduce(reversed, memo, iterator, cb);
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
+ }
+ return array;
}
- function eachOfLimit(obj, limit, iterator, cb) {
- _eachOfLimit(limit)(obj, iterator, cb);
- }
+ /**
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
+ */
+ function arrayEvery(array, predicate) {
+ var index = -1,
+ length = array.length;
- function _withoutIndex(iterator) {
- return function (value, index, callback) {
- return iterator(value, callback);
- };
+ while (++index < length) {
+ if (!predicate(array[index], index, array)) {
+ return false;
+ }
+ }
+ return true;
}
- function eachLimit(arr, limit, iterator, cb) {
- return _eachOfLimit(limit)(arr, _withoutIndex(iterator), cb);
- }
+ /**
+ * Creates a base function for methods like `_.forIn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
- function eachSeries(arr, iterator, cb) {
- return eachOfSeries(arr, _withoutIndex(iterator), cb);
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ };
}
- function each(arr, iterator, cb) {
- return eachOf(arr, _withoutIndex(iterator), cb);
+ /**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseFor = createBaseFor();
+
+ /**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys);
}
/**
@@ -1001,362 +979,241 @@
return value;
}
- function _createTester(eachfn, check, getResult) {
- return function (arr, limit, iterator, cb) {
- function done() {
- if (cb) cb(getResult(false, void 0));
- }
- function iteratee(x, _, callback) {
- if (!cb) return callback();
- iterator(x, function (v) {
- if (cb && check(v)) {
- cb(getResult(true, x));
- cb = iterator = false;
- }
- callback();
- });
- }
- if (arguments.length > 3) {
- eachfn(arr, limit, iteratee, done);
- } else {
- cb = iterator;
- iterator = limit;
- eachfn(arr, iteratee, done);
- }
- };
- }
-
- var some = _createTester(eachOf, Boolean, identity);
-
- function notId(v) {
- return !v;
- }
-
- var every = _createTester(eachOf, notId, notId);
-
- function whilst(test, iterator, cb) {
- cb = cb || noop;
- if (!test()) return cb(null);
- var next = rest(function (err, args) {
- if (err) return cb(err);
- if (test.apply(this, args)) return iterator(next);
- cb.apply(null, [null].concat(args));
- });
- iterator(next);
- }
-
- function ensureAsync(fn) {
- return rest(function (args) {
- var callback = args.pop();
- var sync = true;
- args.push(function () {
- var innerArgs = arguments;
- if (sync) {
- setImmediate$1(function () {
- callback.apply(null, innerArgs);
- });
- } else {
- callback.apply(null, innerArgs);
- }
- });
- fn.apply(this, args);
- sync = false;
- });
- }
-
- function iterator (tasks) {
- function makeCallback(index) {
- function fn() {
- if (tasks.length) {
- tasks[index].apply(null, arguments);
- }
- return fn.next();
- }
- fn.next = function () {
- return index < tasks.length - 1 ? makeCallback(index + 1) : null;
- };
- return fn;
- }
- return makeCallback(0);
- }
-
- function waterfall (tasks, cb) {
- cb = once(cb || noop);
- if (!isArray(tasks)) return cb(new Error('First argument to waterfall must be an array of functions'));
- if (!tasks.length) return cb();
-
- function wrapIterator(iterator) {
- return rest(function (err, args) {
- if (err) {
- cb.apply(null, [err].concat(args));
- } else {
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- } else {
- args.push(cb);
- }
- ensureAsync(iterator).apply(null, args);
- }
- });
- }
- wrapIterator(iterator(tasks))();
+ /**
+ * Converts `value` to a function if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Function} Returns the function.
+ */
+ function toFunction(value) {
+ return typeof value == 'function' ? value : identity;
}
- function until(test, iterator, cb) {
- return whilst(function () {
- return !test.apply(this, arguments);
- }, iterator, cb);
+ /**
+ * Iterates over own enumerable properties of an object invoking `iteratee`
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, toFunction(iteratee));
}
- function unmemoize(fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- }
+ /**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+ function indexOfNaN(array, fromIndex, fromRight) {
+ var length = array.length,
+ index = fromIndex + (fromRight ? 0 : -1);
- function transform(arr, memo, iterator, callback) {
- if (arguments.length === 3) {
- callback = iterator;
- iterator = memo;
- memo = isArray(arr) ? [] : {};
+ while ((fromRight ? index-- : ++index < length)) {
+ var other = array[index];
+ if (other !== other) {
+ return index;
}
-
- eachOf(arr, function (v, k, cb) {
- iterator(memo, v, k, cb);
- }, function (err) {
- callback(err, memo);
- });
- }
-
- function _asyncMap(eachfn, arr, iterator, callback) {
- callback = once(callback || noop);
- arr = arr || [];
- var results = isArrayLike(arr) ? [] : {};
- eachfn(arr, function (value, index, callback) {
- iterator(value, function (err, v) {
- results[index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
+ }
+ return -1;
}
- var mapSeries = doSeries(_asyncMap);
-
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeCeil = Math.ceil;
- var nativeMax$2 = Math.max;
/**
- * The base implementation of `_.range` and `_.rangeRight` which doesn't
- * coerce arguments to numbers.
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
*
* @private
- * @param {number} start The start of the range.
- * @param {number} end The end of the range.
- * @param {number} step The value to increment or decrement by.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Array} Returns the new array of numbers.
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
*/
- function baseRange(start, end, step, fromRight) {
- var index = -1,
- length = nativeMax$2(nativeCeil((end - start) / (step || 1)), 0),
- result = Array(length);
-
- while (length--) {
- result[fromRight ? length : ++index] = start;
- start += step;
+ function baseIndexOf(array, value, fromIndex) {
+ if (value !== value) {
+ return indexOfNaN(array, fromIndex);
}
- return result;
- }
+ var index = fromIndex - 1,
+ length = array.length;
- function timesSeries (count, iterator, callback) {
- mapSeries(baseRange(0, count, 1), iterator, callback);
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
+ }
+ return -1;
}
- var mapLimit = doParallelLimit(_asyncMap);
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax$1 = Math.max;
- function timeLimit(count, limit, iterator, cb) {
- return mapLimit(baseRange(0, count, 1), limit, iterator, cb);
+ /**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
+ * performs a faster binary search.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // using `fromIndex`
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */
+ function indexOf(array, value, fromIndex) {
+ var length = array ? array.length : 0;
+ if (!length) {
+ return -1;
+ }
+ fromIndex = toInteger(fromIndex);
+ if (fromIndex < 0) {
+ fromIndex = nativeMax$1(length + fromIndex, 0);
+ }
+ return baseIndexOf(array, value, fromIndex);
}
- var map = doParallel(_asyncMap);
+ function auto (tasks, concurrency, callback) {
+ if (typeof arguments[1] === 'function') {
+ // concurrency is optional, shift the args.
+ callback = concurrency;
+ concurrency = null;
+ }
+ callback = once(callback || noop);
+ var keys$$ = keys(tasks);
+ var remainingTasks = keys$$.length;
+ if (!remainingTasks) {
+ return callback(null);
+ }
+ if (!concurrency) {
+ concurrency = remainingTasks;
+ }
- function times (count, iterator, callback) {
- map(baseRange(0, count, 1), iterator, callback);
- }
+ var results = {};
+ var runningTasks = 0;
- function sortBy(arr, iterator, cb) {
- map(arr, function (x, cb) {
- iterator(x, function (err, criteria) {
- if (err) return cb(err);
- cb(null, { value: x, criteria: criteria });
+ var listeners = [];
+ function addListener(fn) {
+ listeners.unshift(fn);
+ }
+ function removeListener(fn) {
+ var idx = indexOf(listeners, fn);
+ if (idx >= 0) listeners.splice(idx, 1);
+ }
+ function taskComplete() {
+ remainingTasks--;
+ arrayEach(listeners.slice(), function (fn) {
+ fn();
});
- }, function (err, results) {
- if (err) return cb(err);
- cb(null, arrayMap(results.sort(comparator), baseProperty('value')));
- });
-
- function comparator(left, right) {
- var a = left.criteria,
- b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
}
- }
- var someLimit = _createTester(eachOfLimit, Boolean, identity);
-
- function _parallel(eachfn, tasks, callback) {
- callback = callback || noop;
- var results = isArrayLike(tasks) ? [] : {};
+ addListener(function () {
+ if (!remainingTasks) {
+ callback(null, results);
+ }
+ });
- eachfn(tasks, function (task, key, callback) {
- task(rest(function (err, args) {
+ arrayEach(keys$$, function (k) {
+ var task = isArray(tasks[k]) ? tasks[k] : [tasks[k]];
+ var taskCallback = rest(function (err, args) {
+ runningTasks--;
if (args.length <= 1) {
args = args[0];
}
- results[key] = args;
- callback(err);
- }));
- }, function (err) {
- callback(err, results);
- });
- }
-
- function series(tasks, cb) {
- return _parallel(eachOfSeries, tasks, cb);
- }
-
- function seq() /* functions... */{
- var fns = arguments;
- return rest(function (args) {
- var that = this;
-
- var cb = args[args.length - 1];
- if (typeof cb == 'function') {
- args.pop();
- } else {
- cb = noop;
- }
-
- reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([rest(function (err, nextargs) {
- cb(err, nextargs);
- })]));
- }, function (err, results) {
- cb.apply(that, [err].concat(results));
+ if (err) {
+ var safeResults = {};
+ forOwn(results, function (val, rkey) {
+ safeResults[rkey] = val;
+ });
+ safeResults[k] = args;
+ callback(err, safeResults);
+ } else {
+ results[k] = args;
+ setImmediate$1(taskComplete);
+ }
});
- });
- }
-
- function retry(times, task, callback) {
- var DEFAULT_TIMES = 5;
- var DEFAULT_INTERVAL = 0;
-
- var attempts = [];
-
- var opts = {
- times: DEFAULT_TIMES,
- interval: DEFAULT_INTERVAL
- };
-
- function parseTimes(acc, t) {
- if (typeof t === 'number') {
- acc.times = parseInt(t, 10) || DEFAULT_TIMES;
- } else if (typeof t === 'object') {
- acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
- acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
- } else {
- throw new Error('Unsupported argument type for \'times\': ' + typeof t);
+ var requires = task.slice(0, task.length - 1);
+ // prevent dead-locks
+ var len = requires.length;
+ var dep;
+ while (len--) {
+ if (!(dep = tasks[requires[len]])) {
+ throw new Error('Has inexistant dependency');
+ }
+ if (isArray(dep) && indexOf(dep, k) >= 0) {
+ throw new Error('Has cyclic dependencies');
+ }
}
- }
-
- var length = arguments.length;
- if (length < 1 || length > 3) {
- throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
- } else if (length <= 2 && typeof times === 'function') {
- callback = task;
- task = times;
- }
- if (typeof times !== 'function') {
- parseTimes(opts, times);
- }
- opts.callback = callback;
- opts.task = task;
-
- function wrappedTask(wrappedCallback, wrappedResults) {
- function retryAttempt(task, finalAttempt) {
- return function (seriesCallback) {
- task(function (err, result) {
- seriesCallback(!err || finalAttempt, {
- err: err,
- result: result
- });
- }, wrappedResults);
- };
+ function ready() {
+ return runningTasks < concurrency && !baseHas(results, k) && arrayEvery(requires, function (x) {
+ return baseHas(results, x);
+ });
}
-
- function retryInterval(interval) {
- return function (seriesCallback) {
- setTimeout(function () {
- seriesCallback(null);
- }, interval);
- };
+ if (ready()) {
+ runningTasks++;
+ task[task.length - 1](taskCallback, results);
+ } else {
+ addListener(listener);
}
-
- while (opts.times) {
-
- var finalAttempt = !(opts.times -= 1);
- attempts.push(retryAttempt(opts.task, finalAttempt));
- if (!finalAttempt && opts.interval > 0) {
- attempts.push(retryInterval(opts.interval));
+ function listener() {
+ if (ready()) {
+ runningTasks++;
+ removeListener(listener);
+ task[task.length - 1](taskCallback, results);
}
}
-
- series(attempts, function (done, data) {
- data = data[data.length - 1];
- (wrappedCallback || opts.callback)(data.err, data.result);
- });
- }
-
- // If a callback is passed, run this as a controll flow
- return opts.callback ? wrappedTask() : wrappedTask;
- }
-
- function reject$1(eachfn, arr, iterator, callback) {
- _filter(eachfn, arr, function (value, cb) {
- iterator(value, function (v) {
- cb(!v);
- });
- }, callback);
+ });
}
- var rejectSeries = doSeries(reject$1);
-
- var rejectLimit = doParallelLimit(reject$1);
-
- var reject = doParallel(reject$1);
-
/**
- * A specialized version of `_.forEach` for arrays without support for
- * iteratee shorthands.
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
- * @returns {Array} Returns `array`.
+ * @returns {Array} Returns the new mapped array.
*/
- function arrayEach(array, iteratee) {
+ function arrayMap(array, iteratee) {
var index = -1,
- length = array.length;
+ length = array.length,
+ result = Array(length);
while (++index < length) {
- if (iteratee(array[index], index, array) === false) {
- break;
- }
+ result[index] = iteratee(array[index], index, array);
}
- return array;
+ return result;
}
function queue$1(worker, concurrency, payload) {
@@ -1488,115 +1345,164 @@
return q;
}
- function queue (worker, concurrency) {
- return queue$1(function (items, cb) {
- worker(items[0], cb);
- }, concurrency, 1);
+ function cargo(worker, payload) {
+ return queue$1(worker, 1, payload);
}
- function priorityQueue (worker, concurrency) {
- function _compareTasks(a, b) {
- return a.priority - b.priority;
- }
+ function reduce(arr, memo, iterator, cb) {
+ eachOfSeries(arr, function (x, i, cb) {
+ iterator(memo, x, function (err, v) {
+ memo = v;
+ cb(err);
+ });
+ }, function (err) {
+ cb(err, memo);
+ });
+ }
- function _binarySearch(sequence, item, compare) {
- var beg = -1,
- end = sequence.length - 1;
- while (beg < end) {
- var mid = beg + (end - beg + 1 >>> 1);
- if (compare(item, sequence[mid]) >= 0) {
- beg = mid;
- } else {
- end = mid - 1;
- }
- }
- return beg;
- }
+ function seq() /* functions... */{
+ var fns = arguments;
+ return rest(function (args) {
+ var that = this;
- function _insert(q, data, priority, callback) {
- if (callback != null && typeof callback !== 'function') {
- throw new Error('task callback must be a function');
- }
- q.started = true;
- if (!isArray(data)) {
- data = [data];
- }
- if (data.length === 0) {
- // call drain immediately if there are no tasks
- return setImmediate$1(function () {
- q.drain();
- });
+ var cb = args[args.length - 1];
+ if (typeof cb == 'function') {
+ args.pop();
+ } else {
+ cb = noop;
}
- arrayEach(data, function (task) {
- var item = {
- data: task,
- priority: priority,
- callback: typeof callback === 'function' ? callback : noop
- };
-
- q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- setImmediate$1(q.process);
+ reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([rest(function (err, nextargs) {
+ cb(err, nextargs);
+ })]));
+ }, function (err, results) {
+ cb.apply(that, [err].concat(results));
});
- }
-
- // Start with a normal queue
- var q = queue(worker, concurrency);
+ });
+ }
- // Override push to accept second parameter representing priority
- q.push = function (data, priority, callback) {
- _insert(q, data, priority, callback);
- };
+ var reverse = Array.prototype.reverse;
- // Remove unshift function
- delete q.unshift;
+ function compose() /* functions... */{
+ return seq.apply(null, reverse.call(arguments));
+ }
- return q;
+ function concat$1(eachfn, arr, fn, callback) {
+ var result = [];
+ eachfn(arr, function (x, index, cb) {
+ fn(x, function (err, y) {
+ result = result.concat(y || []);
+ cb(err);
+ });
+ }, function (err) {
+ callback(err, result);
+ });
}
- function parallelLimit(tasks, limit, cb) {
- return _parallel(_eachOfLimit(limit), tasks, cb);
+ function doParallel(fn) {
+ return function (obj, iterator, callback) {
+ return fn(eachOf, obj, iterator, callback);
+ };
}
- function parallel(tasks, cb) {
- return _parallel(eachOf, tasks, cb);
+ var concat = doParallel(concat$1);
+
+ function doSeries(fn) {
+ return function (obj, iterator, callback) {
+ return fn(eachOfSeries, obj, iterator, callback);
+ };
}
- var nexTick = typeof process === 'object' && typeof process.nextTick === 'function' ? process.nextTick : setImmediate$1;
+ var concatSeries = doSeries(concat$1);
- function memoize(fn, hasher) {
- var memo = {};
- var queues = {};
- hasher = hasher || identity;
- var memoized = rest(function memoized(args) {
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (key in memo) {
- setImmediate$1(function () {
- callback.apply(null, memo[key]);
+ var constant = rest(function (values) {
+ var args = [null].concat(values);
+ return function (cb) {
+ return cb.apply(this, args);
+ };
+ });
+
+ function _createTester(eachfn, check, getResult) {
+ return function (arr, limit, iterator, cb) {
+ function done() {
+ if (cb) cb(getResult(false, void 0));
+ }
+ function iteratee(x, _, callback) {
+ if (!cb) return callback();
+ iterator(x, function (v) {
+ if (cb && check(v)) {
+ cb(getResult(true, x));
+ cb = iterator = false;
+ }
+ callback();
});
- } else if (key in queues) {
- queues[key].push(callback);
+ }
+ if (arguments.length > 3) {
+ eachfn(arr, limit, iteratee, done);
} else {
- queues[key] = [callback];
- fn.apply(null, args.concat([rest(function (args) {
- memo[key] = args;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, args);
- }
- })]));
+ cb = iterator;
+ iterator = limit;
+ eachfn(arr, iteratee, done);
}
- });
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
+ };
}
+ function _findGetResult(v, x) {
+ return x;
+ }
+
+ var detect = _createTester(eachOf, identity, _findGetResult);
+
+ function _eachOfLimit(limit) {
+ return function (obj, iterator, callback) {
+ callback = once(callback || noop);
+ obj = obj || [];
+ var nextKey = keyIterator(obj);
+ if (limit <= 0) {
+ return callback(null);
+ }
+ var done = false;
+ var running = 0;
+ var errored = false;
+
+ (function replenish() {
+ if (done && running <= 0) {
+ return callback(null);
+ }
+
+ while (running < limit && !errored) {
+ var key = nextKey();
+ if (key === null) {
+ done = true;
+ if (running <= 0) {
+ callback(null);
+ }
+ return;
+ }
+ running += 1;
+ iterator(obj[key], key, onlyOnce(function (err) {
+ running -= 1;
+ if (err) {
+ callback(err);
+ errored = true;
+ } else {
+ replenish();
+ }
+ }));
+ }
+ })();
+ };
+ }
+
+ function eachOfLimit(obj, limit, iterator, cb) {
+ _eachOfLimit(limit)(obj, iterator, cb);
+ }
+
+ var detectLimit = _createTester(eachOfLimit, identity, _findGetResult);
+
+ var detectSeries = _createTester(eachOfSeries, identity, _findGetResult);
+
function consoleFunc(name) {
return rest(function (fn, args) {
fn.apply(null, args.concat([rest(function (err, args) {
@@ -1615,20 +1521,7 @@
});
}
- var log = consoleFunc('log');
-
- function forever(fn, cb) {
- var done = onlyOnce(cb || noop);
- var task = ensureAsync(fn);
-
- function next(err) {
- if (err) return done(err);
- task(next);
- }
- next();
- }
-
- var everyLimit = _createTester(eachOfLimit, notId, notId);
+ var dir = consoleFunc('dir');
function during(test, iterator, cb) {
cb = cb || noop;
@@ -1651,6 +1544,26 @@
test(check);
}
+ function doDuring(iterator, test, cb) {
+ var calls = 0;
+
+ during(function (next) {
+ if (calls++ < 1) return next(null, true);
+ test.apply(this, arguments);
+ }, iterator, cb);
+ }
+
+ function whilst(test, iterator, cb) {
+ cb = cb || noop;
+ if (!test()) return cb(null);
+ var next = rest(function (err, args) {
+ if (err) return cb(err);
+ if (test.apply(this, args)) return iterator(next);
+ cb.apply(null, [null].concat(args));
+ });
+ iterator(next);
+ }
+
function doWhilst(iterator, test, cb) {
var calls = 0;
return whilst(function () {
@@ -1664,374 +1577,461 @@
}, cb);
}
- function doDuring(iterator, test, cb) {
- var calls = 0;
+ function _withoutIndex(iterator) {
+ return function (value, index, callback) {
+ return iterator(value, callback);
+ };
+ }
- during(function (next) {
- if (calls++ < 1) return next(null, true);
- test.apply(this, arguments);
- }, iterator, cb);
+ function each(arr, iterator, cb) {
+ return eachOf(arr, _withoutIndex(iterator), cb);
}
- var dir = consoleFunc('dir');
+ function eachLimit(arr, limit, iterator, cb) {
+ return _eachOfLimit(limit)(arr, _withoutIndex(iterator), cb);
+ }
- function _findGetResult(v, x) {
- return x;
+ function eachSeries(arr, iterator, cb) {
+ return eachOfSeries(arr, _withoutIndex(iterator), cb);
}
- var detectSeries = _createTester(eachOfSeries, identity, _findGetResult);
+ function ensureAsync(fn) {
+ return rest(function (args) {
+ var callback = args.pop();
+ var sync = true;
+ args.push(function () {
+ var innerArgs = arguments;
+ if (sync) {
+ setImmediate$1(function () {
+ callback.apply(null, innerArgs);
+ });
+ } else {
+ callback.apply(null, innerArgs);
+ }
+ });
+ fn.apply(this, args);
+ sync = false;
+ });
+ }
- var detectLimit = _createTester(eachOfLimit, identity, _findGetResult);
+ function notId(v) {
+ return !v;
+ }
- var detect = _createTester(eachOf, identity, _findGetResult);
+ var every = _createTester(eachOf, notId, notId);
- var constant = rest(function (values) {
- var args = [null].concat(values);
- return function (cb) {
- return cb.apply(this, args);
- };
- });
+ var everyLimit = _createTester(eachOfLimit, notId, notId);
- function concat$1(eachfn, arr, fn, callback) {
- var result = [];
- eachfn(arr, function (x, index, cb) {
- fn(x, function (err, y) {
- result = result.concat(y || []);
- cb(err);
+ function _filter(eachfn, arr, iterator, callback) {
+ var results = [];
+ eachfn(arr, function (x, index, callback) {
+ iterator(x, function (v) {
+ if (v) {
+ results.push({ index: index, value: x });
+ }
+ callback();
});
- }, function (err) {
- callback(err, result);
+ }, function () {
+ callback(arrayMap(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), baseProperty('value')));
});
}
- var concatSeries = doSeries(concat$1);
+ var filter = doParallel(_filter);
- var concat = doParallel(concat$1);
+ function doParallelLimit(fn) {
+ return function (obj, limit, iterator, callback) {
+ return fn(_eachOfLimit(limit), obj, iterator, callback);
+ };
+ }
- var reverse = Array.prototype.reverse;
+ var filterLimit = doParallelLimit(_filter);
- function compose() /* functions... */{
- return seq.apply(null, reverse.call(arguments));
+ var filterSeries = doSeries(_filter);
+
+ function forever(fn, cb) {
+ var done = onlyOnce(cb || noop);
+ var task = ensureAsync(fn);
+
+ function next(err) {
+ if (err) return done(err);
+ task(next);
+ }
+ next();
}
- function cargo(worker, payload) {
- return queue$1(worker, 1, payload);
+ function iterator (tasks) {
+ function makeCallback(index) {
+ function fn() {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments);
+ }
+ return fn.next();
+ }
+ fn.next = function () {
+ return index < tasks.length - 1 ? makeCallback(index + 1) : null;
+ };
+ return fn;
+ }
+ return makeCallback(0);
}
- /**
- * A specialized version of `_.every` for arrays without support for
- * iteratee shorthands.
- *
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} predicate The function invoked per iteration.
- * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
- */
- function arrayEvery(array, predicate) {
- var index = -1,
- length = array.length;
+ var log = consoleFunc('log');
- while (++index < length) {
- if (!predicate(array[index], index, array)) {
- return false;
- }
- }
- return true;
+ function _asyncMap(eachfn, arr, iterator, callback) {
+ callback = once(callback || noop);
+ arr = arr || [];
+ var results = isArrayLike(arr) ? [] : {};
+ eachfn(arr, function (value, index, callback) {
+ iterator(value, function (err, v) {
+ results[index] = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
}
- /**
- * Creates a base function for methods like `_.forIn`.
- *
- * @private
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {Function} Returns the new base function.
- */
- function createBaseFor(fromRight) {
- return function(object, iteratee, keysFunc) {
- var index = -1,
- iterable = Object(object),
- props = keysFunc(object),
- length = props.length;
+ var map = doParallel(_asyncMap);
- while (length--) {
- var key = props[fromRight ? length : ++index];
- if (iteratee(iterable[key], key, iterable) === false) {
- break;
- }
- }
- return object;
- };
+ var mapLimit = doParallelLimit(_asyncMap);
+
+ var mapSeries = doSeries(_asyncMap);
+
+ function memoize(fn, hasher) {
+ var memo = {};
+ var queues = {};
+ hasher = hasher || identity;
+ var memoized = rest(function memoized(args) {
+ var callback = args.pop();
+ var key = hasher.apply(null, args);
+ if (key in memo) {
+ setImmediate$1(function () {
+ callback.apply(null, memo[key]);
+ });
+ } else if (key in queues) {
+ queues[key].push(callback);
+ } else {
+ queues[key] = [callback];
+ fn.apply(null, args.concat([rest(function (args) {
+ memo[key] = args;
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, args);
+ }
+ })]));
+ }
+ });
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
}
- /**
- * The base implementation of `baseForIn` and `baseForOwn` which iterates
- * over `object` properties returned by `keysFunc` invoking `iteratee` for
- * each property. Iteratee functions may exit iteration early by explicitly
- * returning `false`.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @param {Function} keysFunc The function to get the keys of `object`.
- * @returns {Object} Returns `object`.
- */
- var baseFor = createBaseFor();
+ var nexTick = typeof process === 'object' && typeof process.nextTick === 'function' ? process.nextTick : setImmediate$1;
- /**
- * The base implementation of `_.forOwn` without support for iteratee shorthands.
- *
- * @private
- * @param {Object} object The object to iterate over.
- * @param {Function} iteratee The function invoked per iteration.
- * @returns {Object} Returns `object`.
- */
- function baseForOwn(object, iteratee) {
- return object && baseFor(object, iteratee, keys);
+ function _parallel(eachfn, tasks, callback) {
+ callback = callback || noop;
+ var results = isArrayLike(tasks) ? [] : {};
+
+ eachfn(tasks, function (task, key, callback) {
+ task(rest(function (err, args) {
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[key] = args;
+ callback(err);
+ }));
+ }, function (err) {
+ callback(err, results);
+ });
}
- /**
- * Converts `value` to a function if it's not one.
- *
- * @private
- * @param {*} value The value to process.
- * @returns {Function} Returns the function.
- */
- function toFunction(value) {
- return typeof value == 'function' ? value : identity;
+ function parallel(tasks, cb) {
+ return _parallel(eachOf, tasks, cb);
}
- /**
- * Iterates over own enumerable properties of an object invoking `iteratee`
- * for each property. The iteratee is invoked with three arguments:
- * (value, key, object). Iteratee functions may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Object
- * @param {Object} object The object to iterate over.
- * @param {Function} [iteratee=_.identity] The function invoked per iteration.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Foo() {
- * this.a = 1;
- * this.b = 2;
- * }
- *
- * Foo.prototype.c = 3;
- *
- * _.forOwn(new Foo, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'a' then 'b' (iteration order is not guaranteed)
- */
- function forOwn(object, iteratee) {
- return object && baseForOwn(object, toFunction(iteratee));
+ function parallelLimit(tasks, limit, cb) {
+ return _parallel(_eachOfLimit(limit), tasks, cb);
}
- /**
- * Gets the index at which the first occurrence of `NaN` is found in `array`.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {number} fromIndex The index to search from.
- * @param {boolean} [fromRight] Specify iterating from right to left.
- * @returns {number} Returns the index of the matched `NaN`, else `-1`.
- */
- function indexOfNaN(array, fromIndex, fromRight) {
- var length = array.length,
- index = fromIndex + (fromRight ? 0 : -1);
+ function queue (worker, concurrency) {
+ return queue$1(function (items, cb) {
+ worker(items[0], cb);
+ }, concurrency, 1);
+ }
- while ((fromRight ? index-- : ++index < length)) {
- var other = array[index];
- if (other !== other) {
- return index;
+ function priorityQueue (worker, concurrency) {
+ function _compareTasks(a, b) {
+ return a.priority - b.priority;
}
- }
- return -1;
- }
- /**
- * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} fromIndex The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- if (value !== value) {
- return indexOfNaN(array, fromIndex);
- }
- var index = fromIndex - 1,
- length = array.length;
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1;
+ while (beg < end) {
+ var mid = beg + (end - beg + 1 >>> 1);
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return beg;
+ }
- while (++index < length) {
- if (array[index] === value) {
- return index;
+ function _insert(q, data, priority, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!isArray(data)) {
+ data = [data];
+ }
+ if (data.length === 0) {
+ // call drain immediately if there are no tasks
+ return setImmediate$1(function () {
+ q.drain();
+ });
+ }
+ arrayEach(data, function (task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : noop
+ };
+
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ setImmediate$1(q.process);
+ });
}
- }
- return -1;
+
+ // Start with a normal queue
+ var q = queue(worker, concurrency);
+
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback);
+ };
+
+ // Remove unshift function
+ delete q.unshift;
+
+ return q;
}
- /* Built-in method references for those with the same name as other `lodash` methods. */
- var nativeMax$1 = Math.max;
+ var slice = Array.prototype.slice;
- /**
- * Gets the index at which the first occurrence of `value` is found in `array`
- * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
- * for equality comparisons. If `fromIndex` is negative, it's used as the offset
- * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
- * performs a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Array
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value, else `-1`.
- * @example
- *
- * _.indexOf([1, 2, 1, 2], 2);
- * // => 1
- *
- * // using `fromIndex`
- * _.indexOf([1, 2, 1, 2], 2, 2);
- * // => 3
- */
- function indexOf(array, value, fromIndex) {
- var length = array ? array.length : 0;
- if (!length) {
- return -1;
- }
- fromIndex = toInteger(fromIndex);
- if (fromIndex < 0) {
- fromIndex = nativeMax$1(length + fromIndex, 0);
- }
- return baseIndexOf(array, value, fromIndex);
+ function reduceRight(arr, memo, iterator, cb) {
+ var reversed = slice.call(arr).reverse();
+ reduce(reversed, memo, iterator, cb);
}
- function auto (tasks, concurrency, callback) {
- if (typeof arguments[1] === 'function') {
- // concurrency is optional, shift the args.
- callback = concurrency;
- concurrency = null;
- }
- callback = once(callback || noop);
- var keys$$ = keys(tasks);
- var remainingTasks = keys$$.length;
- if (!remainingTasks) {
- return callback(null);
- }
- if (!concurrency) {
- concurrency = remainingTasks;
- }
+ function reject$1(eachfn, arr, iterator, callback) {
+ _filter(eachfn, arr, function (value, cb) {
+ iterator(value, function (v) {
+ cb(!v);
+ });
+ }, callback);
+ }
- var results = {};
- var runningTasks = 0;
+ var reject = doParallel(reject$1);
- var listeners = [];
- function addListener(fn) {
- listeners.unshift(fn);
+ var rejectLimit = doParallelLimit(reject$1);
+
+ var rejectSeries = doSeries(reject$1);
+
+ function series(tasks, cb) {
+ return _parallel(eachOfSeries, tasks, cb);
+ }
+
+ function retry(times, task, callback) {
+ var DEFAULT_TIMES = 5;
+ var DEFAULT_INTERVAL = 0;
+
+ var attempts = [];
+
+ var opts = {
+ times: DEFAULT_TIMES,
+ interval: DEFAULT_INTERVAL
+ };
+
+ function parseTimes(acc, t) {
+ if (typeof t === 'number') {
+ acc.times = parseInt(t, 10) || DEFAULT_TIMES;
+ } else if (typeof t === 'object') {
+ acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
+ acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
+ } else {
+ throw new Error('Unsupported argument type for \'times\': ' + typeof t);
+ }
}
- function removeListener(fn) {
- var idx = indexOf(listeners, fn);
- if (idx >= 0) listeners.splice(idx, 1);
+
+ var length = arguments.length;
+ if (length < 1 || length > 3) {
+ throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
+ } else if (length <= 2 && typeof times === 'function') {
+ callback = task;
+ task = times;
}
- function taskComplete() {
- remainingTasks--;
- arrayEach(listeners.slice(), function (fn) {
- fn();
- });
+ if (typeof times !== 'function') {
+ parseTimes(opts, times);
}
+ opts.callback = callback;
+ opts.task = task;
- addListener(function () {
- if (!remainingTasks) {
- callback(null, results);
+ function wrappedTask(wrappedCallback, wrappedResults) {
+ function retryAttempt(task, finalAttempt) {
+ return function (seriesCallback) {
+ task(function (err, result) {
+ seriesCallback(!err || finalAttempt, {
+ err: err,
+ result: result
+ });
+ }, wrappedResults);
+ };
}
- });
- arrayEach(keys$$, function (k) {
- var task = isArray(tasks[k]) ? tasks[k] : [tasks[k]];
- var taskCallback = rest(function (err, args) {
- runningTasks--;
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- forOwn(results, function (val, rkey) {
- safeResults[rkey] = val;
- });
- safeResults[k] = args;
- callback(err, safeResults);
- } else {
- results[k] = args;
- setImmediate$1(taskComplete);
- }
- });
- var requires = task.slice(0, task.length - 1);
- // prevent dead-locks
- var len = requires.length;
- var dep;
- while (len--) {
- if (!(dep = tasks[requires[len]])) {
- throw new Error('Has inexistant dependency');
- }
- if (isArray(dep) && indexOf(dep, k) >= 0) {
- throw new Error('Has cyclic dependencies');
- }
- }
- function ready() {
- return runningTasks < concurrency && !baseHas(results, k) && arrayEvery(requires, function (x) {
- return baseHas(results, x);
- });
- }
- if (ready()) {
- runningTasks++;
- task[task.length - 1](taskCallback, results);
- } else {
- addListener(listener);
+ function retryInterval(interval) {
+ return function (seriesCallback) {
+ setTimeout(function () {
+ seriesCallback(null);
+ }, interval);
+ };
}
- function listener() {
- if (ready()) {
- runningTasks++;
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
+
+ while (opts.times) {
+
+ var finalAttempt = !(opts.times -= 1);
+ attempts.push(retryAttempt(opts.task, finalAttempt));
+ if (!finalAttempt && opts.interval > 0) {
+ attempts.push(retryInterval(opts.interval));
}
}
- });
+
+ series(attempts, function (done, data) {
+ data = data[data.length - 1];
+ (wrappedCallback || opts.callback)(data.err, data.result);
+ });
+ }
+
+ // If a callback is passed, run this as a controll flow
+ return opts.callback ? wrappedTask() : wrappedTask;
}
- var apply = rest(function (fn, args) {
- return rest(function (callArgs) {
- return fn.apply(null, args.concat(callArgs));
- });
- });
+ var some = _createTester(eachOf, Boolean, identity);
- function applyEach$1(eachfn) {
- return rest(function (fns, args) {
- var go = rest(function (args) {
- var that = this;
- var callback = args.pop();
- return eachfn(fns, function (fn, _, cb) {
- fn.apply(that, args.concat([cb]));
- }, callback);
+ var someLimit = _createTester(eachOfLimit, Boolean, identity);
+
+ function sortBy(arr, iterator, cb) {
+ map(arr, function (x, cb) {
+ iterator(x, function (err, criteria) {
+ if (err) return cb(err);
+ cb(null, { value: x, criteria: criteria });
});
- if (args.length) {
- return go.apply(this, args);
- } else {
- return go;
- }
+ }, function (err, results) {
+ if (err) return cb(err);
+ cb(null, arrayMap(results.sort(comparator), baseProperty('value')));
});
+
+ function comparator(left, right) {
+ var a = left.criteria,
+ b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }
}
- var applyEachSeries = applyEach$1(eachOfSeries);
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil;
+ var nativeMax$2 = Math.max;
+ /**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the new array of numbers.
+ */
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax$2(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
- var applyEach = applyEach$1(eachOf);
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
+ }
+ return result;
+ }
+
+ function times (count, iterator, callback) {
+ map(baseRange(0, count, 1), iterator, callback);
+ }
+
+ function timeLimit(count, limit, iterator, cb) {
+ return mapLimit(baseRange(0, count, 1), limit, iterator, cb);
+ }
+
+ function timesSeries (count, iterator, callback) {
+ mapSeries(baseRange(0, count, 1), iterator, callback);
+ }
+
+ function transform(arr, memo, iterator, callback) {
+ if (arguments.length === 3) {
+ callback = iterator;
+ iterator = memo;
+ memo = isArray(arr) ? [] : {};
+ }
+
+ eachOf(arr, function (v, k, cb) {
+ iterator(memo, v, k, cb);
+ }, function (err) {
+ callback(err, memo);
+ });
+ }
+
+ function unmemoize(fn) {
+ return function () {
+ return (fn.unmemoized || fn).apply(null, arguments);
+ };
+ }
+
+ function until(test, iterator, cb) {
+ return whilst(function () {
+ return !test.apply(this, arguments);
+ }, iterator, cb);
+ }
+
+ function waterfall (tasks, cb) {
+ cb = once(cb || noop);
+ if (!isArray(tasks)) return cb(new Error('First argument to waterfall must be an array of functions'));
+ if (!tasks.length) return cb();
+
+ function wrapIterator(iterator) {
+ return rest(function (err, args) {
+ if (err) {
+ cb.apply(null, [err].concat(args));
+ } else {
+ var next = iterator.next();
+ if (next) {
+ args.push(wrapIterator(next));
+ } else {
+ args.push(cb);
+ }
+ ensureAsync(iterator).apply(null, args);
+ }
+ });
+ }
+ wrapIterator(iterator(tasks))();
+ }
var index = {
applyEach: applyEach,