Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 3x 10x 21x 10x 11x 11x 11x 16x 2x 14x 10x 11x 11x 11x 11x | import { Network } from '@tao.js/core';
import trigramFilter from './trigram-filter';
/** @typedef {import('@tao.js/core').Kernel} Kernel */
/** @typedef {import('./Channel').default} Channel */
const NOOP = () => {};
function addControl(name, control) {
return { ...control, seive: name };
}
// filter function signature: (ac:AppCtx, control:Object)
// filters is: [filterFunc, [exact,]] ...trigrams
/**
* Forwards matching AppCons flowing on the `source`'s network into the
* `destination` Channel's private network. Implemented as an `onDispatch`
* decoration on the source network; chains from destination-channel
* handlers continue the source cascade through the core hop engine.
*
* Clone-and-redirect: the destination entry carries a copy of the observed
* cascade with a `{ seive: name }` tag added (the source cascade object is
* never mutated), and passes the observed hop's `forward` continuation so
* chained AppCons re-join the source cascade.
*
* @param {(string|number)} name - seive tag stamped on redirected cascades
* (`cascade.seive`) and used in the decoration's diagnostic name
* @param {Kernel} source - Kernel-shaped wrapper whose `_network` is a
* `Network` to observe
* @param {Channel} destination - Channel whose private network (`_channel`)
* receives the matching AppCons
* @param {...*} filters - optional leading filter function
* `(ac: AppCtx, cascade: Object) => boolean`, then trigram filters as
* `trigramFilter` accepts (optional `exact` boolean, then short-key
* trigrams or a single array of trigrams)
* @returns {function(): void} dispose - detaches the decoration (a no-op
* when `source`/`destination` are not the required shapes)
*/
export default function seive(name, source, destination, ...filters) {
if (
!source ||
!(source._network instanceof Network) ||
!destination ||
!(destination._channel instanceof Network)
) {
return NOOP;
}
let filterFunction =
typeof filters[0] === 'function' ? filters.shift() : undefined;
let handleFilter = trigramFilter(...filters);
const undecorate = source._network.decorate({
// Stryker disable next-line StringLiteral: decoration name is a diagnostic label with no observable behavior
name: `seive:${name}`,
onDispatch: (ac, envelope, handler, forward) => {
if (filterFunction && !filterFunction(ac, envelope.cascade)) {
return;
}
if (handleFilter(ac)) {
destination._channel.enter(ac, {
cascade: addControl(name, envelope.cascade),
forward,
});
}
},
});
return () => {
undecorate();
filterFunction = null;
handleFilter = null;
};
}
|