1// Given a node in a tree, return all of the peer dependency sets that 2// it is a part of, with the entry (top or non-peer) edges into the sets 3// identified. 4// 5// With this information, we can determine whether it is appropriate to 6// replace the entire peer set with another (and remove the old one), 7// push the set deeper into the tree, and so on. 8// 9// Returns a Map of { edge => Set(peerNodes) }, 10 11const peerEntrySets = node => { 12 // this is the union of all peer groups that the node is a part of 13 // later, we identify all of the entry edges, and create a set of 14 // 1 or more overlapping sets that this node is a part of. 15 const unionSet = new Set([node]) 16 for (const node of unionSet) { 17 for (const edge of node.edgesOut.values()) { 18 if (edge.valid && edge.peer && edge.to) { 19 unionSet.add(edge.to) 20 } 21 } 22 for (const edge of node.edgesIn) { 23 if (edge.valid && edge.peer) { 24 unionSet.add(edge.from) 25 } 26 } 27 } 28 const entrySets = new Map() 29 for (const peer of unionSet) { 30 for (const edge of peer.edgesIn) { 31 // if not valid, it doesn't matter anyway. either it's been previously 32 // peerConflicted, or it's the thing we're interested in replacing. 33 if (!edge.valid) { 34 continue 35 } 36 // this is the entry point into the peer set 37 if (!edge.peer || edge.from.isTop) { 38 // get the subset of peer brought in by this peer entry edge 39 const sub = new Set([peer]) 40 for (const peer of sub) { 41 for (const edge of peer.edgesOut.values()) { 42 if (edge.valid && edge.peer && edge.to) { 43 sub.add(edge.to) 44 } 45 } 46 } 47 // if this subset does not include the node we are focused on, 48 // then it is not relevant for our purposes. Example: 49 // 50 // a -> (b, c, d) 51 // b -> PEER(d) b -> d -> e -> f <-> g 52 // c -> PEER(f, h) c -> (f <-> g, h -> g) 53 // d -> PEER(e) d -> e -> f <-> g 54 // e -> PEER(f) 55 // f -> PEER(g) 56 // g -> PEER(f) 57 // h -> PEER(g) 58 // 59 // The unionSet(e) will include c, but we don't actually care about 60 // it. We only expanded to the edge of the peer nodes in order to 61 // find the entry edges that caused the inclusion of peer sets 62 // including (e), so we want: 63 // Map{ 64 // Edge(a->b) => Set(b, d, e, f, g) 65 // Edge(a->d) => Set(d, e, f, g) 66 // } 67 if (sub.has(node)) { 68 entrySets.set(edge, sub) 69 } 70 } 71 } 72 } 73 74 return entrySets 75} 76 77module.exports = peerEntrySets 78