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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | 1x 1x 1x 1x 1x 1x 1x 1x 28x 31x 31x 1x 30x 22x 6x 22x 8x 8x 1x 53x 3x 3x 3x 3x 1x 53x 53x 53x 53x 53x 53x 53x 23x 30x 30x 30x 30x 3x 30x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x 30x 5x 5x 5x 5x 5x 5x 5x 25x 25x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 1x 15x 4x 25x 1x 22x 22x 22x | import {PluginParams} from '@grnsft/if-core/types';
import {Regroup} from './regroup';
import {addExplainData} from './explain';
import {debugLogger} from '../../common/util/debug-logger';
import {logger} from '../../common/util/logger';
import {mergeObjects} from '../util/helpers';
import {STRINGS} from '../config/strings';
import {ComputeParams, Node, PhasedPipeline} from '../types/compute';
const {
MERGING_DEFAULTS_WITH_INPUT_DATA,
EMPTY_PIPELINE,
CONFIG_WARN,
COMPUTING_PIPELINE_FOR_NODE,
COMPUTING_COMPONENT_PIPELINE,
REGROUPING,
OBSERVING,
} = STRINGS;
/**
* Traverses all child nodes based on children grouping.
*/
const traverse = async (children: any, params: ComputeParams) => {
for (const child in children) {
console.debug(COMPUTING_COMPONENT_PIPELINE(child));
await computeNode(children[child], params);
}
};
/**
* Appends `default` values to `inputs`.
*/
const mergeDefaults = (
inputs: PluginParams[],
defaults: PluginParams | undefined
) => {
if (inputs) {
const response = defaults
? inputs.map(input => mergeObjects(defaults, input))
: inputs;
return response;
}
console.debug(MERGING_DEFAULTS_WITH_INPUT_DATA, '\n');
return defaults ? [defaults] : [];
};
/**
* Warns if the `config` is provided in the manifest.
*/
const warnIfConfigProvided = (node: any) => {
if ('config' in node) {
const plugins = Object.keys(node.config || {});
const joinedPlugins = plugins.join(', ');
const isMore = plugins.length > 1;
logger.warn(CONFIG_WARN(joinedPlugins, isMore));
}
};
/**
* 1. If the node has it's own pipeline, defaults or config then use that,
* otherwise use whatever has been passed down from further up the tree.
* 2. If it's a grouping node, then first of all computes all it's children.
* This is doing a depth first traversal.
* 3. Otherwise merges the defaults into the inputs.
* 4. Iterates over pipeline phases (observe, regroup, compute).
* 5. Observe plugins are used to insert input values
* (isolated execution can be achived by passing `--observe` flag to CLI command).
* 6. Regroup plugin is used to group existing inputs by criteria
* (isolated execution can be achived by passing `--regroup` flag to CLI command).
* Since it creates new children for node, existing inputs and outputs are dropped and recursive traversal is called
* for newbord child component.
* 7. Compute plugins are used to do desired computations and appending the result to outputs
* (isolated execution can be achived by passing `--compute` flag to CLI command).
*/
const computeNode = async (node: Node, params: ComputeParams): Promise<any> => {
const pipeline = node.pipeline || (params.pipeline as PhasedPipeline);
const config = node.config || params.config;
const defaults = node.defaults || params.defaults;
const noFlags = !params.observe && !params.regroup && !params.compute;
debugLogger.setExecutingPluginName();
warnIfConfigProvided(node);
if (node.children) {
return traverse(node.children, {
...params,
pipeline,
defaults,
config,
});
}
let outputStorage = structuredClone(node.inputs) as PluginParams[];
outputStorage = mergeDefaults(outputStorage, defaults);
const pipelineCopy = structuredClone(pipeline) || {};
/** Checks if pipeline is not an array or empty object. */
if (
Array.isArray(pipelineCopy) ||
(typeof pipelineCopy === 'object' &&
pipelineCopy !== null &&
Object.keys(pipelineCopy).length === 0)
) {
logger.warn(EMPTY_PIPELINE);
}
/**
* If iteration is on observe pipeline, then executes observe plugins and sets the inputs value.
*/
if ((noFlags || params.observe) && pipelineCopy.observe) {
while (pipelineCopy.observe.length !== 0) {
const pluginName = pipelineCopy.observe.shift() as string;
console.debug(OBSERVING(pluginName));
debugLogger.setExecutingPluginName(pluginName);
const plugin = params.pluginStorage.get(pluginName);
const nodeConfig = config && config[pluginName];
outputStorage = await plugin.execute(outputStorage, nodeConfig);
node.inputs = outputStorage;
if (params.context.explainer) {
addExplainData({
pluginName,
metadata: plugin.metadata,
});
}
}
}
/**
* If regroup is requested, execute regroup strategy, delete child's inputs, outputs and empty regroup array.
*/
if ((noFlags || params.regroup) && pipelineCopy.regroup) {
const originalOutputs = params.append ? node.outputs || [] : [];
node.children = Regroup(
outputStorage,
originalOutputs,
pipelineCopy.regroup
);
delete node.inputs;
delete node.outputs;
debugLogger.setExecutingPluginName();
console.debug(REGROUPING);
return traverse(node.children, {
...params,
pipeline: {
...pipelineCopy,
regroup: undefined,
},
defaults,
config,
});
}
console.debug('\n');
/**
* If iteration is on compute plugin, then executes compute plugins and sets the outputs value.
*/
if ((noFlags || params.compute) && pipelineCopy.compute) {
const originalOutputs = params.append ? node.outputs || [] : [];
while (pipelineCopy.compute.length !== 0) {
const pluginName = pipelineCopy.compute.shift() as string;
const plugin = params.pluginStorage.get(pluginName);
const nodeConfig = config && config[pluginName];
console.debug(COMPUTING_PIPELINE_FOR_NODE(pluginName));
debugLogger.setExecutingPluginName(pluginName);
outputStorage = await plugin.execute(outputStorage, nodeConfig);
debugLogger.setExecutingPluginName();
node.outputs = outputStorage;
if (params.context.explainer) {
addExplainData({
pluginName,
metadata: plugin.metadata,
});
}
}
if (params.append) {
node.outputs = originalOutputs.concat(node.outputs || []);
}
}
console.debug('\n');
};
/**
* Creates copy of existing tree, then applies computing strategy.
*/
export const compute = async (tree: any, params: ComputeParams) => {
const copyOfTree = structuredClone(tree);
await computeNode(copyOfTree, params);
return copyOfTree;
};
|