bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
84 lines (64 loc) • 1.98 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toposortByLevels = toposortByLevels;
function _graphlib() {
const data = require("graphlib");
_graphlib = function () {
return data;
};
return data;
}
function _logger() {
const data = _interopRequireDefault(require("../../../logger/logger"));
_logger = function () {
return data;
};
return data;
}
function toposortByLevels(graph, throwForCycles = false) {
// @todo: @qballer, once you implement the option to not sort the graph, revisit the throwForCycles arg
const cycles = _graphlib().alg.findCycles(graph);
if (cycles.length) {
// impossible to topsort
if (throwForCycles) {
throw new Error(`fatal: graphlib was unable to topsort the components. circles: ${cycles}`);
}
_logger().default.warn(`unable to topsort. cycles: ${cycles}`);
return [graph.nodes()]; // all nodes on the same level
}
return getGraphSorted(graph).reduce((accum, curr) => {
const inEdges = graph.inEdges(curr);
if (!accum.length) {
accum.push({
inEdgeCount: inEdges ? inEdges.length : 0,
edges: [curr]
});
return accum;
}
if (!inEdges) {
return accum;
}
const prevInEdges = accum[accum.length - 1].inEdgeCount;
if (inEdges.length === prevInEdges) {
accum[accum.length - 1].edges.push(curr);
} else {
accum.push({
inEdgeCount: inEdges.length,
edges: [curr]
});
}
return accum;
}, []).map(level => level.edges);
}
function getGraphSorted(graph) {
try {
return _graphlib().alg.topsort(graph);
} catch (err) {
// should never arrive here, it's just a precaution, as topsort doesn't fail nicely
_logger().default.error(err);
throw new Error(`fatal: graphlib was unable to topsort the components. ${err.toString()}`);
}
}
;