import type * as Lantern from '../types/types.js'; import type { CPUNode } from './CPUNode.js'; import type { NetworkNode } from './NetworkNode.js'; /** * A union of all types derived from BaseNode, allowing type check discrimination * based on `node.type`. If a new node type is created, it should be added here. */ export type Node = CPUNode | NetworkNode; /** * @file This class encapsulates logic for handling resources and tasks used to model the * execution dependency graph of the page. A node has a unique identifier and can depend on other * nodes/be depended on. The construction of the graph maintains some important invariants that are * inherent to the model: * * 1. The graph is a DAG, there are no cycles. * 2. There is always a root node upon which all other nodes eventually depend. * * This allows particular optimizations in this class so that we do no need to check for cycles as * these methods are called and we can always start traversal at the root node. */ declare class BaseNode { static types: { readonly NETWORK: "network"; readonly CPU: "cpu"; }; _id: string; _isMainDocument: boolean; dependents: Node[]; dependencies: Node[]; constructor(id: string); get id(): string; get type(): 'network' | 'cpu'; /** * In microseconds */ get startTime(): number; /** * In microseconds */ get endTime(): number; setIsMainDocument(value: boolean): void; isMainDocument(): boolean; getDependents(): Node[]; getNumberOfDependents(): number; getDependencies(): Node[]; getNumberOfDependencies(): number; getRootNode(): Node; addDependent(node: Node): void; addDependency(node: Node): void; removeDependent(node: Node): void; removeDependency(node: Node): void; removeAllDependencies(): void; /** * Computes whether the given node is anywhere in the dependency graph of this node. * While this method can prevent cycles, it walks the graph and should be used sparingly. * Nodes are always considered dependent on themselves for the purposes of cycle detection. */ isDependentOn(node: BaseNode): boolean; /** * Clones the node's information without adding any dependencies/dependents. */ cloneWithoutRelationships(): Node; /** * Clones the entire graph connected to this node filtered by the optional predicate. If a node is * included by the predicate, all nodes along the paths between the node and the root will be included. If the * node this was called on is not included in the resulting filtered graph, the method will throw. * * This does not clone NetworkNode's `record` or `rawRecord` fields. It may be reasonable to clone the former, * to assist in graph construction, but the latter should never be cloned as one constraint of Lantern is that * the underlying data records are accessible for plain object reference equality checks. */ cloneWithRelationships(predicate?: (arg0: Node) => boolean): Node; /** * Traverses all connected nodes in BFS order, calling `callback` exactly once * on each. `traversalPath` is the shortest (though not necessarily unique) * path from `node` to the root of the iteration. * * The `getNextNodes` function takes a visited node and returns which nodes to * visit next. It defaults to returning the node's dependents. */ traverse(callback: (node: Node, traversalPath: Array>) => void, getNextNodes?: (arg0: Node) => Array>): void; /** * @see BaseNode.traverse */ traverseGenerator(getNextNodes?: (arg0: Node) => Node[]): Generator<{ node: Node; traversalPath: Node[]; }, void, unknown>; /** * If the given node has a cycle, returns a path representing that cycle. * Else returns null. * * Does a DFS on in its dependent graph. */ static findCycle(node: Node, direction?: 'dependents' | 'dependencies' | 'both'): BaseNode[] | null; canDependOn(node: Node): boolean; } export { BaseNode };