import type { Enum } from '../../../shared/src/enum.ts';
import { type ReadonlyJSONValue } from '../../../shared/src/json.ts';
import type { IndexKey } from '../db/index.ts';
import * as FormatVersion from '../format-version-enum.ts';
import { type FrozenJSONValue, type FrozenTag } from '../frozen-json.ts';
import { type Hash } from '../hash.ts';
import type { BTreeRead } from './read.ts';
import type { BTreeWrite } from './write.ts';
type FormatVersion = Enum<typeof FormatVersion>;
export type Entry<V> = readonly [key: string, value: V, sizeOfEntry: number];
export declare const NODE_LEVEL = 0;
export declare const NODE_ENTRIES = 1;
/**
 * The type of B+Tree node chunk data
 */
type BaseNode<V> = FrozenTag<readonly [level: number, entries: ReadonlyArray<Entry<V>>]>;
export type InternalNode = BaseNode<Hash>;
export type DataNode = BaseNode<FrozenJSONValue>;
export declare function makeNodeChunkData<V>(level: number, entries: ReadonlyArray<Entry<V>>, formatVersion: FormatVersion): BaseNode<V>;
export type Node = DataNode | InternalNode;
/**
 * Describes the changes that happened to Replicache after a
 * {@link WriteTransaction} was committed.
 *
 * @experimental This type is experimental and may change in the future.
 */
export type Diff = IndexDiff | NoIndexDiff;
/**
 * @experimental This type is experimental and may change in the future.
 */
export type IndexDiff = readonly DiffOperation<IndexKey>[];
/**
 * @experimental This type is experimental and may change in the future.
 */
export type NoIndexDiff = readonly DiffOperation<string>[];
/**
 * InternalDiff uses string keys even for the secondary index maps.
 */
export type InternalDiff = readonly InternalDiffOperation[];
export type DiffOperationAdd<Key, Value = ReadonlyJSONValue> = {
    readonly op: 'add';
    readonly key: Key;
    readonly newValue: Value;
};
export type DiffOperationDel<Key, Value = ReadonlyJSONValue> = {
    readonly op: 'del';
    readonly key: Key;
    readonly oldValue: Value;
};
export type DiffOperationChange<Key, Value = ReadonlyJSONValue> = {
    readonly op: 'change';
    readonly key: Key;
    readonly oldValue: Value;
    readonly newValue: Value;
};
/**
 * The individual parts describing the changes that happened to the Replicache
 * data. There are three different kinds of operations:
 * - `add`: A new entry was added.
 * - `del`: An entry was deleted.
 * - `change`: An entry was changed.
 *
 * @experimental This type is experimental and may change in the future.
 */
export type DiffOperation<Key> = DiffOperationAdd<Key> | DiffOperationDel<Key> | DiffOperationChange<Key>;
export type InternalDiffOperation<Key = string, Value = FrozenJSONValue> = DiffOperationAdd<Key, Value> | DiffOperationDel<Key, Value> | DiffOperationChange<Key, Value>;
/**
 * Finds the leaf where a key is (if present) or where it should go if not
 * present.
 */
export declare function findLeaf(key: string, hash: Hash, source: BTreeRead, expectedRootHash: Hash): Promise<DataNodeImpl>;
type BinarySearchEntries = readonly Entry<unknown>[];
/**
 * Does a binary search over entries
 *
 * If the key found then the return value is the index it was found at.
 *
 * If the key was *not* found then the return value is the index where it should
 * be inserted at
 */
export declare function binarySearch(key: string, entries: BinarySearchEntries): number;
export declare function binarySearchFound(i: number, entries: BinarySearchEntries, key: string): boolean;
export declare function parseBTreeNode(v: unknown, formatVersion: FormatVersion, getSizeOfEntry: <K, V>(key: K, value: V) => number): InternalNode | DataNode;
export declare function isInternalNode(node: Node): node is InternalNode;
declare abstract class NodeImpl<Value> {
    #private;
    entries: Array<Entry<Value>>;
    hash: Hash;
    abstract readonly level: number;
    readonly isMutable: boolean;
    constructor(entries: Array<Entry<Value>>, hash: Hash, isMutable: boolean);
    abstract set(key: string, value: FrozenJSONValue, entrySize: number, tree: BTreeWrite): Promise<NodeImpl<Value>>;
    abstract del(key: string, tree: BTreeWrite): Promise<NodeImpl<Value> | DataNodeImpl>;
    maxKey(): string;
    getChildNodeSize(tree: BTreeRead): number;
    protected _updateNode(tree: BTreeWrite): void;
}
export declare function toChunkData<V>(node: NodeImpl<V>, formatVersion: FormatVersion): BaseNode<V>;
export declare class DataNodeImpl extends NodeImpl<FrozenJSONValue> {
    #private;
    readonly level = 0;
    set(key: string, value: FrozenJSONValue, entrySize: number, tree: BTreeWrite): Promise<DataNodeImpl>;
    del(key: string, tree: BTreeWrite): Promise<DataNodeImpl>;
    keys(_tree: BTreeRead): AsyncGenerator<string, void>;
    entriesIter(_tree: BTreeRead): AsyncGenerator<Entry<FrozenJSONValue>, void>;
}
export declare class InternalNodeImpl extends NodeImpl<Hash> {
    #private;
    readonly level: number;
    constructor(entries: Array<Entry<Hash>>, hash: Hash, level: number, isMutable: boolean);
    set(key: string, value: FrozenJSONValue, entrySize: number, tree: BTreeWrite): Promise<InternalNodeImpl>;
    del(key: string, tree: BTreeWrite): Promise<InternalNodeImpl | DataNodeImpl>;
    keys(tree: BTreeRead): AsyncGenerator<string, void>;
    entriesIter(tree: BTreeRead): AsyncGenerator<Entry<FrozenJSONValue>, void>;
    getChildren(start: number, length: number, tree: BTreeRead): Promise<Array<InternalNodeImpl | DataNodeImpl>>;
    getCompositeChildren(start: number, length: number, tree: BTreeRead): Promise<InternalNodeImpl | DataNodeImpl>;
}
export declare function newNodeImpl(entries: Array<Entry<FrozenJSONValue>>, hash: Hash, level: number, isMutable: boolean): DataNodeImpl;
export declare function newNodeImpl(entries: Array<Entry<Hash>>, hash: Hash, level: number, isMutable: boolean): InternalNodeImpl;
export declare function newNodeImpl(entries: Array<Entry<FrozenJSONValue>> | Array<Entry<Hash>>, hash: Hash, level: number, isMutable: boolean): DataNodeImpl | InternalNodeImpl;
export declare function isDataNodeImpl(node: DataNodeImpl | InternalNodeImpl): node is DataNodeImpl;
export declare function partition<T>(values: Iterable<T>, getSizeOfEntry: (v: T) => number, min: number, max: number): T[][];
export declare const emptyDataNode: BaseNode<ReadonlyJSONValue>;
export declare const emptyDataNodeImpl: DataNodeImpl;
export declare function createNewInternalEntryForNode(node: NodeImpl<unknown>, getSizeOfEntry: <K, V>(k: K, v: V) => number): [string, Hash, number];
export {};
//# sourceMappingURL=node.d.ts.map