UNPKG

stack-base-iterator

Version:

Base iterator for values retrieved using a stack of async functions returning values

215 lines 8.33 kB
"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; }