// jWorkflow.js // (c) 2010 tinyHippos inc. // jWorkflow is freely distributable under the terms of the MIT license. // Portions of jWorkflow are inspired by Underscore.js var jWorkflow = (function () { function _valid(func) { if (typeof(func) !== 'function') { throw "expected function but was " + typeof(func); } } function _isWorkflow(func) { return typeof func.andThen === 'function' && typeof func.start === 'function' && typeof func.chill === 'function'; } function _isArray(func) { return !!func.map && !!func.reduce; } var transfunctioner = { order: function (func, context) { var _workflow = [], _tasks, _callback = null, _baton = (function () { var _taken = false; return { take: function () { _taken = true; }, pass: function (result) { var task; _taken = false; if (_tasks.length) { task = _tasks.shift(); result = task.func.apply(task.context, [result, _baton]); if (!_taken) { _baton.pass(result); } } else { if (_callback.func) { _callback.func.apply(_callback.context, [result]); } } }, drop: function (result) { _taken = true; _tasks = []; setTimeout(function () { _baton.pass(result); }, 1); } }; }()), _self = { andThen: function (func, context) { if (_isWorkflow(func)) { var f = function (prev, baton) { baton.take(); func.start({ callback: function (result) { baton.pass(result); }, context: context, initialValue: prev }); }; _workflow.push({func: f, context: context}); } else if (_isArray(func)) { var orch = function (prev, baton) { baton.take(); var l = func.length, join = function () { return --l || baton.pass(); }; func.forEach(function (f) { jWorkflow.order(f).start(join); }); }; _workflow.push({func: orch, context: context}); } else { _valid(func); _workflow.push({func: func, context: context}); } return _self; }, chill: function (time) { return _self.andThen(function (prev, baton) { baton.take(); setTimeout(function () { baton.pass(prev); }, time); }); }, start: function () { var callback, context, initialValue; if (arguments[0] && typeof arguments[0] === 'object') { callback = arguments[0].callback; context = arguments[0].context; initialValue = arguments[0].initialValue; } else { callback = arguments[0]; context = arguments[1]; } _callback = {func: callback, context: context}; _tasks = _workflow.slice(); _baton.pass(initialValue); } }; return func ? _self.andThen(func, context) : _self; } }; return transfunctioner; }()); if (typeof module === "object" && typeof require === "function") { module.exports = jWorkflow; }