@notjustcoders/ioc-arise
Version:
Arise type-safe IoC containers from your code. Zero overhead, zero coupling.
69 lines • 2.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TopologicalSorter = void 0;
class TopologicalSorter {
/**
* Performs topological sorting on a dependency graph with cycle detection
* @param graph - A map where keys are nodes and values are their dependencies
* @param order - Sort order: 'asc' for ascending (default) or 'desc' for descending
* @returns Object containing sorted nodes and any detected cycles
*/
static sort(graph, order = 'asc') {
const visited = new Set();
const visiting = new Set();
const sorted = [];
const cycles = [];
const visit = (node, path = []) => {
if (visiting.has(node)) {
// Cycle detected
const cycleStart = path.indexOf(node);
cycles.push(path.slice(cycleStart).concat(node));
return;
}
if (visited.has(node)) {
return;
}
visiting.add(node);
const dependencies = this.getDependencies(graph, node);
for (const dep of dependencies) {
if (this.hasNode(graph, dep)) { // Only visit if dependency exists in graph
visit(dep, [...path, node]);
}
}
visiting.delete(node);
visited.add(node);
sorted.push(node);
};
const nodes = this.getNodes(graph);
for (const node of nodes) {
if (!visited.has(node)) {
visit(node);
}
}
const finalSorted = sorted.reverse();
return {
sorted: order === 'desc' ? finalSorted.reverse() : finalSorted,
cycles
};
}
static getDependencies(graph, node) {
if (graph instanceof Map) {
return graph.get(node) || [];
}
return graph[node] || [];
}
static hasNode(graph, node) {
if (graph instanceof Map) {
return graph.has(node);
}
return node in graph;
}
static getNodes(graph) {
if (graph instanceof Map) {
return Array.from(graph.keys());
}
return Object.keys(graph);
}
}
exports.TopologicalSorter = TopologicalSorter;
//# sourceMappingURL=topological-sorter.js.map