UNPKG

@thi.ng/rstream

Version:

Reactive streams & subscription primitives for constructing dataflow graphs / pipelines

71 lines (70 loc) 2.01 kB
import { dedupe } from "@thi.ng/transducers/dedupe"; import { range } from "@thi.ng/transducers/range"; import { __optsWithID } from "./idgen.js"; import { Subscription, subscription } from "./subscription.js"; const fromObject = (src, opts = {}) => new StreamObj(src, opts); const fromTuple = (src, opts) => new StreamObj(src, { keys: [...range(src.length)], ...opts }); class StreamObj extends Subscription { /** * Object of managed & typed streams for registered keys. */ keys; streams = {}; defaults; constructor(src, opts = {}) { super(void 0, __optsWithID("obj", opts)); this.keys = opts.keys || Object.keys(src); this.defaults = opts.defaults; const _opts = opts.dedupe !== false ? { xform: dedupe(opts.equiv || ((a, b) => a === b)), ...opts } : opts; for (let k of this.keys) { this.streams[k] = subscription(void 0, { ..._opts, id: `${this.id}-${k}` }); } opts.initial !== false && this.next(src); } /** * Receives an object of configured type and feeds each key's new value into * its respective {@link StreamObj.streams}. If the * {@link StreamObjOpts.defaults} option is given, `undefined` key values * are replaced with their specified default. If * {@link StreamObjOpts.dedupe} is enabled (default) only changed values (as * per {@link StreamObjOpts.equiv} predicate option) will be propagated * downstream. * * @param x - */ next(x) { this.cacheLast && (this.last = x); for (let k of this.keys) { const val = x[k]; this.streams[k].next( this.defaults && val === void 0 ? this.defaults[k] : val ); } super.next(x); } done() { for (let k of this.keys) { this.streams[k].done(); } super.done(); } unsubscribe(sub) { if (!sub) { for (let k of this.keys) { this.streams[k].unsubscribe(); } } return super.unsubscribe(sub); } } export { StreamObj, fromObject, fromTuple };