diff options
Diffstat (limited to 'node_modules/asynckit')
| -rw-r--r-- | node_modules/asynckit/LICENSE | 21 | ||||
| -rw-r--r-- | node_modules/asynckit/README.md | 233 | ||||
| -rw-r--r-- | node_modules/asynckit/bench.js | 76 | ||||
| -rw-r--r-- | node_modules/asynckit/index.js | 6 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/abort.js | 29 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/async.js | 34 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/defer.js | 26 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/iterate.js | 75 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/readable_asynckit.js | 91 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/readable_parallel.js | 25 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/readable_serial.js | 25 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/readable_serial_ordered.js | 29 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/state.js | 37 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/streamify.js | 141 | ||||
| -rw-r--r-- | node_modules/asynckit/lib/terminator.js | 29 | ||||
| -rw-r--r-- | node_modules/asynckit/package.json | 63 | ||||
| -rw-r--r-- | node_modules/asynckit/parallel.js | 43 | ||||
| -rw-r--r-- | node_modules/asynckit/serial.js | 17 | ||||
| -rw-r--r-- | node_modules/asynckit/serialOrdered.js | 75 | ||||
| -rw-r--r-- | node_modules/asynckit/stream.js | 21 | 
20 files changed, 1096 insertions, 0 deletions
diff --git a/node_modules/asynckit/LICENSE b/node_modules/asynckit/LICENSE new file mode 100644 index 0000000..c9eca5d --- /dev/null +++ b/node_modules/asynckit/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Alex Indigo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/asynckit/README.md b/node_modules/asynckit/README.md new file mode 100644 index 0000000..ddcc7e6 --- /dev/null +++ b/node_modules/asynckit/README.md @@ -0,0 +1,233 @@ +# asynckit [](https://www.npmjs.com/package/asynckit) + +Minimal async jobs utility library, with streams support. + +[](https://travis-ci.org/alexindigo/asynckit) +[](https://travis-ci.org/alexindigo/asynckit) +[](https://ci.appveyor.com/project/alexindigo/asynckit) + +[](https://coveralls.io/github/alexindigo/asynckit?branch=master) +[](https://david-dm.org/alexindigo/asynckit) +[](https://www.bithound.io/github/alexindigo/asynckit) + +<!-- [](https://www.npmjs.com/package/reamde) --> + +AsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects. +Optionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method. + +It ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators. + +| compression        |     size | +| :----------------- | -------: | +| asynckit.js        | 12.34 kB | +| asynckit.min.js    |  4.11 kB | +| asynckit.min.js.gz |  1.47 kB | + + +## Install + +```sh +$ npm install --save asynckit +``` + +## Examples + +### Parallel Jobs + +Runs iterator over provided array in parallel. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will terminate rest of the active jobs (if abort function is provided) +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var parallel = require('asynckit').parallel +  , assert   = require('assert') +  ; + +var source         = [ 1, 1, 4, 16, 64, 32, 8, 2 ] +  , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] +  , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] +  , target         = [] +  ; + +parallel(source, asyncJob, function(err, result) +{ +  assert.deepEqual(result, expectedResult); +  assert.deepEqual(target, expectedTarget); +}); + +// async job accepts one element from the array +// and a callback function +function asyncJob(item, cb) +{ +  // different delays (in ms) per item +  var delay = item * 25; + +  // pretend different jobs take different time to finish +  // and not in consequential order +  var timeoutId = setTimeout(function() { +    target.push(item); +    cb(null, item * 2); +  }, delay); + +  // allow to cancel "leftover" jobs upon error +  // return function, invoking of which will abort this job +  return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var parallel = require('asynckit/parallel') +  , assert   = require('assert') +  ; + +var source         = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } +  , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } +  , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] +  , expectedKeys   = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ] +  , target         = [] +  , keys           = [] +  ; + +parallel(source, asyncJob, function(err, result) +{ +  assert.deepEqual(result, expectedResult); +  assert.deepEqual(target, expectedTarget); +  assert.deepEqual(keys, expectedKeys); +}); + +// supports full value, key, callback (shortcut) interface +function asyncJob(item, key, cb) +{ +  // different delays (in ms) per item +  var delay = item * 25; + +  // pretend different jobs take different time to finish +  // and not in consequential order +  var timeoutId = setTimeout(function() { +    keys.push(key); +    target.push(item); +    cb(null, item * 2); +  }, delay); + +  // allow to cancel "leftover" jobs upon error +  // return function, invoking of which will abort this job +  return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js). + +### Serial Jobs + +Runs iterator over provided array sequentially. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will not proceed to the rest of the items in the list +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var serial = require('asynckit/serial') +  , assert = require('assert') +  ; + +var source         = [ 1, 1, 4, 16, 64, 32, 8, 2 ] +  , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] +  , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] +  , target         = [] +  ; + +serial(source, asyncJob, function(err, result) +{ +  assert.deepEqual(result, expectedResult); +  assert.deepEqual(target, expectedTarget); +}); + +// extended interface (item, key, callback) +// also supported for arrays +function asyncJob(item, key, cb) +{ +  target.push(key); + +  // it will be automatically made async +  // even it iterator "returns" in the same event loop +  cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-array.js](test/test-serial-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var serial = require('asynckit').serial +  , assert = require('assert') +  ; + +var source         = [ 1, 1, 4, 16, 64, 32, 8, 2 ] +  , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] +  , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] +  , target         = [] +  ; + +var source         = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } +  , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } +  , expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ] +  , target         = [] +  ; + + +serial(source, asyncJob, function(err, result) +{ +  assert.deepEqual(result, expectedResult); +  assert.deepEqual(target, expectedTarget); +}); + +// shortcut interface (item, callback) +// works for object as well as for the arrays +function asyncJob(item, cb) +{ +  target.push(item); + +  // it will be automatically made async +  // even it iterator "returns" in the same event loop +  cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-object.js](test/test-serial-object.js). + +_Note: Since _object_ is an _unordered_ collection of properties, +it may produce unexpected results with sequential iterations. +Whenever order of the jobs' execution is important please use `serialOrdered` method._ + +### Ordered Serial Iterations + +TBD + +For example [compare-property](compare-property) package. + +### Streaming interface + +TBD + +## Want to Know More? + +More examples can be found in [test folder](test/). + +Or open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions. + +## License + +AsyncKit is licensed under the MIT license. diff --git a/node_modules/asynckit/bench.js b/node_modules/asynckit/bench.js new file mode 100644 index 0000000..c612f1a --- /dev/null +++ b/node_modules/asynckit/bench.js @@ -0,0 +1,76 @@ +/* eslint no-console: "off" */ + +var asynckit = require('./') +  , async    = require('async') +  , assert   = require('assert') +  , expected = 0 +  ; + +var Benchmark = require('benchmark'); +var suite = new Benchmark.Suite; + +var source = []; +for (var z = 1; z < 100; z++) +{ +  source.push(z); +  expected += z; +} + +suite +// add tests + +.add('async.map', function(deferred) +{ +  var total = 0; + +  async.map(source, +  function(i, cb) +  { +    setImmediate(function() +    { +      total += i; +      cb(null, total); +    }); +  }, +  function(err, result) +  { +    assert.ifError(err); +    assert.equal(result[result.length - 1], expected); +    deferred.resolve(); +  }); +}, {'defer': true}) + + +.add('asynckit.parallel', function(deferred) +{ +  var total = 0; + +  asynckit.parallel(source, +  function(i, cb) +  { +    setImmediate(function() +    { +      total += i; +      cb(null, total); +    }); +  }, +  function(err, result) +  { +    assert.ifError(err); +    assert.equal(result[result.length - 1], expected); +    deferred.resolve(); +  }); +}, {'defer': true}) + + +// add listeners +.on('cycle', function(ev) +{ +  console.log(String(ev.target)); +}) +.on('complete', function() +{ +  console.log('Fastest is ' + this.filter('fastest').map('name')); +}) +// run async +.run({ 'async': true }); diff --git a/node_modules/asynckit/index.js b/node_modules/asynckit/index.js new file mode 100644 index 0000000..455f945 --- /dev/null +++ b/node_modules/asynckit/index.js @@ -0,0 +1,6 @@ +module.exports = +{ +  parallel      : require('./parallel.js'), +  serial        : require('./serial.js'), +  serialOrdered : require('./serialOrdered.js') +}; diff --git a/node_modules/asynckit/lib/abort.js b/node_modules/asynckit/lib/abort.js new file mode 100644 index 0000000..114367e --- /dev/null +++ b/node_modules/asynckit/lib/abort.js @@ -0,0 +1,29 @@ +// API +module.exports = abort; + +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ +  Object.keys(state.jobs).forEach(clean.bind(state)); + +  // reset leftover jobs +  state.jobs = {}; +} + +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this  state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ +  if (typeof this.jobs[key] == 'function') +  { +    this.jobs[key](); +  } +} diff --git a/node_modules/asynckit/lib/async.js b/node_modules/asynckit/lib/async.js new file mode 100644 index 0000000..7f1288a --- /dev/null +++ b/node_modules/asynckit/lib/async.js @@ -0,0 +1,34 @@ +var defer = require('./defer.js'); + +// API +module.exports = async; + +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param   {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ +  var isAsync = false; + +  // check if async happened +  defer(function() { isAsync = true; }); + +  return function async_callback(err, result) +  { +    if (isAsync) +    { +      callback(err, result); +    } +    else +    { +      defer(function nextTick_callback() +      { +        callback(err, result); +      }); +    } +  }; +} diff --git a/node_modules/asynckit/lib/defer.js b/node_modules/asynckit/lib/defer.js new file mode 100644 index 0000000..b67110c --- /dev/null +++ b/node_modules/asynckit/lib/defer.js @@ -0,0 +1,26 @@ +module.exports = defer; + +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ +  var nextTick = typeof setImmediate == 'function' +    ? setImmediate +    : ( +      typeof process == 'object' && typeof process.nextTick == 'function' +      ? process.nextTick +      : null +    ); + +  if (nextTick) +  { +    nextTick(fn); +  } +  else +  { +    setTimeout(fn, 0); +  } +} diff --git a/node_modules/asynckit/lib/iterate.js b/node_modules/asynckit/lib/iterate.js new file mode 100644 index 0000000..5d2839a --- /dev/null +++ b/node_modules/asynckit/lib/iterate.js @@ -0,0 +1,75 @@ +var async = require('./async.js') +  , abort = require('./abort.js') +  ; + +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ +  // store current index +  var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + +  state.jobs[key] = runJob(iterator, key, list[key], function(error, output) +  { +    // don't repeat yourself +    // skip secondary callbacks +    if (!(key in state.jobs)) +    { +      return; +    } + +    // clean up jobs +    delete state.jobs[key]; + +    if (error) +    { +      // don't process rest of the results +      // stop still active jobs +      // and reset the list +      abort(state); +    } +    else +    { +      state.results[key] = output; +    } + +    // return salvaged results +    callback(error, state.results); +  }); +} + +/** + * Runs iterator over provided job element + * + * @param   {function} iterator - iterator to invoke + * @param   {string|number} key - key/index of the element in the list of jobs + * @param   {mixed} item - job description + * @param   {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ +  var aborter; + +  // allow shortcut if iterator expects only two arguments +  if (iterator.length == 2) +  { +    aborter = iterator(item, async(callback)); +  } +  // otherwise go with full three arguments +  else +  { +    aborter = iterator(item, key, async(callback)); +  } + +  return aborter; +} diff --git a/node_modules/asynckit/lib/readable_asynckit.js b/node_modules/asynckit/lib/readable_asynckit.js new file mode 100644 index 0000000..78ad240 --- /dev/null +++ b/node_modules/asynckit/lib/readable_asynckit.js @@ -0,0 +1,91 @@ +var streamify = require('./streamify.js') +  , defer     = require('./defer.js') +  ; + +// API +module.exports = ReadableAsyncKit; + +/** + * Base constructor for all streams + * used to hold properties/methods + */ +function ReadableAsyncKit() +{ +  ReadableAsyncKit.super_.apply(this, arguments); + +  // list of active jobs +  this.jobs = {}; + +  // add stream methods +  this.destroy = destroy; +  this._start  = _start; +  this._read   = _read; +} + +/** + * Destroys readable stream, + * by aborting outstanding jobs + * + * @returns {void} + */ +function destroy() +{ +  if (this.destroyed) +  { +    return; +  } + +  this.destroyed = true; + +  if (typeof this.terminator == 'function') +  { +    this.terminator(); +  } +} + +/** + * Starts provided jobs in async manner + * + * @private + */ +function _start() +{ +  // first argument – runner function +  var runner = arguments[0] +    // take away first argument +    , args   = Array.prototype.slice.call(arguments, 1) +      // second argument - input data +    , input  = args[0] +      // last argument - result callback +    , endCb  = streamify.callback.call(this, args[args.length - 1]) +    ; + +  args[args.length - 1] = endCb; +  // third argument - iterator +  args[1] = streamify.iterator.call(this, args[1]); + +  // allow time for proper setup +  defer(function() +  { +    if (!this.destroyed) +    { +      this.terminator = runner.apply(null, args); +    } +    else +    { +      endCb(null, Array.isArray(input) ? [] : {}); +    } +  }.bind(this)); +} + + +/** + * Implement _read to comply with Readable streams + * Doesn't really make sense for flowing object mode + * + * @private + */ +function _read() +{ + +} diff --git a/node_modules/asynckit/lib/readable_parallel.js b/node_modules/asynckit/lib/readable_parallel.js new file mode 100644 index 0000000..5d2929f --- /dev/null +++ b/node_modules/asynckit/lib/readable_parallel.js @@ -0,0 +1,25 @@ +var parallel = require('../parallel.js'); + +// API +module.exports = ReadableParallel; + +/** + * Streaming wrapper to `asynckit.parallel` + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableParallel(list, iterator, callback) +{ +  if (!(this instanceof ReadableParallel)) +  { +    return new ReadableParallel(list, iterator, callback); +  } + +  // turn on object mode +  ReadableParallel.super_.call(this, {objectMode: true}); + +  this._start(parallel, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial.js b/node_modules/asynckit/lib/readable_serial.js new file mode 100644 index 0000000..7822698 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial.js @@ -0,0 +1,25 @@ +var serial = require('../serial.js'); + +// API +module.exports = ReadableSerial; + +/** + * Streaming wrapper to `asynckit.serial` + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerial(list, iterator, callback) +{ +  if (!(this instanceof ReadableSerial)) +  { +    return new ReadableSerial(list, iterator, callback); +  } + +  // turn on object mode +  ReadableSerial.super_.call(this, {objectMode: true}); + +  this._start(serial, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial_ordered.js b/node_modules/asynckit/lib/readable_serial_ordered.js new file mode 100644 index 0000000..3de89c4 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial_ordered.js @@ -0,0 +1,29 @@ +var serialOrdered = require('../serialOrdered.js'); + +// API +module.exports = ReadableSerialOrdered; +// expose sort helpers +module.exports.ascending  = serialOrdered.ascending; +module.exports.descending = serialOrdered.descending; + +/** + * Streaming wrapper to `asynckit.serialOrdered` + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} sortMethod - custom sort function + * @param   {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerialOrdered(list, iterator, sortMethod, callback) +{ +  if (!(this instanceof ReadableSerialOrdered)) +  { +    return new ReadableSerialOrdered(list, iterator, sortMethod, callback); +  } + +  // turn on object mode +  ReadableSerialOrdered.super_.call(this, {objectMode: true}); + +  this._start(serialOrdered, list, iterator, sortMethod, callback); +} diff --git a/node_modules/asynckit/lib/state.js b/node_modules/asynckit/lib/state.js new file mode 100644 index 0000000..cbea7ad --- /dev/null +++ b/node_modules/asynckit/lib/state.js @@ -0,0 +1,37 @@ +// API +module.exports = state; + +/** + * Creates initial state object + * for iteration over list + * + * @param   {array|object} list - list to iterate over + * @param   {function|null} sortMethod - function to use for keys sort, + *                                     or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ +  var isNamedList = !Array.isArray(list) +    , initState = +    { +      index    : 0, +      keyedList: isNamedList || sortMethod ? Object.keys(list) : null, +      jobs     : {}, +      results  : isNamedList ? {} : [], +      size     : isNamedList ? Object.keys(list).length : list.length +    } +    ; + +  if (sortMethod) +  { +    // sort array keys based on it's values +    // sort object's keys just on own merit +    initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) +    { +      return sortMethod(list[a], list[b]); +    }); +  } + +  return initState; +} diff --git a/node_modules/asynckit/lib/streamify.js b/node_modules/asynckit/lib/streamify.js new file mode 100644 index 0000000..f56a1c9 --- /dev/null +++ b/node_modules/asynckit/lib/streamify.js @@ -0,0 +1,141 @@ +var async = require('./async.js'); + +// API +module.exports = { +  iterator: wrapIterator, +  callback: wrapCallback +}; + +/** + * Wraps iterators with long signature + * + * @this    ReadableAsyncKit# + * @param   {function} iterator - function to wrap + * @returns {function} - wrapped function + */ +function wrapIterator(iterator) +{ +  var stream = this; + +  return function(item, key, cb) +  { +    var aborter +      , wrappedCb = async(wrapIteratorCallback.call(stream, cb, key)) +      ; + +    stream.jobs[key] = wrappedCb; + +    // it's either shortcut (item, cb) +    if (iterator.length == 2) +    { +      aborter = iterator(item, wrappedCb); +    } +    // or long format (item, key, cb) +    else +    { +      aborter = iterator(item, key, wrappedCb); +    } + +    return aborter; +  }; +} + +/** + * Wraps provided callback function + * allowing to execute snitch function before + * real callback + * + * @this    ReadableAsyncKit# + * @param   {function} callback - function to wrap + * @returns {function} - wrapped function + */ +function wrapCallback(callback) +{ +  var stream = this; + +  var wrapped = function(error, result) +  { +    return finisher.call(stream, error, result, callback); +  }; + +  return wrapped; +} + +/** + * Wraps provided iterator callback function + * makes sure snitch only called once, + * but passes secondary calls to the original callback + * + * @this    ReadableAsyncKit# + * @param   {function} callback - callback to wrap + * @param   {number|string} key - iteration key + * @returns {function} wrapped callback + */ +function wrapIteratorCallback(callback, key) +{ +  var stream = this; + +  return function(error, output) +  { +    // don't repeat yourself +    if (!(key in stream.jobs)) +    { +      callback(error, output); +      return; +    } + +    // clean up jobs +    delete stream.jobs[key]; + +    return streamer.call(stream, error, {key: key, value: output}, callback); +  }; +} + +/** + * Stream wrapper for iterator callback + * + * @this  ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects iterator results + */ +function streamer(error, output, callback) +{ +  if (error && !this.error) +  { +    this.error = error; +    this.pause(); +    this.emit('error', error); +    // send back value only, as expected +    callback(error, output && output.value); +    return; +  } + +  // stream stuff +  this.push(output); + +  // back to original track +  // send back value only, as expected +  callback(error, output && output.value); +} + +/** + * Stream wrapper for finishing callback + * + * @this  ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects final results + */ +function finisher(error, output, callback) +{ +  // signal end of the stream +  // only for successfully finished streams +  if (!error) +  { +    this.push(null); +  } + +  // back to original track +  callback(error, output); +} diff --git a/node_modules/asynckit/lib/terminator.js b/node_modules/asynckit/lib/terminator.js new file mode 100644 index 0000000..d6eb992 --- /dev/null +++ b/node_modules/asynckit/lib/terminator.js @@ -0,0 +1,29 @@ +var abort = require('./abort.js') +  , async = require('./async.js') +  ; + +// API +module.exports = terminator; + +/** + * Terminates jobs in the attached state context + * + * @this  AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ +  if (!Object.keys(this.jobs).length) +  { +    return; +  } + +  // fast forward iteration index +  this.index = this.size; + +  // abort jobs +  abort(this); + +  // send back results we have so far +  async(callback)(null, this.results); +} diff --git a/node_modules/asynckit/package.json b/node_modules/asynckit/package.json new file mode 100644 index 0000000..51147d6 --- /dev/null +++ b/node_modules/asynckit/package.json @@ -0,0 +1,63 @@ +{ +  "name": "asynckit", +  "version": "0.4.0", +  "description": "Minimal async jobs utility library, with streams support", +  "main": "index.js", +  "scripts": { +    "clean": "rimraf coverage", +    "lint": "eslint *.js lib/*.js test/*.js", +    "test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec", +    "win-test": "tape test/test-*.js", +    "browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec", +    "report": "istanbul report", +    "size": "browserify index.js | size-table asynckit", +    "debug": "tape test/test-*.js" +  }, +  "pre-commit": [ +    "clean", +    "lint", +    "test", +    "browser", +    "report", +    "size" +  ], +  "repository": { +    "type": "git", +    "url": "git+https://github.com/alexindigo/asynckit.git" +  }, +  "keywords": [ +    "async", +    "jobs", +    "parallel", +    "serial", +    "iterator", +    "array", +    "object", +    "stream", +    "destroy", +    "terminate", +    "abort" +  ], +  "author": "Alex Indigo <iam@alexindigo.com>", +  "license": "MIT", +  "bugs": { +    "url": "https://github.com/alexindigo/asynckit/issues" +  }, +  "homepage": "https://github.com/alexindigo/asynckit#readme", +  "devDependencies": { +    "browserify": "^13.0.0", +    "browserify-istanbul": "^2.0.0", +    "coveralls": "^2.11.9", +    "eslint": "^2.9.0", +    "istanbul": "^0.4.3", +    "obake": "^0.1.2", +    "phantomjs-prebuilt": "^2.1.7", +    "pre-commit": "^1.1.3", +    "reamde": "^1.1.0", +    "rimraf": "^2.5.2", +    "size-table": "^0.2.0", +    "tap-spec": "^4.1.1", +    "tape": "^4.5.1" +  }, +  "dependencies": {} +} diff --git a/node_modules/asynckit/parallel.js b/node_modules/asynckit/parallel.js new file mode 100644 index 0000000..3c50344 --- /dev/null +++ b/node_modules/asynckit/parallel.js @@ -0,0 +1,43 @@ +var iterate    = require('./lib/iterate.js') +  , initState  = require('./lib/state.js') +  , terminator = require('./lib/terminator.js') +  ; + +// Public API +module.exports = parallel; + +/** + * Runs iterator over provided array elements in parallel + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ +  var state = initState(list); + +  while (state.index < (state['keyedList'] || list).length) +  { +    iterate(list, iterator, state, function(error, result) +    { +      if (error) +      { +        callback(error, result); +        return; +      } + +      // looks like it's the last one +      if (Object.keys(state.jobs).length === 0) +      { +        callback(null, state.results); +        return; +      } +    }); + +    state.index++; +  } + +  return terminator.bind(state, callback); +} diff --git a/node_modules/asynckit/serial.js b/node_modules/asynckit/serial.js new file mode 100644 index 0000000..6cd949a --- /dev/null +++ b/node_modules/asynckit/serial.js @@ -0,0 +1,17 @@ +var serialOrdered = require('./serialOrdered.js'); + +// Public API +module.exports = serial; + +/** + * Runs iterator over provided array elements in series + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ +  return serialOrdered(list, iterator, null, callback); +} diff --git a/node_modules/asynckit/serialOrdered.js b/node_modules/asynckit/serialOrdered.js new file mode 100644 index 0000000..607eafe --- /dev/null +++ b/node_modules/asynckit/serialOrdered.js @@ -0,0 +1,75 @@ +var iterate    = require('./lib/iterate.js') +  , initState  = require('./lib/state.js') +  , terminator = require('./lib/terminator.js') +  ; + +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending  = ascending; +module.exports.descending = descending; + +/** + * Runs iterator over provided sorted array elements in series + * + * @param   {array|object} list - array or object (named list) to iterate over + * @param   {function} iterator - iterator to run + * @param   {function} sortMethod - custom sort function + * @param   {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ +  var state = initState(list, sortMethod); + +  iterate(list, iterator, state, function iteratorHandler(error, result) +  { +    if (error) +    { +      callback(error, result); +      return; +    } + +    state.index++; + +    // are we there yet? +    if (state.index < (state['keyedList'] || list).length) +    { +      iterate(list, iterator, state, iteratorHandler); +      return; +    } + +    // done here +    callback(null, state.results); +  }); + +  return terminator.bind(state, callback); +} + +/* + * -- Sort methods + */ + +/** + * sort helper to sort array elements in ascending order + * + * @param   {mixed} a - an item to compare + * @param   {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ +  return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param   {mixed} a - an item to compare + * @param   {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ +  return -1 * ascending(a, b); +} diff --git a/node_modules/asynckit/stream.js b/node_modules/asynckit/stream.js new file mode 100644 index 0000000..d43465f --- /dev/null +++ b/node_modules/asynckit/stream.js @@ -0,0 +1,21 @@ +var inherits              = require('util').inherits +  , Readable              = require('stream').Readable +  , ReadableAsyncKit      = require('./lib/readable_asynckit.js') +  , ReadableParallel      = require('./lib/readable_parallel.js') +  , ReadableSerial        = require('./lib/readable_serial.js') +  , ReadableSerialOrdered = require('./lib/readable_serial_ordered.js') +  ; + +// API +module.exports = +{ +  parallel      : ReadableParallel, +  serial        : ReadableSerial, +  serialOrdered : ReadableSerialOrdered,  +}; + +inherits(ReadableAsyncKit, Readable); + +inherits(ReadableParallel, ReadableAsyncKit); +inherits(ReadableSerial, ReadableAsyncKit); +inherits(ReadableSerialOrdered, ReadableAsyncKit);  | 
