diff options
Diffstat (limited to 'lib/auto')
-rw-r--r-- | lib/auto/.editorconfig | 10 | ||||
-rw-r--r-- | lib/auto/.gitignore | 8 | ||||
-rw-r--r-- | lib/auto/.jscsrc | 3 | ||||
-rw-r--r-- | lib/auto/.jshintrc | 29 | ||||
-rw-r--r-- | lib/auto/README.md | 13 | ||||
-rw-r--r-- | lib/auto/index.js | 109 | ||||
-rw-r--r-- | lib/auto/package.json | 29 |
7 files changed, 201 insertions, 0 deletions
diff --git a/lib/auto/.editorconfig b/lib/auto/.editorconfig new file mode 100644 index 0000000..7f502d4 --- /dev/null +++ b/lib/auto/.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/auto/.gitignore b/lib/auto/.gitignore new file mode 100644 index 0000000..8feeb01 --- /dev/null +++ b/lib/auto/.gitignore @@ -0,0 +1,8 @@ +node_modules +dist +perf/versions +nyc_output +coverage +*.log +.DS_Store +npm-debug.log diff --git a/lib/auto/.jscsrc b/lib/auto/.jscsrc new file mode 100644 index 0000000..b8cfa17 --- /dev/null +++ b/lib/auto/.jscsrc @@ -0,0 +1,3 @@ +{ + "validateIndentation": 4 +}
\ No newline at end of file diff --git a/lib/auto/.jshintrc b/lib/auto/.jshintrc new file mode 100644 index 0000000..76be34a --- /dev/null +++ b/lib/auto/.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/auto/README.md b/lib/auto/README.md new file mode 100644 index 0000000..2028ee5 --- /dev/null +++ b/lib/auto/README.md @@ -0,0 +1,13 @@ +# async.auto + +![Last version](https://img.shields.io/github/tag/async-js/async.auto.svg?style=flat-square) +[![Dependency status](http://img.shields.io/david/async-js/async.auto.svg?style=flat-square)](https://david-dm.org/async-js/async.auto) +[![Dev Dependencies Status](http://img.shields.io/david/dev/async-js/async.auto.svg?style=flat-square)](https://david-dm.org/async-js/async.auto#info=devDependencies) +[![NPM Status](http://img.shields.io/npm/dm/async.auto.svg?style=flat-square)](https://www.npmjs.org/package/async.auto) +[![Donate](https://img.shields.io/badge/donate-paypal-blue.svg?style=flat-square)](https://paypal.me/kikobeats) + +> [async#auto](https://github.com/async-js/async#async.auto) method as module. + +## License + +MIT © [async-js](https://github.com/async-js) diff --git a/lib/auto/index.js b/lib/auto/index.js new file mode 100644 index 0000000..ec564e9 --- /dev/null +++ b/lib/auto/index.js @@ -0,0 +1,109 @@ +'use strict'; + +var once = require('async.util.once'); +var noop = require('async.util.noop'); +var _keys = require('async.util.keys'); +var reduce = require('async.util.reduce'); +var indexOf = require('async.util.indexof'); +var isArray = require('async.util.isarray'); +var arrayEach = require('async.util.arrayeach'); +var restParam = require('async.util.restparam'); +var forEachOf = require('async.util.foreachof'); +var setImmediate = require('async.util.setimmediate'); + +module.exports = function auto(tasks, concurrency, cb) { + if (typeof arguments[1] === 'function') { + // concurrency is optional, shift the args. + cb = concurrency; + concurrency = null; + } + cb = once(cb || noop); + var keys = _keys(tasks); + var remainingTasks = keys.length; + if (!remainingTasks) { + return cb(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) { + cb(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; + cb(err, safeResults); + } else { + results[k] = args; + 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); + } + } + }); +}; diff --git a/lib/auto/package.json b/lib/auto/package.json new file mode 100644 index 0000000..6fc0097 --- /dev/null +++ b/lib/auto/package.json @@ -0,0 +1,29 @@ +{ + "name": "async.auto", + "description": "async automethod 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.arrayeach": "0.5.2", + "async.util.foreachof": "0.5.2", + "async.util.indexof": "0.5.2", + "async.util.isarray": "0.5.2", + "async.util.keys": "0.5.2", + "async.util.noop": "0.5.2", + "async.util.once": "0.5.2", + "async.util.reduce": "0.5.2", + "async.util.restparam": "0.5.2", + "async.util.setimmediate": "0.5.2" + }, + "keywords": [ + "async", + "async-modularized", + "auto" + ] +} |