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

  1. // Generated by CoffeeScript 1.4.0
  2. (function() {
  3. var balUtilFlow, balUtilTypes,
  4. __slice = [].slice,
  5. __hasProp = {}.hasOwnProperty,
  6. __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; };
  7. balUtilTypes = (typeof require === "function" ? require(__dirname + '/types') : void 0) || this.balUtilTypes;
  8. balUtilFlow = {
  9. wait: function(delay, fn) {
  10. return setTimeout(fn, delay);
  11. },
  12. extractOptsAndCallback: function(opts, next) {
  13. if (balUtilTypes.isFunction(opts) && (next != null) === false) {
  14. next = opts;
  15. opts = {};
  16. } else {
  17. opts || (opts = {});
  18. }
  19. next || (next = opts.next || null);
  20. return [opts, next];
  21. },
  22. fireWithOptionalCallback: function(method, args, context) {
  23. var callback, err, result;
  24. args || (args = []);
  25. callback = args[args.length - 1];
  26. context || (context = null);
  27. result = null;
  28. if (method.length === args.length) {
  29. try {
  30. result = method.apply(context, args);
  31. } catch (caughtError) {
  32. callback(caughtError);
  33. }
  34. } else {
  35. err = null;
  36. try {
  37. result = method.apply(context, args);
  38. if (balUtilTypes.isError(result)) {
  39. err = result;
  40. }
  41. } catch (caughtError) {
  42. err = caughtError;
  43. }
  44. callback(err, result);
  45. }
  46. return result;
  47. },
  48. extend: function() {
  49. var args;
  50. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  51. return this.shallowExtendPlainObjects.apply(this, args);
  52. },
  53. shallowExtendPlainObjects: function() {
  54. var key, obj, objs, target, value, _i, _len;
  55. target = arguments[0], objs = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  56. for (_i = 0, _len = objs.length; _i < _len; _i++) {
  57. obj = objs[_i];
  58. obj || (obj = {});
  59. for (key in obj) {
  60. if (!__hasProp.call(obj, key)) continue;
  61. value = obj[key];
  62. target[key] = value;
  63. }
  64. }
  65. return target;
  66. },
  67. deepExtendPlainObjects: function() {
  68. var key, obj, objs, target, value, _i, _len;
  69. target = arguments[0], objs = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  70. for (_i = 0, _len = objs.length; _i < _len; _i++) {
  71. obj = objs[_i];
  72. obj || (obj = {});
  73. for (key in obj) {
  74. if (!__hasProp.call(obj, key)) continue;
  75. value = obj[key];
  76. if (balUtilTypes.isPlainObject(value)) {
  77. if (!balUtilTypes.isPlainObject(target[key])) {
  78. target[key] = {};
  79. }
  80. balUtilFlow.deepExtendPlainObjects(target[key], value);
  81. } else {
  82. target[key] = value;
  83. }
  84. }
  85. }
  86. return target;
  87. },
  88. dereference: function(source) {
  89. var target;
  90. target = JSON.parse(JSON.stringify(source));
  91. return target;
  92. },
  93. each: function(obj, callback, context) {
  94. var item, key, _i, _len;
  95. context || (context = obj);
  96. if (balUtilTypes.isArray(obj)) {
  97. for (key = _i = 0, _len = obj.length; _i < _len; key = ++_i) {
  98. item = obj[key];
  99. if (callback.call(context, item, key, obj) === false) {
  100. break;
  101. }
  102. }
  103. } else {
  104. for (key in obj) {
  105. if (!__hasProp.call(obj, key)) continue;
  106. item = obj[key];
  107. if (callback.call(context, item, key, obj) === false) {
  108. break;
  109. }
  110. }
  111. }
  112. return this;
  113. },
  114. flow: function(opts) {
  115. var action, actions, args, next, object, tasks;
  116. object = opts.object, action = opts.action, args = opts.args, tasks = opts.tasks, next = opts.next;
  117. if (!action) {
  118. throw new Error('balUtilFlow.flow called without any action');
  119. }
  120. actions = action.split(/[,\s]+/g);
  121. tasks || (tasks = new balUtilFlow.Group(next));
  122. balUtilFlow.each(actions, function(action) {
  123. return tasks.push(function(complete) {
  124. var argsClone, fn;
  125. argsClone = (args || []).slice();
  126. argsClone.push(complete);
  127. fn = object[action];
  128. return fn.apply(object, argsClone);
  129. });
  130. });
  131. tasks.sync();
  132. return this;
  133. }
  134. };
  135. /*
  136. Usage:
  137. # Add tasks to a queue then fire them in parallel (asynchronously)
  138. tasks = new Group (err) -> next err
  139. tasks.push (complete) -> someAsyncFunction(arg1, arg2, complete)
  140. tasks.push (complete) -> anotherAsyncFunction(arg1, arg2, complete)
  141. tasks.async()
  142. # Add tasks to a queue then fire them in serial (synchronously)
  143. tasks = new Group (err) -> next err
  144. tasks.push (complete) -> someAsyncFunction(arg1, arg2, complete)
  145. tasks.push (complete) -> anotherAsyncFunction(arg1, arg2, complete)
  146. tasks.sync()
  147. */
  148. balUtilFlow.Group = (function() {
  149. _Class.prototype.total = 0;
  150. _Class.prototype.completed = 0;
  151. _Class.prototype.running = 0;
  152. _Class.prototype.exited = false;
  153. _Class.prototype.breakOnError = true;
  154. _Class.prototype.autoClear = false;
  155. _Class.prototype.queue = [];
  156. _Class.prototype.mode = 'async';
  157. _Class.prototype.lastResult = null;
  158. _Class.prototype.results = [];
  159. _Class.prototype.errors = [];
  160. _Class.prototype.next = function() {
  161. throw new Error('Groups require a completion callback');
  162. };
  163. function _Class() {
  164. var arg, args, autoClear, breakOnError, mode, next, _i, _len;
  165. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  166. this.clear();
  167. for (_i = 0, _len = args.length; _i < _len; _i++) {
  168. arg = args[_i];
  169. if (balUtilTypes.isString(arg)) {
  170. this.mode = arg;
  171. } else if (balUtilTypes.isFunction(arg)) {
  172. this.next = arg;
  173. } else if (balUtilTypes.isObject(arg)) {
  174. next = arg.next, mode = arg.mode, breakOnError = arg.breakOnError, autoClear = arg.autoClear;
  175. if (next) {
  176. this.next = next;
  177. }
  178. if (mode) {
  179. this.mode = mode;
  180. }
  181. if (breakOnError) {
  182. this.breakOnError = breakOnError;
  183. }
  184. if (autoClear) {
  185. this.autoClear = autoClear;
  186. }
  187. } else {
  188. throw new Error('Unknown argument sent to Groups constructor');
  189. }
  190. }
  191. }
  192. _Class.prototype.clear = function() {
  193. this.total = 0;
  194. this.completed = 0;
  195. this.running = 0;
  196. this.exited = false;
  197. this.queue = [];
  198. this.results = [];
  199. this.errors = [];
  200. this.lastResult = null;
  201. return this;
  202. };
  203. _Class.prototype.hasTasks = function() {
  204. return this.queue.length !== 0;
  205. };
  206. _Class.prototype.hasCompleted = function() {
  207. return this.total !== 0 && this.total === this.completed;
  208. };
  209. _Class.prototype.isRunning = function() {
  210. return this.running !== 0;
  211. };
  212. _Class.prototype.hasExited = function(value) {
  213. if (value != null) {
  214. this.exited = value;
  215. }
  216. return this.exited === true;
  217. };
  218. _Class.prototype.logError = function(err) {
  219. if (this.errors[this.errors.length - 1] !== err) {
  220. this.errors.push(err);
  221. }
  222. return this;
  223. };
  224. _Class.prototype.complete = function() {
  225. var args, err;
  226. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  227. err = args[0] || void 0;
  228. this.lastResult = args;
  229. if (err) {
  230. this.logError(err);
  231. }
  232. this.results.push(args);
  233. if (this.running !== 0) {
  234. --this.running;
  235. }
  236. if (this.hasExited()) {
  237. } else {
  238. if (err && this.breakOnError) {
  239. this.exit();
  240. } else {
  241. ++this.completed;
  242. if (this.hasTasks()) {
  243. this.nextTask();
  244. } else if (this.isRunning() === false && this.hasCompleted()) {
  245. this.exit();
  246. }
  247. }
  248. }
  249. return this;
  250. };
  251. _Class.prototype.completer = function() {
  252. var _this = this;
  253. return function() {
  254. var args;
  255. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  256. return _this.complete.apply(_this, args);
  257. };
  258. };
  259. _Class.prototype.exit = function(err) {
  260. var errors, lastResult, results;
  261. if (err == null) {
  262. err = null;
  263. }
  264. if (err) {
  265. this.logError(err);
  266. }
  267. if (this.hasExited()) {
  268. } else {
  269. lastResult = this.lastResult;
  270. results = this.results;
  271. if (this.errors.length === 0) {
  272. errors = null;
  273. } else if (this.errors.length === 1) {
  274. errors = this.errors[0];
  275. } else {
  276. errors = this.errors;
  277. }
  278. if (this.autoClear) {
  279. this.clear();
  280. } else {
  281. this.hasExited(true);
  282. }
  283. this.next(errors, lastResult, results);
  284. }
  285. return this;
  286. };
  287. _Class.prototype.tasks = function(tasks) {
  288. var task, _i, _len;
  289. for (_i = 0, _len = tasks.length; _i < _len; _i++) {
  290. task = tasks[_i];
  291. this.push(task);
  292. }
  293. return this;
  294. };
  295. _Class.prototype.push = function() {
  296. var args;
  297. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  298. ++this.total;
  299. this.queue.push(args);
  300. return this;
  301. };
  302. _Class.prototype.pushAndRun = function() {
  303. var args;
  304. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  305. if (this.mode === 'sync' && this.isRunning()) {
  306. this.push.apply(this, args);
  307. } else {
  308. ++this.total;
  309. this.runTask(args);
  310. }
  311. return this;
  312. };
  313. _Class.prototype.nextTask = function() {
  314. var task;
  315. if (this.hasTasks()) {
  316. task = this.queue.shift();
  317. this.runTask(task);
  318. }
  319. return this;
  320. };
  321. _Class.prototype.runTask = function(task) {
  322. var me, run;
  323. me = this;
  324. try {
  325. run = function() {
  326. var complete, _context, _task;
  327. ++me.running;
  328. complete = me.completer();
  329. if (balUtilTypes.isArray(task)) {
  330. if (task.length === 2) {
  331. _context = task[0];
  332. _task = task[1];
  333. } else if (task.length === 1) {
  334. _task = task[0];
  335. _context = null;
  336. } else {
  337. throw new Error('balUtilFlow.Group an invalid task was pushed');
  338. }
  339. } else {
  340. _task = task;
  341. }
  342. return balUtilFlow.fireWithOptionalCallback(_task, [complete], _context);
  343. };
  344. if (this.completed !== 0 && (this.mode === 'async' || (this.completed % 100) === 0)) {
  345. setTimeout(run, 0);
  346. } else {
  347. run();
  348. }
  349. } catch (err) {
  350. this.complete(err);
  351. }
  352. return this;
  353. };
  354. _Class.prototype.run = function() {
  355. var task, _i, _len, _ref;
  356. if (this.isRunning() === false) {
  357. this.hasExited(false);
  358. if (this.hasTasks()) {
  359. if (this.mode === 'sync') {
  360. this.nextTask();
  361. } else {
  362. _ref = this.queue;
  363. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  364. task = _ref[_i];
  365. this.nextTask();
  366. }
  367. }
  368. } else {
  369. this.exit();
  370. }
  371. }
  372. return this;
  373. };
  374. _Class.prototype.async = function() {
  375. this.mode = 'async';
  376. this.run();
  377. return this;
  378. };
  379. _Class.prototype.sync = function() {
  380. this.mode = 'sync';
  381. this.run();
  382. return this;
  383. };
  384. return _Class;
  385. })();
  386. balUtilFlow.Block = (function(_super) {
  387. __extends(_Class, _super);
  388. _Class.prototype.blockBefore = function(block) {};
  389. _Class.prototype.blockAfter = function(block, err) {};
  390. _Class.prototype.blockTaskBefore = function(block, task, err) {};
  391. _Class.prototype.blockTaskAfter = function(block, task, err) {};
  392. function _Class(opts) {
  393. var block, complete, fn, name, parentBlock;
  394. block = this;
  395. name = opts.name, fn = opts.fn, parentBlock = opts.parentBlock, complete = opts.complete;
  396. block.blockName = name;
  397. if (parentBlock != null) {
  398. block.parentBlock = parentBlock;
  399. }
  400. block.mode = 'sync';
  401. block.fn = fn;
  402. _Class.__super__.constructor.call(this, function(err) {
  403. block.blockAfter(block, err);
  404. return typeof complete === "function" ? complete(err) : void 0;
  405. });
  406. block.blockBefore(block);
  407. if (block.fn != null) {
  408. if (block.fn.length === 3) {
  409. block.total = Infinity;
  410. }
  411. try {
  412. block.fn(function(name, fn) {
  413. return block.block(name, fn);
  414. }, function(name, fn) {
  415. return block.task(name, fn);
  416. }, function(err) {
  417. return block.exit(err);
  418. });
  419. if (block.fn.length !== 3) {
  420. block.run();
  421. }
  422. } catch (err) {
  423. block.exit(err);
  424. }
  425. } else {
  426. block.total = Infinity;
  427. }
  428. this;
  429. }
  430. _Class.prototype.block = function(name, fn) {
  431. var block, pushBlock;
  432. block = this;
  433. pushBlock = function(fn) {
  434. if (block.total === Infinity) {
  435. return block.pushAndRun(fn);
  436. } else {
  437. return block.push(fn);
  438. }
  439. };
  440. pushBlock(function(complete) {
  441. var subBlock;
  442. return subBlock = block.createSubBlock({
  443. name: name,
  444. fn: fn,
  445. complete: complete
  446. });
  447. });
  448. return this;
  449. };
  450. _Class.prototype.createSubBlock = function(opts) {
  451. opts.parentBlock = this;
  452. return new balUtilFlow.Block(opts);
  453. };
  454. _Class.prototype.task = function(name, fn) {
  455. var block, pushTask;
  456. block = this;
  457. pushTask = function(fn) {
  458. if (block.total === Infinity) {
  459. return block.pushAndRun(fn);
  460. } else {
  461. return block.push(fn);
  462. }
  463. };
  464. pushTask(function(complete) {
  465. var preComplete;
  466. preComplete = function(err) {
  467. block.blockTaskAfter(block, name, err);
  468. return complete(err);
  469. };
  470. block.blockTaskBefore(block, name);
  471. return balUtilFlow.fireWithOptionalCallback(fn, [preComplete]);
  472. });
  473. return this;
  474. };
  475. return _Class;
  476. })(balUtilFlow.Group);
  477. balUtilFlow.Runner = (function() {
  478. _Class.prototype.runnerBlock = null;
  479. function _Class() {
  480. var _ref;
  481. if ((_ref = this.runnerBlock) == null) {
  482. this.runnerBlock = new balUtilFlow.Block();
  483. }
  484. }
  485. _Class.prototype.getRunnerBlock = function() {
  486. return this.runnerBlock;
  487. };
  488. _Class.prototype.block = function() {
  489. var args, _ref;
  490. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  491. return (_ref = this.getRunnerBlock()).block.apply(_ref, args);
  492. };
  493. _Class.prototype.task = function() {
  494. var args, _ref;
  495. args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  496. return (_ref = this.getRunnerBlock()).task.apply(_ref, args);
  497. };
  498. return _Class;
  499. })();
  500. if (typeof module !== "undefined" && module !== null) {
  501. module.exports = balUtilFlow;
  502. } else {
  503. this.balUtilFlow = balUtilFlow;
  504. }
  505. }).call(this);