UNPKG

@thi.ng/rstream

Version:

Reactive streams & subscription primitives for constructing dataflow graphs / pipelines

73 lines (72 loc) 1.88 kB
import { assert } from "@thi.ng/errors/assert"; import { State } from "./api.js"; import { __optsWithID } from "./idgen.js"; import { Subscription } from "./subscription.js"; const metaStream = (factory, opts) => new MetaStream(factory, opts); class MetaStream extends Subscription { factory; stream; sub; emitLast; doneRequested; constructor(factory, opts = {}) { super(void 0, __optsWithID("metastram", opts)); this.factory = factory; this.emitLast = opts.emitLast === true; this.doneRequested = false; } next(x) { if (this.state < State.DONE) { if (this.stream) { this.stream.unsubscribe(this.sub); } let stream = this.factory(x); if (stream) { this.stream = stream; this.sub = this.stream.subscribe({ next: (x2) => { stream === this.stream && super.dispatch(x2); this.doneRequested && this.done(); }, done: () => { this.stream.unsubscribe(this.sub); if (stream === this.stream) { this.stream = void 0; this.sub = void 0; } }, error: (e) => super.error(e), __owner: this }); } } } done() { if (this.emitLast && !this.doneRequested) { this.doneRequested = true; } else { if (this.stream) { this.detach(true); } this.closeIn !== "never" && super.done(); } } unsubscribe(sub) { if (this.stream && (!sub || this.subs.length === 1)) { this.detach(!sub); } return super.unsubscribe(sub); } detach(force) { if (force || this.closeOut !== "never") { assert(!!this.stream, "input stream already removed"); this.stream.unsubscribe(this.sub); delete this.stream; delete this.sub; } } } export { MetaStream, metaStream };