taskgroup
Advanced tools
Comparing version 3.4.0 to 4.0.0
// Generated by CoffeeScript 1.7.1 | ||
(function() { | ||
var EventEmitter, Task, TaskGroup, ambi, domain, events, extendOnClass, setImmediate, _ref, | ||
var EventEmitter, Interface, Task, TaskGroup, ambi, domain, events, extendOnClass, queue, setImmediate, util, _ref, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -10,2 +10,4 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | ||
queue = process.nextTick; | ||
ambi = require('ambi'); | ||
@@ -21,22 +23,133 @@ | ||
EventEmitter = events.EventEmitter; | ||
util = require('util'); | ||
EventEmitter = require('events').EventEmitter; | ||
extendOnClass = require('extendonclass').extendOnClass; | ||
Interface = (function(_super) { | ||
__extends(Interface, _super); | ||
function Interface() { | ||
var me; | ||
Interface.__super__.constructor.apply(this, arguments); | ||
me = this; | ||
this.on('error', function() { | ||
var args, err; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
err = args[0]; | ||
if (me.listeners('done').length !== 0) { | ||
return this.emit.apply(this, ['done'].concat(__slice.call(args))); | ||
} else if (err && me.listeners('error').length === 1) { | ||
console.error(err.stack || err); | ||
throw err; | ||
} | ||
}); | ||
this.on('completed', function() { | ||
var args, err; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
err = args[0]; | ||
if (me.listeners('done').length !== 0) { | ||
return this.emit.apply(this, ['done'].concat(__slice.call(args))); | ||
} else if (err && me.listeners('completed').length === 1) { | ||
console.error(err.stack || err); | ||
throw err; | ||
} | ||
}); | ||
this; | ||
} | ||
Interface.prototype.complete = function() { | ||
var err; | ||
err = (function() { | ||
throw Error('interface should provide this'); | ||
})(); | ||
this.emit('error', err); | ||
return this; | ||
}; | ||
Interface.prototype.whenDone = function(listener) { | ||
if (typeof listener === 'function') { | ||
this.on('done', listener.bind(this)); | ||
} | ||
return this; | ||
}; | ||
Interface.prototype.onceDone = function(listener) { | ||
if (typeof listener === 'function') { | ||
this.once('done', listener); | ||
} | ||
return this; | ||
}; | ||
Interface.prototype.done = function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return this.onceDone.apply(this, args); | ||
}; | ||
Interface.prototype.getNames = function(opts) { | ||
var name, names, _ref1; | ||
if (opts == null) { | ||
opts = {}; | ||
} | ||
if (opts.format == null) { | ||
opts.format = 'string'; | ||
} | ||
if (opts.separator == null) { | ||
opts.separator = ' ➞ '; | ||
} | ||
names = ((_ref1 = this.config.parent) != null ? _ref1.getNames({ | ||
format: 'array' | ||
}) : void 0) || []; | ||
if (name = this.getName()) { | ||
names.push(name); | ||
} | ||
if (opts.format !== 'array') { | ||
names = names.join(opts.separator); | ||
} | ||
return names; | ||
}; | ||
Interface.prototype.getName = function() { | ||
var _base; | ||
return (_base = this.config).name != null ? _base.name : _base.name = "" + this.type + " " + (Math.random()); | ||
}; | ||
Interface.prototype.getConfig = function() { | ||
return this.config; | ||
}; | ||
return Interface; | ||
})(EventEmitter); | ||
Task = (function(_super) { | ||
__extends(Task, _super); | ||
Task.extend = extendOnClass; | ||
Task.prototype.type = 'task'; | ||
Task.create = function(a, b, c, d, e, f, g) { | ||
return new Task(a, b, d, e, f, g); | ||
Task.isTask = function(item) { | ||
return (item != null ? item.type : void 0) === 'task' || item instanceof Task; | ||
}; | ||
Task.prototype.type = 'task'; | ||
Task.subclass = extendOnClass; | ||
Task.create = function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return (function(func, args, ctor) { | ||
ctor.prototype = func.prototype; | ||
var child = new ctor, result = func.apply(child, args); | ||
return Object(result) === result ? result : child; | ||
})(this, args, function(){}); | ||
}; | ||
Task.prototype.err = null; | ||
Task.prototype.result = null; | ||
Task.prototype.running = false; | ||
Task.prototype.status = null; | ||
Task.prototype.completed = false; | ||
Task.prototype.events = null; | ||
@@ -47,11 +160,2 @@ Task.prototype.taskDomain = null; | ||
/* | ||
name: null | ||
method: null | ||
args: null | ||
parent: null | ||
context: null | ||
*/ | ||
function Task() { | ||
@@ -64,8 +168,12 @@ var args, _base, _base1; | ||
} | ||
if ((_base = this.config).name == null) { | ||
_base.name = "Task " + (Math.random()); | ||
if ((_base = this.config).run == null) { | ||
_base.run = false; | ||
} | ||
if ((_base1 = this.config).run == null) { | ||
_base1.run = false; | ||
if ((_base1 = this.config).onError == null) { | ||
_base1.onError = 'exit'; | ||
} | ||
if (this.events == null) { | ||
this.events = []; | ||
} | ||
this.events.push('error', 'started', 'running', 'failed', 'passed', 'completed', 'destroyed'); | ||
this.setConfig(args); | ||
@@ -110,3 +218,3 @@ this; | ||
if (value) { | ||
this.once('complete', value.bind(this)); | ||
this.done(value); | ||
} | ||
@@ -121,33 +229,69 @@ break; | ||
Task.prototype.getConfig = function() { | ||
return this.config; | ||
Task.prototype.hasStarted = function() { | ||
return this.status !== null; | ||
}; | ||
Task.prototype.reset = function() { | ||
this.completed = false; | ||
this.running = false; | ||
this.result = null; | ||
return this; | ||
Task.prototype.hasExited = function() { | ||
var _ref1; | ||
return (_ref1 = this.status) === 'completed' || _ref1 === 'destroyed'; | ||
}; | ||
Task.prototype.uncaughtExceptionCallback = function() { | ||
Task.prototype.isDestroyed = function() { | ||
return this.status === 'destroyed'; | ||
}; | ||
Task.prototype.isComplete = function() { | ||
var _ref1; | ||
return (_ref1 = this.status) === 'failed' || _ref1 === 'passed' || _ref1 === 'destroyed'; | ||
}; | ||
Task.prototype.exit = function() { | ||
var args, err; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
err = args[0]; | ||
if (!this.completed) { | ||
this.complete(args); | ||
if (args[0] != null) { | ||
if (this.err == null) { | ||
this.err = args[0]; | ||
} | ||
} | ||
this.emit('error', err); | ||
if (this.isComplete() === false) { | ||
if (args.length !== 0) { | ||
this.result = args; | ||
} | ||
if (this.err != null) { | ||
this.status = 'failed'; | ||
} else { | ||
this.status = 'passed'; | ||
} | ||
this.emit(this.status, this.err); | ||
this.complete(); | ||
} else if (this.config.onError !== 'ignore') { | ||
err = new Error("The task [" + (this.getNames()) + "] just completed, but it had already completed earlier, this is unexpected. State information is:\n" + (util.inspect({ | ||
error: this.err, | ||
previousResult: this.result, | ||
currentArguments: args | ||
}))); | ||
this.emit('error', err); | ||
} | ||
return this; | ||
}; | ||
Task.prototype.completionCallback = function() { | ||
var args, err; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
if (!this.completed) { | ||
this.complete(args); | ||
this.emit.apply(this, ['complete'].concat(__slice.call(this.result))); | ||
Task.prototype.complete = function() { | ||
var complete; | ||
complete = this.isComplete(); | ||
if (complete) { | ||
this.emit.apply(this, ['completed'].concat(__slice.call(this.result || []))); | ||
this.err = null; | ||
} | ||
return complete; | ||
}; | ||
Task.prototype.whenDone = function(listener) { | ||
if (this.isComplete()) { | ||
queue((function(_this) { | ||
return function() { | ||
return listener.apply(_this, _this.result || []); | ||
}; | ||
})(this)); | ||
} else { | ||
err = new Error("A task's completion callback has fired when the task was already in a completed state, this is unexpected"); | ||
this.emit('error', err); | ||
Task.__super__.whenDone.call(this, listener); | ||
} | ||
@@ -157,34 +301,70 @@ return this; | ||
Task.prototype.destroy = function() { | ||
this.removeAllListeners(); | ||
Task.prototype.onceDone = function(listener) { | ||
if (this.isComplete()) { | ||
queue((function(_this) { | ||
return function() { | ||
return listener.apply(_this, _this.result || []); | ||
}; | ||
})(this)); | ||
} else { | ||
Task.__super__.onceDone.call(this, listener); | ||
} | ||
return this; | ||
}; | ||
Task.prototype.complete = function(result) { | ||
this.completed = true; | ||
this.running = false; | ||
this.result = result; | ||
Task.prototype.resetResults = function() { | ||
this.result = []; | ||
return this; | ||
}; | ||
Task.prototype.destroy = function() { | ||
this.done((function(_this) { | ||
return function() { | ||
if (_this.status === 'destroyed') { | ||
return; | ||
} | ||
_this.emit(_this.status = 'destroyed'); | ||
_this.resetResults(); | ||
return _this.removeAllListeners(); | ||
}; | ||
})(this)); | ||
return this; | ||
}; | ||
Task.prototype.fire = function() { | ||
var args, fire, me; | ||
var args, err, fire, me; | ||
me = this; | ||
args = (this.config.args || []).concat([this.completionCallback.bind(this)]); | ||
if ((me.config.method != null) === false) { | ||
err = new Error("The task [" + (me.getNames()) + "] failed to run as no method was defined for it."); | ||
me.emit('error', err); | ||
return this; | ||
} | ||
args = (this.config.args || []).concat([this.exit.bind(this)]); | ||
if ((this.taskDomain != null) === false && ((domain != null ? domain.create : void 0) != null)) { | ||
this.taskDomain = domain.create(); | ||
this.taskDomain.on('error', this.uncaughtExceptionCallback.bind(this)); | ||
this.taskDomain.on('error', this.exit.bind(this)); | ||
} | ||
fire = function() { | ||
var err, methodToFire, _ref1; | ||
var methodToFire, _ref1; | ||
try { | ||
if ((_ref1 = me.config.method) != null ? _ref1.bind : void 0) { | ||
methodToFire = me.config.method.bind(me.config.context || me); | ||
methodToFire = me.config.method.bind(me); | ||
me.status = 'running'; | ||
me.emit(me.status); | ||
if (me.config.timeout) { | ||
me.timeout = setTimeout(function() { | ||
if (me.isComplete() === false) { | ||
err = new Error("The task [" + (me.getNames()) + "] has timed out."); | ||
return me.exit(err); | ||
} | ||
}, me.config.timeout); | ||
} | ||
return ambi.apply(null, [methodToFire].concat(__slice.call(args))); | ||
} else { | ||
throw new Error("The task " + me.config.name + " was fired but has no method to fire"); | ||
err = new Error("The task [" + (me.getNames()) + "] was fired but has no method to fire"); | ||
throw err; | ||
} | ||
} catch (_error) { | ||
err = _error; | ||
return me.uncaughtExceptionCallback(err); | ||
return me.exit(err); | ||
} | ||
@@ -201,12 +381,15 @@ }; | ||
Task.prototype.run = function() { | ||
var err; | ||
if (this.completed) { | ||
err = new Error("A task was about to run but it has already completed, this is unexpected"); | ||
this.emit('error', err); | ||
} else { | ||
this.reset(); | ||
this.running = true; | ||
this.emit('run'); | ||
setImmediate(this.fire.bind(this)); | ||
} | ||
queue((function(_this) { | ||
return function() { | ||
var err; | ||
if (_this.hasStarted()) { | ||
err = new Error("The task [" + (_this.getNames()) + "] was just about to start, but it already started earlier, this is unexpected."); | ||
return _this.emit('error', err); | ||
} else { | ||
_this.status = 'started'; | ||
_this.emit(_this.status); | ||
return _this.fire(); | ||
} | ||
}; | ||
})(this)); | ||
return this; | ||
@@ -217,3 +400,3 @@ }; | ||
})(EventEmitter); | ||
})(Interface); | ||
@@ -223,35 +406,38 @@ TaskGroup = (function(_super) { | ||
TaskGroup.extend = extendOnClass; | ||
TaskGroup.prototype.type = 'taskgroup'; | ||
TaskGroup.create = function(a, b, c, d, e, f, g) { | ||
return new TaskGroup(a, b, d, e, f, g); | ||
TaskGroup.isTaskGroup = function(group) { | ||
return (group != null ? group.type : void 0) === 'taskgroup' || group instanceof TaskGroup; | ||
}; | ||
TaskGroup.prototype.type = 'taskgroup'; | ||
TaskGroup.subclass = extendOnClass; | ||
TaskGroup.prototype.running = 0; | ||
TaskGroup.create = function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return (function(func, args, ctor) { | ||
ctor.prototype = func.prototype; | ||
var child = new ctor, result = func.apply(child, args); | ||
return Object(result) === result ? result : child; | ||
})(this, args, function(){}); | ||
}; | ||
TaskGroup.prototype.remaining = null; | ||
TaskGroup.prototype.itemsRemaining = null; | ||
TaskGroup.prototype.err = null; | ||
TaskGroup.prototype.itemsRunning = null; | ||
TaskGroup.prototype.itemsCompleted = null; | ||
TaskGroup.prototype.results = null; | ||
TaskGroup.prototype.paused = true; | ||
TaskGroup.prototype.err = null; | ||
TaskGroup.prototype.bubbleEvents = null; | ||
TaskGroup.prototype.status = null; | ||
TaskGroup.prototype.events = null; | ||
TaskGroup.prototype.config = null; | ||
/* | ||
name: null | ||
method: null | ||
concurrency: 1 # use 0 for unlimited | ||
pauseOnError: true | ||
parent: null | ||
*/ | ||
function TaskGroup() { | ||
var args, me, _base, _base1, _base2, _base3; | ||
var args, me, _base, _base1; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
@@ -263,30 +449,62 @@ me = this; | ||
} | ||
if ((_base = this.config).name == null) { | ||
_base.name = "Task Group " + (Math.random()); | ||
if ((_base = this.config).concurrency == null) { | ||
_base.concurrency = 1; | ||
} | ||
if ((_base1 = this.config).concurrency == null) { | ||
_base1.concurrency = 1; | ||
if ((_base1 = this.config).onError == null) { | ||
_base1.onError = 'exit'; | ||
} | ||
if ((_base2 = this.config).pauseOnError == null) { | ||
_base2.pauseOnError = true; | ||
if (this.itemsRemaining == null) { | ||
this.itemsRemaining = []; | ||
} | ||
if ((_base3 = this.config).run == null) { | ||
_base3.run = false; | ||
if (this.itemsRunning == null) { | ||
this.itemsRunning = []; | ||
} | ||
if (this.itemsCompleted == null) { | ||
this.itemsCompleted = []; | ||
} | ||
if (this.results == null) { | ||
this.results = []; | ||
} | ||
if (this.remaining == null) { | ||
this.remaining = []; | ||
if (this.events == null) { | ||
this.events = []; | ||
} | ||
if (this.bubbleEvents == null) { | ||
this.bubbleEvents = ['complete', 'run', 'error']; | ||
} | ||
this.events.push('error', 'started', 'running', 'passed', 'failed', 'completed', 'destroyed'); | ||
this.setConfig(args); | ||
process.nextTick(this.fire.bind(this)); | ||
this.on('item.complete', this.itemCompletionCallback.bind(this)); | ||
this.on('item.error', this.itemUncaughtExceptionCallback.bind(this)); | ||
queue(this.autoRun.bind(this)); | ||
this; | ||
} | ||
TaskGroup.prototype.setNestedTaskConfig = function(config) { | ||
var key, value, _base; | ||
if (config == null) { | ||
config = {}; | ||
} | ||
if ((_base = this.config).nestedTaskConfig == null) { | ||
_base.nestedTaskConfig = {}; | ||
} | ||
for (key in config) { | ||
if (!__hasProp.call(config, key)) continue; | ||
value = config[key]; | ||
this.config.nestedTaskConfig[key] = value; | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.setNestedConfig = function(config) { | ||
var key, value, _base; | ||
if (config == null) { | ||
config = {}; | ||
} | ||
this.setConfig(config); | ||
if ((_base = this.config).nestedConfig == null) { | ||
_base.nestedConfig = {}; | ||
} | ||
for (key in config) { | ||
if (!__hasProp.call(config, key)) continue; | ||
value = config[key]; | ||
this.config.nestedConfig[key] = value; | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.setConfig = function(opts) { | ||
@@ -327,3 +545,3 @@ var arg, args, key, value, _i, _len; | ||
if (value) { | ||
this.once('complete', value.bind(this)); | ||
this.done(value); | ||
} | ||
@@ -356,14 +574,30 @@ break; | ||
TaskGroup.prototype.getConfig = function() { | ||
return this.config; | ||
TaskGroup.prototype.addMethod = function(method, config) { | ||
if (config == null) { | ||
config = {}; | ||
} | ||
if (method == null) { | ||
method = this.config.method.bind(this); | ||
} | ||
method.isTaskGroupMethod = true; | ||
if (config.name == null) { | ||
config.name = 'taskgroup method for ' + this.getName(); | ||
} | ||
if (config.args == null) { | ||
config.args = [this.addGroup.bind(this), this.addTask.bind(this)]; | ||
} | ||
if (config.includeInResults == null) { | ||
config.includeInResults = false; | ||
} | ||
return this.addTask(method, config); | ||
}; | ||
TaskGroup.prototype.fire = function() { | ||
TaskGroup.prototype.autoRun = function() { | ||
var item, _base; | ||
if (this.config.method) { | ||
this.addTask(this.config.method.bind(this), { | ||
args: [this.addGroup.bind(this), this.addTask.bind(this)], | ||
includeInResults: false | ||
}); | ||
if (!this.config.parent) { | ||
this.run(); | ||
item = this.addMethod(); | ||
if ((this.config.parent != null) === false) { | ||
if ((_base = this.config).run == null) { | ||
_base.run = true; | ||
} | ||
} | ||
@@ -377,44 +611,5 @@ } | ||
TaskGroup.prototype.itemCompletionCallback = function() { | ||
var args, item; | ||
TaskGroup.prototype.addItem = function() { | ||
var args, item, me, _base; | ||
item = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | ||
if (item.config.includeInResults !== false) { | ||
this.results.push(args); | ||
} | ||
if (args[0]) { | ||
this.err = args[0]; | ||
} | ||
if (this.running > 0) { | ||
--this.running; | ||
} | ||
if (this.paused) { | ||
return; | ||
} | ||
if (!this.complete()) { | ||
this.nextItems(); | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.itemUncaughtExceptionCallback = function(item, err) { | ||
this.exit(err); | ||
return this; | ||
}; | ||
TaskGroup.prototype.getTotals = function() { | ||
var completed, remaining, running, total; | ||
running = this.running; | ||
remaining = this.remaining.length; | ||
completed = this.results.length; | ||
total = running + remaining + completed; | ||
return { | ||
running: running, | ||
remaining: remaining, | ||
completed: completed, | ||
total: total | ||
}; | ||
}; | ||
TaskGroup.prototype.addItem = function(item) { | ||
var me; | ||
me = this; | ||
@@ -427,18 +622,37 @@ if (!item) { | ||
}); | ||
if (item.type === 'task') { | ||
this.bubbleEvents.forEach(function(bubbleEvent) { | ||
return item.on(bubbleEvent, function() { | ||
if (args.length !== 0) { | ||
item.setConfig.apply(item, args); | ||
} | ||
if ((_base = item.config).name == null) { | ||
_base.name = "" + item.type + " " + (this.getItemsTotal() + 1) + " for " + (this.getName()); | ||
} | ||
if (Task.isTask(item)) { | ||
if (this.config.nestedConfig != null) { | ||
item.setConfig(this.config.nestedConfig); | ||
} | ||
if (this.config.nestedTaskConfig != null) { | ||
item.setConfig(this.config.nestedTaskConfig); | ||
} | ||
item.events.forEach(function(event) { | ||
return item.on(event, function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return me.emit.apply(me, ["task." + bubbleEvent, item].concat(__slice.call(args))); | ||
return me.emit.apply(me, ["task." + event, item].concat(__slice.call(args))); | ||
}); | ||
}); | ||
this.emit('task.add', item); | ||
} | ||
if (item.type === 'taskgroup') { | ||
this.bubbleEvents.forEach(function(bubbleEvent) { | ||
return item.on(bubbleEvent, function() { | ||
} else if (TaskGroup.isTaskGroup(item)) { | ||
if (this.config.nestedConfig != null) { | ||
item.setNestedConfig(this.config.nestedConfig); | ||
} | ||
if (this.config.nestedTaskConfig != null) { | ||
item.setConfig({ | ||
nestedTaskConfig: this.config.nestedTaskConfig | ||
}); | ||
} | ||
item.events.forEach(function(event) { | ||
return item.on(event, function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return me.emit.apply(me, ["group." + bubbleEvent, item].concat(__slice.call(args))); | ||
return me.emit.apply(me, ["group." + event, item].concat(__slice.call(args))); | ||
}); | ||
@@ -448,14 +662,23 @@ }); | ||
} | ||
this.bubbleEvents.forEach(function(bubbleEvent) { | ||
return item.on(bubbleEvent, function() { | ||
item.events.forEach(function(event) { | ||
return item.on(event, function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return me.emit.apply(me, ["item." + bubbleEvent, item].concat(__slice.call(args))); | ||
return me.emit.apply(me, ["item." + event, item].concat(__slice.call(args))); | ||
}); | ||
}); | ||
/* | ||
* Bubble item error event directly | ||
item.on 'error', (args...) -> | ||
me.emit('error', args...) | ||
*/ | ||
this.emit('item.add', item); | ||
this.remaining.push(item); | ||
if (!this.paused) { | ||
this.nextItems(); | ||
} | ||
item.done(function() { | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return me.itemCompletionCallback.apply(me, [item].concat(__slice.call(args))); | ||
}); | ||
this.itemsRemaining.push(item); | ||
this.fire(); | ||
return item; | ||
@@ -482,7 +705,7 @@ }; | ||
TaskGroup.prototype.createTask = function() { | ||
var args, task, _ref1; | ||
var args, task; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
if (((_ref1 = args[0]) != null ? _ref1.type : void 0) === 'task') { | ||
if (Task.isTask(args[0])) { | ||
task = args[0]; | ||
task.setConfig(args.slice(1)); | ||
task.setConfig.apply(task, args.slice(1)); | ||
} else { | ||
@@ -499,9 +722,10 @@ task = (function(func, args, ctor) { | ||
TaskGroup.prototype.addTask = function() { | ||
var args; | ||
var args, task; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return this.addItem(this.createTask.apply(this, args)); | ||
task = this.addItem(this.createTask.apply(this, args)); | ||
return this; | ||
}; | ||
TaskGroup.prototype.addTasks = function() { | ||
var args, item, items; | ||
var args, item, items, tasks; | ||
items = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | ||
@@ -511,3 +735,3 @@ if (!Array.isArray(items)) { | ||
} | ||
return (function() { | ||
tasks = (function() { | ||
var _i, _len, _results; | ||
@@ -521,10 +745,11 @@ _results = []; | ||
}).call(this); | ||
return this; | ||
}; | ||
TaskGroup.prototype.createGroup = function() { | ||
var args, taskgroup, _ref1; | ||
var args, taskgroup; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
if (((_ref1 = args[0]) != null ? _ref1.type : void 0) === 'taskgroup') { | ||
if (TaskGroup.isTaskGroup(args[0])) { | ||
taskgroup = args[0]; | ||
taskgroup.setConfig(args.slice(1)); | ||
taskgroup.setConfig.apply(taskgroup, args.slice(1)); | ||
} else { | ||
@@ -541,9 +766,10 @@ taskgroup = (function(func, args, ctor) { | ||
TaskGroup.prototype.addGroup = function() { | ||
var args; | ||
var args, group; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
return this.addItem(this.createGroup.apply(this, args)); | ||
group = this.addItem(this.createGroup.apply(this, args)); | ||
return this; | ||
}; | ||
TaskGroup.prototype.addGroups = function() { | ||
var args, item, items; | ||
var args, groups, item, items; | ||
items = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | ||
@@ -553,3 +779,3 @@ if (!Array.isArray(items)) { | ||
} | ||
return (function() { | ||
groups = (function() { | ||
var _i, _len, _results; | ||
@@ -563,17 +789,153 @@ _results = []; | ||
}).call(this); | ||
return this; | ||
}; | ||
TaskGroup.prototype.getItemsTotal = function() { | ||
var completed, remaining, running, total; | ||
running = this.itemsRunning.length; | ||
remaining = this.itemsRemaining.length; | ||
completed = this.itemsCompleted.length; | ||
total = running + remaining + completed; | ||
return total; | ||
}; | ||
TaskGroup.prototype.getItemNames = function() { | ||
var completed, remaining, results, running, total; | ||
running = this.itemsRunning.map(function(item) { | ||
return item.getName(); | ||
}); | ||
remaining = this.itemsRemaining.map(function(item) { | ||
return item.getName(); | ||
}); | ||
completed = this.itemsCompleted.map(function(item) { | ||
return item.getName(); | ||
}); | ||
results = this.results; | ||
total = running.length + remaining.length + completed.length; | ||
return { | ||
remaining: remaining, | ||
running: running, | ||
completed: completed, | ||
total: total, | ||
results: results | ||
}; | ||
}; | ||
TaskGroup.prototype.getItemTotals = function() { | ||
var completed, remaining, results, running, total; | ||
running = this.itemsRunning.length; | ||
remaining = this.itemsRemaining.length; | ||
completed = this.itemsCompleted.length; | ||
results = this.results.length; | ||
total = running + remaining + completed; | ||
return { | ||
remaining: remaining, | ||
running: running, | ||
completed: completed, | ||
total: total, | ||
results: results | ||
}; | ||
}; | ||
TaskGroup.prototype.hasRunning = function() { | ||
return this.itemsRunning.length !== 0; | ||
}; | ||
TaskGroup.prototype.hasRemaining = function() { | ||
return this.itemsRemaining.length !== 0; | ||
}; | ||
TaskGroup.prototype.hasItems = function() { | ||
return this.remaining.length !== 0; | ||
return this.hasRunning() || this.hasRemaining(); | ||
}; | ||
TaskGroup.prototype.isReady = function() { | ||
return !this.config.concurrency || this.running < this.config.concurrency; | ||
TaskGroup.prototype.hasStarted = function() { | ||
return this.status !== null; | ||
}; | ||
TaskGroup.prototype.nextItems = function() { | ||
TaskGroup.prototype.hasResult = function() { | ||
return (this.err != null) || this.results.length !== 0; | ||
}; | ||
TaskGroup.prototype.hasExited = function() { | ||
var _ref1; | ||
return (_ref1 = this.status) === 'completed' || _ref1 === 'destroyed'; | ||
}; | ||
TaskGroup.prototype.hasSlots = function() { | ||
return this.config.concurrency === 0 || this.itemsRunning.length < this.config.concurrency; | ||
}; | ||
TaskGroup.prototype.shouldPause = function() { | ||
return this.config.onError === 'exit' && (this.err != null); | ||
}; | ||
TaskGroup.prototype.shouldFire = function() { | ||
return this.shouldPause() === false && this.hasRemaining() && this.hasSlots(); | ||
}; | ||
TaskGroup.prototype.isEmpty = function() { | ||
return this.hasItems() === false; | ||
}; | ||
TaskGroup.prototype.isPaused = function() { | ||
return this.shouldPause() && this.hasRunning() === false; | ||
}; | ||
TaskGroup.prototype.isComplete = function() { | ||
return this.hasStarted() && (this.isPaused() || this.isEmpty()); | ||
}; | ||
TaskGroup.prototype.complete = function() { | ||
var complete, item, _i, _len, _ref1; | ||
complete = this.isComplete(); | ||
if (complete) { | ||
this.emit('completed', this.err, this.results); | ||
this.err = null; | ||
_ref1 = this.itemsCompleted; | ||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | ||
item = _ref1[_i]; | ||
item.destroy(); | ||
} | ||
this.itemsCompleted = []; | ||
} | ||
return complete; | ||
}; | ||
TaskGroup.prototype.whenDone = function(handler) { | ||
if (this.isComplete()) { | ||
queue((function(_this) { | ||
return function() { | ||
return handler.call(_this, _this.err, _this.results); | ||
}; | ||
})(this)); | ||
} else { | ||
TaskGroup.__super__.whenDone.call(this, handler); | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.onceDone = function(handler) { | ||
if (this.isComplete()) { | ||
queue((function(_this) { | ||
return function() { | ||
return handler.call(_this, _this.err, _this.results); | ||
}; | ||
})(this)); | ||
} else { | ||
TaskGroup.__super__.onceDone.call(this, handler); | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.resetResults = function() { | ||
this.results = []; | ||
return this; | ||
}; | ||
TaskGroup.prototype.fireNextItems = function() { | ||
var item, items, result; | ||
items = []; | ||
while (true) { | ||
item = this.nextItem(); | ||
item = this.fireNextItem(); | ||
if (item) { | ||
@@ -585,38 +947,61 @@ items.push(item); | ||
} | ||
result = items.length ? items : false; | ||
result = items.length !== 0 ? items : false; | ||
return result; | ||
}; | ||
TaskGroup.prototype.nextItem = function() { | ||
var nextItem; | ||
if (this.hasItems()) { | ||
if (this.isReady()) { | ||
nextItem = this.remaining.shift(); | ||
++this.running; | ||
nextItem.run(); | ||
return nextItem; | ||
TaskGroup.prototype.fireNextItem = function() { | ||
var fire, item, result; | ||
result = false; | ||
fire = this.shouldFire(); | ||
if (fire) { | ||
if (this.status !== 'running') { | ||
this.emit(this.status = 'running'); | ||
} | ||
item = this.itemsRemaining.shift(); | ||
this.itemsRunning.push(item); | ||
item.run(); | ||
result = item; | ||
} | ||
return false; | ||
return result; | ||
}; | ||
TaskGroup.prototype.complete = function() { | ||
var completed, empty, pause; | ||
pause = this.config.pauseOnError && this.err; | ||
empty = this.hasItems() === false && this.running === 0; | ||
completed = pause || empty; | ||
if (completed) { | ||
if (pause) { | ||
this.pause(); | ||
TaskGroup.prototype.itemCompletionCallback = function() { | ||
var args, index, indexError, item; | ||
item = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | ||
if (this.config.onError === 'exit' && args[0]) { | ||
if (this.err == null) { | ||
this.err = args[0]; | ||
} | ||
this.emit('complete', this.err, this.results); | ||
this.err = null; | ||
this.results = []; | ||
} | ||
return completed; | ||
index = this.itemsRunning.indexOf(item); | ||
if (index === -1) { | ||
if (this.err == null) { | ||
this.err = indexError = new Error("Could not find [" + (item.getNames()) + "] in the running queue"); | ||
} | ||
console.log(indexError.message); | ||
} else { | ||
this.itemsRunning = this.itemsRunning.slice(0, index).concat(this.itemsRunning.slice(index + 1)); | ||
} | ||
this.itemsCompleted.push(item); | ||
if (item.config.includeInResults !== false) { | ||
this.results.push(args); | ||
} | ||
this.fire(); | ||
return this; | ||
}; | ||
TaskGroup.prototype.fire = function() { | ||
if (this.hasStarted()) { | ||
if (this.isComplete()) { | ||
this.exit(); | ||
} else if (this.shouldPause() === false) { | ||
this.fireNextItems(); | ||
} | ||
} | ||
return this; | ||
}; | ||
TaskGroup.prototype.clear = function() { | ||
var item, _i, _len, _ref1; | ||
_ref1 = this.remaining.splice(0); | ||
_ref1 = this.itemsRemaining; | ||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | ||
@@ -626,2 +1011,3 @@ item = _ref1[_i]; | ||
} | ||
this.itemsRemaining = []; | ||
return this; | ||
@@ -631,10 +1017,11 @@ }; | ||
TaskGroup.prototype.destroy = function() { | ||
this.stop(); | ||
this.removeAllListeners(); | ||
return this; | ||
}; | ||
TaskGroup.prototype.stop = function() { | ||
this.pause(); | ||
this.clear(); | ||
this.done((function(_this) { | ||
return function() { | ||
_this.status = 'destroyed'; | ||
_this.emit(_this.status); | ||
_this.resetResults(); | ||
return _this.removeAllListeners(); | ||
}; | ||
})(this)); | ||
return this; | ||
@@ -644,7 +1031,9 @@ }; | ||
TaskGroup.prototype.exit = function(err) { | ||
if (err) { | ||
this.err = err; | ||
if (err != null) { | ||
if (this.err == null) { | ||
this.err = err; | ||
} | ||
} | ||
this.stop(); | ||
this.running = 0; | ||
this.status = this.err != null ? 'failed' : 'passed'; | ||
this.emit(this.status, this.err); | ||
this.complete(); | ||
@@ -654,18 +1043,12 @@ return this; | ||
TaskGroup.prototype.pause = function() { | ||
this.paused = true; | ||
return this; | ||
}; | ||
TaskGroup.prototype.run = function() { | ||
var args, me; | ||
var args; | ||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
me = this; | ||
this.paused = false; | ||
this.emit('run'); | ||
process.nextTick(function() { | ||
if (!me.complete()) { | ||
return me.nextItems(); | ||
} | ||
}); | ||
queue((function(_this) { | ||
return function() { | ||
_this.status = 'started'; | ||
_this.emit(_this.status); | ||
return queue(_this.fire.bind(_this)); | ||
}; | ||
})(this)); | ||
return this; | ||
@@ -676,3 +1059,3 @@ }; | ||
})(EventEmitter); | ||
})(Interface); | ||
@@ -679,0 +1062,0 @@ module.exports = { |
{ | ||
"title": "TaskGroup", | ||
"name": "taskgroup", | ||
"version": "3.4.0", | ||
"version": "4.0.0", | ||
"description": "Group together synchronous and asynchronous tasks and execute them with support for concurrency, naming, and nesting.", | ||
@@ -48,3 +48,3 @@ "homepage": "https://github.com/bevry/taskgroup", | ||
"engines": { | ||
"node": ">=0.4" | ||
"node": ">=0.8" | ||
}, | ||
@@ -60,3 +60,4 @@ "dependencies": { | ||
"chai": "~1.9.1", | ||
"projectz": "~0.3.11" | ||
"projectz": "~0.3.11", | ||
"biscotto": "^2.1.2" | ||
}, | ||
@@ -70,3 +71,7 @@ "directories": { | ||
}, | ||
"main": "./out/lib/taskgroup.js" | ||
"main": "./out/lib/taskgroup.js", | ||
"cakeConfiguration": { | ||
"COFFEE_SRC_PATH": "src", | ||
"BISCOTTO_SRC_PATH": "src" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
377319
23
1254
22
6
1
80
2