import type { ImmutableArray } from "./array.js";
import type { AbsolutePath } from "./path.js";
import type { Query } from "./query.js";
/** Set of valid props for an element. */
export type ElementProps = {
    readonly children?: Elements;
};
/**
 * Element with a type, props, and optional key (compatible with `React.ReactElement`).
 * - Declared as a `type`, not an `interface`, so its implicit index signature lets it satisfy `Data` — `queryElements()` runs elements through `queryItems<T extends Data>`.
 */
export type Element<P extends ElementProps = ElementProps> = {
    readonly type: string | ((props: P) => Elements | null);
    readonly props: P;
    readonly key: string | null;
    readonly $$typeof?: symbol;
};
/** Collection of elements (compatible with `React.ReactNode`). */
export type Elements<T extends Element = Element> = undefined | null | string | T | Iterable<Elements<T>>;
/** Props for a tree element — must have a `tree-` prefixed type. */
export interface TreeElementProps extends ElementProps {
    /**
     * The primary identifier shown in menus, cards, and other listings.
     * - Always set. For files this is the basename (e.g. `"array"` from `array.ts`); for directories it's the directory name;
     *   for documented symbols it's the declared name (e.g. `"getFirst"`).
     * - `key` is typically the slugified version of `name`.
     */
    readonly name: string;
    /**
     * Optional visual-only override for `name`, set only when a confident source is available
     * (e.g. a markdown `<h1>`, a docblock title).
     * - Renderers should fall back to `name` when `title` is missing.
     */
    readonly title?: string | undefined;
    /**
     * Short summary used for the page's `<meta name="description">` tag — not rendered as visible page body.
     * - Pages plumb this through `Meta.description`; `<Head>` emits the meta tag.
     * - For visible body content (rendered inside the page) use `content` instead.
     */
    readonly description?: string | undefined;
    /**
     * Markup source string that should be rendered as the element's visible body content.
     * - Rendered via the `<Markup>` component (typically inside a `<Prose>` wrapper).
     * - For Markdown files this is the file's body (the title `# h1` is lifted into `title`); for TypeScript symbols this is the JSDoc description.
     */
    readonly content?: string | undefined;
    /** Children of a tree element must be other tree elements. */
    readonly children?: TreeElements | undefined;
}
/**
 * Element in a heirarchical tree.
 * - Has a `tree-` prefixed type string.
 * - Requires a string `key` prop (can be resolved to a path).
 * - Props can include `title`, `description`, and/or `content` to be useful.
 */
export interface TreeElement<P extends TreeElementProps = TreeElementProps> extends Element<P> {
    readonly key: string;
    readonly type: `tree-${string}`;
}
/** Collection of tree elements. */
export type TreeElements = Elements<TreeElement>;
/** Props for a directory element. */
export interface DirectoryElementProps extends TreeElementProps {
    /**
     * Source location for the element — the absolute filesystem path it was extracted from.
     * - For directories this is the directory path; for files this is the file path.
     */
    readonly source: AbsolutePath;
}
/**
 * Element representing a directory in a file tree.
 * - Content is absorbed from an index file (e.g. `README.md` or `INDEX.md`) if present.
 * - Children are the files and subdirectories within this directory.
 */
export interface DirectoryElement extends TreeElement<DirectoryElementProps> {
    readonly type: "tree-directory";
}
/** Props for a file element. */
export interface FileElementProps extends TreeElementProps {
    /**
     * Source location for the element — the absolute filesystem path it was extracted from.
     * - For directories this is the directory path; for files this is the file path.
     */
    readonly source: AbsolutePath;
}
/**
 * Element representing a file in a file tree.
 * - For TypeScript files, children are the exported code symbols.
 * - For Markdown files, children are typically empty (content is the parsed markdown).
 */
export interface FileElement extends TreeElement<FileElementProps> {
    readonly type: "tree-file";
}
/** A single parameter for a documented code symbol. */
export interface DocumentationParam {
    readonly name: string;
    /** Type expression (e.g. `"string"`, `"number"`); renderers default to `"unknown"` when missing. */
    readonly type?: string | undefined;
    readonly description?: string | undefined;
    readonly optional?: boolean | undefined;
}
/** A single `@returns` entry — multiple allowed to document union return types separately. */
export interface DocumentationReturn {
    /** Type expression for the return value; renderers default to `"unknown"` when missing. */
    readonly type?: string | undefined;
    readonly description?: string | undefined;
}
/** A single `@throws` entry — multiple allowed to document distinct error types. */
export interface DocumentationThrow {
    /** Type expression for the thrown value; renderers default to `"unknown"` when missing. */
    readonly type?: string | undefined;
    readonly description?: string | undefined;
}
/** A single `@example` entry — the example text/code block. */
export interface DocumentationExample {
    readonly description?: string | undefined;
}
/**
 * Props for a documented code symbol — a single shape for any kind of code element.
 * - `kind` distinguishes the symbol category (e.g. `"function"`, `"class"`, `"property"`, or any string).
 * - All props are optional — not every kind uses every prop (e.g. `returns` only makes sense for functions).
 * - `signatures` is an array so overloaded function/method declarations can each contribute their own signature to the same documentation element.
 */
export interface DocumentationElementProps extends TreeElementProps {
    readonly kind?: string | undefined;
    readonly signatures?: ImmutableArray<string> | undefined;
    readonly params?: ImmutableArray<DocumentationParam> | undefined;
    readonly returns?: ImmutableArray<DocumentationReturn> | undefined;
    readonly throws?: ImmutableArray<DocumentationThrow> | undefined;
    readonly examples?: ImmutableArray<DocumentationExample> | undefined;
    readonly extends?: string | undefined;
    readonly implements?: ImmutableArray<string> | undefined;
}
/**
 * Element representing a documented code symbol.
 * - The `kind` prop distinguishes specific symbol types (function, class, property, etc.) without baking the list in.
 */
export interface DocumentationElement extends TreeElement<DocumentationElementProps> {
    readonly type: "tree-documentation";
}
declare module "react" {
    namespace JSX {
        interface IntrinsicElements {
            "tree-directory": DirectoryElementProps;
            "tree-file": FileElementProps;
            "tree-documentation": DocumentationElementProps;
        }
    }
}
/** Is an unknown value an element? */
export declare function isElement(value: unknown): value is Element;
/** Is an unknown value a collection of elements? */
export declare function isElements(value: unknown): value is Elements;
/**
 * Strip all tags from elements to produce a plain text string.
 * - A `<br>` element becomes a newline (`\n`) — matching DOM `innerText`, so words either side of a line break don't fuse together.
 *
 * @param elements An element, a plain string, or null/undefined (or an array of those things).
 * @returns The combined string made from the elements.
 *
 * @example `- Item with *strong*\n- Item with _em_` becomes `Item with strong Item with em`
 */
export declare function getElementText(elements: Elements): string;
/**
 * Walk an `Elements` value into a flat iterable of `Element` objects.
 * - Accepts any shape the `Elements` union allows: a single element, a (possibly deeply nested) iterable, `null`, `undefined`, or a string (strings are skipped — there's no element to yield).
 * - Recurses through *iterable nesting* only (e.g. `[[a, b], c]` flattens to `a, b, c`); it does NOT descend into an element's own `props.children`. Walking deeper is the consumer's job.
 *
 * The point of this helper is to remove the "is it one element, a list, undefined, or some nested thing" branching from every consumer that needs to dispatch over elements — pass it in, get a clean flat iterable out.
 */
export declare function walkElements<T extends Element>(elements: Elements<T>): Iterable<T>;
export declare function walkElements(elements: Elements): Iterable<Element>;
/**
 * Filter elements yielded by `walkElements()` using a `Query<Element>` object.
 * - Supports any property query (e.g. `{ type: "tree-file" }`, `{ type: ["tree-file", "tree-directory"] }`), sorting, limiting — anything `queryItems()` accepts.
 */
export declare function queryElements(elements: Elements, query: Query<Element>): Iterable<Element>;
/** Filter elements yielded by `walkElements()` using a match function. */
export declare function filterElements(elements: Elements, match: (element: Element) => boolean): Iterable<Element>;
/**
 * Resolve an element in a tree by walking a sequence of names from `root`.
 * - The `root` element's own name is never matched against path segments — it's the container, not a step in the path.
 * - A child's `name` may contain `/` separators, in which case it matches multiple consecutive path segments
 *   (e.g. a module named `"util/string"` matches the segments `["util", "string"]`).
 * - If `path` is empty, returns `root` itself.
 * - Returns `undefined` if no descendant matches at any level.
 *
 * Splitting the path:
 * - We accept a raw `Segments` array, so callers can join paths later however they wish.
 * - Element paths have no canonical string representation so we use `Segments` instead.
 * - To split the names in `a.b.c` dotted data format use `mapItems(getElementPaths(root), splitDataPath)`
 * - To split the names in `/a/b/c` absolute path format use `mapItems(getElementPaths(root), splitAbsolutePath)`
 *
 * @param root The root element to walk from. Its own `name` is treated as a label, not a path segment.
 * @param path An array of path segments naming descendants of `root`.
 *
 * @example resolveElementPath(root, ["util", "array"]) // Element with name "array" inside child with name "util"
 * @example resolveElementPath(root, ["util", "string"]) // Module child with composite name "util/string"
 * @example resolveElementPath(root, []) // `root` itself
 */
export declare function resolveElementPath(root: TreeElement, path: readonly string[]): TreeElement | undefined;
/**
 * Deeply iterate a tree from `root` and yield path segments for each reachable element.
 * - Yields `[]` for `root` itself.
 * - Yields `[name]` for each immediate child, `[name, name]` for grandchildren, etc.
 * - The `root` element's own name never appears in any yielded path — it's the container.
 * - Children with no `name` prop are skipped (and their descendants are not yielded).
 *
 * Joining the paths:
 * - We return a `Segments` array for each element, so callers can join paths later however they wish.
 * - Element paths have no canonical string representation so we use `Segments` instead.
 * - To join the names in `a.b.c` dotted data format use `mapItems(getElementPaths(root), joinDataPath)`
 * - To join the names in `/a/b/c` absolute path format use `mapItems(getElementPaths(root), p => joinPath("/", p))`
 *
 * @param root The root element to walk from. Its own `name` is treated as a label, not a path segment.
 * @param depth Controls how many levels of children to recurse into (defaults to infinite depth).
 * - `depth=0` yields only `[]` (the root itself).
 *
 * @returns Iterable set of path segment arrays, each representing one descendant (or the root).
 */
export declare function getElementPaths(root: TreeElement, depth?: number): Iterable<readonly string[]>;
/** Combine two `Elements`, preserving both if both are set. */
export declare function mergeElements<T extends Element>(a: Elements<T>, b: Elements<T>): Elements<T>;
export declare function mergeElements(a: Elements, b: Elements): Elements;
