1// when an optional dep fails to install, we need to remove the branch of the 2// graph up to the first optionalDependencies, as well as any nodes that are 3// only required by other nodes in the set. 4// 5// This function finds the set of nodes that will need to be removed in that 6// case. 7// 8// Note that this is *only* going to work with trees where calcDepFlags 9// has been called, because we rely on the node.optional flag. 10 11const gatherDepSet = require('./gather-dep-set.js') 12const optionalSet = node => { 13 if (!node.optional) { 14 return new Set() 15 } 16 17 // start with the node, then walk up the dependency graph until we 18 // get to the boundaries that define the optional set. since the 19 // node is optional, we know that all paths INTO this area of the 20 // graph are optional, but there may be non-optional dependencies 21 // WITHIN the area. 22 const set = new Set([node]) 23 for (const node of set) { 24 for (const edge of node.edgesIn) { 25 if (!edge.optional) { 26 set.add(edge.from) 27 } 28 } 29 } 30 31 // now that we've hit the boundary, gather the rest of the nodes in 32 // the optional section. that's the set of dependencies that are only 33 // depended upon by other nodes within the set, or optional dependencies 34 // from outside the set. 35 return gatherDepSet(set, edge => !edge.optional) 36} 37 38module.exports = optionalSet 39