UNPKG

1.68 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.topologicalSort = void 0;
4/**
5 * Return a topological sort of all elements of xs, according to the given dependency functions
6 *
7 * Returns tranches of packages that do not have a dependency on each other.
8 *
9 * Dependencies outside the referenced set are ignored.
10 *
11 * Not a stable sort, but in order to keep the order as stable as possible, we'll sort by key
12 * among elements of equal precedence.
13 *
14 * @param xs - The elements to sort
15 * @param keyFn - Return an element's identifier
16 * @param depFn - Return the identifiers of an element's dependencies
17 */
18function topologicalSort(xs, keyFn, depFn) {
19 const remaining = new Map();
20 for (const element of xs) {
21 const key = keyFn(element);
22 remaining.set(key, { key, element, dependencies: depFn(element) });
23 }
24 const ret = new Array();
25 while (remaining.size > 0) {
26 // All elements with no more deps in the set can be ordered
27 const selectable = Array.from(remaining.values()).filter((e) => e.dependencies.every((d) => !remaining.has(d)));
28 selectable.sort((a, b) => (a.key < b.key ? -1 : b.key < a.key ? 1 : 0));
29 ret.push(selectable.map((s) => s.element));
30 for (const selected of selectable) {
31 remaining.delete(selected.key);
32 }
33 // If we didn't make any progress, we got stuck
34 if (selectable.length === 0) {
35 throw new Error(`Could not determine ordering between: ${Array.from(remaining.keys()).join(', ')}`);
36 }
37 }
38 return ret;
39}
40exports.topologicalSort = topologicalSort;
41//# sourceMappingURL=toposort.js.map
\No newline at end of file