@thi.ng/rstream
Version:
Reactive streams & subscription primitives for constructing dataflow graphs / pipelines
75 lines (74 loc) • 1.69 kB
JavaScript
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
};