UNPKG

@johngw/stream

Version:

Reactive programming tools using the WHATWG Streams API.

79 lines 2.5 kB
import { ControllableSource } from '../sources/ControllableSource.js'; import { SourceComposite } from '../sources/SourceComposite.js'; /** * A ForkableSink is the underlying logic for "1 Writable to many Readables". * * @group Sinks * @see {@link ForkableStream:class} * @example * ``` * const forkable = new ForkableSink<T>() * const writable = new WritableStream(forkable) * * fromCollection([1, 2, 3, 4, 5, 6, 7]).pipeTo(writable) * * forkable.fork().pipeTo(write(x => console.info('fork1', x))) * // fork1 1, fork1 2, fork1 3, fork1 4, fork1 5, fork1 6, fork1 7 * * forkable.fork().pipeTo(write(x => console.info('fork2', x))) * // fork2 1, fork2 2, fork2 3, fork2 4, fork2 5, fork2 6, fork2 7 * ``` */ export class ForkableSink { #error; #finished = false; #controllers = new Map(); abort(reason) { for (const [controller] of this.#controllers) controller.error(reason); this.#controllers.clear(); this.#error = reason; this.#finished = true; } close() { for (const [controller] of this.#controllers) { try { controller.close(); } catch (error) { // potentially already closed } } this.#controllers.clear(); this.#finished = true; } write(chunk) { for (const [controller] of this.#controllers) if (controller.desiredSize) controller.enqueue(chunk); } get finished() { return this.#finished; } fork(underlyingSource, queuingStrategy) { return this._pipeThroughController(this._addController(underlyingSource, queuingStrategy)); } _addController(underlyingSource = {}, queuingStrategy) { const controller = new ControllableSource(); const stream = new ReadableStream(new SourceComposite([ controller, underlyingSource, { cancel: () => { this.#controllers.delete(controller); }, }, ]), queuingStrategy); if (!this.#finished) this.#controllers.set(controller, stream); return [controller, stream]; } _pipeThroughController([controller, stream]) { if (this.#error) controller.error(this.#error); else if (this.#finished) controller.close(); return stream; } } //# sourceMappingURL=ForkableSink.js.map