streams
Version:
A lazy streams library for functional composition in JavaScript.
394 lines • 21.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IteratorStream = void 0;
const as_iterable_1 = require("./util/as-iterable");
/**
* An asynchronous stream that produces elements of type `T` on demand.
*
* This is an extension of the built-in `AsyncIterable<T>` protocol.
*
* The operations defined here in IteratorStream are a superset of the
* operations described in the
* [Iterator Helpers](https://github.com/tc39/proposal-iterator-helpers)
* proposal.
*
* The behavior of all operations here that correspond to operations in the
* `Iterator Helpers` proposal are defined (as best as possible) to match
* exactly with the behavior of the corresponding `Iterator Helpers`
* operations. This is intended to allow users of this library to seamlessly
* switch between this library and the `Iterator Helpers` once those are
* implemented and available.
*
* However, this library is NOT a polyfill for `Iterator Helpers`. To use
* this library, an iterable iterator or generator needs to be explicitly
* wrapped in an IteratorStream like in this example:
*
* ```
* import "streams/sync";
*
* function* generator() {
* yield* [1, 2, 3];
* }
*
* generator() // returns an AsyncGenerator
* .stream() // convert to IteratorStream first!
* .forEach(console.log); // use the IteratorStream APIs
* ```
*/
class IteratorStream {
iterator;
/**
* Creates an IteratorStream from a Iterator or Iterable.
*
* ```
* IteratorStream.from([1, 2, 3]).map(x => x * 2).forEach(console.log);
* ```
*/
static from(it) {
if (typeof it[Symbol.iterator] === "function") {
return new IteratorStream(it[Symbol.iterator]());
}
return new IteratorStream(it);
}
next;
return;
throw;
constructor(iterator) {
this.iterator = iterator;
this.next = () => this.iterator.next();
if (this.iterator.return !== undefined) {
this.return = () => this.iterator.return();
}
if (this.iterator.throw !== undefined) {
this.throw = (e) => this.iterator.throw(e);
}
}
stream() {
return this;
}
[Symbol.iterator]() {
return this;
}
[Symbol.dispose]() {
this.return?.();
}
// #region Intermediate operations
/**
* Returns a new stream that skips elements of this stream not matched by the
* `predicate`.
*
* See also [IteratorHelpers#filter](https://github.com/tc39/proposal-iterator-helpers#filterfiltererfn).
*
* @param predicate a function that decides whether to include each element
* in the new stream (true) or to exclude the element (false)
*/
filter(predicate) {
function* filterOperator(it) {
for (const v of it) {
if (predicate(v)) {
yield v;
}
}
}
return new IteratorStream(filterOperator(this));
}
/**
* Returns a new stream that transforms each element of this stream
* using the provided function.
*
* See also [IteratorHelpers#map](https://github.com/tc39/proposal-iterator-helpers#mapmapperfn).
*
* @param transform a function to apply to each element of this stream
*/
map(transform) {
function* mapOperator(it) {
for (const v of it) {
yield transform(v);
}
}
return new IteratorStream(mapOperator(this));
}
/**
*
* See also [IteratorHelpers#flatMap](https://github.com/tc39/proposal-iterator-helpers#flatmapmapperfn).
*
* @param transform
*/
flatMap(transform) {
function* flatMapOperator(it) {
for (const nested of it) {
yield* (0, as_iterable_1.asIterable)(transform(nested));
}
}
return new IteratorStream(flatMapOperator(this));
}
batch(batchSize) {
if (batchSize < 1) {
throw new Error("batchSize should be positive");
}
function* batchOperator(it) {
let acc = [];
for (const v of it) {
acc.push(v);
if (acc.length === batchSize) {
yield acc;
acc = [];
}
}
if (acc.length > 0) {
yield acc;
}
}
return new IteratorStream(batchOperator(this));
}
/**
* Returns a new stream that produces up to the first `limit` number of
* elements of this stream.
*
* See also [IteratorHelpers#take](https://github.com/tc39/proposal-iterator-helpers#takelimit).
*
* @param limit the maximum number of items to produce
*/
take(limit) {
function* takeOperator(it) {
let count = 0;
if (count >= limit) {
return;
}
for (const v of it) {
yield v;
count += 1;
if (count >= limit) {
return;
}
}
}
return new IteratorStream(takeOperator(this));
}
/**
*
* See also [IteratorHelpers#drop](https://github.com/tc39/proposal-iterator-helpers#droplimit).
*
* @param n
*/
drop(n) {
function* dropOperator(it) {
let count = 0;
for (const v of it) {
if (count >= n) {
yield v;
}
count += 1;
}
}
return new IteratorStream(dropOperator(this));
}
dropWhile(predicate) {
function* dropWhileOperator(it) {
let dropping = true;
for (const v of it) {
dropping = dropping && predicate(v);
if (!dropping) {
yield v;
}
}
}
return new IteratorStream(dropWhileOperator(this));
}
takeWhile(predicate) {
function* takeWhileOperator(it) {
for (const v of it) {
if (!predicate(v)) {
return;
}
yield v;
}
}
return new IteratorStream(takeWhileOperator(this));
}
peek(observer) {
function* peekOperator(it) {
for (const v of it) {
observer(v);
yield v;
}
}
return new IteratorStream(peekOperator(this));
}
// #endregion Intermediate operations
// #region Terminal operations
/**
*
* See also [IteratorHelpers#forEach](https://github.com/tc39/proposal-iterator-helpers#foreachfn).
*
* @param block
*/
forEach(block) {
for (const v of this) {
block(v);
}
}
collect(container, accumulator, finisher) {
for (const v of this) {
accumulator(container, v);
}
return finisher ? finisher(container) : container;
}
/**
*
* See also [IteratorHelpers#every](https://github.com/tc39/proposal-iterator-helpers#everyfn).
*
* @param predicate
*/
every(predicate) {
for (const v of this) {
if (!predicate(v)) {
return false;
}
}
return true;
}
/**
* See also [IteratorHelpers#some](https://github.com/tc39/proposal-iterator-helpers#somefn).
*
* @param predicate
*/
some(predicate) {
for (const v of this) {
if (predicate(v)) {
return true;
}
}
return false;
}
none(predicate) {
for (const v of this) {
if (predicate(v)) {
return false;
}
}
return true;
}
count() {
let count = 0;
for (const _ of this) {
count += 1;
}
return count;
}
/**
* Returns the first element that matches the predicate.
*
* This is the same as the {@link first()} method except that the predicate is
* required and a `TypeError` will be thrown if a predicate is not supplied.
*
* See also [IteratorHelpers#find](https://github.com/tc39/proposal-iterator-helpers#findfn).
*
* @param predicate
*/
find(predicate) {
for (const v of this) {
if (predicate(v)) {
return v;
}
}
return undefined;
}
first(predicate = (_) => true) {
for (const v of this) {
if (predicate(v)) {
return v;
}
}
return undefined;
}
last(predicate = (_) => true) {
let result;
for (const v of this) {
if (predicate(v)) {
result = v;
}
}
return result;
}
max(comparator) {
let result;
let firstItem = true;
for (const v of this) {
if (firstItem) {
result = v;
firstItem = false;
}
else {
result = comparator(result, v) > 0 ? result : v;
}
}
return result;
}
min(comparator) {
let result;
let firstItem = true;
for (const v of this) {
if (firstItem) {
result = v;
firstItem = false;
}
else {
result = comparator(result, v) < 0 ? result : v;
}
}
return result;
}
/**
*
* See also [IteratorHelpers#reduce](https://github.com/tc39/proposal-iterator-helpers#reducereducer--initialvalue-).
*
* @param reducer
* @param initial
*/
reduce(reducer, initial) {
const hasInitial = arguments.length >= 2;
let firstItem = !hasInitial;
let result = initial;
for (const v of this) {
if (firstItem) {
result = v; // R assumed to be T when no initial value
firstItem = false;
}
else {
result = reducer(result, v);
}
}
if (firstItem) {
throw new TypeError("reduce without initial value but stream is empty");
}
return result;
}
fold(reducer, initial) {
const hasInitial = arguments.length >= 2;
let firstItem = !hasInitial;
let result = initial;
for (const v of this) {
if (firstItem) {
result = v; // R assumed to be T when no initial value
firstItem = false;
}
else {
result = reducer(result, v);
}
}
return result;
}
/**
* See also [IteratorHelpers#toArray](https://github.com/tc39/proposal-iterator-helpers#toarray).
*/
toArray() {
const result = [];
for (const v of this) {
result.push(v);
}
return result;
}
}
exports.IteratorStream = IteratorStream;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0b3Itc3RyZWFtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2l0ZXJhdG9yLXN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxvREFBZ0Q7QUFFaEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsTUFBYSxjQUFjO0lBcUJJO0lBcEI3Qjs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUNULEVBQWlEO1FBRWpELElBQUksT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzlDLE9BQU8sSUFBSSxjQUFjLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUNELE9BQU8sSUFBSSxjQUFjLENBQUMsRUFBcUMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFUSxJQUFJLENBQXFDO0lBQ3pDLE1BQU0sQ0FBc0M7SUFDNUMsS0FBSyxDQUFpRDtJQUUvRCxZQUE2QixRQUF5QztRQUF6QyxhQUFRLEdBQVIsUUFBUSxDQUFpQztRQUNwRSxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFrQyxDQUFDO1FBQ3ZFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFPLEVBQWtDLENBQUM7UUFDNUQsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBTSxDQUFDLENB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