@connectv/core
Version:
agent-based reactive programming library for typescript/javascript
101 lines • 3.51 kB
JavaScript
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