/**
 * Utility constants and functions
 */
import { Any, AnyObject, ArrayOrObject, Comparator } from "../types";
export { hashCode } from "./_hash";
/** Represents an error reported by the mingo library. */
export declare class MingoError extends Error {
}
export declare const MISSING: unique symbol;
export declare const isPrimitive: (v: Any) => boolean;
type Cmp = string | number | boolean;
export declare const simpleCmp: <T = Cmp>(a: T, b: T) => 0 | 1 | -1;
/**
 * Compare function which adheres to MongoDB comparison order.
 *
 * @param a The first value
 * @param b The second value
 * @returns {Number}
 */
export declare const compare: (a: Any, b: Any) => number;
/**
 * Determine whether two values are the same or strictly equivalent.
 * Checking whether values are the same only applies to built in objects.
 * For custom objects, they are equal only of their toString() representation are equal if defined.
 *
 * @param a The first value
 * @param b The second value
 * @return True if values are equivalent, false otherwise.
 */
export declare function isEqual(a: Any, b: Any): boolean;
/**
 * A map implementation that uses value comparison for keys instead of referential identity.
 *
 * IMPORTANT! we assume objects are never modified once the hash is computed and put in the Map.
 * Modifying an object after adding to the Map will cause incorrect behaviour.
 */
export declare class HashMap<K, V> extends Map<K, V> {
    #private;
    private constructor();
    /**
     * Returns a new {@link HashMap} object.
     * @param fn An optional custom hash function
     */
    static init<K, V>(): HashMap<K, V>;
    clear(): void;
    /**
     * @returns true if an element in the Map existed and has been removed, or false if the element does not exist.
     */
    delete(key: K): boolean;
    /**
     * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
     * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
     */
    get(key: K): V | undefined;
    /**
     * @returns boolean indicating whether an element with the specified key exists or not.
     */
    has(key: K): boolean;
    /**
     * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
     */
    set(key: K, value: V): this;
    /**
     * @returns the number of elements in the Map.
     */
    get size(): number;
}
export declare function assert(condition: Any, msg: string): void;
/**
 * Returns the name of type in lowercase including custom types.
 * @param v Any value
 */
export declare function typeOf(v: Any): string;
export declare const isBoolean: (v: Any) => v is boolean;
export declare const isString: (v: Any) => v is string;
export declare const isSymbol: (v: Any) => boolean;
export declare const isNumber: (v: Any) => v is number;
export declare const isInteger: (number: unknown) => boolean;
export declare const isArray: (arg: any) => arg is any[];
export declare const isObject: (v: Any) => v is AnyObject;
export declare const isObjectLike: (v: Any) => boolean;
export declare const isDate: (v: Any) => v is Date;
export declare const isRegExp: (v: Any) => v is RegExp;
export declare const isFunction: (v: Any) => boolean;
export declare const isNil: (v: Any) => v is undefined;
export declare const truthy: (arg: Any, strict?: boolean) => boolean;
export declare const isEmpty: (x: Any) => boolean;
/** ensure a value is an array or wrapped within one. */
export declare const ensureArray: <T>(x: T | T[]) => T[];
export declare const has: (obj: object, ...props: string[]) => boolean;
/**
 * Deep clone an object.
 */
export declare const cloneDeep: <T>(v: T, refs?: WeakSet<object>) => T;
/**
 * Returns the intersection of multiple arrays.
 *
 * @param  {Array} input An array of arrays from which to find intersection.
 * @return {Array} Array of intersecting values.
 */
export declare function intersection<T = Any>(input: T[][]): T[];
/**
 * Flatten the array
 *
 * @param xs The array to flatten
 * @param depth The number of nested lists to iterate. @default 1
 */
export declare function flatten(xs: Any[], depth?: number): Any[];
/**
 * Return a new unique version of the collection
 * @param  {Array} input The input collection
 * @return {Array}
 */
export declare function unique<T = Any>(input: T[]): T[];
/**
 * Groups the collection into sets by the returned key
 *
 * @param collection
 * @param keyFunc {Function} to compute the group key of an item in the collection
 */
export declare function groupBy<T = Any, K = Any>(collection: T[], keyFunc: (a: T, i: number) => K): Map<K | null, T[]>;
/** Options to resolve() and resolveGraph() functions */
interface ResolveOptions {
    /** Unwrap the final array value.  */
    unwrapArray?: boolean;
    /** Replace "undefined" values with special MISSING symbol value. */
    preserveMissing?: boolean;
    /** Preserve values for untouched keys of objects. */
    preserveKeys?: boolean;
    /** Preserve untouched indexes in arrays. */
    preserveIndex?: boolean;
    /** pre-splitted selector path */
    pathArray?: string[];
}
/**
 * Resolve the value of the field (dot separated) on the given object
 * @param obj {AnyObject} the object context
 * @param selector {String} dot separated path to field
 */
export declare function resolve(obj: ArrayOrObject, selector: string, options?: Pick<ResolveOptions, "unwrapArray" | "pathArray">): Any;
/**
 * Returns the full object to the resolved value given by the selector.
 *
 * @param obj {AnyObject} the object context
 * @param selector {String} dot separated path to field
 */
export declare function resolveGraph(obj: ArrayOrObject, selector: string, options?: ResolveOptions): ArrayOrObject | undefined;
/**
 * Filter out all MISSING values from the object in-place
 *
 * @param obj The object to filter
 * @private
 */
export declare function filterMissing(obj: ArrayOrObject): void;
/** Options passed to the walk function. */
export interface WalkOptions {
    buildGraph?: boolean;
    descendArray?: boolean;
}
export type Indexed = string | number;
/**
 * Walk the object graph and execute the given transform function
 *
 * @param  {AnyObject|Array} obj   The object to traverse.
 * @param  {String} selector    The selector to navigate.
 * @param  {Callback} fn Callback to execute for value at the end the traversal.
 * @param  {WalkOptions} options The opetions to use for the function.
 */
export declare function walk(obj: AnyObject, selector: string, fn: (_o: AnyObject, _k: string) => void, options?: WalkOptions): void;
/**
 * Set the value of the given object field
 *
 * @param obj {AnyObject|Array} the object context
 * @param selector {String} path to field
 * @param value {*} the value to set.
 */
export declare function setValue(obj: AnyObject, selector: string, value: Any): void;
/**
 * Removes an element from the container.
 * If the selector resolves to an array and the leaf is a non-numeric key,
 * the remove operation will be performed on objects of the array.
 *
 * @param obj {ArrayOrObject} object or array
 * @param selector {String} dot separated path to element to remove
 */
export declare function removeValue(obj: AnyObject, selector: string, options?: Pick<WalkOptions, "descendArray">): void;
/**
 * Check whether the given name passes for an operator. We assume AnyVal field name starting with '$' is an operator.
 * This is cheap and safe to do since keys beginning with '$' should be reserved for internal use.
 * @param {String} name
 */
export declare const isOperator: (name: string) => boolean;
/**
 * Simplify expression for easy evaluation with query operators map
 * @param expr
 * @returns {*}
 */
export declare function normalize(expr: Any): Any;
/**
 * Find the insert index for the given key in a sorted array.
 *
 * @param sorted The sorted array to search
 * @param item The search key
 * @param comparator Optional custom compare function
 */
export declare function findInsertIndex<T = Any>(sorted: T[], item: T, comparator?: Comparator<T>): number;
/** Simple to trie for validating path conflicts */
export declare class PathValidator {
    private root;
    constructor();
    add(selector: string): boolean;
}
