/**
 * Utility constants and functions
 */
import { Any, ArrayOrObject, Callback, Comparator, HashFunction } from "./types";
/** Represents an error reported by the mingo library. */
export declare class MingoError extends Error {
}
/**
 * Compare function which adheres to MongoDB comparison order.
 *
 * @param a The first value
 * @param b The second value
 * @returns {Number}
 */
export declare const compare: <T = Any>(a: T, b: T) => number;
/**
 * 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 ValueMap<K, V> extends Map<K, V> {
    #private;
    private constructor();
    /**
     * Returns a new {@link ValueMap} object.
     * @param fn An optional custom hash function
     */
    static init<K, V>(fn?: HashFunction): ValueMap<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: boolean, message: 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 isNotNaN: (v: Any) => boolean;
export declare const isArray: (arg: any) => arg is any[];
export declare function isObject(v: Any): v is object;
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) => boolean;
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, prop: string) => boolean;
/**
 * Deep clone an object.
 */
export declare const cloneDeep: <T>(v: T, refs?: Set<Any>) => T;
/**
 * Deep merge objects or arrays. When the inputs have unmergeable types, the right hand value is returned.
 * If inputs are arrays, elements in the same position are merged together.
 * Remaining elements are appended to the target object.
 *
 * @param target Target object to merge into.
 * @param input  Source object to merge from.
 * @private
 */
export declare function merge(target: Any, input: Any): Any;
/**
 * Returns the intersection of multiple arrays.
 *
 * @param  {Array} input An array of arrays from which to find intersection.
 * @param  {Function} hashFunction Custom function to hash values, default the hashCode method
 * @return {Array} Array of intersecting values.
 */
export declare function intersection(input: Any[][], hashFunction?: HashFunction): Any[];
/**
 * 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[];
/**
 * Determine whether two values are the same or strictly equivalent.
 * Checking whether values are the same only applies to built in objects.
 * For user-defined objects this checks for only referential equality so
 * two different instances with the same values are not equal.
 *
 * @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;
/**
 * Return a new unique version of the collection
 * @param  {Array} input The input collection
 * @return {Array}
 */
export declare function unique(input: Any[], hashFunction?: HashFunction): Any[];
/**
 * Encode value to string using a simple non-colliding stable scheme.
 * Handles user-defined types by processing keys on first non-empty prototype.
 * If a user-defined type provides a "toString" function, it is used.
 *
 * @param value The value to convert to a string representation.
 * @returns {string}
 */
export declare const stringify: (v: Any, refs?: Set<Any>) => string;
/**
 * Generate hash code.
 * This selected function is the result of benchmarking various hash functions.
 * This version performs well and can hash 10^6 documents in ~3s with on average 100 collisions.
 *
 * @param value
 * @returns {number|null}
 */
export declare function hashCode(value: Any, hashFunction?: HashFunction): number;
/**
 * Groups the collection into sets by the returned key
 *
 * @param collection
 * @param keyFn {Function} to compute the group key of an item in the collection
 * @returns {Map<Any, Any[]>}
 */
export declare function groupBy(collection: Any[], keyFn: Callback<Any>, hashFunction?: HashFunction): Map<Any, Any[]>;
/**
 * Merge elements into the dest
 *
 * @param {*} target The target object
 * @param {*} rest The array of elements to merge into dest
 * @private
 */
export declare function into(target: ArrayOrObject, ...rest: ArrayOrObject[]): ArrayOrObject;
/** 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;
}
/**
 * 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
 * @returns {*}
 */
export declare function resolve(obj: ArrayOrObject, selector: string, options?: Pick<ResolveOptions, "unwrapArray">): 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;
}
/**
 * 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.
 * @return {*}
 */
export declare function walk(obj: ArrayOrObject, selector: string, fn: Callback<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. if it is function, it is invoked with the old value and must return the new value.
 */
export declare function setValue(obj: ArrayOrObject, 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: ArrayOrObject, 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 function 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(sorted: Any[], item: Any, comparator?: Comparator): number;
export {};
