| 1 | | // Generated by CoffeeScript 1.4.0 |
| 2 | | /* |
| 3 | | each(elements) |
| 4 | | .mode(parallel=false|true|integer) |
| 5 | | .on('item', callback) |
| 6 | | .on('error', callback) |
| 7 | | .on('end', callback) |
| 8 | | .on('both', callback) |
| 9 | | Chained and parallel async iterator in one elegant function |
| 10 | | */ |
| 11 | | |
| 12 | 1 | module.exports = function(elements) { |
| 13 | 52 | var eacher, errors, events, isObject, keys, next, parallel, run, times, type; |
| 14 | 52 | type = typeof elements; |
| 15 | 52 | if (elements === null || type === 'undefined' || type === 'number' || type === 'string' || type === 'function' || type === 'boolean') { |
| 16 | 16 | elements = [elements]; |
| 17 | 36 | } else if (!Array.isArray(elements)) { |
| 18 | 9 | isObject = true; |
| 19 | | } |
| 20 | 52 | if (isObject) { |
| 21 | 9 | keys = Object.keys(elements); |
| 22 | | } |
| 23 | 52 | errors = []; |
| 24 | 52 | parallel = 1; |
| 25 | 52 | events = { |
| 26 | | item: [], |
| 27 | | error: [], |
| 28 | | end: [], |
| 29 | | both: [] |
| 30 | | }; |
| 31 | 52 | times = []; |
| 32 | 52 | eacher = {}; |
| 33 | 52 | eacher.total = keys ? keys.length : elements.length; |
| 34 | 52 | eacher.started = 0; |
| 35 | 52 | eacher.done = 0; |
| 36 | 52 | times = 1; |
| 37 | 52 | eacher.paused = 0; |
| 38 | 52 | eacher.readable = true; |
| 39 | 52 | eacher.pause = function() { |
| 40 | 10 | return eacher.paused++; |
| 41 | | }; |
| 42 | 52 | eacher.resume = function() { |
| 43 | 10 | eacher.paused--; |
| 44 | 10 | return run(); |
| 45 | | }; |
| 46 | 52 | eacher.parallel = function(mode) { |
| 47 | 34 | if (typeof mode === 'number') { |
| 48 | 15 | parallel = mode; |
| 49 | 19 | } else if (mode) { |
| 50 | 16 | parallel = mode; |
| 51 | | } else { |
| 52 | 3 | parallel = 1; |
| 53 | | } |
| 54 | 34 | return eacher; |
| 55 | | }; |
| 56 | 52 | eacher.times = function(t) { |
| 57 | 6 | times = t; |
| 58 | 6 | return eacher; |
| 59 | | }; |
| 60 | 52 | eacher.on = function(ev, callback) { |
| 61 | 136 | events[ev].push(callback); |
| 62 | 136 | return eacher; |
| 63 | | }; |
| 64 | 52 | run = function() { |
| 65 | 16723 | var args, emit, emitError, index, lboth, lerror, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3; |
| 66 | 16723 | if (eacher.paused) { |
| 67 | 35 | return; |
| 68 | | } |
| 69 | 16688 | if (eacher.done === eacher.total * times || (errors.length && eacher.started === eacher.done)) { |
| 70 | 52 | eacher.readable = false; |
| 71 | 52 | if (errors.length) { |
| 72 | 10 | if (parallel !== 1) { |
| 73 | 6 | if (errors.length === 1) { |
| 74 | 3 | args = [errors[0], errors]; |
| 75 | | } else { |
| 76 | 3 | args = [new Error("Multiple errors (" + errors.length + ")"), errors]; |
| 77 | | } |
| 78 | | } else { |
| 79 | 4 | args = [errors[0]]; |
| 80 | | } |
| 81 | 10 | lerror = events.error.length; |
| 82 | 10 | lboth = events.both.length; |
| 83 | 10 | emitError = lerror || (!lerror && !lboth); |
| 84 | 10 | _ref = events.error; |
| 85 | 10 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
| 86 | 8 | emit = _ref[_i]; |
| 87 | 8 | if (emitError) { |
| 88 | 8 | emit.apply(null, args); |
| 89 | | } |
| 90 | | } |
| 91 | | } else { |
| 92 | 42 | args = []; |
| 93 | 42 | _ref1 = events.end; |
| 94 | 42 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
| 95 | 36 | emit = _ref1[_j]; |
| 96 | 36 | emit(); |
| 97 | | } |
| 98 | | } |
| 99 | 52 | _ref2 = events.both; |
| 100 | 52 | for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { |
| 101 | 13 | emit = _ref2[_k]; |
| 102 | 13 | emit.apply(null, args); |
| 103 | | } |
| 104 | 52 | return; |
| 105 | | } |
| 106 | 16636 | if (errors.length !== 0) { |
| 107 | 10 | return; |
| 108 | | } |
| 109 | 16626 | while ((parallel === true ? (eacher.total * times - eacher.started) > 0 : Math.min(parallel - eacher.started + eacher.done, eacher.total * times - eacher.started))) { |
| 110 | 16670 | if (errors.length !== 0) { |
| 111 | 9 | break; |
| 112 | | } |
| 113 | 16661 | index = Math.floor(eacher.started / times); |
| 114 | 16661 | eacher.started++; |
| 115 | 16661 | try { |
| 116 | 16661 | _ref3 = events.item; |
| 117 | 16661 | for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { |
| 118 | 16661 | emit = _ref3[_l]; |
| 119 | 16661 | switch (emit.length) { |
| 120 | | case 1: |
| 121 | 6 | args = [next]; |
| 122 | 6 | break; |
| 123 | | case 2: |
| 124 | 6 | if (keys) { |
| 125 | 3 | args = [elements[keys[index]], next]; |
| 126 | | } else { |
| 127 | 3 | args = [elements[index], next]; |
| 128 | | } |
| 129 | 6 | break; |
| 130 | | case 3: |
| 131 | 16644 | if (keys) { |
| 132 | 27 | args = [keys[index], elements[keys[index]], next]; |
| 133 | | } else { |
| 134 | 16617 | args = [elements[index], index, next]; |
| 135 | | } |
| 136 | 16644 | break; |
| 137 | | case 4: |
| 138 | 3 | if (keys) { |
| 139 | 3 | args = [keys[index], elements[keys[index]], index, next]; |
| 140 | | } else { |
| 141 | 0 | return next(new Error('Invalid arguments in item callback')); |
| 142 | | } |
| 143 | 3 | break; |
| 144 | | default: |
| 145 | 2 | return next(new Error('Invalid arguments in item callback')); |
| 146 | | } |
| 147 | 16659 | emit.apply(null, args); |
| 148 | | } |
| 149 | | } catch (e) { |
| 150 | 1 | if (eacher.readable) { |
| 151 | 1 | next(e); |
| 152 | | } |
| 153 | | } |
| 154 | | } |
| 155 | 16624 | return null; |
| 156 | | }; |
| 157 | 52 | next = function(err) { |
| 158 | 16661 | if ((err != null) && err instanceof Error) { |
| 159 | 13 | errors.push(err); |
| 160 | | } |
| 161 | 16661 | eacher.done++; |
| 162 | 16661 | return run(); |
| 163 | | }; |
| 164 | 52 | process.nextTick(run); |
| 165 | 52 | return eacher; |
| 166 | | }; |