/**
 * a way to enforce specific rankings of nodes
 *
 * A rank accessor assigns a numeric rank to some nodes. In general, nodes with
 * a lower rank come *before* nodes with a higher rank. Layering operators that
 * take a rank accessor additionally guarantee that nodes with the same rank
 * will share the same layer (if possible).
 *
 * @example
 *
 * This example demonstrates passing through a rank value that might exist on a
 * node.
 *
 * ```ts
 * function memberRank({ data }: GraphNode<{ rank?: number }>): number | undefined {
 *   return data.rank;
 * }
 * ```
 */
export type Rank<in NodeDatum = never, in LinkDatum = never> = (node: GraphNode<NodeDatum, LinkDatum>) => number | undefined;
/**
 * a link between nodes, with attached information
 *
 * The immutable version of {@link MutGraphLink}.
 */
export interface GraphLink<out NodeDatum = unknown, out LinkDatum = unknown> {
    /** The dag node this link comes from */
    readonly source: GraphNode<NodeDatum, LinkDatum>;
    /** The dag node this link goes to */
    readonly target: GraphNode<NodeDatum, LinkDatum>;
    /** layout control points assigned to the link */
    points: [number, number][];
    /** user data attached to this link */
    data: LinkDatum;
}
/**
 * a mutable link between nodes
 *
 * The mutable version of {@link GraphLink}.
 */
export interface MutGraphLink<in out NodeDatum, in out LinkDatum> extends GraphLink<NodeDatum, LinkDatum> {
    readonly source: MutGraphNode<NodeDatum, LinkDatum>;
    readonly target: MutGraphNode<NodeDatum, LinkDatum>;
    /** remove this link from the graph */
    delete(): void;
}
/**
 * A graph representation
 *
 * Graphs are collections of {@link GraphNode}s, held together by
 * {@link GraphLink}s, although there's no requirement that they're connected.
 * Graphs support iterating over their {@link nodes} and {@link links} as well
 * as checking if certain properties hold. Each node is also defined as a graph
 * of just its connected component, so all methods of a graph also apply to any
 * individual node, treated as all nodes reachable from the current node.
 *
 * The structure of a Graph is immutable, allowing for appropriate variance
 * with readonly methods. For a graph whos structure can be modified, see
 * {@link MutGraph}.
 *
 * Methods names preceeded by an `n` will return a number, often the length of
 * the iterable produces by the method sans-prefix.
 */
export interface Graph<out NodeDatum = unknown, out LinkDatum = unknown> {
    /**
     * an iterator over every {@link GraphNode | node} in the graph
     *
     * @remarks
     * Be careful not to modify the graph structure while iterating as any
     * modification, including adding or removing links, can change the behavior
     * of iteration giving unexpected results. If you want to guarantee
     * consistent iteration, allocating an array first with `[...graph.nodes()]` will
     * ensure consistent iteration.
     */
    nodes(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * compute a topological order of the graph
     *
     * If the graph can't be represented in topological order, this will try to
     * minimize the number of edge inversions. Optimally minimizing inversions is
     * np-complete, so this will only be approximate.
     *
     * You can optionally specify a {@link Rank} accessor that defines a
     * numerical rank for every node. Nodes with a lower rank will come before
     * nodes of a higher rank even if that requires more edge inversions. Nodes
     * without a rank are unconstrained.
     */
    topological(rank?: Rank<NodeDatum, LinkDatum>): GraphNode<NodeDatum, LinkDatum>[];
    /**
     * an iterator over every {@link GraphLink | link} in the graph
     */
    links(): IterableIterator<GraphLink<NodeDatum, LinkDatum>>;
    /** the number of nodes in the graph */
    nnodes(): number;
    /** the number of links in the graph */
    nlinks(): number;
    /**
     * an iterator over the roots of the graph
     *
     * The roots are defined as a set of nodes such that every node in the graph
     * is a descendant of one of the roots, an no root is a descendant of any
     * other root. It is guaranteed to include every node with no parents, but
     * one node in a cycle may be chosen if there is no unique root for that
     * cycle.
     *
     * @remarks the current implementation will return a minimal root set as long
     * as source cycles contain a node with a single parent.
     */
    roots(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * an iterator over the leaves of the graph
     *
     * The leaves are defined as a set of nodes such that every node in the graph
     * is an ancestor of one of the leaves, an no leaf is an ancestor of any
     * other leaf. It is guaranteed to include every node with no children, but
     * one node in a cycle may be chosen if there is no unique leaf for that
     * cycle.
     *
     * @remarks the current implementation will return a minimal leaf set as long
     * as target cycles contain a node with a single child.
     */
    leaves(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * an iterator over the sources of the graph
     *
     * Sources are nodes with no parents (in-degree zero). Unlike {@link roots},
     * this does not attempt cycle handling.
     */
    sources(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * an iterator over the sinks of the graph
     *
     * Sinks are nodes with no children (out-degree zero). Unlike {@link leaves},
     * this does not attempt cycle handling.
     */
    sinks(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * split a graph into connected components
     *
     * @remarks
     * Since each node behaves like a graph of its connected component,
     * this is equivalent with returning a graph of each connected component.
     *
     * @returns splits an iterable over a single node in each connected
     * component
     */
    split(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * true if every node in the graph is reachable from every other
     */
    connected(): boolean;
    /**
     * true if at least one node in this graph has multiple links to the same child
     */
    multi(): boolean;
    /**
     * true if there no cycles in the graph
     */
    acyclic(): boolean;
    /**
     * serialize the graph
     *
     * @remarks this is intended to be called automatically by `JSON.stringify`.
     */
    toJSON(): unknown;
}
/**
 * a mutable graph representation
 *
 * In addition to all of the methods inherent to {@link Graph}s, this also
 * allows structure graph modification with the {@link node} and {@link link}
 * methods to either create an empty node or create a link between two nodes.
 * Nodes and links can be removed with the delete method on
 * {@link MutGraphNode#delete | nodes} and {@link MutGraphLink#delete | links}.
 *
 * ## Performance
 *
 * In order to keep track of caches, internally adding links runs union-find
 * which has near, but not quite, constant complexity. However, various methods
 * can run in linear time making some access patterns run in worst case
 * quadratic if they're called in between modifications. This was ultimately
 * deemed acceptable as all modification will likely come before a layout, and
 * that will always take linear time.
 */
export interface MutGraph<in out NodeDatum, in out LinkDatum> extends Graph<NodeDatum, LinkDatum> {
    nodes(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    links(): IterableIterator<MutGraphLink<NodeDatum, LinkDatum>>;
    split(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    roots(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    leaves(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    sources(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    sinks(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    /**
     * add a new node with datum
     *
     * If `undefined` extends NodeDatum, datum can be elided and simply called as
     * ```ts
     * grf.node();
     * ```
     */
    node(...datum: undefined extends NodeDatum ? [datum?: NodeDatum] : [datum: NodeDatum]): MutGraphNode<NodeDatum, LinkDatum>;
    /**
     * add a new link from source to target
     *
     * If `undefined` extends LinkDatum, datum can be elided and simply called as
     * ```ts
     * grf.link(source, target);
     * ```
     */
    link(source: MutGraphNode<NodeDatum, LinkDatum>, target: MutGraphNode<NodeDatum, LinkDatum>, ...datum: undefined extends LinkDatum ? [datum?: LinkDatum] : [datum: LinkDatum]): MutGraphLink<NodeDatum, LinkDatum>;
}
export interface GraphNodeMixin<out NodeDatum, out LinkDatum> {
    /** user data for this node */
    data: NodeDatum;
    /** raw (possibly undefined) x coordinate for a node */
    ux?: number | undefined;
    /** raw (possibly undefined) y coordinate for a node */
    uy?: number | undefined;
    /**
     * view of {@link ux} that throws if ux is undefined
     */
    x: number;
    /**
     * view of {@link uy} that throws if uy is undefined
     */
    y: number;
    /** the number of unique parent nodes */
    nparents(): number;
    /** the number of unique child nodes */
    nchildren(): number;
    /** the number of parent links */
    nparentLinks(): number;
    /** the number of child links */
    nchildLinks(): number;
    /** the number of links from a specific node */
    nparentLinksTo(node: GraphNode<NodeDatum, LinkDatum>): number;
    /** iterator over every link from a specific node */
    parentLinksTo(node: GraphNode<NodeDatum, LinkDatum>): IterableIterator<GraphLink<NodeDatum, LinkDatum>>;
    /** the number of links to a specific node */
    nchildLinksTo(node: GraphNode<NodeDatum, LinkDatum>): number;
    /** iterator over every link to a specific node */
    childLinksTo(node: GraphNode<NodeDatum, LinkDatum>): IterableIterator<GraphLink<NodeDatum, LinkDatum>>;
    /** iterator over this node's unique parent nodes */
    parents(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /** iterator over this node's unique child nodes */
    children(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /** iterator over this node's unique parent nodes and the number of links from them */
    parentCounts(): IterableIterator<[GraphNode<NodeDatum, LinkDatum>, number]>;
    /** iterator over this node's unique child nodes and the number of links to them */
    childCounts(): IterableIterator<[GraphNode<NodeDatum, LinkDatum>, number]>;
    /**
     * iterator of links to this node from its parents
     *
     * The order of links is guaranteed to not change between iterations.
     */
    parentLinks(): IterableIterator<GraphLink<NodeDatum, LinkDatum>>;
    /**
     * iterator of links from this node to its children
     *
     * The order of links is guaranteed to not change between iterations.
     */
    childLinks(): IterableIterator<GraphLink<NodeDatum, LinkDatum>>;
    /**
     * iterator of all nodes reachable though parents
     *
     * The iterator includes this node.
     */
    ancestors(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
    /**
     * iterator of all nodes reachable though children
     *
     * The iterator includes this node.
     */
    descendants(): IterableIterator<GraphNode<NodeDatum, LinkDatum>>;
}
/**
 * a node in a graph
 *
 * Nodes provide all the same interfaces that {@link Graph}s do in terms of
 * node properties and iteration. When called on a node, the nodes behaves as a
 * graph of just its connected component. Therefore new nodes will always be
 * {@link acyclic}, {@link connected}, and not {@link multi}.
 *
 * In addition, nodes also expose properties of their immediate neighborhoods,
 * iterators and counts of nodes they directly touch.
 *
 * This is the immutable version of {@link MutGraphNode}.
 */
export interface GraphNode<out NodeDatum = unknown, out LinkDatum = unknown> extends Graph<NodeDatum, LinkDatum>, GraphNodeMixin<NodeDatum, LinkDatum> {
}
/**
 * a mutable node in a graph
 *
 * This possesses all of the methods of both {@link MutGraph} and {@link
 * GraphNode}, while also adding the ability to directly add {@link parent}s or
 * {@link child}ren and to {@link delete | remove} the node and all links from
 * the graph.
 */
export interface MutGraphNode<in out NodeDatum, in out LinkDatum> extends MutGraph<NodeDatum, LinkDatum>, GraphNodeMixin<NodeDatum, LinkDatum> {
    /** {@inheritDoc GraphNode#parentLinksTo} */
    parentLinksTo(node: GraphNode<NodeDatum, LinkDatum>): IterableIterator<MutGraphLink<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#childLinksTo} */
    childLinksTo(node: GraphNode<NodeDatum, LinkDatum>): IterableIterator<MutGraphLink<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#parents} */
    parents(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#children} */
    children(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#parentCounts} */
    parentCounts(): IterableIterator<[
        MutGraphNode<NodeDatum, LinkDatum>,
        number
    ]>;
    /** {@inheritDoc GraphNode#childCounts} */
    childCounts(): IterableIterator<[MutGraphNode<NodeDatum, LinkDatum>, number]>;
    /** {@inheritDoc GraphNode#parentLinks} */
    parentLinks(): IterableIterator<MutGraphLink<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#childLinks} */
    childLinks(): IterableIterator<MutGraphLink<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#ancestors} */
    ancestors(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    /** {@inheritDoc GraphNode#descendants} */
    descendants(): IterableIterator<MutGraphNode<NodeDatum, LinkDatum>>;
    /** add a new link from a parent node */
    parent(par: MutGraphNode<NodeDatum, LinkDatum>, ...datum: undefined extends LinkDatum ? [datum?: LinkDatum] : [datum: LinkDatum]): MutGraphLink<NodeDatum, LinkDatum>;
    /** add a new link to a child node */
    child(chi: MutGraphNode<NodeDatum, LinkDatum>, ...datum: undefined extends LinkDatum ? [datum?: LinkDatum] : [datum: LinkDatum]): MutGraphLink<NodeDatum, LinkDatum>;
    /**
     * remove this node and all of its links from the graph
     *
     * Once a node is deleted, none of its methods are valid or guaranteed to do
     * the correct thing.
     */
    delete(): void;
}
/**
 * create a new mutable empty {@link MutGraph}
 *
 * When creating a new mutable graph via typescript, you must specify the type
 * of the node data and link data you intend on using, since these types are
 * invariant for mutable graphs.
 *
 * @example
 * Creating a graph with node and link data:
 *
 * ```ts
 * // create a new graph
 * const grf = graph<string, number>();
 * // add two nodes with some data
 * const a = grf.node("a");
 * const b = grf.node("b");
 * // add a new link with the data `1`
 * const link = grf.link(a, b, 1);
 * grf.connected(); // true
 * ```
 *
 * @example
 * If `undefined` extends the data types then they can be omitted:
 * ```
 * // create a new graph
 * const grf = graph<undefined | string, undefined | number>();
 * const a = grf.node();
 * const b = grf.node();
 * const link = grf.link(a, b);
 * grf.connected(); // true
 * ```
 *
 * @typeParam NodeDatum - the extra user data attached to each node
 * @typeParam LinkDatum - the extra data attached to each link
 */
export declare function graph<NodeDatum, LinkDatum>(): MutGraph<NodeDatum, LinkDatum>;
