UNPKG

@thi.ng/rstream

Version:

Reactive streams & subscription primitives for constructing dataflow graphs / pipelines

97 lines (96 loc) 2.19 kB
import { EquivMap } from "@thi.ng/associative/equiv-map"; import { unsupported } from "@thi.ng/errors/unsupported"; import { __optsWithID } from "./idgen.js"; import { LOGGER } from "./logger.js"; import { Subscription, subscription } from "./subscription.js"; const pubsub = (opts) => new PubSub(opts); class PubSub extends Subscription { topicfn; topics; constructor(opts) { super( void 0, __optsWithID("pubsub", { xform: opts.xform }) ); this.topicfn = opts.topic; this.topics = new EquivMap(void 0, { equiv: opts.equiv }); } /** * Unsupported. Use {@link PubSub.subscribeTopic} instead. */ subscribe() { return unsupported(`use subscribeTopic() instead`); } /** * Unsupported. Use {@link PubSub.subscribeTopic} instead. */ transform() { return unsupported(`use subscribeTopic() instead`); } subscribeTopic(topicID, sub, opts) { let t = this.topics.get(topicID); !t && this.topics.set( topicID, t = subscription( void 0, __optsWithID("topic", { closeOut: "never" }) ) ); return t.subscribe(sub, opts); } transformTopic(topicID, xform, opts = {}) { return this.subscribeTopic( topicID, { error: opts.error }, { ...opts, xform } ); } unsubscribeTopic(topicID, sub) { const t = this.topics.get(topicID); return t ? t.unsubscribe(sub) : false; } unsubscribe(sub) { if (!sub) { for (let t of this.topics.values()) { t.unsubscribe(); } this.topics.clear(); return super.unsubscribe(); } return unsupported(); } done() { for (let t of this.topics.values()) { t.done(); } super.done(); } dispatch(x) { LOGGER.debug(this.id, "dispatch", x); this.cacheLast && (this.last = x); const t = this.topicfn(x); if (t !== void 0) { const sub = this.topics.get(t); if (sub) { try { sub.next?.(x); } catch (e) { if (!sub.error || !sub.error(e)) { return this.unhandledError(e); } } } } } } export { PubSub, pubsub };