--- /dev/null
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = queue;
+
+var _baseIndexOf = require('lodash/_baseIndexOf');
+
+var _baseIndexOf2 = _interopRequireDefault(_baseIndexOf);
+
+var _isArray = require('lodash/isArray');
+
+var _isArray2 = _interopRequireDefault(_isArray);
+
+var _noop = require('lodash/noop');
+
+var _noop2 = _interopRequireDefault(_noop);
+
+var _rest = require('./rest');
+
+var _rest2 = _interopRequireDefault(_rest);
+
+var _onlyOnce = require('./onlyOnce');
+
+var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
+
+var _setImmediate = require('./setImmediate');
+
+var _setImmediate2 = _interopRequireDefault(_setImmediate);
+
+var _DoublyLinkedList = require('./DoublyLinkedList');
+
+var _DoublyLinkedList2 = _interopRequireDefault(_DoublyLinkedList);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function queue(worker, concurrency, payload) {
+ if (concurrency == null) {
+ concurrency = 1;
+ } else if (concurrency === 0) {
+ throw new Error('Concurrency must not be zero');
+ }
+
+ function _insert(data, insertAtFront, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!(0, _isArray2.default)(data)) {
+ data = [data];
+ }
+ if (data.length === 0 && q.idle()) {
+ // call drain immediately if there are no tasks
+ return (0, _setImmediate2.default)(function () {
+ q.drain();
+ });
+ }
+
+ for (var i = 0, l = data.length; i < l; i++) {
+ var item = {
+ data: data[i],
+ callback: callback || _noop2.default
+ };
+
+ if (insertAtFront) {
+ q._tasks.unshift(item);
+ } else {
+ q._tasks.push(item);
+ }
+ }
+ (0, _setImmediate2.default)(q.process);
+ }
+
+ function _next(tasks) {
+ return (0, _rest2.default)(function (args) {
+ workers -= 1;
+
+ for (var i = 0, l = tasks.length; i < l; i++) {
+ var task = tasks[i];
+ var index = (0, _baseIndexOf2.default)(workersList, task, 0);
+ if (index >= 0) {
+ workersList.splice(index);
+ }
+
+ task.callback.apply(task, args);
+
+ if (args[0] != null) {
+ q.error(args[0], task.data);
+ }
+ }
+
+ if (workers <= q.concurrency - q.buffer) {
+ q.unsaturated();
+ }
+
+ if (q.idle()) {
+ q.drain();
+ }
+ q.process();
+ });
+ }
+
+ var workers = 0;
+ var workersList = [];
+ var isProcessing = false;
+ var q = {
+ _tasks: new _DoublyLinkedList2.default(),
+ concurrency: concurrency,
+ payload: payload,
+ saturated: _noop2.default,
+ unsaturated: _noop2.default,
+ buffer: concurrency / 4,
+ empty: _noop2.default,
+ drain: _noop2.default,
+ error: _noop2.default,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(data, false, callback);
+ },
+ kill: function () {
+ q.drain = _noop2.default;
+ q._tasks.empty();
+ },
+ unshift: function (data, callback) {
+ _insert(data, true, callback);
+ },
+ process: function () {
+ // Avoid trying to start too many processing operations. This can occur
+ // when callbacks resolve synchronously (#1267).
+ if (isProcessing) {
+ return;
+ }
+ isProcessing = true;
+ while (!q.paused && workers < q.concurrency && q._tasks.length) {
+ var tasks = [],
+ data = [];
+ var l = q._tasks.length;
+ if (q.payload) l = Math.min(l, q.payload);
+ for (var i = 0; i < l; i++) {
+ var node = q._tasks.shift();
+ tasks.push(node);
+ data.push(node.data);
+ }
+
+ if (q._tasks.length === 0) {
+ q.empty();
+ }
+ workers += 1;
+ workersList.push(tasks[0]);
+
+ if (workers === q.concurrency) {
+ q.saturated();
+ }
+
+ var cb = (0, _onlyOnce2.default)(_next(tasks));
+ worker(data, cb);
+ }
+ isProcessing = false;
+ },
+ length: function () {
+ return q._tasks.length;
+ },
+ running: function () {
+ return workers;
+ },
+ workersList: function () {
+ return workersList;
+ },
+ idle: function () {
+ return q._tasks.length + workers === 0;
+ },
+ pause: function () {
+ q.paused = true;
+ },
+ resume: function () {
+ if (q.paused === false) {
+ return;
+ }
+ q.paused = false;
+ (0, _setImmediate2.default)(q.process);
+ }
+ };
+ return q;
+}
+module.exports = exports['default'];
\ No newline at end of file