UNPKG

@connectv/core

Version:

agent-based reactive programming library for typescript/javascript

101 lines 3.51 kB
import { tap } from 'rxjs/operators'; import { Emission, MergedEmissionContextVal } from '../shared/emission'; import group from '../pin/group'; import pin from '../pin/pin'; import { Source } from '../pin/source'; import { block } from '../pin/filter'; import pipe from '../pin/pipe'; import { Agent } from './agent'; /** * * Represents [join](https://connective.dev/docs/join) agents. * */ export class Join extends Agent { /** * * @param keys the keys of the joined object * @param pop should it pop the fork tag or not? Default is `true` * */ constructor(keys, pop = true) { super({ inputs: keys, outputs: ['output'] }); this.keys = keys; this.pop = pop; this._cache = {}; this._inject = new Source(); } _receive(key, emission) { if (emission.context.__fork) { if (emission.context.__fork instanceof MergedEmissionContextVal) emission.context.__fork.values.forEach(v => this._fill(v, key, emission)); else this._fill(emission.context.__fork, key, emission); } else this._fill([], key, emission); } _cache_key(fork) { return fork.join(';'); } _fill(fork, key, emission) { let _fork = this._cache_key(fork); let _cache = this._cache[_fork] = this._cache[_fork] || {}; _cache[key] = emission; if (this._complete(_cache)) this._emit(_cache, fork); } _emit(cache, fork) { delete this._cache[this._cache_key(fork)]; let emission = Emission.from(Object.values(cache), Object.entries(cache).reduce((obj, entry) => { obj[entry[0]] = entry[1].value; return obj; }, {})); emission.context.__fork = this.pop ? fork.slice(0, -1) : [...fork]; this._inject.emit(emission); } _complete(cache) { return Object.values(cache).length == this.keys.length; } createOutput(label) { this.checkOutput(label); return group(group(...this.keys.map(key => this.in(key).to(pipe(tap(e => this._receive(key, e)))))).to(block()), this._inject).to(pin()); } createEntries() { return this.keys.map(key => this.in(key)); } createExits() { return [this.output]; } /** * * Shortcut for `.out('output')`, which will emit the joined object. * [Read this](https://connective.dev/docs/handle-error#signature) for more details. * */ get output() { return this.out('output'); } clear() { this._inject.clear(); this._cache = {}; return this; } } /** * * Creates a [join](https://connective.dev/docs/join) agent. Join agents * will re-join values created from the same forked emission in parallel, creating * a joined object with given keys. * [Checkout the docs](https://connective.dev/docs/join) for examples and further information. * * @param keys the keys of the joined object. An input will be created per key. * */ export function join(...keys) { return new Join(keys); } /** * * Creates a [join](https://connective.dev/join) agent that does not pop * the fork tag upon joining. * [Checkout the docs](https://connective.dev/docs/join) for examples and further information. * * @param keys the keys of the joined object. An input will be created per key. */ export function peekJoin(...keys) { return new Join(keys, false); } export default join; //# sourceMappingURL=join.js.map