diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..7f502d449
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+# editorconfig.org
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
diff --git a/.gitignore b/.gitignore
index 9134974d9..8feeb01fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ perf/versions
nyc_output
coverage
*.log
+.DS_Store
+npm-debug.log
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..4274f795c
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,4 @@
+lib
+scripts
+support/dependencies.json
+support/module_template.md
diff --git a/Makefile b/Makefile
index 87279f40c..4c90871fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,18 @@
export PATH := ./node_modules/.bin/:$(PATH):./bin/
PACKAGE = asyncjs
+REQUIRE_NAME = async
XYZ = node_modules/.bin/xyz --repo git@github.com:caolan/async.git
+BROWSERIFY = node_modules/.bin/browserify
BUILDDIR = dist
-SRC = lib/async.js
+SRC = lib/index.js
all: lint test clean build
build: $(wildcard lib/*.js)
mkdir -p $(BUILDDIR)
- cp $(SRC) $(BUILDDIR)/async.js
+ browserify $(SRC) -o $(BUILDDIR)/async.js -s $(REQUIRE_NAME)
uglifyjs $(BUILDDIR)/async.js -mc \
--source-map $(BUILDDIR)/async.min.map \
-o $(BUILDDIR)/async.min.js
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 000000000..2655edff1
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,88 @@
+'use strict';
+
+var gulp = require('gulp');
+var path = require('path');
+var fs = require('fs-extra');
+var pkg = require('./package.json');
+var jsonFuture = require('json-future');
+var template = require('lodash.template');
+
+var moduleDeps = JSON.parse(template(fs.readFileSync('./support/dependencies.json').toString())({
+ version: pkg.version}
+ ));
+
+var MODULES_PATH = './lib/';
+
+function getFolders(dir) {
+ return fs.readdirSync(dir)
+ .filter(function(file) {
+ return fs.statSync(path.join(dir, file)).isDirectory();
+ });
+}
+
+function generatePackage(name) {
+ function generateKeywords(name) {
+ var keywords = [
+ 'async',
+ 'async-modularized'
+ ];
+
+ keywords.push(name);
+ return keywords;
+ }
+
+ function generateDefaultFields(name) {
+ var ORIGINAL_FIELDS = [
+ 'author',
+ 'version',
+ 'repository',
+ 'license'
+ ];
+
+ var structure = {
+ name: 'async.' + name,
+ description: 'async ' + name + 'method as module.',
+ main: './index.js',
+ repository: "async-js/async." + name
+ };
+
+ ORIGINAL_FIELDS.forEach(function(field) {
+ structure[field] = pkg[field];
+ });
+
+ if (Object.keys(moduleDeps[name]).length > 0)
+ structure.dependencies = moduleDeps[name];
+
+ return structure;
+ }
+
+ var modulePackage = generateDefaultFields(name);
+ modulePackage.keywords = generateKeywords(name);
+ return modulePackage;
+}
+
+function generateReadme(name, dist) {
+ var filepath = path.resolve('support/module_template.md');
+ var tpl = fs.readFileSync(filepath).toString();
+ tpl = template(tpl)({name: name});
+ fs.writeFileSync(dist, tpl);
+}
+
+function copyMetaFiles(dist) {
+ var files = ['.editorconfig', '.jscsrc', '.jshintrc', '.gitignore'];
+
+ files.forEach(function(file) {
+ var metafile = path.resolve(file);
+ var distFile = path.resolve(dist, file);
+ fs.copySync(metafile, distFile);
+ });
+}
+
+gulp.task('package', function() {
+ return getFolders(MODULES_PATH).map(function(module) {
+ var dist = path.resolve(MODULES_PATH, module);
+ jsonFuture.save(path.resolve(dist, 'package.json'), generatePackage(module));
+ generateReadme(module, path.resolve(dist, 'README.md'));
+ copyMetaFiles(dist);
+ });
+});
diff --git a/lib/apply/.editorconfig b/lib/apply/.editorconfig
new file mode 100644
index 000000000..7f502d449
--- /dev/null
+++ b/lib/apply/.editorconfig
@@ -0,0 +1,10 @@
+# editorconfig.org
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
diff --git a/lib/apply/.gitignore b/lib/apply/.gitignore
new file mode 100644
index 000000000..8feeb01fe
--- /dev/null
+++ b/lib/apply/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+dist
+perf/versions
+nyc_output
+coverage
+*.log
+.DS_Store
+npm-debug.log
diff --git a/lib/apply/.jscsrc b/lib/apply/.jscsrc
new file mode 100644
index 000000000..b8cfa1731
--- /dev/null
+++ b/lib/apply/.jscsrc
@@ -0,0 +1,3 @@
+{
+ "validateIndentation": 4
+}
\ No newline at end of file
diff --git a/lib/apply/.jshintrc b/lib/apply/.jshintrc
new file mode 100644
index 000000000..76be34a84
--- /dev/null
+++ b/lib/apply/.jshintrc
@@ -0,0 +1,29 @@
+{
+ // Enforcing options
+ "eqeqeq": false,
+ "forin": true,
+ "indent": 4,
+ "noarg": true,
+ "undef": true,
+ "unused": true,
+ "trailing": true,
+ "evil": true,
+ "laxcomma": true,
+
+ // Relaxing options
+ "onevar": false,
+ "asi": false,
+ "eqnull": true,
+ "expr": false,
+ "loopfunc": true,
+ "sub": true,
+ "browser": true,
+ "node": true,
+ "globals": {
+ "self": true,
+ "define": true,
+ "describe": true,
+ "context": true,
+ "it": true
+ }
+}
diff --git a/lib/apply/README.md b/lib/apply/README.md
new file mode 100644
index 000000000..3caa57674
--- /dev/null
+++ b/lib/apply/README.md
@@ -0,0 +1,13 @@
+# async.apply
+
+![Last version](https://img.shields.io/github/tag/async-js/async.apply.svg?style=flat-square)
+[![Dependency status](http://img.shields.io/david/async-js/async.apply.svg?style=flat-square)](https://david-dm.org/async-js/async.apply)
+[![Dev Dependencies Status](http://img.shields.io/david/dev/async-js/async.apply.svg?style=flat-square)](https://david-dm.org/async-js/async.apply#info=devDependencies)
+[![NPM Status](http://img.shields.io/npm/dm/async.apply.svg?style=flat-square)](https://www.npmjs.org/package/async.apply)
+[![Donate](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square)](https://paypal.me/kikobeats)
+
+> [async#apply](https://github.com/async-js/async#async.apply) method as module.
+
+## License
+
+MIT © [async-js](https://github.com/async-js)
diff --git a/lib/apply/index.js b/lib/apply/index.js
new file mode 100644
index 000000000..e27ef80db
--- /dev/null
+++ b/lib/apply/index.js
@@ -0,0 +1,9 @@
+'use strict';
+
+var restParam = require('async.util.restparam');
+
+module.exports = restParam(function(fn, args) {
+ return restParam(function(callArgs) {
+ return fn.apply(null, args.concat(callArgs));
+ });
+});
diff --git a/lib/apply/package.json b/lib/apply/package.json
new file mode 100644
index 000000000..6d8e5dc61
--- /dev/null
+++ b/lib/apply/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "async.apply",
+ "description": "async applymethod as module.",
+ "main": "./index.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/caolan/async.git"
+ },
+ "author": "Caolan McMahon",
+ "version": "0.5.2",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.restparam": "0.5.2"
+ },
+ "keywords": [
+ "async",
+ "async-modularized",
+ "apply"
+ ]
+}
diff --git a/lib/applyeach/.editorconfig b/lib/applyeach/.editorconfig
new file mode 100644
index 000000000..7f502d449
--- /dev/null
+++ b/lib/applyeach/.editorconfig
@@ -0,0 +1,10 @@
+# editorconfig.org
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
diff --git a/lib/applyeach/.gitignore b/lib/applyeach/.gitignore
new file mode 100644
index 000000000..8feeb01fe
--- /dev/null
+++ b/lib/applyeach/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+dist
+perf/versions
+nyc_output
+coverage
+*.log
+.DS_Store
+npm-debug.log
diff --git a/lib/applyeach/.jscsrc b/lib/applyeach/.jscsrc
new file mode 100644
index 000000000..b8cfa1731
--- /dev/null
+++ b/lib/applyeach/.jscsrc
@@ -0,0 +1,3 @@
+{
+ "validateIndentation": 4
+}
\ No newline at end of file
diff --git a/lib/applyeach/.jshintrc b/lib/applyeach/.jshintrc
new file mode 100644
index 000000000..76be34a84
--- /dev/null
+++ b/lib/applyeach/.jshintrc
@@ -0,0 +1,29 @@
+{
+ // Enforcing options
+ "eqeqeq": false,
+ "forin": true,
+ "indent": 4,
+ "noarg": true,
+ "undef": true,
+ "unused": true,
+ "trailing": true,
+ "evil": true,
+ "laxcomma": true,
+
+ // Relaxing options
+ "onevar": false,
+ "asi": false,
+ "eqnull": true,
+ "expr": false,
+ "loopfunc": true,
+ "sub": true,
+ "browser": true,
+ "node": true,
+ "globals": {
+ "self": true,
+ "define": true,
+ "describe": true,
+ "context": true,
+ "it": true
+ }
+}
diff --git a/lib/applyeach/README.md b/lib/applyeach/README.md
new file mode 100644
index 000000000..a8e68c33f
--- /dev/null
+++ b/lib/applyeach/README.md
@@ -0,0 +1,13 @@
+# async.applyeach
+
+![Last version](https://img.shields.io/github/tag/async-js/async.applyeach.svg?style=flat-square)
+[![Dependency status](http://img.shields.io/david/async-js/async.applyeach.svg?style=flat-square)](https://david-dm.org/async-js/async.applyeach)
+[![Dev Dependencies Status](http://img.shields.io/david/dev/async-js/async.applyeach.svg?style=flat-square)](https://david-dm.org/async-js/async.applyeach#info=devDependencies)
+[![NPM Status](http://img.shields.io/npm/dm/async.applyeach.svg?style=flat-square)](https://www.npmjs.org/package/async.applyeach)
+[![Donate](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square)](https://paypal.me/kikobeats)
+
+> [async#applyeach](https://github.com/async-js/async#async.applyeach) method as module.
+
+## License
+
+MIT © [async-js](https://github.com/async-js)
diff --git a/lib/applyeach/index.js b/lib/applyeach/index.js
new file mode 100644
index 000000000..9519afdb4
--- /dev/null
+++ b/lib/applyeach/index.js
@@ -0,0 +1,6 @@
+'use strict';
+
+var eachOf = require('async.eachof');
+var applyEach = require('async.util.applyeach');
+
+module.exports = applyEach(eachOf);
diff --git a/lib/applyeach/package.json b/lib/applyeach/package.json
new file mode 100644
index 000000000..996beca61
--- /dev/null
+++ b/lib/applyeach/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "async.applyeach",
+ "description": "async applyeachmethod as module.",
+ "main": "./index.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/caolan/async.git"
+ },
+ "author": "Caolan McMahon",
+ "version": "0.5.2",
+ "license": "MIT",
+ "dependencies": {
+ "async.eachof": "0.5.2",
+ "async.util.applyeach": "0.5.2"
+ },
+ "keywords": [
+ "async",
+ "async-modularized",
+ "applyeach"
+ ]
+}
diff --git a/lib/applyeachseries/.editorconfig b/lib/applyeachseries/.editorconfig
new file mode 100644
index 000000000..7f502d449
--- /dev/null
+++ b/lib/applyeachseries/.editorconfig
@@ -0,0 +1,10 @@
+# editorconfig.org
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
diff --git a/lib/applyeachseries/.gitignore b/lib/applyeachseries/.gitignore
new file mode 100644
index 000000000..8feeb01fe
--- /dev/null
+++ b/lib/applyeachseries/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+dist
+perf/versions
+nyc_output
+coverage
+*.log
+.DS_Store
+npm-debug.log
diff --git a/lib/applyeachseries/.jscsrc b/lib/applyeachseries/.jscsrc
new file mode 100644
index 000000000..b8cfa1731
--- /dev/null
+++ b/lib/applyeachseries/.jscsrc
@@ -0,0 +1,3 @@
+{
+ "validateIndentation": 4
+}
\ No newline at end of file
diff --git a/lib/applyeachseries/.jshintrc b/lib/applyeachseries/.jshintrc
new file mode 100644
index 000000000..76be34a84
--- /dev/null
+++ b/lib/applyeachseries/.jshintrc
@@ -0,0 +1,29 @@
+{
+ // Enforcing options
+ "eqeqeq": false,
+ "forin": true,
+ "indent": 4,
+ "noarg": true,
+ "undef": true,
+ "unused": true,
+ "trailing": true,
+ "evil": true,
+ "laxcomma": true,
+
+ // Relaxing options
+ "onevar": false,
+ "asi": false,
+ "eqnull": true,
+ "expr": false,
+ "loopfunc": true,
+ "sub": true,
+ "browser": true,
+ "node": true,
+ "globals": {
+ "self": true,
+ "define": true,
+ "describe": true,
+ "context": true,
+ "it": true
+ }
+}
diff --git a/lib/applyeachseries/README.md b/lib/applyeachseries/README.md
new file mode 100644
index 000000000..bedaee7f0
--- /dev/null
+++ b/lib/applyeachseries/README.md
@@ -0,0 +1,13 @@
+# async.applyeachseries
+
+![Last version](https://img.shields.io/github/tag/async-js/async.applyeachseries.svg?style=flat-square)
+[![Dependency status](http://img.shields.io/david/async-js/async.applyeachseries.svg?style=flat-square)](https://david-dm.org/async-js/async.applyeachseries)
+[![Dev Dependencies Status](http://img.shields.io/david/dev/async-js/async.applyeachseries.svg?style=flat-square)](https://david-dm.org/async-js/async.applyeachseries#info=devDependencies)
+[![NPM Status](http://img.shields.io/npm/dm/async.applyeachseries.svg?style=flat-square)](https://www.npmjs.org/package/async.applyeachseries)
+[![Donate](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square)](https://paypal.me/kikobeats)
+
+> [async#applyeachseries](https://github.com/async-js/async#async.applyeachseries) method as module.
+
+## License
+
+MIT © [async-js](https://github.com/async-js)
diff --git a/lib/applyeachseries/index.js b/lib/applyeachseries/index.js
new file mode 100644
index 000000000..8d4d3cfad
--- /dev/null
+++ b/lib/applyeachseries/index.js
@@ -0,0 +1,6 @@
+'use strict';
+
+var eachOfSeries = require('async.eachofseries');
+var applyEach = require('async.util.applyeach');
+
+module.exports = applyEach(eachOfSeries);
diff --git a/lib/applyeachseries/package.json b/lib/applyeachseries/package.json
new file mode 100644
index 000000000..70ee71a0d
--- /dev/null
+++ b/lib/applyeachseries/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "async.applyeachseries",
+ "description": "async applyeachseriesmethod as module.",
+ "main": "./index.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/caolan/async.git"
+ },
+ "author": "Caolan McMahon",
+ "version": "0.5.2",
+ "license": "MIT",
+ "dependencies": {
+ "async.eachofseries": "0.5.2",
+ "async.util.applyeach": "0.5.2"
+ },
+ "keywords": [
+ "async",
+ "async-modularized",
+ "applyeachseries"
+ ]
+}
diff --git a/lib/async.js b/lib/async.js
deleted file mode 100644
index 3748ac070..000000000
--- a/lib/async.js
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*!
- * async
- * https://github.com/caolan/async
- *
- * Copyright 2010-2014 Caolan McMahon
- * Released under the MIT license
- */
-(function () {
-
- var async = {};
- function noop() {}
- function identity(v) {
- return v;
- }
- function toBool(v) {
- return !!v;
- }
- function notId(v) {
- return !v;
- }
-
- // global on the server, window in the browser
- var previous_async;
-
- // Establish the root object, `window` (`self`) in the browser, `global`
- // on the server, or `this` in some virtual machines. We use `self`
- // instead of `window` for `WebWorker` support.
- var root = typeof self === 'object' && self.self === self && self ||
- typeof global === 'object' && global.global === global && global ||
- this;
-
- if (root != null) {
- previous_async = root.async;
- }
-
- async.noConflict = function () {
- root.async = previous_async;
- return async;
- };
-
- function only_once(fn) {
- return function() {
- if (fn === null) throw new Error("Callback was already called.");
- fn.apply(this, arguments);
- fn = null;
- };
- }
-
- function _once(fn) {
- return function() {
- if (fn === null) return;
- fn.apply(this, arguments);
- fn = null;
- };
- }
-
- //// cross-browser compatiblity functions ////
-
- var _toString = Object.prototype.toString;
-
- var _isArray = Array.isArray || function (obj) {
- return _toString.call(obj) === '[object Array]';
- };
-
- // Ported from underscore.js isObject
- var _isObject = function(obj) {
- var type = typeof obj;
- return type === 'function' || type === 'object' && !!obj;
- };
-
- function _isArrayLike(arr) {
- return _isArray(arr) || (
- // has a positive integer length property
- typeof arr.length === "number" &&
- arr.length >= 0 &&
- arr.length % 1 === 0
- );
- }
-
- function _arrayEach(arr, iterator) {
- var index = -1,
- length = arr.length;
-
- while (++index < length) {
- iterator(arr[index], index, arr);
- }
- }
-
- function _map(arr, iterator) {
- var index = -1,
- length = arr.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iterator(arr[index], index, arr);
- }
- return result;
- }
-
- function _range(count) {
- return _map(Array(count), function (v, i) { return i; });
- }
-
- function _reduce(arr, iterator, memo) {
- _arrayEach(arr, function (x, i, a) {
- memo = iterator(memo, x, i, a);
- });
- return memo;
- }
-
- function _forEachOf(object, iterator) {
- _arrayEach(_keys(object), function (key) {
- iterator(object[key], key);
- });
- }
-
- function _indexOf(arr, item) {
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === item) return i;
- }
- return -1;
- }
-
- var _keys = Object.keys || function (obj) {
- var keys = [];
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- return keys;
- };
-
- function _keyIterator(coll) {
- var i = -1;
- var len;
- var keys;
- if (_isArrayLike(coll)) {
- len = coll.length;
- return function next() {
- i++;
- return i < len ? i : null;
- };
- } else {
- keys = _keys(coll);
- len = keys.length;
- return function next() {
- i++;
- return i < len ? keys[i] : null;
- };
- }
- }
-
- // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
- // This accumulates the arguments passed into an array, after a given index.
- // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
- function _restParam(func, startIndex) {
- startIndex = startIndex == null ? func.length - 1 : +startIndex;
- return function() {
- var length = Math.max(arguments.length - startIndex, 0);
- var rest = Array(length);
- for (var index = 0; index < length; index++) {
- rest[index] = arguments[index + startIndex];
- }
- switch (startIndex) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, arguments[0], rest);
- }
- // Currently unused but handle cases outside of the switch statement:
- // var args = Array(startIndex + 1);
- // for (index = 0; index < startIndex; index++) {
- // args[index] = arguments[index];
- // }
- // args[startIndex] = rest;
- // return func.apply(this, args);
- };
- }
-
- function _withoutIndex(iterator) {
- return function (value, index, callback) {
- return iterator(value, callback);
- };
- }
-
- //// exported async module functions ////
-
- //// nextTick implementation with browser-compatible fallback ////
-
- // capture the global reference to guard against fakeTimer mocks
- var _setImmediate = typeof setImmediate === 'function' && setImmediate;
-
- var _delay = _setImmediate ? function(fn) {
- // not a direct alias for IE10 compatibility
- _setImmediate(fn);
- } : function(fn) {
- setTimeout(fn, 0);
- };
-
- if (typeof process === 'object' && typeof process.nextTick === 'function') {
- async.nextTick = process.nextTick;
- } else {
- async.nextTick = _delay;
- }
- async.setImmediate = _setImmediate ? _delay : async.nextTick;
-
-
- async.forEach =
- async.each = function (arr, iterator, callback) {
- return async.eachOf(arr, _withoutIndex(iterator), callback);
- };
-
- async.forEachSeries =
- async.eachSeries = function (arr, iterator, callback) {
- return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
- };
-
-
- async.forEachLimit =
- async.eachLimit = function (arr, limit, iterator, callback) {
- return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
- };
-
- async.forEachOf =
- async.eachOf = function (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, only_once(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);
- }
- }
- };
-
- async.forEachOfSeries =
- async.eachOfSeries = function (obj, iterator, callback) {
- callback = _once(callback || noop);
- obj = obj || [];
- var nextKey = _keyIterator(obj);
- var key = nextKey();
- function iterate() {
- var sync = true;
- if (key === null) {
- return callback(null);
- }
- iterator(obj[key], key, only_once(function (err) {
- if (err) {
- callback(err);
- }
- else {
- key = nextKey();
- if (key === null) {
- return callback(null);
- } else {
- if (sync) {
- async.setImmediate(iterate);
- } else {
- iterate();
- }
- }
- }
- }));
- sync = false;
- }
- iterate();
- };
-
-
-
- async.forEachOfLimit =
- async.eachOfLimit = function (obj, limit, iterator, callback) {
- _eachOfLimit(limit)(obj, iterator, callback);
- };
-
- 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, only_once(function (err) {
- running -= 1;
- if (err) {
- callback(err);
- errored = true;
- }
- else {
- replenish();
- }
- }));
- }
- })();
- };
- }
-
-
- function doParallel(fn) {
- return function (obj, iterator, callback) {
- return fn(async.eachOf, obj, iterator, callback);
- };
- }
- function doParallelLimit(fn) {
- return function (obj, limit, iterator, callback) {
- return fn(_eachOfLimit(limit), obj, iterator, callback);
- };
- }
- function doSeries(fn) {
- return function (obj, iterator, callback) {
- return fn(async.eachOfSeries, obj, iterator, callback);
- };
- }
-
- 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);
- });
- }
-
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
- async.mapLimit = doParallelLimit(_asyncMap);
-
- // reduce only has a series version, as doing reduce in parallel won't
- // work in many situations.
- async.inject =
- async.foldl =
- async.reduce = function (arr, memo, iterator, callback) {
- async.eachOfSeries(arr, function (x, i, callback) {
- iterator(memo, x, function (err, v) {
- memo = v;
- callback(err);
- });
- }, function (err) {
- callback(err, memo);
- });
- };
-
- async.foldr =
- async.reduceRight = function (arr, memo, iterator, callback) {
- var reversed = _map(arr, identity).reverse();
- async.reduce(reversed, memo, iterator, callback);
- };
-
- async.transform = function (arr, memo, iterator, callback) {
- if (arguments.length === 3) {
- callback = iterator;
- iterator = memo;
- memo = _isArray(arr) ? [] : {};
- }
-
- async.eachOf(arr, function(v, k, cb) {
- iterator(memo, v, k, cb);
- }, function(err) {
- callback(err, memo);
- });
- };
-
- 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(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- }
-
- async.select =
- async.filter = doParallel(_filter);
-
- async.selectLimit =
- async.filterLimit = doParallelLimit(_filter);
-
- async.selectSeries =
- async.filterSeries = doSeries(_filter);
-
- function _reject(eachfn, arr, iterator, callback) {
- _filter(eachfn, arr, function(value, cb) {
- iterator(value, function(v) {
- cb(!v);
- });
- }, callback);
- }
- async.reject = doParallel(_reject);
- async.rejectLimit = doParallelLimit(_reject);
- async.rejectSeries = doSeries(_reject);
-
- 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);
- }
- };
- }
-
- async.any =
- async.some = _createTester(async.eachOf, toBool, identity);
-
- async.someLimit = _createTester(async.eachOfLimit, toBool, identity);
-
- async.all =
- async.every = _createTester(async.eachOf, notId, notId);
-
- async.everyLimit = _createTester(async.eachOfLimit, notId, notId);
-
- function _findGetResult(v, x) {
- return x;
- }
- async.detect = _createTester(async.eachOf, identity, _findGetResult);
- async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
- async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);
-
- async.sortBy = function (arr, iterator, callback) {
- async.map(arr, function (x, callback) {
- iterator(x, function (err, criteria) {
- if (err) {
- callback(err);
- }
- else {
- callback(null, {value: x, criteria: criteria});
- }
- });
- }, function (err, results) {
- if (err) {
- return callback(err);
- }
- else {
- callback(null, _map(results.sort(comparator), function (x) {
- return x.value;
- }));
- }
-
- });
-
- function comparator(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }
- };
-
- async.auto = function (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;
- }
-
- var results = {};
- var runningTasks = 0;
-
- 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(0), function (fn) {
- fn();
- });
- }
-
- addListener(function () {
- if (!remainingTasks) {
- callback(null, results);
- }
- });
-
- _arrayEach(keys, function (k) {
- var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
- var taskCallback = _restParam(function(err, args) {
- runningTasks--;
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- _forEachOf(results, function(val, rkey) {
- safeResults[rkey] = val;
- });
- safeResults[k] = args;
- callback(err, safeResults);
- }
- else {
- results[k] = args;
- async.setImmediate(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 && _reduce(requires, function (a, x) {
- return (a && results.hasOwnProperty(x));
- }, true) && !results.hasOwnProperty(k);
- }
- if (ready()) {
- runningTasks++;
- task[task.length - 1](taskCallback, results);
- }
- else {
- addListener(listener);
- }
- function listener() {
- if (ready()) {
- runningTasks++;
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- }
- });
- };
-
-
-
- async.retry = function(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 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 retryInterval(interval){
- return function(seriesCallback){
- setTimeout(function(){
- seriesCallback(null);
- }, interval);
- };
- }
-
- while (opts.times) {
-
- var finalAttempt = !(opts.times-=1);
- attempts.push(retryAttempt(opts.task, finalAttempt));
- if(!finalAttempt && opts.interval > 0){
- attempts.push(retryInterval(opts.interval));
- }
- }
-
- async.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;
- };
-
- async.waterfall = function (tasks, callback) {
- callback = _once(callback || noop);
- if (!_isArray(tasks)) {
- var err = new Error('First argument to waterfall must be an array of functions');
- return callback(err);
- }
- if (!tasks.length) {
- return callback();
- }
- function wrapIterator(iterator) {
- return _restParam(function (err, args) {
- if (err) {
- callback.apply(null, [err].concat(args));
- }
- else {
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- }
- else {
- args.push(callback);
- }
- ensureAsync(iterator).apply(null, args);
- }
- });
- }
- wrapIterator(async.iterator(tasks))();
- };
-
- function _parallel(eachfn, tasks, callback) {
- callback = callback || noop;
- var results = _isArrayLike(tasks) ? [] : {};
-
- eachfn(tasks, function (task, key, callback) {
- task(_restParam(function (err, args) {
- if (args.length <= 1) {
- args = args[0];
- }
- results[key] = args;
- callback(err);
- }));
- }, function (err) {
- callback(err, results);
- });
- }
-
- async.parallel = function (tasks, callback) {
- _parallel(async.eachOf, tasks, callback);
- };
-
- async.parallelLimit = function(tasks, limit, callback) {
- _parallel(_eachOfLimit(limit), tasks, callback);
- };
-
- async.series = function(tasks, callback) {
- _parallel(async.eachOfSeries, tasks, callback);
- };
-
- async.iterator = function (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);
- };
-
- async.apply = _restParam(function (fn, args) {
- return _restParam(function (callArgs) {
- return fn.apply(
- null, args.concat(callArgs)
- );
- });
- });
-
- function _concat(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);
- });
- }
- async.concat = doParallel(_concat);
- async.concatSeries = doSeries(_concat);
-
- async.whilst = function (test, iterator, callback) {
- callback = callback || noop;
- if (test()) {
- var next = _restParam(function(err, args) {
- if (err) {
- callback(err);
- } else if (test.apply(this, args)) {
- iterator(next);
- } else {
- callback.apply(null, [null].concat(args));
- }
- });
- iterator(next);
- } else {
- callback(null);
- }
- };
-
- async.doWhilst = function (iterator, test, callback) {
- var calls = 0;
- return async.whilst(function() {
- return ++calls <= 1 || test.apply(this, arguments);
- }, iterator, callback);
- };
-
- async.until = function (test, iterator, callback) {
- return async.whilst(function() {
- return !test.apply(this, arguments);
- }, iterator, callback);
- };
-
- async.doUntil = function (iterator, test, callback) {
- return async.doWhilst(iterator, function() {
- return !test.apply(this, arguments);
- }, callback);
- };
-
- async.during = function (test, iterator, callback) {
- callback = callback || noop;
-
- var next = _restParam(function(err, args) {
- if (err) {
- callback(err);
- } else {
- args.push(check);
- test.apply(this, args);
- }
- });
-
- var check = function(err, truth) {
- if (err) {
- callback(err);
- } else if (truth) {
- iterator(next);
- } else {
- callback(null);
- }
- };
-
- test(check);
- };
-
- async.doDuring = function (iterator, test, callback) {
- var calls = 0;
- async.during(function(next) {
- if (calls++ < 1) {
- next(null, true);
- } else {
- test.apply(this, arguments);
- }
- }, iterator, callback);
- };
-
- function _queue(worker, concurrency, payload) {
- if (concurrency == null) {
- concurrency = 1;
- }
- else if(concurrency === 0) {
- throw new Error('Concurrency must not be zero');
- }
- function _insert(q, data, pos, 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 && q.idle()) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- q.drain();
- });
- }
- _arrayEach(data, function(task) {
- var item = {
- data: task,
- callback: callback || noop
- };
-
- if (pos) {
- q.tasks.unshift(item);
- } else {
- q.tasks.push(item);
- }
-
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- });
- async.setImmediate(q.process);
- }
- function _next(q, tasks) {
- return function(){
- workers -= 1;
-
- var removed = false;
- var args = arguments;
- _arrayEach(tasks, function (task) {
- _arrayEach(workersList, function (worker, index) {
- if (worker === task && !removed) {
- workersList.splice(index, 1);
- removed = true;
- }
- });
-
- task.callback.apply(task, args);
- });
- if (q.tasks.length + workers === 0) {
- q.drain();
- }
- q.process();
- };
- }
-
- var workers = 0;
- var workersList = [];
- var q = {
- tasks: [],
- concurrency: concurrency,
- payload: payload,
- saturated: noop,
- empty: noop,
- drain: noop,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(q, data, false, callback);
- },
- kill: function () {
- q.drain = noop;
- q.tasks = [];
- },
- unshift: function (data, callback) {
- _insert(q, data, true, callback);
- },
- process: function () {
- while(!q.paused && workers < q.concurrency && q.tasks.length){
-
- var tasks = q.payload ?
- q.tasks.splice(0, q.payload) :
- q.tasks.splice(0, q.tasks.length);
-
- var data = _map(tasks, function (task) {
- return task.data;
- });
-
- if (q.tasks.length === 0) {
- q.empty();
- }
- workers += 1;
- workersList.push(tasks[0]);
- var cb = only_once(_next(q, tasks));
- worker(data, cb);
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- },
- workersList: function () {
- return workersList;
- },
- idle: function() {
- return q.tasks.length + workers === 0;
- },
- pause: function () {
- q.paused = true;
- },
- resume: function () {
- if (q.paused === false) { return; }
- q.paused = false;
- var resumeCount = Math.min(q.concurrency, q.tasks.length);
- // Need to call q.process once per concurrent
- // worker to preserve full concurrency after pause
- for (var w = 1; w <= resumeCount; w++) {
- async.setImmediate(q.process);
- }
- }
- };
- return q;
- }
-
- async.queue = function (worker, concurrency) {
- var q = _queue(function (items, cb) {
- worker(items[0], cb);
- }, concurrency, 1);
-
- return q;
- };
-
- async.priorityQueue = function (worker, concurrency) {
-
- function _compareTasks(a, b){
- return a.priority - b.priority;
- }
-
- 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 _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 async.setImmediate(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();
- }
- async.setImmediate(q.process);
- });
- }
-
- // Start with a normal queue
- var q = async.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;
- };
-
- async.cargo = function (worker, payload) {
- return _queue(worker, 1, payload);
- };
-
- function _console_fn(name) {
- return _restParam(function (fn, args) {
- fn.apply(null, args.concat([_restParam(function (err, args) {
- if (typeof console === 'object') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- }
- else if (console[name]) {
- _arrayEach(args, function (x) {
- console[name](x);
- });
- }
- }
- })]));
- });
- }
- async.log = _console_fn('log');
- async.dir = _console_fn('dir');
- /*async.info = _console_fn('info');
- async.warn = _console_fn('warn');
- async.error = _console_fn('error');*/
-
- async.memoize = function (fn, hasher) {
- var memo = {};
- var queues = {};
- hasher = hasher || identity;
- var memoized = _restParam(function memoized(args) {
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (key in memo) {
- async.setImmediate(function () {
- callback.apply(null, memo[key]);
- });
- }
- else if (key in queues) {
- queues[key].push(callback);
- }
- else {
- queues[key] = [callback];
- fn.apply(null, args.concat([_restParam(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;
- };
-
- async.unmemoize = function (fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- };
-
- function _times(mapper) {
- return function (count, iterator, callback) {
- mapper(_range(count), iterator, callback);
- };
- }
-
- async.times = _times(async.map);
- async.timesSeries = _times(async.mapSeries);
- async.timesLimit = function (count, limit, iterator, callback) {
- return async.mapLimit(_range(count), limit, iterator, callback);
- };
-
- async.seq = function (/* functions... */) {
- var fns = arguments;
- return _restParam(function (args) {
- var that = this;
-
- var callback = args[args.length - 1];
- if (typeof callback == 'function') {
- args.pop();
- } else {
- callback = noop;
- }
-
- async.reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
- cb(err, nextargs);
- })]));
- },
- function (err, results) {
- callback.apply(that, [err].concat(results));
- });
- });
- };
-
- async.compose = function (/* functions... */) {
- return async.seq.apply(null, Array.prototype.reverse.call(arguments));
- };
-
-
- function _applyEach(eachfn) {
- return _restParam(function(fns, args) {
- var go = _restParam(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 {
- return go;
- }
- });
- }
-
- async.applyEach = _applyEach(async.eachOf);
- async.applyEachSeries = _applyEach(async.eachOfSeries);
-
-
- async.forever = function (fn, callback) {
- var done = only_once(callback || noop);
- var task = ensureAsync(fn);
- function next(err) {
- if (err) {
- return done(err);
- }
- task(next);
- }
- next();
- };
-
- function ensureAsync(fn) {
- return _restParam(function (args) {
- var callback = args.pop();
- args.push(function () {
- var innerArgs = arguments;
- if (sync) {
- async.setImmediate(function () {
- callback.apply(null, innerArgs);
- });
- } else {
- callback.apply(null, innerArgs);
- }
- });
- var sync = true;
- fn.apply(this, args);
- sync = false;
- });
- }
-
- async.ensureAsync = ensureAsync;
-
- async.constant = _restParam(function(values) {
- var args = [null].concat(values);
- return function (callback) {
- return callback.apply(this, args);
- };
- });
-
- async.wrapSync =
- async.asyncify = function asyncify(func) {
- return _restParam(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));
- });
- } else {
- callback(null, result);
- }
- });
- };
-
- // Node.js
- if (typeof module === 'object' && module.exports) {
- module.exports = async;
- }
- // AMD / RequireJS
- else if (typeof define === 'function' && define.amd) {
- define([], function () {
- return async;
- });
- }
- // included directly via
-
+