iter-tools-es
Version:
The iterable toolbox
143 lines (120 loc) • 2.9 kB
JavaScript
const {
split
} = require('./symbols.js');
const {
AsyncIterableIterator
} = require('./async-iterable-iterator.js');
const {
AsyncPeekerator
} = require('./async-peekerator.js');
class AsyncPartIterator extends AsyncIterableIterator {
constructor(partsIterator) {
super();
this.partsIterator = partsIterator;
this.inactive = false;
this.done = false;
}
assertActive() {
if (this.inactive && !this.done) {
throw new Error('Cannot take from this split part. It is no longer the active part.');
}
}
async next() {
const {
spliterator
} = this.partsIterator;
const {
current
} = spliterator;
this.assertActive();
if (this.done || current.done || current.value === split) {
this.done = true;
await this.partsIterator.maybeReturnSource();
return {
value: undefined,
done: true
};
} else {
await spliterator.advance();
return current;
}
}
async return() {
this.done = true;
await this.partsIterator.maybeReturnSource();
return {
value: undefined,
done: true
};
}
async throw() {
return await this.return();
}
}
exports.AsyncPartIterator = AsyncPartIterator;
class AsyncPartsIterator extends AsyncIterableIterator {
constructor(source, strategy, options) {
super();
this.source = source;
this.strategy = strategy;
this.options = options;
this.initialized = false;
this.returned = false;
this.spliterator = null;
this.currentPart = null;
this.splitStep = null;
}
async init() {
this.initialized = true;
const {
source,
strategy,
options
} = this;
this.spliterator = await AsyncPeekerator.from(strategy(split, options, source));
}
async maybeReturnSource() {
if (this.spliterator && this.returned && this.currentPart.done) {
await this.spliterator.return();
}
}
async next() {
if (!this.initialized) await this.init();
const {
spliterator
} = this;
if (spliterator.done) {
return {
value: undefined,
done: true
};
}
if (this.currentPart !== null) {
if (spliterator.value !== split || spliterator.current === this.splitStep) {
this.currentPart.inactive = true;
while (!spliterator.done && spliterator.value !== split) {
await spliterator.advance();
}
}
await spliterator.advance();
}
this.splitStep = spliterator.current;
this.currentPart = new AsyncPartIterator(this);
return {
value: this.currentPart,
done: false
};
}
async return(value) {
this.returned = true;
await this.maybeReturnSource();
return {
value,
done: true
};
}
async throw() {
return await this.return();
}
}
exports.AsyncPartsIterator = AsyncPartsIterator;