getDependencyLevels.js
1.58 KB
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
var each = require('std/each')
var getCode = require('./getCode')
var getRequireStatements = require('./getRequireStatements')
var resolve = require('./resolve')
module.exports = getDependencyLevels
function getDependencyLevels(mainModulePath) {
var leaves = []
var root = []
root.isRoot = true
root.path = mainModulePath
_buildDependencyTreeOf(root)
var levels = []
var seenPaths = {}
_buildLevel(leaves)
return levels
// builds full dependency tree, noting every dependency of every node
function _buildDependencyTreeOf(node) {
var requireStatements = getRequireStatements(getCode(node.path))
if (requireStatements.length == 0) {
return leaves.push(node)
}
each(requireStatements, function(requireStatement) {
var childNode = []
childNode.path = resolve.requireStatement(requireStatement, node.path)
childNode.parent = node
node.push(childNode)
_buildDependencyTreeOf(childNode)
})
node.waitingForNumChildren = node.length
}
// builds a list of dependency levels, where nodes in each level is dependent only on nodes in levels below it
// the dependency levels allow for parallel loading of every file in any given level
function _buildLevel(nodes) {
var level = []
levels.push(level)
var parents = []
each(nodes, function(node) {
if (!seenPaths[node.path]) {
seenPaths[node.path] = true
level.push(node.path)
}
if (node.isRoot) { return }
node.parent.waitingForNumChildren -= 1
if (node.parent.waitingForNumChildren == 0) {
parents.push(node.parent)
}
})
if (!parents.length) { return }
_buildLevel(parents)
}
}