-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
run-topologically.js
45 lines (35 loc) · 1.14 KB
/
run-topologically.js
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
"use strict";
const PQueue = require("p-queue");
const figgyPudding = require("figgy-pudding");
const QueryGraph = require("@lerna/query-graph");
module.exports = runTopologically;
const TopologicalConfig = figgyPudding({
packages: {},
concurrency: {},
"reject-cycles": {},
rejectCycles: "reject-cycles",
runner: {},
});
function runTopologically(_opts) {
const opts = TopologicalConfig(_opts);
const { packages, concurrency, rejectCycles, runner } = opts;
const queue = new PQueue({ concurrency });
const graph = new QueryGraph(packages, rejectCycles);
return new Promise((resolve, reject) => {
const returnValues = [];
const queueNextAvailablePackages = () =>
graph.getAvailablePackages().forEach(({ pkg, name }) => {
graph.markAsTaken(name);
queue
.add(() =>
runner(pkg)
.then(value => returnValues.push(value))
.then(() => graph.markAsDone(pkg))
.then(() => queueNextAvailablePackages())
)
.catch(reject);
});
queueNextAvailablePackages();
return queue.onIdle().then(() => resolve(returnValues));
});
}