UNPKG

iteragain

Version:

Javascript Iterable/Iterator/Generator-function utilities.

90 lines 3.29 kB
/** * Wraps `iterator` to allow for seeking backwards and forwards. An internal cache of length `maxLength` is kept and * progressively added to when iterating forwards. */ var SeekableIterator = /** @class */ (function () { function SeekableIterator(iterator, maxLength) { if (maxLength === void 0) { maxLength = Infinity; } this.iterator = iterator; this.maxLength = maxLength; this.cache = []; /** Absolute index of the next value `next()` will return. */ this.i = 0; /** Absolute index of `cache[0]`. Increments when the cache evicts its oldest entry. */ this.base = 0; this.iteratorDone = false; } Object.defineProperty(SeekableIterator.prototype, "elements", { get: function () { return this.cache; }, enumerable: false, configurable: true }); Object.defineProperty(SeekableIterator.prototype, "done", { get: function () { return this.iteratorDone ? !this.cache.length || this.i >= this.base + this.cache.length : false; }, enumerable: false, configurable: true }); SeekableIterator.prototype[Symbol.iterator] = function () { return this; }; SeekableIterator.prototype.next = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.done) return { done: true, value: undefined }; if (this.i < this.base + this.cache.length) { return { done: false, value: this.cache[this.i++ - this.base] }; } var next = (_a = this.iterator).next.apply(_a, args); if (next.done) { this.iteratorDone = true; return next; } this.add(next.value); return { done: false, value: this.cache[this.i++ - this.base] }; }; /** * Seeks forward/backwards to the index `i`. `i` may be any positive or negative number. Negative numbers seek * starting from the end of the internal cache (e.g. -1 is the last element). */ SeekableIterator.prototype.seek = function (i) { if (i < 0) i = this.base + this.cache.length + i; if (i > this.i) while (this.i < i && !this.done) this.next(); else if (i < this.i) this.i = Math.max(i, this.base); }; /** * Peek ahead of where the current iteration is. This doesn't consume any values of the iterator. * @param ahead optional, the number of elements to peek ahead. */ SeekableIterator.prototype.peek = function (ahead) { if (ahead === void 0) { ahead = 1; } var result = []; for (var i = 0; i < ahead; i++) result.push(this.next().value); this.i -= ahead; return result; }; /** Add `value` to the `cache`. */ SeekableIterator.prototype.add = function (value) { this.cache.push(value); if (this.cache.length > this.maxLength) { this.cache.shift(); this.base++; } }; return SeekableIterator; }()); export { SeekableIterator }; export default SeekableIterator; //# sourceMappingURL=SeekableIterator.js.map