UNPKG

@thi.ng/rstream

Version:

Reactive streams & subscription primitives for constructing dataflow graphs / pipelines

75 lines (74 loc) 1.69 kB
import { isFunction } from "@thi.ng/checks/is-function"; import { __optsWithID } from "./idgen.js"; import { LOGGER } from "./logger.js"; import { Subscription } from "./subscription.js"; function stream(src, opts) { return new Stream(src, opts); } const reactive = (val, opts) => { const res = new Stream(opts); res.next(val); return res; }; class Stream extends Subscription { src; _cancel; _inited; constructor(src, opts) { const [_src, _opts] = isFunction(src) ? [src, opts || {}] : [void 0, src || {}]; super( _opts.error ? { error: _opts.error } : void 0, __optsWithID("stream", _opts) ); this.src = _src; this._inited = false; } subscribe(sub, opts = {}) { const $sub = super.subscribe(sub, opts); if (!this._inited) { if (this.src) { try { this._cancel = this.src(this) || (() => void 0); } catch (e) { let s = this.wrapped; if (!s || !s.error || !s.error(e)) { this.unhandledError(e); } } } this._inited = true; } return $sub; } unsubscribe(sub) { const res = super.unsubscribe(sub); if (res && (!sub || (!this.subs || !this.subs.length) && this.closeOut !== "never")) { this.cancel(); } return res; } done() { this.cancel(); super.done(); delete this.src; delete this._cancel; } error(e) { if (super.error(e)) return true; this.cancel(); return false; } cancel() { if (this._cancel) { LOGGER.debug(this.id, "cancel"); const f = this._cancel; delete this._cancel; f(); } } } export { Stream, reactive, stream };