import { type ComputedRef, type Ref } from 'vue';
import type { CascadeMode, GetChildren, LoadChildren, NodeKey, SelectionMode } from './types.js';
/**
 * Internal load state for a single node's children.
 *
 *   - `loading`            — Effect in flight
 *   - `loaded(children)`   — successful resolution, cached children array
 *   - `error(err)`         — Effect failed; component does NOT auto-retry
 */
export type LoadState<Node> = {
    status: 'loading';
} | {
    status: 'loaded';
    children: Node[];
} | {
    status: 'error';
    error: unknown;
};
export interface UseTreeStateOptions<Node, E = unknown> {
    rootsRef: Ref<Node[]> | ComputedRef<Node[]>;
    /**
     * Apply a structural mutation; for controlled mode the parent gets
     *  `update:roots`, for uncontrolled we mutate the internal copy.
     */
    setRoots: (next: Node[]) => void;
    getKey: (node: Node) => NodeKey;
    getChildren?: GetChildren<Node>;
    loadChildren?: LoadChildren<Node, E>;
    selectionMode: () => SelectionMode;
    cascade: () => CascadeMode;
    selectable: (node: Node, depth: number) => boolean;
    /** Initial selection — read once on init, then state is internal. */
    initialSelection: () => NodeKey[];
    /** Initial expanded set — read once on init. */
    initialExpanded: () => NodeKey[];
    /** Called whenever the selection changes (any cause). */
    onSelectionChange: (next: NodeKey[]) => void;
}
interface LocatedNode<Node> {
    node: Node;
    parent: Node | null;
    depth: number;
    index: number;
    /** Sibling array that contains `node` — used for in-place splice ops. */
    siblings: Node[];
}
/**
 * State machine for `<Tree>`. Pure-ish — only side-effect is running the
 * user-supplied `loadChildren` Effect.
 *
 * Indexing invariants:
 *   - All maps/sets key by `NodeKey` (never node identity), so reorders /
 *     drag-drop preserve state.
 *   - Mutation methods splice in place on the existing children arrays,
 *     never recreating nodes.
 */
export declare function useTreeState<Node, E = unknown>(opts: UseTreeStateOptions<Node, E>): {
    expanded: import("vue").Reactive<Set<string>>;
    selected: import("vue").Reactive<Set<string>>;
    loadState: Map<string, LoadState<Node>>;
    focusedKey: Ref<string | null, string | null>;
    rootsView: import("vue").ShallowRef<Node[], Node[]>;
    locate: (key: NodeKey) => LocatedNode<Node> | null;
    resolvedChildren: (node: Node) => Node[] | undefined | null;
    isExpandable: (node: Node) => boolean;
    isIndeterminate: (node: Node, depth: number) => boolean;
    isVisuallySelected: (node: Node, depth: number) => boolean;
    flattenVisible: (filter?: (node: Node) => boolean) => Array<{
        node: Node;
        depth: number;
        key: NodeKey;
    }>;
    selectedNodes: ComputedRef<Node[]>;
    syncRoots: () => void;
    expand: (key: NodeKey) => void;
    collapse: (key: NodeKey) => void;
    toggleExpand: (key: NodeKey) => void;
    selectKey: (key: NodeKey) => void;
    deselectKey: (key: NodeKey) => void;
    clearSelection: () => void;
    toggleMulti: (key: NodeKey) => void;
    insert: (parentKey: NodeKey | null, node: Node, index?: number) => void;
    remove: (key: NodeKey) => void;
    move: (key: NodeKey, newParentKey: NodeKey | null, index: number) => void;
    update: (key: NodeKey, patch: Partial<Node>) => void;
    invalidate: (key: NodeKey) => void;
    retry: (key: NodeKey) => void;
    findPath: (key: NodeKey) => Node[] | null;
    snapshot: () => {
        roots: Node[];
        selected: string[];
        expanded: string[];
    };
};
export {};
