/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { Listenable } from "@fluidframework/core-interfaces/internal";
import { type AnchorEvents, type AnchorNode, type TreeValue } from "../../core/index.js";
import { TreeStatus, type FlexTreeNode, type HydratedFlexTreeNode } from "../../feature-libraries/index.js";
import type { Context, HydratedContext } from "./context.js";
import type { TreeNode } from "./treeNode.js";
import type { TreeNodeSchema } from "./treeNodeSchema.js";
import type { Unhydrated } from "./types.js";
import { UnhydratedFlexTreeNode } from "./unhydratedFlexTree.js";
export declare function getKernel(node: TreeNode): TreeNodeKernel;
/**
 * Detects if the given 'candidate' is a TreeNode.
 *
 * @remarks
 * Supports both Hydrated and {@link Unhydrated} TreeNodes, both of which return true.
 *
 * Because the common usage is to check if a value being inserted/set is a TreeNode,
 * this function permits calling with primitives as well as objects.
 *
 * Primitives will always return false (as they are copies of data, not references to nodes).
 *
 * @param candidate - Value which may be a TreeNode
 * @returns true if the given 'candidate' is a hydrated TreeNode.
 */
export declare function isTreeNode(candidate: unknown): candidate is TreeNode | Unhydrated<TreeNode>;
/**
 * Returns a schema for a value if the value is a {@link TreeNode}.
 *
 * Returns undefined for other values.
 * @remarks
 * Does not give schema for a {@link TreeLeafValue}.
 */
export declare function tryGetTreeNodeSchema(value: unknown): undefined | TreeNodeSchema;
/**
 * Contains state and an internal API for managing {@link TreeNode}s.
 * @remarks All {@link TreeNode}s have an associated kernel object.
 * The kernel has the same lifetime as the node and spans both its unhydrated and hydrated states.
 */
export declare class TreeNodeKernel {
    #private;
    readonly node: TreeNode;
    readonly schema: TreeNodeSchema;
    private readonly initialContext;
    private disposed;
    /**
     * Generation number which is incremented any time we have an edit on the node.
     * Used during iteration to make sure there has been no edits that were concurrently made.
     * @remarks
     * This is updated monotonically by this class when edits are applied.
     * TODO: update this when applying edits to unhydrated trees.
     *
     * If TypeScript supported making this immutable from outside the class without making it readonly from inside, that would be used here,
     * but they only way to do that is add a separate public accessor and make it private, which was deemed not worth the boilerplate, runtime overhead and bundle size.
     */
    generationNumber: number;
    /**
     * Create a TreeNodeKernel which can be looked up with {@link getKernel}.
     *
     * @param initialContext - context from when this node was originally created. Only used when unhydrated.
     * @param innerNode - When unhydrated the MapTreeNode. Otherwise HydratedFlexTreeNode.
     * @remarks
     * Exactly one kernel per TreeNode should be created.
     */
    constructor(node: TreeNode, schema: TreeNodeSchema, innerNode: InnerNode, initialContext: Context);
    get context(): Context;
    /**
     * Transition from {@link Unhydrated} to hydrated.
     * Bi-directionally associates the given hydrated TreeNode to the HydratedFlexTreeNode.
     * @remarks
     * Happens at most once for any given node.
     * Cleans up mappings to {@link UnhydratedFlexTreeNode} - it is assumed that they are no longer needed once this node has an anchor node.
     */
    hydrate(inner: HydratedFlexTreeNode): void;
    private createHydratedState;
    getStatus(): TreeStatus;
    get events(): Listenable<KernelEvents>;
    dispose(): void;
    isHydrated(): this is {
        anchorNode: AnchorNode;
        context: HydratedContext;
    };
    get anchorNode(): AnchorNode | undefined;
    /**
     * Retrieves the flex node associated with the given target.
     * @remarks
     * For {@link Unhydrated} nodes, this returns the MapTreeNode.
     *
     * For hydrated nodes it returns a FlexTreeNode backed by the forest.
     *
     * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.
     */
    getInnerNode(): InnerNode;
    /**
     * Retrieves the {@link UnhydratedFlexTreeNode} if unhydrated. otherwise undefined.
     */
    getInnerNodeIfUnhydrated(): UnhydratedFlexTreeNode | undefined;
}
declare const kernelEvents: readonly ["childrenChangedAfterBatch", "subtreeChangedAfterBatch"];
type KernelEvents = Pick<AnchorEvents, (typeof kernelEvents)[number]>;
/**
 * Call the provided callback with {@link TreeNode}s' events paused until after the callback's completion.
 *
 * Events that would otherwise have been emitted immediately are merged and buffered until after the
 * provided callback has been completed.
 *
 * @remarks
 * Note: this should be used with caution. User application behaviors are implicitly coupled to event timing.
 * Disrupting this timing can lead to unexpected behavior.
 */
export declare function withBufferedTreeEvents(callback: () => void): void;
/**
 * For hydrated nodes this is a HydratedFlexTreeNode thats a projection of forest content.
 * For {@link Unhydrated} nodes this is a UnhydratedFlexTreeNode.
 */
export type InnerNode = FlexTreeNode;
/**
 * Narrows innerNode to either {@link UnhydratedFlexTreeNode} or {@link HydratedFlexTreeNode}.
 */
export declare function splitInnerNodeType(innerNode: InnerNode): asserts innerNode is UnhydratedFlexTreeNode | HydratedFlexTreeNode;
/**
 * An anchor slot which associates an anchor with its corresponding {@link TreeNode}, if there is one.
 * @remarks
 * For this to work, we have to require that there is at most a single view using a given AnchorSet.
 * FlexTree already has this assumption, and we also assume there is a single simple-tree per FlexTree, so this is valid.
 */
export declare const simpleTreeNodeSlot: import("../../core/index.js").AnchorSlot<TreeNode>;
/**
 * Dispose a TreeNode (if any) for an existing anchor without disposing the anchor.
 */
export declare function tryDisposeTreeNode(anchorNode: AnchorNode): void;
/**
 * Gets the {@link TreeNodeSchema} for the {@link InnerNode}.
 */
export declare function getSimpleNodeSchemaFromInnerNode(innerNode: InnerNode): TreeNodeSchema;
/**
 * Gets the {@link Context} for the {@link InnerNode}.
 */
export declare function getSimpleContextFromInnerNode(innerNode: InnerNode): Context;
/**
 * Retrieves the flex node associated with the given target.
 * @remarks
 * For {@link Unhydrated} nodes, this returns the MapTreeNode.
 *
 * For hydrated nodes it returns a FlexTreeNode backed by the forest.
 *
 * @throws A {@link @fluidframework/telemetry-utils#UsageError} if the node has been deleted.
 */
export declare function getInnerNode(treeNode: TreeNode): InnerNode;
/**
 * Gets a tree node from an anchor node
 */
export declare function treeNodeFromAnchor(anchorNode: AnchorNode): TreeNode | TreeValue;
/**
 * Constructs a TreeNode from an InnerNode.
 * @remarks
 * This does not do caching or validation: caller must ensure duplicate nodes for a given inner node are not created, and that the inner node is valid.
 */
export declare function createTreeNodeFromInner(innerNode: InnerNode): TreeNode | TreeValue;
/**
 * Creating multiple simple tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.
 * This slot is used to detect if one already exists and error if creating a second.
 * @remarks
 * See also {@link ContextSlot} in which the flex-tree context is stored.
 */
export declare const SimpleContextSlot: import("../../core/index.js").AnchorSlot<HydratedContext>;
export {};
//# sourceMappingURL=treeNodeKernel.d.ts.map