UNPKG

2.25 kBJavaScriptView Raw
1'use strict';
2
3var getParameterNames = require('get-parameter-names');
4
5exports.dfs = function(tasks, taskNames) {
6 var alreadyVisited = {};
7 var toExecute = {};
8
9 var execDfs = function(taskName) {
10 var task = tasks[taskName];
11 alreadyVisited[taskName] = true;
12 if (!task) {
13 throw 'No such dependency: ' + taskName;
14 }
15
16 var isSync = true;
17 for (var i = 0; i < task.dep.length; ++i) {
18 var dependency = tasks[task.dep[i]];
19
20 if (alreadyVisited[task.dep[i]]) {
21 throw 'Cycle detected, task: ' + task.name;
22 }
23
24 execDfs(task.dep[i]);
25
26 isSync = isSync && (dependency.value ||
27 dependency.isSync);
28 }
29
30 if (task.task) {
31 var params = getParameterNames(task.task);
32 task.isSync = isSync &&
33 params.indexOf('callback') === -1 &&
34 params.indexOf('cb') === -1;
35 } else {
36 task.isSync = true;
37 }
38 }
39
40 for (var i = 0; i < taskNames.length; ++i) {
41 alreadyVisited = {};
42
43 execDfs(taskNames[i]);
44
45 for (var key in alreadyVisited) {
46 toExecute[key] = true;
47 }
48 }
49
50 return Object.keys(toExecute);
51};
52
53exports.topoSort = function(tasks, taskNames) {
54 var sorted = [];
55 var upcoming = [];
56 var alreadyVisited = {};
57
58 for (var i = 0; i < taskNames.length; ++i) {
59 var task = tasks[taskNames[i]];
60 for (var j = 0; j < task.dep.length; ++j) {
61 tasks[task.dep[j]].dependents = tasks[task.dep[j]].dependents || [];
62 tasks[task.dep[j]].dependents.push(task.name);
63 }
64 }
65
66 for (var i = 0; i < taskNames.length; ++i) {
67 var dependencies = tasks[taskNames[i]].dep;
68 if (dependencies.length === 0) {
69 upcoming.push(taskNames[i]);
70 }
71 }
72
73 while (upcoming.length) {
74 var taskName = upcoming.shift();
75 var task = tasks[taskName];
76 alreadyVisited[taskName] = true;
77 sorted.push(taskName);
78
79 for (var i = 0; i < (task.dependents || []).length; ++i) {
80 var dependent = tasks[task.dependents[i]];
81 var ready = true;
82 for (var j = 0; j < dependent.dep.length; ++j) {
83 ready = ready && alreadyVisited[dependent.dep[j]];
84 if (!ready) {
85 break;
86 }
87 }
88
89 if (ready) {
90 upcoming.push(task.dependents[i]);
91 }
92 }
93 }
94
95 return sorted;
96};
\No newline at end of file