@npmcli/arborist 2.6.3 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/lib/timers.js +3 -1
- package/lib/arborist/build-ideal-tree.js +118 -693
- package/lib/arborist/index.js +1 -1
- package/lib/arborist/load-actual.js +1 -1
- package/lib/arborist/load-virtual.js +1 -1
- package/lib/arborist/rebuild.js +3 -3
- package/lib/arborist/reify.js +149 -43
- package/lib/calc-dep-flags.js +3 -3
- package/lib/can-place-dep.js +405 -0
- package/lib/deepest-nesting-target.js +16 -0
- package/lib/diff.js +5 -7
- package/lib/edge.js +2 -0
- package/lib/node.js +40 -6
- package/lib/peer-entry-sets.js +72 -0
- package/lib/place-dep.js +536 -0
- package/lib/printable.js +10 -0
- package/lib/shrinkwrap.js +9 -6
- package/package.json +8 -4
- package/lib/peer-set.js +0 -25
- package/lib/update-root-package-json.js +0 -95
package/lib/arborist/index.js
CHANGED
|
@@ -315,7 +315,7 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
315
315
|
|
|
316
316
|
[_loadFSTree] (node) {
|
|
317
317
|
const did = this[_actualTreeLoaded]
|
|
318
|
-
node = node.target
|
|
318
|
+
node = node.target
|
|
319
319
|
|
|
320
320
|
// if a Link target has started, but not completed, then
|
|
321
321
|
// a Promise will be in the cache to indicate this.
|
|
@@ -221,7 +221,7 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
221
221
|
[assignBundles] (nodes) {
|
|
222
222
|
for (const [location, node] of nodes) {
|
|
223
223
|
// Skip assignment of parentage for the root package
|
|
224
|
-
if (!location || node.
|
|
224
|
+
if (!location || node.isLink && !node.target.location)
|
|
225
225
|
continue
|
|
226
226
|
const { name, parent, package: { inBundle }} = node
|
|
227
227
|
|
package/lib/arborist/rebuild.js
CHANGED
|
@@ -169,7 +169,7 @@ module.exports = cls => class Builder extends cls {
|
|
|
169
169
|
const queue = [...set].sort(sortNodes)
|
|
170
170
|
|
|
171
171
|
for (const node of queue) {
|
|
172
|
-
const { package: { bin, scripts = {} } } = node
|
|
172
|
+
const { package: { bin, scripts = {} } } = node.target
|
|
173
173
|
const { preinstall, install, postinstall, prepare } = scripts
|
|
174
174
|
const tests = { bin, preinstall, install, postinstall, prepare }
|
|
175
175
|
for (const [key, has] of Object.entries(tests)) {
|
|
@@ -202,7 +202,7 @@ module.exports = cls => class Builder extends cls {
|
|
|
202
202
|
!(meta.originalLockfileVersion >= 2)
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
const { package: pkg, hasInstallScript } = node
|
|
205
|
+
const { package: pkg, hasInstallScript } = node.target
|
|
206
206
|
const { gypfile, bin, scripts = {} } = pkg
|
|
207
207
|
|
|
208
208
|
const { preinstall, install, postinstall, prepare } = scripts
|
|
@@ -263,7 +263,7 @@ module.exports = cls => class Builder extends cls {
|
|
|
263
263
|
devOptional,
|
|
264
264
|
package: pkg,
|
|
265
265
|
location,
|
|
266
|
-
} = node.target
|
|
266
|
+
} = node.target
|
|
267
267
|
|
|
268
268
|
// skip any that we know we'll be deleting
|
|
269
269
|
if (this[_trashList].has(path))
|
package/lib/arborist/reify.js
CHANGED
|
@@ -5,6 +5,7 @@ const pacote = require('pacote')
|
|
|
5
5
|
const AuditReport = require('../audit-report.js')
|
|
6
6
|
const {subset, intersects} = require('semver')
|
|
7
7
|
const npa = require('npm-package-arg')
|
|
8
|
+
const debug = require('../debug.js')
|
|
8
9
|
|
|
9
10
|
const {dirname, resolve, relative} = require('path')
|
|
10
11
|
const {depth: dfwalk} = require('treeverse')
|
|
@@ -15,6 +16,7 @@ const mkdirp = require('mkdirp-infer-owner')
|
|
|
15
16
|
const justMkdirp = require('mkdirp')
|
|
16
17
|
const moveFile = require('@npmcli/move-file')
|
|
17
18
|
const rimraf = promisify(require('rimraf'))
|
|
19
|
+
const PackageJson = require('@npmcli/package-json')
|
|
18
20
|
const packageContents = require('@npmcli/installed-package-contents')
|
|
19
21
|
const { checkEngine, checkPlatform } = require('npm-install-checks')
|
|
20
22
|
|
|
@@ -24,7 +26,6 @@ const Diff = require('../diff.js')
|
|
|
24
26
|
const retirePath = require('../retire-path.js')
|
|
25
27
|
const promiseAllRejectLate = require('promise-all-reject-late')
|
|
26
28
|
const optionalSet = require('../optional-set.js')
|
|
27
|
-
const updateRootPackageJson = require('../update-root-package-json.js')
|
|
28
29
|
const calcDepFlags = require('../calc-dep-flags.js')
|
|
29
30
|
const { saveTypeMap, hasSubKey } = require('../add-rm-pkg-deps.js')
|
|
30
31
|
|
|
@@ -50,6 +51,7 @@ const _createSparseTree = Symbol.for('createSparseTree')
|
|
|
50
51
|
const _loadShrinkwrapsAndUpdateTrees = Symbol.for('loadShrinkwrapsAndUpdateTrees')
|
|
51
52
|
const _shrinkwrapInflated = Symbol('shrinkwrapInflated')
|
|
52
53
|
const _bundleUnpacked = Symbol('bundleUnpacked')
|
|
54
|
+
const _bundleMissing = Symbol('bundleMissing')
|
|
53
55
|
const _reifyNode = Symbol.for('reifyNode')
|
|
54
56
|
const _extractOrLink = Symbol('extractOrLink')
|
|
55
57
|
// defined by rebuild mixin
|
|
@@ -83,8 +85,9 @@ const _omitPeer = Symbol('omitPeer')
|
|
|
83
85
|
|
|
84
86
|
const _global = Symbol.for('global')
|
|
85
87
|
|
|
88
|
+
const _pruneBundledMetadeps = Symbol('pruneBundledMetadeps')
|
|
89
|
+
|
|
86
90
|
// defined by Ideal mixin
|
|
87
|
-
const _pruneBundledMetadeps = Symbol.for('pruneBundledMetadeps')
|
|
88
91
|
const _resolvedAdd = Symbol.for('resolvedAdd')
|
|
89
92
|
const _usePackageLock = Symbol.for('usePackageLock')
|
|
90
93
|
const _formatPackageLock = Symbol.for('formatPackageLock')
|
|
@@ -112,6 +115,10 @@ module.exports = cls => class Reifier extends cls {
|
|
|
112
115
|
this[_sparseTreeDirs] = new Set()
|
|
113
116
|
this[_sparseTreeRoots] = new Set()
|
|
114
117
|
this[_trashList] = new Set()
|
|
118
|
+
// the nodes we unpack to read their bundles
|
|
119
|
+
this[_bundleUnpacked] = new Set()
|
|
120
|
+
// child nodes we'd EXPECT to be included in a bundle, but aren't
|
|
121
|
+
this[_bundleMissing] = new Set()
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
// public method
|
|
@@ -289,8 +296,8 @@ module.exports = cls => class Reifier extends cls {
|
|
|
289
296
|
|
|
290
297
|
const filterNodes = []
|
|
291
298
|
if (this[_global] && this.explicitRequests.size) {
|
|
292
|
-
const idealTree = this.idealTree.target
|
|
293
|
-
const actualTree = this.actualTree.target
|
|
299
|
+
const idealTree = this.idealTree.target
|
|
300
|
+
const actualTree = this.actualTree.target
|
|
294
301
|
// we ONLY are allowed to make changes in the global top-level
|
|
295
302
|
// children where there's an explicit request.
|
|
296
303
|
for (const { name } of this.explicitRequests) {
|
|
@@ -334,7 +341,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
334
341
|
// removed later on in the process. optionally, also mark them
|
|
335
342
|
// as a retired paths, so that we move them out of the way and
|
|
336
343
|
// replace them when rolling back on failure.
|
|
337
|
-
[_addNodeToTrashList] (node, retire) {
|
|
344
|
+
[_addNodeToTrashList] (node, retire = false) {
|
|
338
345
|
const paths = [node.path, ...node.binPaths]
|
|
339
346
|
const moves = this[_retiredPaths]
|
|
340
347
|
this.log.silly('reify', 'mark', retire ? 'retired' : 'deleted', paths)
|
|
@@ -404,10 +411,9 @@ module.exports = cls => class Reifier extends cls {
|
|
|
404
411
|
return
|
|
405
412
|
|
|
406
413
|
process.emit('time', 'reify:trashOmits')
|
|
407
|
-
|
|
408
|
-
// not the parent-less top level nodes
|
|
414
|
+
|
|
409
415
|
const filter = node =>
|
|
410
|
-
node.
|
|
416
|
+
node.top.isProjectRoot &&
|
|
411
417
|
(node.peer && this[_omitPeer] ||
|
|
412
418
|
node.dev && this[_omitDev] ||
|
|
413
419
|
node.optional && this[_omitOptional] ||
|
|
@@ -611,10 +617,9 @@ module.exports = cls => class Reifier extends cls {
|
|
|
611
617
|
[_loadBundlesAndUpdateTrees] (
|
|
612
618
|
depth = 0, bundlesByDepth = this[_getBundlesByDepth]()
|
|
613
619
|
) {
|
|
614
|
-
if (depth === 0)
|
|
615
|
-
this[_bundleUnpacked] = new Set()
|
|
620
|
+
if (depth === 0)
|
|
616
621
|
process.emit('time', 'reify:loadBundles')
|
|
617
|
-
|
|
622
|
+
|
|
618
623
|
const maxBundleDepth = bundlesByDepth.get('maxBundleDepth')
|
|
619
624
|
if (depth > maxBundleDepth) {
|
|
620
625
|
// if we did something, then prune the tree and update the diffs
|
|
@@ -643,14 +648,30 @@ module.exports = cls => class Reifier extends cls {
|
|
|
643
648
|
}))
|
|
644
649
|
// then load their unpacked children and move into the ideal tree
|
|
645
650
|
.then(nodes =>
|
|
646
|
-
promiseAllRejectLate(nodes.map(node =>
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
651
|
+
promiseAllRejectLate(nodes.map(async node => {
|
|
652
|
+
const arb = new this.constructor({
|
|
653
|
+
...this.options,
|
|
654
|
+
path: node.path,
|
|
655
|
+
})
|
|
656
|
+
const notTransplanted = new Set(node.children.keys())
|
|
657
|
+
await arb.loadActual({
|
|
658
|
+
root: node,
|
|
659
|
+
// don't transplant any sparse folders we created
|
|
660
|
+
// loadActual will set node.package to {} for empty directories
|
|
661
|
+
// if by chance there are some empty folders in the node_modules
|
|
662
|
+
// tree for some other reason, then ok, ignore those too.
|
|
663
|
+
transplantFilter: node => {
|
|
664
|
+
if (node.package._id) {
|
|
665
|
+
// it's actually in the bundle if it gets transplanted
|
|
666
|
+
notTransplanted.delete(node.name)
|
|
667
|
+
return true
|
|
668
|
+
} else
|
|
669
|
+
return false
|
|
670
|
+
},
|
|
671
|
+
})
|
|
672
|
+
for (const name of notTransplanted)
|
|
673
|
+
this[_bundleMissing].add(node.children.get(name))
|
|
674
|
+
})))
|
|
654
675
|
// move onto the next level of bundled items
|
|
655
676
|
.then(() => this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth))
|
|
656
677
|
}
|
|
@@ -664,7 +685,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
664
685
|
const node = diff.ideal
|
|
665
686
|
if (!node)
|
|
666
687
|
return
|
|
667
|
-
if (node.isProjectRoot
|
|
688
|
+
if (node.isProjectRoot)
|
|
668
689
|
return
|
|
669
690
|
|
|
670
691
|
const { bundleDependencies } = node.package
|
|
@@ -686,6 +707,27 @@ module.exports = cls => class Reifier extends cls {
|
|
|
686
707
|
// https://github.com/npm/cli/issues/1597#issuecomment-667639545
|
|
687
708
|
[_pruneBundledMetadeps] (bundlesByDepth) {
|
|
688
709
|
const bundleShadowed = new Set()
|
|
710
|
+
|
|
711
|
+
// Example dep graph:
|
|
712
|
+
// root -> (a, c)
|
|
713
|
+
// a -> BUNDLE(b)
|
|
714
|
+
// b -> c
|
|
715
|
+
// c -> b
|
|
716
|
+
//
|
|
717
|
+
// package tree:
|
|
718
|
+
// root
|
|
719
|
+
// +-- a
|
|
720
|
+
// | +-- b(1)
|
|
721
|
+
// | +-- c(1)
|
|
722
|
+
// +-- b(2)
|
|
723
|
+
// +-- c(2)
|
|
724
|
+
// 1. mark everything that's shadowed by anything in the bundle. This
|
|
725
|
+
// marks b(2) and c(2).
|
|
726
|
+
// 2. anything with edgesIn from outside the set, mark not-extraneous,
|
|
727
|
+
// remove from set. This unmarks c(2).
|
|
728
|
+
// 3. continue until no change
|
|
729
|
+
// 4. remove everything in the set from the tree. b(2) is pruned
|
|
730
|
+
|
|
689
731
|
// create the list of nodes shadowed by children of bundlers
|
|
690
732
|
for (const bundles of bundlesByDepth.values()) {
|
|
691
733
|
// skip the 'maxBundleDepth' item
|
|
@@ -701,36 +743,50 @@ module.exports = cls => class Reifier extends cls {
|
|
|
701
743
|
}
|
|
702
744
|
}
|
|
703
745
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
746
|
+
|
|
747
|
+
// lib -> (a@1.x) BUNDLE(a@1.2.3 (b@1.2.3))
|
|
748
|
+
// a@1.2.3 -> (b@1.2.3)
|
|
749
|
+
// a@1.3.0 -> (b@2)
|
|
750
|
+
// b@1.2.3 -> ()
|
|
751
|
+
// b@2 -> (c@2)
|
|
752
|
+
//
|
|
753
|
+
// root
|
|
754
|
+
// +-- lib
|
|
755
|
+
// | +-- a@1.2.3
|
|
756
|
+
// | +-- b@1.2.3
|
|
757
|
+
// +-- b@2 <-- shadowed, now extraneous
|
|
758
|
+
// +-- c@2 <-- also shadowed, because only dependent is shadowed
|
|
759
|
+
for (const shadow of bundleShadowed) {
|
|
760
|
+
for (const shadDep of shadow.edgesOut.values()) {
|
|
761
|
+
/* istanbul ignore else - pretty unusual situation, just being
|
|
762
|
+
* defensive here. Would mean that a bundled dep has a dependency
|
|
763
|
+
* that is unmet. which, weird, but if you bundle it, we take
|
|
764
|
+
* whatever you put there and assume the publisher knows best. */
|
|
765
|
+
if (shadDep.to) {
|
|
766
|
+
bundleShadowed.add(shadDep.to)
|
|
767
|
+
shadDep.to.extraneous = true
|
|
711
768
|
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
712
771
|
|
|
772
|
+
let changed
|
|
773
|
+
do {
|
|
774
|
+
changed = false
|
|
775
|
+
for (const shadow of bundleShadowed) {
|
|
713
776
|
for (const edge of shadow.edgesIn) {
|
|
714
|
-
if (!edge.from
|
|
777
|
+
if (!bundleShadowed.has(edge.from)) {
|
|
715
778
|
shadow.extraneous = false
|
|
716
779
|
bundleShadowed.delete(shadow)
|
|
717
780
|
changed = true
|
|
718
|
-
|
|
719
|
-
for (const shadDep of shadow.edgesOut.values()) {
|
|
720
|
-
/* istanbul ignore else - pretty unusual situation, just being
|
|
721
|
-
* defensive here. Would mean that a bundled dep has a dependency
|
|
722
|
-
* that is unmet. which, weird, but if you bundle it, we take
|
|
723
|
-
* whatever you put there and assume the publisher knows best. */
|
|
724
|
-
if (shadDep.to)
|
|
725
|
-
bundleShadowed.add(shadDep.to)
|
|
726
|
-
}
|
|
781
|
+
break
|
|
727
782
|
}
|
|
728
783
|
}
|
|
729
784
|
}
|
|
730
|
-
}
|
|
785
|
+
} while (changed)
|
|
786
|
+
|
|
731
787
|
for (const shadow of bundleShadowed) {
|
|
732
|
-
shadow.parent = null
|
|
733
788
|
this[_addNodeToTrashList](shadow)
|
|
789
|
+
shadow.root = null
|
|
734
790
|
}
|
|
735
791
|
}
|
|
736
792
|
|
|
@@ -781,6 +837,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
781
837
|
const node = diff.ideal
|
|
782
838
|
const bd = this[_bundleUnpacked].has(node)
|
|
783
839
|
const sw = this[_shrinkwrapInflated].has(node)
|
|
840
|
+
const bundleMissing = this[_bundleMissing].has(node)
|
|
784
841
|
|
|
785
842
|
// check whether we still need to unpack this one.
|
|
786
843
|
// test the inDepBundle last, since that's potentially a tree walk.
|
|
@@ -788,7 +845,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
788
845
|
!node.isRoot && // root node already exists
|
|
789
846
|
!bd && // already unpacked to read bundle
|
|
790
847
|
!sw && // already unpacked to read sw
|
|
791
|
-
!node.inDepBundle // already unpacked by another dep's bundle
|
|
848
|
+
(bundleMissing || !node.inDepBundle) // already unpacked by another dep's bundle
|
|
792
849
|
|
|
793
850
|
if (doUnpack)
|
|
794
851
|
unpacks.push(this[_reifyNode](node))
|
|
@@ -815,8 +872,26 @@ module.exports = cls => class Reifier extends cls {
|
|
|
815
872
|
const moves = this[_retiredPaths]
|
|
816
873
|
this[_retiredUnchanged] = {}
|
|
817
874
|
return promiseAllRejectLate(this.diff.children.map(diff => {
|
|
818
|
-
|
|
875
|
+
// skip if nothing was retired
|
|
876
|
+
if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE')
|
|
877
|
+
return
|
|
878
|
+
|
|
879
|
+
const { path: realFolder } = diff.actual
|
|
819
880
|
const retireFolder = moves[realFolder]
|
|
881
|
+
/* istanbul ignore next - should be impossible */
|
|
882
|
+
debug(() => {
|
|
883
|
+
if (!retireFolder) {
|
|
884
|
+
const er = new Error('trying to un-retire but not retired')
|
|
885
|
+
throw Object.assign(er, {
|
|
886
|
+
realFolder,
|
|
887
|
+
retireFolder,
|
|
888
|
+
actual: diff.actual,
|
|
889
|
+
ideal: diff.ideal,
|
|
890
|
+
action: diff.action,
|
|
891
|
+
})
|
|
892
|
+
}
|
|
893
|
+
})
|
|
894
|
+
|
|
820
895
|
this[_retiredUnchanged][retireFolder] = []
|
|
821
896
|
return promiseAllRejectLate(diff.unchanged.map(node => {
|
|
822
897
|
// no need to roll back links, since we'll just delete them anyway
|
|
@@ -824,7 +899,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
824
899
|
return mkdirp(dirname(node.path)).then(() => this[_reifyNode](node))
|
|
825
900
|
|
|
826
901
|
// will have been moved/unpacked along with bundler
|
|
827
|
-
if (node.inDepBundle)
|
|
902
|
+
if (node.inDepBundle && !this[_bundleMissing].has(node))
|
|
828
903
|
return
|
|
829
904
|
|
|
830
905
|
this[_retiredUnchanged][retireFolder].push(node)
|
|
@@ -887,6 +962,18 @@ module.exports = cls => class Reifier extends cls {
|
|
|
887
962
|
filter: diff => diff.action === 'ADD' || diff.action === 'CHANGE',
|
|
888
963
|
})
|
|
889
964
|
|
|
965
|
+
// pick up link nodes from the unchanged list as we want to run their
|
|
966
|
+
// scripts in every install despite of having a diff status change
|
|
967
|
+
for (const node of this.diff.unchanged) {
|
|
968
|
+
const tree = node.root.target
|
|
969
|
+
|
|
970
|
+
// skip links that only live within node_modules as they are most
|
|
971
|
+
// likely managed by packages we installed, we only want to rebuild
|
|
972
|
+
// unchanged links we directly manage
|
|
973
|
+
if (node.isLink && node.target.fsTop === tree)
|
|
974
|
+
nodes.push(node)
|
|
975
|
+
}
|
|
976
|
+
|
|
890
977
|
return this.rebuild({ nodes, handleOptionalFailure: true })
|
|
891
978
|
.then(() => process.emit('timeEnd', 'reify:build'))
|
|
892
979
|
}
|
|
@@ -1029,6 +1116,25 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1029
1116
|
|
|
1030
1117
|
const promises = [this[_saveLockFile](saveOpt)]
|
|
1031
1118
|
|
|
1119
|
+
const updatePackageJson = async (tree) => {
|
|
1120
|
+
const pkgJson = await PackageJson.load(tree.path)
|
|
1121
|
+
.catch(() => new PackageJson(tree.path))
|
|
1122
|
+
const {
|
|
1123
|
+
dependencies = {},
|
|
1124
|
+
devDependencies = {},
|
|
1125
|
+
optionalDependencies = {},
|
|
1126
|
+
peerDependencies = {},
|
|
1127
|
+
} = tree.package
|
|
1128
|
+
|
|
1129
|
+
pkgJson.update({
|
|
1130
|
+
dependencies,
|
|
1131
|
+
devDependencies,
|
|
1132
|
+
optionalDependencies,
|
|
1133
|
+
peerDependencies,
|
|
1134
|
+
})
|
|
1135
|
+
await pkgJson.save()
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1032
1138
|
// grab any from explicitRequests that had deps removed
|
|
1033
1139
|
for (const { from: tree } of this.explicitRequests)
|
|
1034
1140
|
updatedTrees.add(tree)
|
|
@@ -1036,7 +1142,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1036
1142
|
for (const tree of updatedTrees) {
|
|
1037
1143
|
// refresh the edges so they have the correct specs
|
|
1038
1144
|
tree.package = tree.package
|
|
1039
|
-
promises.push(
|
|
1145
|
+
promises.push(updatePackageJson(tree))
|
|
1040
1146
|
}
|
|
1041
1147
|
|
|
1042
1148
|
await Promise.all(promises)
|
package/lib/calc-dep-flags.js
CHANGED
|
@@ -29,7 +29,7 @@ const calcDepFlagsStep = (node) => {
|
|
|
29
29
|
resetParents(node, 'optional')
|
|
30
30
|
|
|
31
31
|
// for links, map their hierarchy appropriately
|
|
32
|
-
if (node.
|
|
32
|
+
if (node.isLink) {
|
|
33
33
|
node.target.dev = node.dev
|
|
34
34
|
node.target.optional = node.optional
|
|
35
35
|
node.target.devOptional = node.devOptional
|
|
@@ -92,10 +92,10 @@ const unsetFlag = (node, flag) => {
|
|
|
92
92
|
tree: node,
|
|
93
93
|
visit: node => {
|
|
94
94
|
node.extraneous = node[flag] = false
|
|
95
|
-
if (node.
|
|
95
|
+
if (node.isLink)
|
|
96
96
|
node.target.extraneous = node.target[flag] = false
|
|
97
97
|
},
|
|
98
|
-
getChildren: node => [...
|
|
98
|
+
getChildren: node => [...node.target.edgesOut.values()]
|
|
99
99
|
.filter(edge => edge.to && edge.to[flag] &&
|
|
100
100
|
(flag !== 'peer' && edge.type === 'peer' || edge.type === 'prod'))
|
|
101
101
|
.map(edge => edge.to),
|