{"version":3,"sources":["index.js","parallel.js","lib/iterate.js","lib/async.js","lib/defer.js","lib/abort.js","lib/state.js","lib/terminator.js","serial.js","serialOrdered.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;AACA,ACHA;ADIA,ACHA;ADIA,ACHA;ADIA,AENA,ADGA;ACFA,ADGA;ACFA,ADGA;AELA,ADGA,ADGA;AELA,ADGA,ADGA;AELA,ADGA,ADGA;AELA,ACHA,AFMA,ADGA;AELA,ACHA,AFMA,ADGA;AELA,ACHA,AFMA,ADGA;AIXA,AFMA,ACHA,AFMA,ADGA;AIXA,AFMA,ACHA,AFMA,ADGA;AIXA,AFMA,ACHA,AFMA,ADGA;AIXA,AFMA,ACHA,AFMA,AIZA,ALeA;AIXA,AFMA,ACHA,AFMA,AIZA,ALeA;AIXA,AFMA,ACHA,AFMA,AIZA,ALeA;AIXA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA;AIXA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA;AIXA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA;AIXA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA;AHUA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA;AHUA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA;AHUA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ACHA,AFMA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ADGA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ADGA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ADGA,AIZA,ACHA,ANkBA,AOrBA,ACHA;AJaA,AFMA,ADGA,AIZA,ACHA,ANkBA,AQxBA;AJaA,AFMA,ADGA,AIZA,ACHA,ANkBA,AQxBA;AJaA,AHSA,AIZA,ACHA,ANkBA,AQxBA;APsBA,AIZA,ACHA,ANkBA,AQxBA;APsBA,AIZA,ACHA,ANkBA,AQxBA;APsBA,AIZA,ACHA,AENA;APsBA,AIZA,ACHA,AENA;APsBA,AIZA,ACHA,AENA;APsBA,AIZA,ACHA,AENA;APsBA,AIZA,AGTA;APsBA,AIZA,AGTA;APsBA,AIZA,AGTA;APsBA,AIZA,AGTA;APsBA,AIZA,AGTA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;APsBA,AOrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":["module.exports =\n{\n parallel : require('./parallel.js'),\n serial : require('./serial.js'),\n serialOrdered : require('./serialOrdered.js')\n};\n","var iterate = require('./lib/iterate.js')\n , initState = require('./lib/state.js')\n , terminator = require('./lib/terminator.js')\n ;\n\n// Public API\nmodule.exports = parallel;\n\n/**\n * Runs iterator over provided array elements in parallel\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction parallel(list, iterator, callback)\n{\n var state = initState(list);\n\n while (state.index < (state['keyedList'] || list).length)\n {\n iterate(list, iterator, state, function(error, result)\n {\n if (error)\n {\n callback(error, result);\n return;\n }\n\n // looks like it's the last one\n if (Object.keys(state.jobs).length === 0)\n {\n callback(null, state.results);\n return;\n }\n });\n\n state.index++;\n }\n\n return terminator.bind(state, callback);\n}\n","var async = require('./async.js')\n , abort = require('./abort.js')\n ;\n\n// API\nmodule.exports = iterate;\n\n/**\n * Iterates over each job object\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {object} state - current job status\n * @param {function} callback - invoked when all elements processed\n */\nfunction iterate(list, iterator, state, callback)\n{\n // store current index\n var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;\n\n state.jobs[key] = runJob(iterator, key, list[key], function(error, output)\n {\n // don't repeat yourself\n // skip secondary callbacks\n if (!(key in state.jobs))\n {\n return;\n }\n\n // clean up jobs\n delete state.jobs[key];\n\n if (error)\n {\n // don't process rest of the results\n // stop still active jobs\n // and reset the list\n abort(state);\n }\n else\n {\n state.results[key] = output;\n }\n\n // return salvaged results\n callback(error, state.results);\n });\n}\n\n/**\n * Runs iterator over provided job element\n *\n * @param {function} iterator - iterator to invoke\n * @param {string|number} key - key/index of the element in the list of jobs\n * @param {mixed} item - job description\n * @param {function} callback - invoked after iterator is done with the job\n * @returns {function|mixed} - job abort function or something else\n */\nfunction runJob(iterator, key, item, callback)\n{\n var aborter;\n\n // allow shortcut if iterator expects only two arguments\n if (iterator.length == 2)\n {\n aborter = iterator(item, async(callback));\n }\n // otherwise go with full three arguments\n else\n {\n aborter = iterator(item, key, async(callback));\n }\n\n return aborter;\n}\n","var defer = require('./defer.js');\n\n// API\nmodule.exports = async;\n\n/**\n * Runs provided callback asynchronously\n * even if callback itself is not\n *\n * @param {function} callback - callback to invoke\n * @returns {function} - augmented callback\n */\nfunction async(callback)\n{\n var isAsync = false;\n\n // check if async happened\n defer(function() { isAsync = true; });\n\n return function async_callback(err, result)\n {\n if (isAsync)\n {\n callback(err, result);\n }\n else\n {\n defer(function nextTick_callback()\n {\n callback(err, result);\n });\n }\n };\n}\n","module.exports = defer;\n\n/**\n * Runs provided function on next iteration of the event loop\n *\n * @param {function} fn - function to run\n */\nfunction defer(fn)\n{\n var nextTick = typeof setImmediate == 'function'\n ? setImmediate\n : (\n typeof process == 'object' && typeof process.nextTick == 'function'\n ? process.nextTick\n : null\n );\n\n if (nextTick)\n {\n nextTick(fn);\n }\n else\n {\n setTimeout(fn, 0);\n }\n}\n","// API\nmodule.exports = abort;\n\n/**\n * Aborts leftover active jobs\n *\n * @param {object} state - current state object\n */\nfunction abort(state)\n{\n Object.keys(state.jobs).forEach(clean.bind(state));\n\n // reset leftover jobs\n state.jobs = {};\n}\n\n/**\n * Cleans up leftover job by invoking abort function for the provided job id\n *\n * @this state\n * @param {string|number} key - job id to abort\n */\nfunction clean(key)\n{\n if (typeof this.jobs[key] == 'function')\n {\n this.jobs[key]();\n }\n}\n","// API\nmodule.exports = state;\n\n/**\n * Creates initial state object\n * for iteration over list\n *\n * @param {array|object} list - list to iterate over\n * @param {function|null} sortMethod - function to use for keys sort,\n * or `null` to keep them as is\n * @returns {object} - initial state object\n */\nfunction state(list, sortMethod)\n{\n var isNamedList = !Array.isArray(list)\n , initState =\n {\n index : 0,\n keyedList: isNamedList || sortMethod ? Object.keys(list) : null,\n jobs : {},\n results : isNamedList ? {} : [],\n size : isNamedList ? Object.keys(list).length : list.length\n }\n ;\n\n if (sortMethod)\n {\n // sort array keys based on it's values\n // sort object's keys just on own merit\n initState.keyedList.sort(isNamedList ? sortMethod : function(a, b)\n {\n return sortMethod(list[a], list[b]);\n });\n }\n\n return initState;\n}\n","var abort = require('./abort.js')\n , async = require('./async.js')\n ;\n\n// API\nmodule.exports = terminator;\n\n/**\n * Terminates jobs in the attached state context\n *\n * @this AsyncKitState#\n * @param {function} callback - final callback to invoke after termination\n */\nfunction terminator(callback)\n{\n if (!Object.keys(this.jobs).length)\n {\n return;\n }\n\n // fast forward iteration index\n this.index = this.size;\n\n // abort jobs\n abort(this);\n\n // send back results we have so far\n async(callback)(null, this.results);\n}\n","var serialOrdered = require('./serialOrdered.js');\n\n// Public API\nmodule.exports = serial;\n\n/**\n * Runs iterator over provided array elements in series\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction serial(list, iterator, callback)\n{\n return serialOrdered(list, iterator, null, callback);\n}\n","var iterate = require('./lib/iterate.js')\n , initState = require('./lib/state.js')\n , terminator = require('./lib/terminator.js')\n ;\n\n// Public API\nmodule.exports = serialOrdered;\n// sorting helpers\nmodule.exports.ascending = ascending;\nmodule.exports.descending = descending;\n\n/**\n * Runs iterator over provided sorted array elements in series\n *\n * @param {array|object} list - array or object (named list) to iterate over\n * @param {function} iterator - iterator to run\n * @param {function} sortMethod - custom sort function\n * @param {function} callback - invoked when all elements processed\n * @returns {function} - jobs terminator\n */\nfunction serialOrdered(list, iterator, sortMethod, callback)\n{\n var state = initState(list, sortMethod);\n\n iterate(list, iterator, state, function iteratorHandler(error, result)\n {\n if (error)\n {\n callback(error, result);\n return;\n }\n\n state.index++;\n\n // are we there yet?\n if (state.index < (state['keyedList'] || list).length)\n {\n iterate(list, iterator, state, iteratorHandler);\n return;\n }\n\n // done here\n callback(null, state.results);\n });\n\n return terminator.bind(state, callback);\n}\n\n/*\n * -- Sort methods\n */\n\n/**\n * sort helper to sort array elements in ascending order\n *\n * @param {mixed} a - an item to compare\n * @param {mixed} b - an item to compare\n * @returns {number} - comparison result\n */\nfunction ascending(a, b)\n{\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/**\n * sort helper to sort array elements in descending order\n *\n * @param {mixed} a - an item to compare\n * @param {mixed} b - an item to compare\n * @returns {number} - comparison result\n */\nfunction descending(a, b)\n{\n return -1 * ascending(a, b);\n}\n"]}