@haragei/dag
Version:
A Directed Acyclic Graph (DAG) library with online cycle detection and topological ordering.
1 lines • 51.6 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/errors.ts","../src/internal/order.ts","../src/internal/priority-queue.ts","../src/internal/union.ts","../src/dag.ts"],"sourcesContent":["/**\n * Error thrown when a cycle would be introduced in a DAG.\n */\nexport class CycleError extends Error {\n public constructor() {\n super('Cycle detected');\n this.name = 'CycleError';\n }\n}\n","import type { Node } from './node';\n\n/**\n * Compares two Node<T> objects by order.\n *\n * @param lhs - The left hand-side operand.\n * @param rhs - The right hand-side operand.\n * @return Negative number if 'lhs' is less than 'rhs', positive number if\n * `lhs` is greater than `rhs`, or 0 if they have equal order.\n */\nexport function byOrder<T>(lhs: Node<T>, rhs: Node<T>): -1 | 0 | 1 {\n return byValue(lhs.order, rhs.order);\n}\n\n/**\n * Compares two numbers by value.\n *\n * @param lhs - The left hand-side operand.\n * @param rhs - The right hand-side operand.\n * @return Negative number if 'lhs' is less than 'rhs', positive number if\n * `lhs` is greater than `rhs`, or 0 if they are equal.\n */\nexport function byValue(lhs: number, rhs: number): -1 | 0 | 1 {\n return lhs < rhs ? -1 : lhs == rhs ? 0 : +1;\n}\n","/**\n * A simple priority queue based on a sorted array.\n */\nexport class PriorityQueue<T> {\n #data: T[];\n #priorities: number[];\n\n /**\n * Creates a new, empty priority queue.\n */\n public constructor() {\n this.#data = [];\n this.#priorities = [];\n }\n\n /**\n * Enqueues an item with the given priority.\n *\n * The priority is in ascending order, where lower values have higher priority.\n *\n * @param item - Item to insert to the queue.\n * @param priority - Item priority to use to re-prioritize the queue.\n */\n public enqueue(item: T, priority: number): void {\n const { length } = this.#data;\n\n this.#data.push(item);\n this.#priorities.push(priority);\n\n if (length > 0 && this.#priorities[length - 1]! > priority) {\n let lo = 0,\n hi = length;\n\n while (lo < hi) {\n const mid = lo + Math.trunc((hi - lo) / 2);\n if (this.#priorities[mid]! < priority) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n if (lo < length) {\n this.#data.copyWithin(lo + 1, lo, length);\n this.#data[lo] = item;\n\n this.#priorities.copyWithin(lo + 1, lo, length);\n this.#priorities[lo] = priority;\n }\n }\n }\n\n /**\n * Returns iterator over all queue items in priority order.\n *\n * @returns Queue item iterator in priority order.\n */\n [Symbol.iterator](): Iterator<T> {\n return this.#data[Symbol.iterator]();\n }\n\n /**\n * Returns an array containing all queue items in priority order.\n *\n * @return Queue items in priority order.\n */\n public toArray(): T[] {\n return this.#data.slice(0);\n }\n}\n","/**\n * Combines two sets into a new set.\n *\n * @param a - The first set.\n * @param b - The second set.\n * @return A new set that contains all elements from both input sets.\n */\nexport function union<T>(a: Set<T>, b: Set<T>): Set<T> {\n if ('union' in a) {\n return a.union(b);\n }\n\n const result = new Set<T>(a);\n for (const item of b) {\n result.add(item);\n }\n\n return result;\n}\n","import { CycleError } from './errors';\nimport type { Node } from './internal/node';\nimport { byOrder, byValue } from './internal/order';\nimport { PriorityQueue } from './internal/priority-queue';\nimport { union } from './internal/union';\n\n/**\n * Represents a set of nodes that can be processed in parallel as defined by\n * their relationship to each other in the graph.\n */\nexport type ParallelCollection<T> = Set<T | SerialCollection<T>>;\n\n/**\n * Represents a list of nodes that must be processed sequentially as defined by\n * their relationship to each other in the graph.\n */\nexport type SerialCollection<T> = (T | Set<T>)[];\n\n/**\n * A Directed Acyclic Graph structure with online cycle detection and topological ordering.\n */\nexport class DAG<T> {\n /**\n * The internal state of the graph.\n */\n #nodes: Map<T, Node<T>>;\n\n /**\n * a topological order of the nodes in the graph.\n */\n #order: T[];\n\n /**\n * Creates a new DAG with optional initial nodes.\n *\n * @param initialNodes - An optional iterable of initial nodes to populate the graph with.\n */\n public constructor(initialNodes?: Iterable<T>) {\n this.#nodes = new Map();\n this.#order = [];\n\n if (initialNodes) {\n for (const node of initialNodes) {\n this.#ensureNodeExists(node);\n }\n }\n }\n\n /**\n * Returns a list of all nodes in the graph in a topological order.\n *\n * **Note:** for every `U -> V` directed edge, `U` will appear\n * before `V` in a topological order.\n *\n * @return An array of all graph nodes in a topological order.\n */\n public get order(): T[] {\n return this.#order.slice(0);\n }\n\n /**\n * Returns the number of nodes in the graph.\n *\n * @return Number of nodes in the graph\n */\n public get size(): number {\n return this.#nodes.size;\n }\n\n /**\n * Iterates over all nodes in the graph in a topological order.\n *\n * @alias keys\n * @return An iterator over all nodes in the graph.\n */\n [Symbol.iterator](): IterableIterator<T> {\n return this.#order[Symbol.iterator]();\n }\n\n /**\n * Iterates over all nodes in the graph in a topological order.\n *\n * @return An iterator over all nodes in the graph.\n */\n keys(): IterableIterator<T> {\n return this.#order[Symbol.iterator]();\n }\n\n /**\n * Creates a new, independent copy of this DAG.\n *\n * @return Clone of this DAG.\n */\n public copy(): DAG<T> {\n const clone = new DAG<T>();\n\n clone.#order = this.#order.slice(0);\n clone.#nodes = new Map();\n\n for (const [id, node] of this.#nodes) {\n clone.#nodes.set(id, {\n id,\n order: node.order,\n incoming: new Set(node.incoming),\n outgoing: new Set(node.outgoing),\n });\n }\n\n return clone;\n }\n\n /**\n * Removes all nodes (and their edges) from the graph.\n *\n * @return This DAG.\n */\n public clear(): this {\n this.#nodes.clear();\n this.#order.splice(0, this.#order.length);\n return this;\n }\n\n /**\n * Adds a node to the graph.\n * If the node already exists, this is a no-op.\n *\n * @param node - The node to add.\n * @return This DAG.\n */\n public add(node: T): this {\n this.#ensureNodeExists(node);\n return this;\n }\n\n /**\n * Checks if a specific node exists in the graph.\n *\n * @param node - The node to check.\n * @return `true` if the node exists, `false` otherwise.\n */\n public has(node: T): boolean {\n return this.#nodes.has(node);\n }\n\n /**\n * Removes a specified node from the graph.\n * If such node doesn't exist, this is a no-op.\n *\n * **Note:** This also removes all edges from or to the specified node.\n *\n * @param node - The node to remove.\n * @return This DAG.\n */\n public delete(node: T): this {\n const state = this.#nodes.get(node);\n\n if (state) {\n const index = state.order;\n const last = this.#order.length - 1;\n\n for (let i = index; i < last; i++) {\n this.#order[i] = this.#order[i + 1]!;\n this.#nodes.get(this.#order[i]!)!.order = i;\n }\n\n this.#order.pop();\n\n for (const id of state.incoming) {\n this.#nodes.get(id)!.outgoing.delete(node);\n }\n for (const id of state.outgoing) {\n this.#nodes.get(id)!.incoming.delete(node);\n }\n\n this.#nodes.delete(node);\n }\n\n return this;\n }\n\n /**\n * Tries to add a directed edge to the graph.\n *\n * If any of the nodes doesn't already exist, it will be added.\n *\n * If inserting the given edge would introduce a cycle no changes\n * are made to the graph and CycleError is thrown.\n *\n * Adding an edge from a node to that same node (i.e. `from` and `to` are\n * the same) is considered a cycle and such edge cannot be added.\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n * @return This DAG.\n */\n public addEdge(from: T, to: T): this {\n if (from == to) {\n throw new CycleError();\n }\n\n this.#addEdge(from, to);\n\n return this;\n }\n\n /**\n * Tries to add a directed edge to the graph.\n *\n * If any of the nodes doesn't already exist, it will be added.\n *\n * If inserting the given edge would introduce a cycle no changes\n * are made to the graph and `false` is returned.\n *\n * Adding an edge from a node to that same node (i.e. `from` and `to` are\n * the same) is considered a cycle and such edge cannot be added.\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n * @return `true` if the edge was added, `false` otherwise.\n */\n public tryAddEdge(from: T, to: T): boolean {\n try {\n this.addEdge(from, to);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Checks if a specific (directed) edge exists in the graph.\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n * @return `true` if the edge exists, `false` otherwise.\n */\n public hasEdge(from: T, to: T): boolean {\n const node = this.#nodes.get(from);\n return node !== undefined && node.outgoing.has(to);\n }\n\n /**\n * Removes a specified edge from the graph.\n * If such edge doesn't exist, this is a no-op.\n *\n * **Note:** this removes a directed edge. If an edge A -> B exists,\n * it will not be removed with a removeEdge(B, A) call.\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n * @return This DAG.\n */\n public deleteEdge(from: T, to: T): this {\n if (this.hasEdge(from, to)) {\n this.#nodes.get(from)!.outgoing.delete(to);\n this.#nodes.get(to)!.incoming.delete(from);\n }\n\n return this;\n }\n\n /**\n * Removes all outgoing edges from a given node.\n * If such node doesn't exist, this is a no-op.\n *\n * @param node - The node to remove outgoing edges from.\n * @return This DAG.\n */\n public deleteOutgoingEdgesOf(node: T): this {\n return this.#deleteAllEdges('outgoing', node);\n }\n\n /**\n * Removes all incoming edges to a given node.\n * If such node doesn't exist, this is a no-op.\n *\n * @param node - The node to remove incoming edges to.\n * @return This DAG.\n */\n public deleteIncomingEdgesOf(node: T): this {\n return this.#deleteAllEdges('incoming', node);\n }\n\n /**\n * Returns the given nodes in a topological order.\n *\n * In a case that a node does not exist in the graph, it is pushed to the end of the array.\n *\n * @param nodes - The nodes to sort.\n * @return An array of the given nodes in a topological order.\n */\n public getNodeOrder(...nodes: T[]): T[] {\n return this.sortNodes(nodes);\n }\n\n /**\n * Sorts the given array of nodes, in place by their topological order.\n *\n * In a case that a node does not exist in the graph, it is pushed to the end of the array.\n *\n * @param nodes - The nodes to sort.\n * @return The input array of nodes, sorted in a topological order.\n */\n public sortNodes(nodes: T[]): T[] {\n return nodes.sort((lhsId, rhsId) => {\n const lhs = this.#nodes.get(lhsId);\n if (!lhs) {\n return +1;\n }\n\n const rhs = this.#nodes.get(rhsId);\n if (!rhs) {\n return -1;\n }\n\n return byValue(lhs.order, rhs.order);\n });\n }\n\n /**\n * Returns (an unordered) set of all immediate predecessors of the given nodes.\n *\n * @param nodes - The nodes to get immediate predecessors of.\n * @return An unordered set of all immediate predecessors of the given nodes.\n */\n public getImmediatePredecessorsOf(...nodes: T[]): Set<T> {\n return this.#getImmediate('incoming', ...nodes);\n }\n\n /**\n * Returns an iterable of all immediate predecessors of the given nodes which\n * iterates over them in a topological order.\n *\n * @param nodes - The nodes to get immediate predecessors of.\n * @return A topologically ordered iterable of all immediate predecessors of the given nodes.\n */\n public getOrderedImmediatePredecessorsOf(...nodes: T[]): Iterable<T> {\n return this.#toOrderedIterable(this.getImmediatePredecessorsOf(...nodes));\n }\n\n /**\n * Returns (an unordered) set of all predecessors of the given nodes.\n *\n * @param nodes - The nodes to get predecessors of.\n * @return An unordered set of all predecessors of the given nodes.\n */\n public getPredecessorsOf(...nodes: T[]): Set<T> {\n return this.#getReachable('incoming', ...nodes);\n }\n\n /**\n * Returns an iterable of all predecessors of the given nodes which\n * iterates over them in a topological order.\n *\n * @param nodes - The nodes to get predecessors of.\n * @return A topologically ordered iterable of all predecessors of the given nodes.\n */\n public getOrderedPredecessorsOf(...nodes: T[]): Iterable<T> {\n return this.#toOrderedIterable(this.getPredecessorsOf(...nodes));\n }\n\n /**\n * Returns (an unordered) set of all immediate successors of the given nodes.\n *\n * @param nodes - The nodes to get immediate successors of.\n * @return An unordered set of all immediate successors of the given nodes.\n */\n public getImmediateSuccessorsOf(...nodes: T[]): Set<T> {\n return this.#getImmediate('outgoing', ...nodes);\n }\n\n /**\n * Returns an iterable of all immediate successors of the given nodes which\n * iterates over them in a topological order.\n *\n * @param nodes - The nodes to get immediate successors of.\n * @return A topologically ordered iterable of all immediate successors of the given nodes.\n */\n public getOrderedImmediateSuccessorsOf(...nodes: T[]): Iterable<T> {\n return this.#toOrderedIterable(this.getImmediateSuccessorsOf(...nodes));\n }\n\n /**\n * Returns (an unordered) set of all successors of the given nodes.\n *\n * @param nodes - The nodes to get successors of.\n * @return An unordered set of all successors of the given nodes.\n */\n public getSuccessorsOf(...nodes: T[]): Set<T> {\n return this.#getReachable('outgoing', ...nodes);\n }\n\n /**\n * Returns an iterable of all successors of the given nodes which\n * iterates over them in a topological order.\n *\n * @param nodes - The nodes to get successors of.\n * @return A topologically ordered iterable of all successors of the given nodes.\n */\n public getOrderedSuccessorsOf(...nodes: T[]): Iterable<T> {\n return this.#toOrderedIterable(this.getSuccessorsOf(...nodes));\n }\n\n /**\n * Checks whether a directed path between two nodes exists in the graph.\n *\n * If A is directly connected to B, `hasPath(A, B)` is exactly the same as `hasEdge(A, B)`.\n * On the other hand, if only the edges `A -> B` and `A -> C` exists in the\n * graph, a `hasPath(A, C)` returns `true`, while `hasEdge(A, C)` returns `false`.\n *\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n * @return `true` if a directed path exists, `false` otherwise.\n */\n public hasPath(from: T, to: T): boolean {\n if (from == to) {\n return false;\n }\n\n const fromNode = this.#nodes.get(from);\n const toNode = this.#nodes.get(to);\n\n if (!fromNode || !toNode || fromNode.order > toNode.order) {\n return false;\n }\n\n if (fromNode.outgoing.has(to)) {\n return true;\n }\n\n const queue = [from];\n const visited = new Set(queue);\n\n while (queue.length > 0) {\n for (const successor of this.#nodes.get(queue.shift()!)!.outgoing) {\n if (successor == to) {\n return true;\n }\n\n if (!visited.has(successor)) {\n visited.add(successor);\n queue.push(successor);\n }\n }\n }\n\n return false;\n }\n\n /**\n * Merges two nodes if such action would not introduce a cycle.\n *\n * \"Merging\" of A and B is performed by making:\n * - all immediate predecessors of B be immediate predecessors of A, and\n * - all immediate successors of B be immediate successors of A.\n *\n * After that remapping, node B gets removed from the graph.\n *\n * **Note:** This method is a no-op if either A or B is absent in the graph.\n *\n * If there is a path between A and B (in either direction), a CycleError\n * gets thrown, and the graph is not changed.\n *\n * @param a - The first node to merge.\n * @param b - The second node to merge.\n * @return This DAG.\n */\n public mergeNodes(a: T, b: T): this {\n if (a == b) {\n return this;\n }\n\n const nodeA = this.#nodes.get(a);\n const nodeB = this.#nodes.get(b);\n\n if (nodeA && nodeB) {\n if (this.hasPath(a, b) || this.hasPath(b, a)) {\n throw new CycleError();\n }\n\n for (const predecessor of nodeB.incoming) {\n this.addEdge(predecessor, a);\n }\n\n for (const successor of nodeB.outgoing) {\n this.addEdge(a, successor);\n }\n\n this.delete(b);\n }\n\n return this;\n }\n\n /**\n * Tries to merge two nodes if such action would not introduce a cycle.\n *\n * \"Merging\" of A and B is performed by making:\n * - all immediate predecessors of B be immediate predecessors of A, and\n * - all immediate successors of B be immediate successors of A.\n *\n * After that remapping, node B gets removed from the graph.\n *\n * **Note:** This method is a no-op if either A or B is absent in the graph.\n *\n * If there is a path between A and B (in either direction), the merging would\n * introduce a cycle so this function returns `false`, and the graph is not changed.\n *\n * @param a - The first node to merge.\n * @param b - The second node to merge.\n * @return True if the nodes were successfully merged, or if\n * at least one of the given nodes is not present in the graph.\n */\n tryMergeNodes(a: T, b: T): boolean {\n try {\n this.mergeNodes(a, b);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Returns an array of node arrays, where each inner array represents a subgraph.\n *\n * The nodes in each subgraph are topologically ordered.\n *\n * @return An array of independent subgraphs.\n */\n subGraphs(): T[][] {\n const result: T[][] = [];\n\n if (this.#order.length == 0) {\n return result;\n }\n\n const visited = new Set<T>();\n\n for (const id of this.#order) {\n if (visited.has(id)) {\n continue;\n }\n\n const subGraph = new PriorityQueue<T>();\n const stack = [id];\n\n while (stack.length > 0) {\n const id = stack.pop()!;\n\n if (visited.has(id)) {\n continue;\n }\n\n const node = this.#nodes.get(id)!;\n\n visited.add(id);\n subGraph.enqueue(id, node.order);\n\n for (const successor of node.outgoing) {\n if (!visited.has(successor)) {\n stack.push(successor);\n }\n }\n }\n\n result.push(subGraph.toArray());\n }\n\n return result;\n }\n\n /**\n * Returns a set of all subgraphs in the graph.\n *\n * Each subgraph is represented either as a single node, or as an array which\n * is meant to be processed sequentially and its items are either a single node\n * or a Set of nodes that can be processed in parallel.\n *\n * @example\n * ```typescript\n * const dag = new DAG<string>(['Z']);\n * dag.addEdge('A', 'B');\n * dag.addEdge('A', 'C');\n * dag.addEdge('B', 'D');\n * dag.addEdge('C', 'D');\n * dag.addEdge('X', 'Y');\n *\n * console.log(dag.parallelize());\n * // Set(3) { [ 'A', Set(2) { 'B', 'C' }, 'D' ], [ 'X', 'Y' ], 'Z' }\n *```\n *\n * @return A set of all subgraphs in the graph, parallelized.\n */\n parallelize(): ParallelCollection<T> {\n const result: ParallelCollection<T> = new Set();\n\n for (const subGraph of this.subGraphs()) {\n result.add(this.#parallelize(subGraph));\n }\n\n return result;\n }\n\n /**\n * Returns a list of all nodes in the given subgraph, ordered topologically.\n * The list is meant to be processed sequentially and its items are either\n * a single node or a Set of nodes that can be processed in parallel.\n *\n * @param subGraph - The subgraph to parallelize.\n * @return The parallelized subgraph.\n */\n #parallelize(subGraph: ReadonlyArray<T>): SerialCollection<T> | T {\n if (subGraph.length == 1) {\n return subGraph[0]!;\n }\n\n const levels: Map<T, number> = new Map();\n const groups: Set<T>[] = [];\n\n for (const nodeId of subGraph) {\n const node = this.#nodes.get(nodeId);\n if (!node) {\n continue;\n }\n\n const level = Math.max(\n 0,\n ...Array.from(node.incoming, (id) => (levels.get(id) || 0) + 1),\n );\n\n levels.set(nodeId, level);\n if (groups.length <= level) {\n groups.push(new Set<T>());\n }\n groups[level]!.add(nodeId);\n }\n\n return groups.map((group) => (group.size == 1 ? Array.from(group)[0]! : group));\n }\n\n /**\n * Adds a node to the graph and returns it.\n * If the node already exists, it is returned unchanged.\n *\n * @param id - The node to add.\n * @returns The Node state object.\n */\n #ensureNodeExists(id: T): Node<T> {\n let node = this.#nodes.get(id);\n if (node) {\n return node;\n }\n\n node = {\n id,\n order: this.#order.length,\n incoming: new Set(),\n outgoing: new Set(),\n };\n\n this.#nodes.set(id, node);\n this.#order.push(id);\n\n return node;\n }\n\n /**\n * Tries to add a directed edge to the graph.\n *\n * If any of the nodes doesn't already exist, it will be added.\n *\n * If inserting the given edge would introduce a cycle no changes\n * are made to the graph and CycleError is thrown.\n *\n * @param from - The \"source\" node.\n * @param to - The \"target\" node.\n */\n #addEdge(from: T, to: T): void {\n if (this.hasEdge(from, to)) {\n return;\n }\n\n //\n // This function implements the PK algorithm for incremental\n // topological ordering as presented in the paper:\n //\n //\t\tPEARCE, David J.; KELLY, Paul HJ. A dynamic algorithm for\n //\t\ttopologically sorting directed acyclic graphs.\n //\t\tLecture notes in computer science, 2004, 3059: 383-398.\n //\n //\t\thttps://citeseerx.ist.psu.edu/document?doi=388da0bed2a1658a34de39b28921de48f353b2ed\n //\n\n // N.B. intentionally reversing direction\n const u = this.#ensureNodeExists(to);\n const v = this.#ensureNodeExists(from);\n\n if (u.order < v.order) {\n const successors = this.#findSuccessors(u, v.order);\n const predecessors = this.#findPredecessors(v, u.order);\n\n successors.sort(byOrder);\n predecessors.sort(byOrder);\n\n const totalPredecessors = predecessors.length;\n const totalAffected = totalPredecessors + successors.length;\n\n const topology = new Array<number>(totalAffected);\n\n let i = 0;\n for (const { order } of successors) {\n topology[i++] = order;\n }\n for (const { order } of predecessors) {\n topology[i++] = order;\n }\n\n topology.sort(byValue);\n\n for (i = 0; i < totalPredecessors; i++) {\n const index = topology[i]!;\n const predecessor = predecessors[i]!;\n this.#order[index] = predecessor.id;\n predecessor.order = index;\n }\n for (i = totalPredecessors; i < totalAffected; i++) {\n const index = topology[i]!;\n const successor = successors[i - totalPredecessors]!;\n this.#order[index] = successor.id;\n successor.order = index;\n }\n }\n\n u.incoming.add(from);\n v.outgoing.add(to);\n }\n\n /**\n * Removes all edges from a given node in the given direction (i.e. incoming or outgoing).\n * If such node doesn't exist, this is a no-op.\n *\n * @param direction - The direction of the edges to remove.\n * @param node - The node whose incoming edges to remove.\n * @return This DAG.\n */\n #deleteAllEdges(direction: 'incoming' | 'outgoing', node: T): this {\n const state = this.#nodes.get(node);\n\n if (state) {\n const reversed = direction == 'incoming' ? 'outgoing' : 'incoming';\n\n for (const from of state[direction]) {\n this.#nodes.get(from)![reversed].delete(node);\n }\n\n state[direction].clear();\n }\n\n return this;\n }\n\n /**\n * Returns all successors of the given node, such that their current topological\n * order is less than the given one. These nodes will need to be reordered.\n *\n * @param startNode - The node whose successors to return.\n * @param order - The order to constrain the successor set with.\n * @return The unordered list of successors nodes.\n */\n #findSuccessors(startNode: Node<T>, order: number): Node<T>[] {\n const result: Node<T>[] = [];\n const visited = new Set<T>();\n const stack = [startNode];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n\n if (visited.has(node.id)) {\n continue;\n }\n\n visited.add(node.id);\n result.push(node);\n\n for (const id of node.outgoing) {\n const successor = this.#nodes.get(id)!;\n\n if (successor.order == order) {\n throw new CycleError();\n }\n if (!visited.has(id) && successor.order < order) {\n stack.push(successor);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Returns all predecessors of the given node, such that their current topological\n * order is greater than the given one. These nodes will need to be reordered.\n *\n * @param startNode - The node whose predecessors to return.\n * @param order - The order to constrain the predecessor set with.\n * @return The unordered list of predecessors nodes.\n */\n #findPredecessors(startNode: Node<T>, order: number): Node<T>[] {\n const result: Node<T>[] = [];\n const visited = new Set<T>();\n const stack = [startNode];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n\n if (visited.has(node.id)) {\n continue;\n }\n\n visited.add(node.id);\n result.push(node);\n\n for (const id of node.incoming) {\n const predecessor = this.#nodes.get(id)!;\n\n if (!visited.has(id) && predecessor.order >= order) {\n stack.push(predecessor);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Returns (an unordered) set of all immediate neighbors of the given nodes.\n *\n * @param direction - The direction of the edges to traverse.\n * @param nodes - Nodes whose immediate neighbors to return.\n * @return An unordered set of all immediate neighbors of the given nodes.\n */\n #getImmediate(direction: 'incoming' | 'outgoing', ...nodes: T[]): Set<T> {\n let results = new Set<T>();\n\n for (const id of nodes) {\n const node = this.#nodes.get(id);\n if (node) {\n results = union(results, node[direction]);\n }\n }\n\n for (const id of nodes) {\n results.delete(id);\n }\n\n return results;\n }\n\n /**\n * Returns (an unordered) set of all nodes reachable from the given nodes.\n *\n * @param direction - The direction of the edges to traverse.\n * @param nodes - Nodes whose reachable nodes to return.\n * @return An unordered set of all reachable nodes of the given nodes..\n */\n #getReachable(direction: 'incoming' | 'outgoing', ...nodes: T[]): Set<T> {\n const results = new Set(nodes);\n const queue = nodes.slice(0);\n\n while (queue.length > 0) {\n const node = this.#nodes.get(queue.shift()!);\n if (!node) {\n continue;\n }\n\n for (const id of node[direction]) {\n if (!results.has(id)) {\n results.add(id);\n queue.push(id);\n }\n }\n }\n\n for (const id of nodes) {\n results.delete(id);\n }\n\n return results;\n }\n\n /**\n * Returns a new iterable which iterates over the nodes\n * in the given iterable in topological order.\n *\n * **Note:** This function assumes that all nodes\n * in the given iterable are present in the graph.\n *\n * @param ids - An iterable of node ids.\n * @returns Iterable over the given nodes in topological order.\n */\n #toOrderedIterable(ids: Iterable<T>): Iterable<T> {\n const queue = new PriorityQueue<T>();\n\n for (const id of ids) {\n queue.enqueue(id, this.#nodes.get(id)!.order);\n }\n\n return queue;\n }\n}\n"],"names":[],"mappings":"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