UNPKG

topological-sort-group

Version:

Topological sorting and cycle detection. Optional grouping for parallel processing

58 lines (57 loc) 2.11 kB
import get from './deepGet.js'; const isArray = Array.isArray || ((x)=>Object.prototype.toString.call(x) === '[object Array]'); let Graph = class Graph { static from(nodes, options) { const graph = new Graph(options); nodes.forEach((node)=>isArray(node) ? graph.add.apply(graph, node) : graph.add(node)); return graph; } key(keyOrValue) { if (this.path) return typeof keyOrValue === 'object' ? get(keyOrValue, this.path) : keyOrValue; return keyOrValue; } keys() { const keys = []; for(const key in this.nodeMap)keys.push(key); return keys; } value(key) { return this.nodeMap[key].value; } edges(key) { return this.nodeMap[key].edges; } add(keyOrValue, toKeyOrValue) { const key = this.key(keyOrValue); const value = this.path ? typeof keyOrValue === 'object' ? keyOrValue : undefined : keyOrValue; if (value !== undefined) { if (this.nodeMap[key] === undefined) this.nodeMap[key] = { value, edges: [] }; else if (this.nodeMap[key].value !== value) throw new Error(`Adding different node values to same graph. Key ${key}. Existing: ${JSON.stringify(this.nodeMap[key].value)}. New: ${JSON.stringify(value)}`); } // biome-ignore lint/style/noArguments: <explanation> if (arguments.length === 1) return; // add edge this.add(toKeyOrValue); const toKey = this.key(toKeyOrValue); this.nodeMap[key].edges.push(toKey); } degrees() { const degrees = {}; for(const from in this.nodeMap){ if (degrees[from] === undefined) degrees[from] = 0; this.nodeMap[from].edges.forEach((key)=>{ if (degrees[key] === undefined) degrees[key] = 0; degrees[key]++; }); } return degrees; } constructor(options){ this.path = options ? options.path || undefined : undefined; this.nodeMap = {}; } }; export { Graph as default };