(
paths: any,
candidates: ICallback[],
callbacks: ICallback[] = candidates,
graphs: any = {}
)
| 195 | } |
| 196 | |
| 197 | export const getReadyCallbacks = ( |
| 198 | paths: any, |
| 199 | candidates: ICallback[], |
| 200 | callbacks: ICallback[] = candidates, |
| 201 | graphs: any = {} |
| 202 | ): ICallback[] => { |
| 203 | // Skip if there's no candidates |
| 204 | if (!candidates.length) { |
| 205 | return []; |
| 206 | } |
| 207 | |
| 208 | // Find all outputs of all active callbacks |
| 209 | const outputs = map( |
| 210 | combineIdAndProp, |
| 211 | reduce<ICallback, any[]>( |
| 212 | (o, cb) => concat(o, flatten(cb.getOutputs(paths))), |
| 213 | [], |
| 214 | callbacks |
| 215 | ) |
| 216 | ); |
| 217 | |
| 218 | // Make `outputs` hash table for faster access |
| 219 | let outputsMap: {[key: string]: boolean} = {}; |
| 220 | outputs.forEach(output => (outputsMap[output] = true)); |
| 221 | |
| 222 | // find all the outputs touched by activeCallbacks |
| 223 | // remove this check if graph is accessible all the time |
| 224 | |
| 225 | if (Object.keys(graphs).length) { |
| 226 | //not sure if graph will be accessible all the time |
| 227 | const allTouchedOutputs: {[key: string]: boolean}[] = flatten( |
| 228 | map( |
| 229 | cb => getAllSubsequentOutputsForCallback(graphs, paths, cb), |
| 230 | callbacks |
| 231 | ) |
| 232 | ); |
| 233 | |
| 234 | // overrrides the outputsMap, will duplicate callbacks filtered |
| 235 | // this is only done to silence typescript errors |
| 236 | if (allTouchedOutputs.length > 0) { |
| 237 | outputsMap = Object.assign( |
| 238 | allTouchedOutputs[0], |
| 239 | ...allTouchedOutputs |
| 240 | ); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | // Ramda.JS `difference` function is slow because it compares objects entirely |
| 245 | // This cause the following `filter` to be exponentially slow as the number of inputs or outputs grow |
| 246 | // We can optimize this by comparing only the `id+prop` part of the inputs & outputs. |
| 247 | // Original difference takes 380ms on average to compute difference between 200 inputs and 1 output. |
| 248 | // The following function takes 1-2ms on average. |
| 249 | const differenceBasedOnId = (inputs: any[], outputs: any[]): any[] => |
| 250 | inputs.filter( |
| 251 | input => |
| 252 | !outputs.some( |
| 253 | output => |
| 254 | combineIdAndProp(input) === combineIdAndProp(output) |
no test coverage detected
searching dependent graphs…