stack-base-iterator
Version:
Base iterator for values retrieved using a stack of async functions returning values
215 lines • 8.33 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: Object.getOwnPropertyDescriptor(all, name).get
});
}
_export(exports, {
get LinkedList () {
return _LinkedListts.default;
},
get default () {
return StackBaseIterator;
}
});
var _asynccompat = /*#__PURE__*/ _interop_require_default(require("async-compat"));
var _iteratornextcallback = /*#__PURE__*/ _interop_require_default(require("iterator-next-callback"));
var _maximizeiterator = require("maximize-iterator");
var _pinkiepromise = /*#__PURE__*/ _interop_require_default(require("pinkie-promise"));
var _LinkedListts = /*#__PURE__*/ _interop_require_default(require("./LinkedList.js"));
function _class_call_check(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
// biome-ignore lint/suspicious/noShadowRestrictedNames: Legacy
var Symbol = typeof global.Symbol === 'undefined' ? {
asyncIterator: '@@'
} : global.Symbol;
var StackBaseIterator = /*#__PURE__*/ function() {
"use strict";
function StackBaseIterator() {
var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
_class_call_check(this, StackBaseIterator);
this.options = _object_spread({}, options);
this.options.error = options.error || function defaultError(err) {
return !!err; // fail on errors
};
this.done = false;
this.stack = [];
this.queued = [];
this.processors = new _LinkedListts.default();
this.processing = new _LinkedListts.default();
}
var _proto = StackBaseIterator.prototype;
_proto.isDone = function isDone() {
return this.done;
};
_proto.push = function push(fn) {
var _this = this;
for(var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
rest[_key - 1] = arguments[_key];
}
if (this.done) return console.log('Attempting to push on a done iterator');
this.stack.push(fn);
!rest.length || rest.forEach(function(x) {
return _this.stack.push(x);
});
this._pump();
};
_proto.next = function next() {
var _this = this;
return new _pinkiepromise.default(function(resolve, reject) {
_this._processOrQueue(function(err, result) {
err ? reject(err) : resolve(result);
});
});
};
_proto[Symbol.asyncIterator] = function() {
return this;
};
_proto.forEach = function forEach(fn, options, callback) {
var _this = this;
if (typeof fn !== 'function') throw new Error('Missing each function');
if (typeof options === 'function') {
callback = options;
options = {};
}
if (typeof callback === 'function') {
if (this.done) {
callback(null, true);
return;
}
options = options || {};
var processorOptions = {
each: fn,
callbacks: options.callbacks || false,
concurrency: options.concurrency || 1,
limit: options.limit || Infinity,
error: options.error || function defaultError() {
return true; // default is exit on error
},
total: 0,
counter: 0,
canProcess: function() {
return !_this.done && _this.stack.length > 0 && _this.queued.length < _this.stack.length;
}
};
var processor = (0, _maximizeiterator.createProcessor)((0, _iteratornextcallback.default)(this), processorOptions, function(err) {
if (!_this.destroyed) _this.processors.remove(processor);
processor = null;
options = null;
var done = !_this.stack.length;
if ((err || done) && !_this.done) _this.end(err);
return callback(err, _this.done || done);
});
this.processors.push(processor);
this._pump();
return;
}
return new Promise(function(resolve, reject) {
return _this.forEach(fn, options, function(err, done) {
err ? reject(err) : resolve(done);
});
});
};
_proto.end = function end(err) {
if (this.done) return;
this.done = true;
while(this.processors.length > 0)this.processors.pop()(err || true);
while(this.processing.length > 0)err ? this.processing.pop()(err) : this.processing.pop()(null, {
done: true,
value: null
});
while(this.queued.length > 0)err ? this.queued.pop()(err) : this.queued.pop()(null, {
done: true,
value: null
});
while(this.stack.length > 0)this.stack.pop();
};
_proto.destroy = function destroy(err) {
if (this.destroyed) throw new Error('Already destroyed');
this.destroyed = true;
this.end(err);
};
_proto._pump = function _pump() {
if (!this.done && this.processors.length > 0 && this.stack.length > 0 && this.stack.length > this.queued.length) this.processors.last()(false); // try to queue more
while(this.stack.length > 0 && this.queued.length > 0){
this._processOrQueue(this.queued.pop());
if (!this.done && this.processors.length > 0 && this.stack.length > 0 && this.stack.length > this.queued.length) this.processors.last()(false); // try to queue more
}
};
_proto._processOrQueue = function _processOrQueue(callback) {
var _this = this;
if (this.done) {
callback(null, {
done: true,
value: null
});
return;
}
// nothing to process so queue
if (this.stack.length === 0) {
this.queued.push(callback);
return;
}
// process next
var next = this.stack.pop();
this.processing.push(callback);
next(this, function(err, result) {
_this.processing.remove(callback);
// done
if (_this.done) return callback(null, {
done: true,
value: null
});
// skip error
if (err && _asynccompat.default.defaultValue(_this.options.error(err), true)) err = null;
// handle callback
if (err) callback(err);
else if (!result) _this._processOrQueue(callback);
else callback(null, result);
// done
if (_this.stack.length === 0 && _this.processing.length === 0 && !_this.done) _this.end(); // end
});
};
return StackBaseIterator;
}();
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }