@johngw/stream
Version:
Reactive programming tools using the WHATWG Streams API.
90 lines • 2.74 kB
JavaScript
import { assertNever } from 'assert-never';
import { isArrayLike, isAsyncIterable, isIterable, isIteratorOrAsyncIterator, isNonNullObject, } from '@johngw/stream-common/Object';
export function fromCollection(collection, queuingStrategy) {
return new ReadableStream(isIterable(collection)
? new IteratorSource(collection[Symbol.iterator]())
: isAsyncIterable(collection)
? new IteratorSource(collection[Symbol.asyncIterator]())
: isIteratorOrAsyncIterator(collection)
? new IteratorSource(collection)
: isArrayLike(collection)
? new ArrayLikeSource(collection)
: isNonNullObject(collection)
? new IteratorSource((function* () {
for (const key in collection) {
if (Object.prototype.hasOwnProperty.call(collection, key)) {
yield [key, collection[key]];
}
}
})())
: assertNever(collection), queuingStrategy);
}
/**
* An underlying source for an `Iterator` or `AsyncIterator`.
*
* @group Sources
* @example
* ```
* const reader = new ReadableStream(new IteratorSource((function* () {
* yield 1
* yield 2
* })()))
* ```
*/
export class IteratorSource {
#iterator;
constructor(iterator) {
this.#iterator = iterator;
}
async pull(controller) {
while (controller.desiredSize) {
let result;
try {
result = await this.#iterator.next();
}
catch (error) {
return controller.error(error);
}
if (result.done)
return controller.close();
else
controller.enqueue(result.value);
}
}
}
/**
* An underlying source for an `ArrayLike`.
*
* @group Sources
* @example
* ```
* const reader = new ReadableStream(new ArrayLikeSource({
* 0: 'zero',
* 1: 'one',
* length: 2
* }))
* ```
*/
export class ArrayLikeSource {
#arrayLike;
#length;
#i = 0;
constructor(arrayLike) {
this.#arrayLike = arrayLike;
this.#length = arrayLike.length;
}
start(controller) {
if (this.#finished)
controller.close();
}
pull(controller) {
for (; controller.desiredSize && this.#i < this.#length; this.#i++)
controller.enqueue(this.#arrayLike[this.#i]);
if (this.#finished)
controller.close();
}
get #finished() {
return this.#i === this.#length;
}
}
//# sourceMappingURL=fromCollection.js.map