"use strict"; const util = require("util"); // TODO: Publish this as a stand-alone module module.exports = function kahn(nodes) { let queue = []; let list = []; // Start with all the zero-dependency nodes for (let node of nodes) { if (node.parents.length === 0) { queue.push(node); } } while (queue.length > 0) { let current = queue.shift(); list.push(current); // For each dependent/parent of this item for (let child of current.children) { child.parents.splice(child.parents.indexOf(current), 1); // If all its dependencies have been fully processed and removed if (child.parents.length === 0) { queue.push(child); } else { // TODO: Add a proper loop checker! if (child.children.some((item) => item === child) || child.parents.some((item) => item === child)) { throw new Error(`Dependency on self encountered: ${util.inspect(child)}`); } } } } return list; };