@johngw/stream
Version:
Reactive programming tools using the WHATWG Streams API.
78 lines • 2.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Subject = void 0;
const ForkableStream_1 = require("@johngw/stream/sinks/ForkableStream");
const ControllableStream_1 = require("@johngw/stream/sources/ControllableStream");
/**
* The base class for all subjects.
*
* @group Subjects
* @see {@link Subject:class}
* @see {@link StatefulSubject:class}
*/
class Subject {
#controllable;
#controllers = new Set();
#forkable;
constructor({ controllable = new ControllableStream_1.ControllableStream(), forkable = new ForkableStream_1.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();
}
}
exports.Subject = Subject;
//# sourceMappingURL=Subject.js.map