UNPKG

@johngw/stream

Version:

Reactive programming tools using the WHATWG Streams API.

74 lines 2.53 kB
import { ForkableStream } from '@johngw/stream/sinks/ForkableStream'; import { ControllableStream } from '@johngw/stream/sources/ControllableStream'; /** * The base class for all subjects. * * @group Subjects * @see {@link Subject:class} * @see {@link StatefulSubject:class} */ export class Subject { #controllable; #controllers = new Set(); #forkable; constructor({ controllable = new ControllableStream(), forkable = new ForkableStream(), pre = [], post = [], transform, pipeThroughOptions, pipeToOptions, } = {}) { this.#controllable = controllable; this.#forkable = forkable; const inReadable = pre.reduce((readable, transform) => readable.pipeThrough(transform, pipeThroughOptions), controllable); (transform ? post.reduce((readable, transform) => readable.pipeThrough(transform, pipeThroughOptions), inReadable.pipeThrough(transform, pipeThroughOptions)) : inReadable) .pipeTo(this.forkable, pipeToOptions) .catch(() => { // errors can be handled in downstream forks }); } get controllable() { return this.#controllable; } get finished() { return this.#forkable.finished; } get forkable() { return this.#forkable; } fork() { return this.#forkable.fork(); } write(queuingStrategy) { const controller = this.control(); return new WritableStream({ abort(reason) { controller.error(reason); }, close() { controller.close(); }, write(chunk) { controller.enqueue(chunk); }, }, queuingStrategy); } /** * Returns a proxy to the ControllableStream. Once all proxies * have been closed, then the source is also closed. */ control() { const controller = new Proxy(this.#controllable, { get: (target, prop) => { if (prop === 'close') return this.#closeController.bind(this, controller); const value = target[prop]; return typeof value === 'function' ? value.bind(target) : value; }, }); this.#controllers.add(controller); return controller; } #closeController(controller) { this.#controllers.delete(controller); if (!this.#controllers.size) this.#controllable.close(); } } //# sourceMappingURL=Subject.js.map