import { type MapArgs, MultiMap, type Some } from '@loken/utilities';
import type { HCNode } from '../nodes/node.js';
import type { NodePredicate } from '../nodes/node.types.js';
import type { Identify } from '../utilities/identify.js';
import type { Relation } from '../utilities/relations.js';
/** Contains the `id`, `item` and `node` for a `HCNode` in a `Hierarchy`. */
export type HierarchyEntry<Item, Id> = [id: Id, item: Item, node: HCNode<Item>];
/**
 * Keeps track of the a set of nodes and their roots
 * and provides structural modification.
 */
export declare class Hierarchy<Item, Id = Item> {
    #private;
    /** Create a hierarchy using the provided `identify` function. */
    constructor(identify: Identify<Item, Id>);
    /** Get a shallow clone of the roots. */
    get roots(): HCNode<Item>[];
    /** Get a shallow clone of the root items. */
    get rootItems(): Item[];
    /** Get a shallow clone of the root IDs. */
    get rootIds(): Id[];
    /** Get a shallow clone of all nodes. */
    get nodes(): HCNode<Item>[];
    /** Get a shallow clone of all node items. */
    get nodeItems(): Item[];
    /** Get a shallow clone of all node IDs. */
    get nodeIds(): Id[];
    /** Means of getting an ID for an `item`. */
    get identify(): Identify<Item, Id>;
    /** Map the `ids` to a boolean signifying their presence. */
    has<Ids extends Id[]>(...ids: Ids): MapArgs<Ids, boolean, true, false>;
    /** Is every `Id` in the `ids` present? */
    hasEvery(ids: Some<Id>): boolean;
    /** Is some `Id` in the `ids` present? */
    hasSome(ids: Some<Id>): boolean;
    /**
     * Get node or nodes by their `Id`.
     * @param ids The IDs of nodes to retrieve.
     * @returns A single node when you pass a single ID and a fixed length tuple of nodes when you pass multiple IDs.
     * @throws The 'id' must be a hierarchy member.
     * @throws Must provide at least one argument.
     */
    get<Ids extends Id[]>(...ids: Ids): MapArgs<Ids, HCNode<Item>, true, false>;
    /**
     * Get nodes by their `Id`s.
     * @param ids The IDs of nodes to retrieve.
     * @returns An array of nodes.
     */
    getSome(ids: Some<Id>): HCNode<Item>[];
    /**
     * Get item or items by `Id`.
     * @param ids The IDs of items to retrieve.
     * @throws The 'id' must be a hierarchy member.
     * @throws Must provide at least one argument.
     * @returns A single item when you pass a single ID and a fixed length tuple of items when you pass multiple IDs.
     */
    getItems<Ids extends Id[]>(...ids: Ids): MapArgs<Ids, Item, true, false>;
    /**
     * Get item or items by `Id`.
     * @param ids The IDs of items to retrieve.
     * @returns An array of items.
     */
    getSomeItems(ids: Some<Id>): Item[];
    /**
     * Attach the provided `roots`.
     * @param roots Nodes to attach.
     */
    attachRoot(roots: Some<HCNode<Item>>): this;
    /**
     * Attach the provided `children` to the node of the provided `parentId`.
     * @param parentId The ID of the node to attach to.
     * @param children Nodes to attach.
     */
    attach(parentId: Id, children: Some<HCNode<Item>>): this;
    /**
     * Detach the provided `nodes`.
     * @param nodes Nodes to detach.
     */
    detach(nodes: Some<HCNode<Item>>): this;
    /**
     * Get the chain of ancestor nodes starting with the node for the item matching the `id`.
     */
    getAncestors(ids: Some<Id>, includeSelf?: boolean): HCNode<Item>[];
    /**
     * Get the items from the chain of ancestor nodes starting with the node for the item matching the `id`.
     */
    getAncestorItems(ids: Some<Id>, includeSelf?: boolean): Item[];
    /**
     * Get the IDs from the chain of ancestor nodes starting with the node for the item matching the `id`.
     */
    getAncestorIds(ids: Some<Id>, includeSelf?: boolean): Id[];
    /**
     * Get the entries from the chain of ancestor nodes starting with the node for the item matching the `id`.
     */
    getAncestorEntries(id: Id, includeSelf?: boolean): HierarchyEntry<Item, Id>[];
    /**
     * Get the chain of descendant nodes starting with the nodes for the items matching the `ids`.
     */
    getDescendants(ids: Some<Id>, includeSelf?: boolean): HCNode<Item>[];
    /**
     * Get the items from the chain of descendant nodes starting with the nodes for the items matching the `ids`.
     */
    getDescendantItems(ids: Some<Id>, includeSelf?: boolean): Item[];
    /**
     * Get the IDs from the chain of descendant nodes starting with the nodes for the items matching the `ids`.
     */
    getDescendantIds(ids: Some<Id>, includeSelf?: boolean): Id[];
    /**
     * Get the entries from the chain of descendant nodes starting with the nodes for the items matching the `ids`.
     */
    getDescendantEntries(ids: Some<Id>, includeSelf?: boolean): HierarchyEntry<Item, Id>[];
    /**
     * Get the chain of descendant nodes starting with the hierarchy `roots`.
     */
    getAllDescendants(includeSelf?: boolean): HCNode<Item>[];
    /**
     * Get the items from the chain of descendant nodes starting with the hierarchy `roots`.
     */
    getAllDescendantItems(includeSelf?: boolean): Item[];
    /**
     * Get the IDs from the chain of descendant nodes starting with the hierarchy `roots`.
     */
    getAllDescendantIds(includeSelf?: boolean): Id[];
    /**
     * Get the entries from the chain of descendant nodes starting with the hierarchy `roots`.
     */
    getAllDescendantEntries(includeSelf?: boolean): HierarchyEntry<Item, Id>[];
    /**
     * Find nodes matching a list of `Id`s or a `HCNode<Item>` predicate.
     */
    find(search: Some<Id> | NodePredicate<Item>): HCNode<Item>[];
    /**
     * Find nodes matching a list of `Id`s or a `HCNode<Item>` predicate.
     */
    findItems(search: Some<Id> | NodePredicate<Item>): Item[];
    /**
     * Find `Id`s matching a list of `Id`s or a `HCNode<Item>` predicate.
     */
    findIds(search: Some<Id> | NodePredicate<Item>): Id[];
    /**
     * Find entries matching a list of `Id`s or a `HCNode<Item>` predicate.
     */
    findEntries(search: Some<Id> | NodePredicate<Item>): HierarchyEntry<Item, Id>[];
    /** Find the common ancestor node which is the closest to the `ids`. */
    findCommonAncestor(ids: Some<Id>, includeSelf?: boolean): HCNode<Item> | undefined;
    /** Find the ancestor nodes common to the `ids`. */
    findCommonAncestors(ids: Some<Id>, includeSelf?: boolean): HCNode<Item>[] | undefined;
    /**
     * Find a node matching the `search` which is an ancestor of a node with one of the `ids`.
     */
    findAncestor(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): HCNode<Item> | undefined;
    /**
     * Find a node matching the `search` which is an ancestor of a node with one of the `ids`.
     */
    findAncestors(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): HCNode<Item>[];
    /**
     * Find a node matching the `search` which is an descendant of a node with one of the `ids`.
     */
    findDescendant(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): HCNode<Item> | undefined;
    /**
     * Find nodes matching the `search` which are descendants of a node with one of the `ids`.
     */
    findDescendants(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): HCNode<Item>[];
    /**
     * Does a node with one of the `ids` have an ancestor node matching the `search`?
     */
    hasAncestor(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): boolean;
    /**
     * Does a node with one of the `ids` have a descendant node matching the `search`?
     */
    hasDescendant(ids: Some<Id>, search: Some<Id> | NodePredicate<Item>, includeSelf?: boolean): boolean;
    /**
     * Create a new `Hierarchy` from matching items.
     *
     * @param search A list of `Id`s or a `HCNode<Item>` predicate.
     * @param include Optional facets to include: The nodes that are `matches`, their `ancestors` and/or their `descendants` in the result.
     * - When not specified you are getting all three facets as a default.
     * - When the options object is specified you must opt in to the facets you want and must enable at least one.
     * @returns A new `Hierarchy<Item, Id>` with new nodes wrapping the same `Item`s as in the searched hierarchy pruned to fit the search and `include` facets.
     * @throws If you provide `include` options but enable no facets.
     */
    search(search: Some<Id> | NodePredicate<Item>, include?: {
        matches?: boolean;
        ancestors?: boolean;
        descendants?: boolean;
    }): Hierarchy<Item, Id>;
    protected normalizeSearch(search: Some<Id> | NodePredicate<Item>): NodePredicate<Item>;
    /** Create a map of ids to child-ids by traversing the `hierarchy`. */
    toChildMap(): MultiMap<Id>;
    /** Create a map of ids to descendant-ids by traversing the `hierarchy`. */
    toDescendantMap(): MultiMap<Id>;
    /** Create a map of ids to ancestor-ids by traversing the `hierarchy`. */
    toAncestorMap(): MultiMap<Id>;
    /** Create a list of relations by traversing the graph of the `hierarchy`. */
    toRelations(): Relation<Id>[];
}
//# sourceMappingURL=hierarchy.d.ts.map