UNPKG

iteragain

Version:

Javascript Iterable/Iterator/Generator-function utilities.

72 lines 2.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SeekableIterator = void 0; /** * Wraps `iterator` to allow for seeking backwards and forwards. An internal cache of length `maxLength` is kept and * progressively added to when iterating forwards. */ class SeekableIterator { constructor(iterator, maxLength = Infinity) { this.iterator = iterator; this.maxLength = maxLength; this.cache = []; this.i = 0; this.iteratorDone = false; } get elements() { return this.cache; } get done() { // If the iterator is done, then determine if `i` is at the end of the cache. return this.iteratorDone ? !this.cache.length || this.i >= this.cache.length : false; } [Symbol.iterator]() { return this; } next(...args) { if (this.done) return { done: true, value: undefined }; const cachedValue = this.cache[this.i++]; if (cachedValue !== undefined) return { done: false, value: cachedValue }; const next = this.iterator.next(...args); if (next.done) this.iteratorDone = true; else this.add(next.value); return next; } /** * 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). */ seek(i) { if (i < 0) i = this.cache.length + i; if (i > this.i) while (this.i < i && !this.done) this.next(); else if (i < this.i) this.i = i; } /** * 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. */ peek(ahead = 1) { const result = []; for (let i = 0; i < ahead; i++) result.push(this.next().value); this.i -= ahead; return result; } /** Add `value` to the `cache`. */ add(value) { this.cache.push(value); if (this.cache.length > this.maxLength) this.cache.shift(); } } exports.SeekableIterator = SeekableIterator; exports.default = SeekableIterator; //# sourceMappingURL=SeekableIterator.js.map