You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

568 lines
15 KiB

// Generated by CoffeeScript 1.4.0
(function() {
var balUtilFlow, balUtilTypes,
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__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; };
balUtilTypes = (typeof require === "function" ? require(__dirname + '/types') : void 0) || this.balUtilTypes;
balUtilFlow = {
wait: function(delay, fn) {
return setTimeout(fn, delay);
},
extractOptsAndCallback: function(opts, next) {
if (balUtilTypes.isFunction(opts) && (next != null) === false) {
next = opts;
opts = {};
} else {
opts || (opts = {});
}
next || (next = opts.next || null);
return [opts, next];
},
fireWithOptionalCallback: function(method, args, context) {
var callback, err, result;
args || (args = []);
callback = args[args.length - 1];
context || (context = null);
result = null;
if (method.length === args.length) {
try {
result = method.apply(context, args);
} catch (caughtError) {
callback(caughtError);
}
} else {
err = null;
try {
result = method.apply(context, args);
if (balUtilTypes.isError(result)) {
err = result;
}
} catch (caughtError) {
err = caughtError;
}
callback(err, result);
}
return result;
},
extend: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return this.shallowExtendPlainObjects.apply(this, args);
},
shallowExtendPlainObjects: function() {
var key, obj, objs, target, value, _i, _len;
target = arguments[0], objs = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = objs.length; _i < _len; _i++) {
obj = objs[_i];
obj || (obj = {});
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
value = obj[key];
target[key] = value;
}
}
return target;
},
deepExtendPlainObjects: function() {
var key, obj, objs, target, value, _i, _len;
target = arguments[0], objs = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = objs.length; _i < _len; _i++) {
obj = objs[_i];
obj || (obj = {});
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
value = obj[key];
if (balUtilTypes.isPlainObject(value)) {
if (!balUtilTypes.isPlainObject(target[key])) {
target[key] = {};
}
balUtilFlow.deepExtendPlainObjects(target[key], value);
} else {
target[key] = value;
}
}
}
return target;
},
dereference: function(source) {
var target;
target = JSON.parse(JSON.stringify(source));
return target;
},
each: function(obj, callback, context) {
var item, key, _i, _len;
context || (context = obj);
if (balUtilTypes.isArray(obj)) {
for (key = _i = 0, _len = obj.length; _i < _len; key = ++_i) {
item = obj[key];
if (callback.call(context, item, key, obj) === false) {
break;
}
}
} else {
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
item = obj[key];
if (callback.call(context, item, key, obj) === false) {
break;
}
}
}
return this;
},
flow: function(opts) {
var action, actions, args, next, object, tasks;
object = opts.object, action = opts.action, args = opts.args, tasks = opts.tasks, next = opts.next;
if (!action) {
throw new Error('balUtilFlow.flow called without any action');
}
actions = action.split(/[,\s]+/g);
tasks || (tasks = new balUtilFlow.Group(next));
balUtilFlow.each(actions, function(action) {
return tasks.push(function(complete) {
var argsClone, fn;
argsClone = (args || []).slice();
argsClone.push(complete);
fn = object[action];
return fn.apply(object, argsClone);
});
});
tasks.sync();
return this;
}
};
/*
Usage:
# Add tasks to a queue then fire them in parallel (asynchronously)
tasks = new Group (err) -> next err
tasks.push (complete) -> someAsyncFunction(arg1, arg2, complete)
tasks.push (complete) -> anotherAsyncFunction(arg1, arg2, complete)
tasks.async()
# Add tasks to a queue then fire them in serial (synchronously)
tasks = new Group (err) -> next err
tasks.push (complete) -> someAsyncFunction(arg1, arg2, complete)
tasks.push (complete) -> anotherAsyncFunction(arg1, arg2, complete)
tasks.sync()
*/
balUtilFlow.Group = (function() {
_Class.prototype.total = 0;
_Class.prototype.completed = 0;
_Class.prototype.running = 0;
_Class.prototype.exited = false;
_Class.prototype.breakOnError = true;
_Class.prototype.autoClear = false;
_Class.prototype.queue = [];
_Class.prototype.mode = 'async';
_Class.prototype.lastResult = null;
_Class.prototype.results = [];
_Class.prototype.errors = [];
_Class.prototype.next = function() {
throw new Error('Groups require a completion callback');
};
function _Class() {
var arg, args, autoClear, breakOnError, mode, next, _i, _len;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.clear();
for (_i = 0, _len = args.length; _i < _len; _i++) {
arg = args[_i];
if (balUtilTypes.isString(arg)) {
this.mode = arg;
} else if (balUtilTypes.isFunction(arg)) {
this.next = arg;
} else if (balUtilTypes.isObject(arg)) {
next = arg.next, mode = arg.mode, breakOnError = arg.breakOnError, autoClear = arg.autoClear;
if (next) {
this.next = next;
}
if (mode) {
this.mode = mode;
}
if (breakOnError) {
this.breakOnError = breakOnError;
}
if (autoClear) {
this.autoClear = autoClear;
}
} else {
throw new Error('Unknown argument sent to Groups constructor');
}
}
}
_Class.prototype.clear = function() {
this.total = 0;
this.completed = 0;
this.running = 0;
this.exited = false;
this.queue = [];
this.results = [];
this.errors = [];
this.lastResult = null;
return this;
};
_Class.prototype.hasTasks = function() {
return this.queue.length !== 0;
};
_Class.prototype.hasCompleted = function() {
return this.total !== 0 && this.total === this.completed;
};
_Class.prototype.isRunning = function() {
return this.running !== 0;
};
_Class.prototype.hasExited = function(value) {
if (value != null) {
this.exited = value;
}
return this.exited === true;
};
_Class.prototype.logError = function(err) {
if (this.errors[this.errors.length - 1] !== err) {
this.errors.push(err);
}
return this;
};
_Class.prototype.complete = function() {
var args, err;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
err = args[0] || void 0;
this.lastResult = args;
if (err) {
this.logError(err);
}
this.results.push(args);
if (this.running !== 0) {
--this.running;
}
if (this.hasExited()) {
} else {
if (err && this.breakOnError) {
this.exit();
} else {
++this.completed;
if (this.hasTasks()) {
this.nextTask();
} else if (this.isRunning() === false && this.hasCompleted()) {
this.exit();
}
}
}
return this;
};
_Class.prototype.completer = function() {
var _this = this;
return function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return _this.complete.apply(_this, args);
};
};
_Class.prototype.exit = function(err) {
var errors, lastResult, results;
if (err == null) {
err = null;
}
if (err) {
this.logError(err);
}
if (this.hasExited()) {
} else {
lastResult = this.lastResult;
results = this.results;
if (this.errors.length === 0) {
errors = null;
} else if (this.errors.length === 1) {
errors = this.errors[0];
} else {
errors = this.errors;
}
if (this.autoClear) {
this.clear();
} else {
this.hasExited(true);
}
this.next(errors, lastResult, results);
}
return this;
};
_Class.prototype.tasks = function(tasks) {
var task, _i, _len;
for (_i = 0, _len = tasks.length; _i < _len; _i++) {
task = tasks[_i];
this.push(task);
}
return this;
};
_Class.prototype.push = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
++this.total;
this.queue.push(args);
return this;
};
_Class.prototype.pushAndRun = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (this.mode === 'sync' && this.isRunning()) {
this.push.apply(this, args);
} else {
++this.total;
this.runTask(args);
}
return this;
};
_Class.prototype.nextTask = function() {
var task;
if (this.hasTasks()) {
task = this.queue.shift();
this.runTask(task);
}
return this;
};
_Class.prototype.runTask = function(task) {
var me, run;
me = this;
try {
run = function() {
var complete, _context, _task;
++me.running;
complete = me.completer();
if (balUtilTypes.isArray(task)) {
if (task.length === 2) {
_context = task[0];
_task = task[1];
} else if (task.length === 1) {
_task = task[0];
_context = null;
} else {
throw new Error('balUtilFlow.Group an invalid task was pushed');
}
} else {
_task = task;
}
return balUtilFlow.fireWithOptionalCallback(_task, [complete], _context);
};
if (this.completed !== 0 && (this.mode === 'async' || (this.completed % 100) === 0)) {
setTimeout(run, 0);
} else {
run();
}
} catch (err) {
this.complete(err);
}
return this;
};
_Class.prototype.run = function() {
var task, _i, _len, _ref;
if (this.isRunning() === false) {
this.hasExited(false);
if (this.hasTasks()) {
if (this.mode === 'sync') {
this.nextTask();
} else {
_ref = this.queue;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
task = _ref[_i];
this.nextTask();
}
}
} else {
this.exit();
}
}
return this;
};
_Class.prototype.async = function() {
this.mode = 'async';
this.run();
return this;
};
_Class.prototype.sync = function() {
this.mode = 'sync';
this.run();
return this;
};
return _Class;
})();
balUtilFlow.Block = (function(_super) {
__extends(_Class, _super);
_Class.prototype.blockBefore = function(block) {};
_Class.prototype.blockAfter = function(block, err) {};
_Class.prototype.blockTaskBefore = function(block, task, err) {};
_Class.prototype.blockTaskAfter = function(block, task, err) {};
function _Class(opts) {
var block, complete, fn, name, parentBlock;
block = this;
name = opts.name, fn = opts.fn, parentBlock = opts.parentBlock, complete = opts.complete;
block.blockName = name;
if (parentBlock != null) {
block.parentBlock = parentBlock;
}
block.mode = 'sync';
block.fn = fn;
_Class.__super__.constructor.call(this, function(err) {
block.blockAfter(block, err);
return typeof complete === "function" ? complete(err) : void 0;
});
block.blockBefore(block);
if (block.fn != null) {
if (block.fn.length === 3) {
block.total = Infinity;
}
try {
block.fn(function(name, fn) {
return block.block(name, fn);
}, function(name, fn) {
return block.task(name, fn);
}, function(err) {
return block.exit(err);
});
if (block.fn.length !== 3) {
block.run();
}
} catch (err) {
block.exit(err);
}
} else {
block.total = Infinity;
}
this;
}
_Class.prototype.block = function(name, fn) {
var block, pushBlock;
block = this;
pushBlock = function(fn) {
if (block.total === Infinity) {
return block.pushAndRun(fn);
} else {
return block.push(fn);
}
};
pushBlock(function(complete) {
var subBlock;
return subBlock = block.createSubBlock({
name: name,
fn: fn,
complete: complete
});
});
return this;
};
_Class.prototype.createSubBlock = function(opts) {
opts.parentBlock = this;
return new balUtilFlow.Block(opts);
};
_Class.prototype.task = function(name, fn) {
var block, pushTask;
block = this;
pushTask = function(fn) {
if (block.total === Infinity) {
return block.pushAndRun(fn);
} else {
return block.push(fn);
}
};
pushTask(function(complete) {
var preComplete;
preComplete = function(err) {
block.blockTaskAfter(block, name, err);
return complete(err);
};
block.blockTaskBefore(block, name);
return balUtilFlow.fireWithOptionalCallback(fn, [preComplete]);
});
return this;
};
return _Class;
})(balUtilFlow.Group);
balUtilFlow.Runner = (function() {
_Class.prototype.runnerBlock = null;
function _Class() {
var _ref;
if ((_ref = this.runnerBlock) == null) {
this.runnerBlock = new balUtilFlow.Block();
}
}
_Class.prototype.getRunnerBlock = function() {
return this.runnerBlock;
};
_Class.prototype.block = function() {
var args, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return (_ref = this.getRunnerBlock()).block.apply(_ref, args);
};
_Class.prototype.task = function() {
var args, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return (_ref = this.getRunnerBlock()).task.apply(_ref, args);
};
return _Class;
})();
if (typeof module !== "undefined" && module !== null) {
module.exports = balUtilFlow;
} else {
this.balUtilFlow = balUtilFlow;
}
}).call(this);