iter-tools-es
Version:
The iterable toolbox
161 lines (128 loc) • 3.34 kB
JavaScript
const {
asyncIterableCurry,
asyncCallReturn
} = require('../../internal/async-iterable.js');
const {
AsyncIterableIterator
} = require('../../internal/async-iterable-iterator.js');
const {
asyncParallelEach
} = require('../../internal/async-parallel-each.js');
const {
AsyncPeekerator
} = require('../../internal/async-peekerator.js');
const {
__asyncMap
} = require('../$map/async-map.js');
const {
__asyncToArray
} = require('../$to-array/async-to-array.js');
const _ = Symbol.for('_');
const __advance = Symbol.for('__advance');
class AsyncSummarizedPeekerator extends AsyncPeekerator {
constructor(iterator, first, inputSummary) {
super(iterator, first);
this[_].inputSummary = inputSummary;
}
async advance() {
await this[_].inputSummary.advanceBuffer(this);
}
async [__advance]() {
await super.advance();
}
}
class AsyncInputSummaryInternal {
constructor() {
this.buffers = [];
this.notDoneBuffer = null;
this.index = 0;
}
init(buffers) {
this.buffers = buffers;
this.updateNotDone();
}
updateNotDone() {
this.notDoneBuffer = this.buffers.find(buffer => !buffer.done);
}
async advanceBuffer(buffer) {
const wasDone = buffer.done;
await buffer[__advance]();
this.index++;
if (!wasDone && buffer.done) {
this.updateNotDone();
}
}
}
class AsyncInputSummary {
constructor(internal) {
this[_] = internal;
}
advance() {
throw new Error('advance() is not supported on an interleave summary');
}
get current() {
return {
value: this.value,
done: this.done
};
}
get value() {
return this[_].notDoneBuffer;
}
get done() {
return this[_].notDoneBuffer === undefined;
}
get index() {
return this[_].index;
}
}
exports.AsyncInputSummary = AsyncInputSummary;
class AsyncInterleaver extends AsyncIterableIterator {
constructor(sources, strategy, options) {
super();
this.sources = sources;
this.strategy = strategy;
this.options = options;
this.initialized = false;
this.inputSummary = new AsyncInputSummaryInternal(sources);
}
async init() {
this.initialized = true;
const {
strategy,
options,
inputSummary
} = this;
this.buffers = await __asyncToArray(__asyncMap(this.sources, source => AsyncSummarizedPeekerator.from(source, inputSummary)));
this.iterator = strategy(options, new AsyncInputSummary(inputSummary), ...this.buffers);
await inputSummary.init(this.buffers);
}
async returnBuffers() {
await asyncParallelEach(this.buffers, buffer => buffer.return());
}
async next() {
if (!this.initialized) await this.init();
const step = await this.iterator.next();
if (step.done) await this.returnBuffers();
return step;
}
async return() {
await asyncCallReturn(this.iterator);
await this.returnBuffers();
return {
value: undefined,
done: true
};
}
}
function __asyncInterleave(sources, strategy, options = {}) {
return new AsyncInterleaver(sources, strategy, options);
}
exports.__asyncInterleave = __asyncInterleave;
const asyncInterleave = /*#__PURE__*/asyncIterableCurry(__asyncInterleave, {
variadic: true,
growRight: true,
minArgs: 1,
maxArgs: 2
});
exports.asyncInterleave = asyncInterleave;