iter-tools-es
Version:
The iterable toolbox
86 lines (69 loc) • 1.86 kB
JavaScript
const {
CircularBuffer
} = require('../../internal/circular-buffer.js');
const {
asyncIterableCurry
} = require('../../internal/async-iterable.js');
const {
makeValidateArgs
} = require('./internal/validate-args.js');
async function* __asyncSliceFromStart(source, start = 0, end = Infinity, step = 1) {
let currentPos = 0;
let nextValidPos = start;
const bufferSize = Math.abs(end);
let buffer;
let counter = 0;
if (end < 0) {
buffer = new CircularBuffer(bufferSize);
}
for await (let value of source) {
if (buffer) {
value = buffer.push(value);
counter++;
if (counter <= bufferSize) {
continue;
}
}
if (currentPos >= end && end >= 0) {
break;
}
if (nextValidPos === currentPos) {
yield value;
nextValidPos += step;
}
currentPos++;
}
}
exports.__asyncSliceFromStart = __asyncSliceFromStart;
async function asyncBufferedSlice(source, start, end, step) {
const bufferSize = Math.abs(start);
const buffer = new CircularBuffer(bufferSize);
let counter = 0;
for await (const value of source) {
buffer.push(value);
counter++;
}
let newEnd;
if (isFinite(end) && end > 0) {
newEnd = end - (counter - buffer.size);
if (newEnd < 0) return [];
} else {
newEnd = end;
}
return __asyncSliceFromStart(buffer, 0, newEnd, step);
}
async function* __asyncSlice(source, start = 0, end = Infinity, step = 1) {
if (start >= 0) {
yield* __asyncSliceFromStart(source, start, end, step);
} else {
yield* await asyncBufferedSlice(source, start, end, step);
}
}
exports.__asyncSlice = __asyncSlice;
const asyncSlice = /*#__PURE__*/asyncIterableCurry(__asyncSlice, {
validateArgs: /*#__PURE__*/makeValidateArgs('asyncSlice'),
growRight: true,
minArgs: 0,
maxArgs: 3
});
exports.asyncSlice = asyncSlice;