/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { StableId } from "@fluidframework/runtime-definitions";
/**
 * Subset of Map interface.
 */
export interface MapGetSet<K, V> {
    get(key: K): V | undefined;
    set(key: K, value: V): void;
}
/**
 * Make all transitive properties in T readonly
 */
export declare type RecursiveReadonly<T> = {
    readonly [P in keyof T]: RecursiveReadonly<T[P]>;
};
/**
 * Remove `readonly` from all fields.
 */
export declare type Mutable<T> = {
    -readonly [P in keyof T]: T[P];
};
/**
 * Casts a readonly object to a mutable one.
 * Better than casting to `Mutable<Foo>` because it doesn't risk casting a non-`Foo` to a `Mutable<Foo>`.
 * @param readonly - The object with readonly fields.
 * @returns The same object but with a type that makes all fields mutable.
 */
export declare function asMutable<T>(readonly: T): Mutable<T>;
export declare function clone<T>(original: T): T;
/**
 * @alpha
 */
export declare function fail(message: string): never;
/**
 * Checks whether or not the given object is a `readonly` array.
 *
 * Note that this does NOT indicate if a given array should be treated as readonly.
 * This instead indicates if an object is an Array, and is typed to tolerate the readonly case.
 */
export declare function isReadonlyArray<T>(x: readonly T[] | unknown): x is readonly T[];
/**
 * Creates and populates a new array.
 * @param size - The size of the array to be created.
 * @param filler - Callback for populating the array with a value for a given index
 */
export declare function makeArray<T>(size: number, filler: (index: number) => T): T[];
/**
 * Compares two sets using callbacks.
 * Early returns on first false comparison.
 *
 * @param a - One Set.
 * @param b - The other Set.
 * @param aExtra - Called for items in `a` but not `b`.
 * @param bExtra - Called for items in `b` but not `a`.
 * @param same - Called for items in `a` and `b`.
 * @returns false iff any of the call backs returned false.
 */
export declare function compareSets<T>({ a, b, aExtra, bExtra, same, }: {
    a: ReadonlySet<T> | ReadonlyMap<T, unknown>;
    b: ReadonlySet<T> | ReadonlyMap<T, unknown>;
    aExtra?: (t: T) => boolean;
    bExtra?: (t: T) => boolean;
    same?: (t: T) => boolean;
}): boolean;
/**
 * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
 * @param map - The map to query/update
 * @param key - The key to lookup in the map
 * @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists
 * @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
 */
export declare function getOrCreate<K, V>(map: MapGetSet<K, V>, key: K, defaultValue: (key: K) => V): V;
/**
 * Utility for dictionaries whose values are lists.
 * Gets the list associated with the provided key, if it exists.
 * Otherwise, creates an entry with an empty list, and returns that list.
 */
export declare function getOrAddEmptyToMap<K, V>(map: MapGetSet<K, V[]>, key: K): V[];
/**
 * Map one iterable to another by transforming each element one at a time
 * @param iterable - the iterable to transform
 * @param map - the transformation function to run on each element of the iterable
 * @returns a new iterable of elements which have been transformed by the `map` function
 */
export declare function mapIterable<T, U>(iterable: Iterable<T>, map: (t: T) => U): Iterable<U>;
/**
 * Returns an iterable of tuples containing pairs of elements from the given iterables
 * @param iterableA - an iterable to zip together with `iterableB`
 * @param iterableB - an iterable to zip together with `iterableA`
 * @returns in iterable of tuples of elements zipped together from `iterableA` and `iterableB`.
 * If the input iterables are of different lengths, then the extra elements in the longer will be ignored.
 */
export declare function zipIterables<T, U>(iterableA: Iterable<T>, iterableB: Iterable<U>): Iterable<[T, U]>;
/**
 * Use for Json compatible data.
 *
 * Note that this does not robustly forbid non json comparable data via type checking,
 * but instead mostly restricts access to it.
 * @alpha
 */
export declare type JsonCompatible = string | number | boolean | null | JsonCompatible[] | JsonCompatibleObject;
/**
 * Use for Json object compatible data.
 *
 * Note that this does not robustly forbid non json comparable data via type checking,
 * but instead mostly restricts access to it.
 * @alpha
 */
export declare type JsonCompatibleObject = {
    [P in string]?: JsonCompatible;
};
/**
 * Use for readonly view of Json compatible data.
 *
 * Note that this does not robustly forbid non json comparable data via type checking,
 * but instead mostly restricts access to it.
 * @alpha
 */
export declare type JsonCompatibleReadOnly = string | number | boolean | null | readonly JsonCompatibleReadOnly[] | {
    readonly [P in string]?: JsonCompatibleReadOnly;
};
/**
 * @remarks - TODO: Audit usage of this type in schemas, evaluating whether it is necessary and performance
 * of alternatives.
 *
 * True "arbitrary serializable data" is probably fine, but some persisted types declarations might be better
 * expressed using composition of schemas for runtime validation, even if we don't think making the types
 * generic is worth the maintenance cost.
 */
export declare const JsonCompatibleReadOnlySchema: import("@sinclair/typebox").TAny;
/**
 * Returns if a particular json compatible value is an object.
 * Does not include `null` or arrays.
 */
export declare function isJsonObject(value: JsonCompatibleReadOnly): value is {
    readonly [P in string]?: JsonCompatibleReadOnly;
};
export declare function assertValidIndex(index: number, array: {
    readonly length: number;
}, allowOnePastEnd?: boolean): void;
export declare function assertNonNegativeSafeInteger(index: number): void;
/**
 * Assume that `TInput` is a `TAssumeToBe`.
 *
 * @remarks
 * This is useful in generic code when it is impractical (or messy)
 * to to convince the compiler that a generic type `TInput` will extend `TAssumeToBe`.
 * In these cases `TInput` can be replaced with `Assume<TInput, TAssumeToBe>` to allow compilation of the generic code.
 * When the generic code is parameterized with a concrete type, if that type actually does extend `TAssumeToBe`,
 * it will behave like `TInput` was used directly.
 *
 * @alpha
 */
export declare type Assume<TInput, TAssumeToBe> = TInput extends TAssumeToBe ? TInput : TAssumeToBe;
/**
 * Runs `f` with {@link generateStableId} altered to return sequential StableIds starting as a fixed seed.
 * Used to make test logic that uses {@link generateStableId} deterministic.
 *
 * @remarks
 * Only use this function for testing purposes.
 *
 * @example
 * ```ts
 * function f() {
 *    const id = generateStableId();
 *    ...
 * }
 * const result = useDeterministicStableId(f());
 * ```
 */
export declare function useDeterministicStableId<T>(f: () => T): T;
/**
 * Generates a random StableId.
 *
 * For test usage desiring deterministic results, see {@link useDeterministicStableId}.
 */
export declare function generateStableId(): StableId;
/**
 * Convert an object into a Map.
 *
 * This function must only be used with objects specifically intended to encode map like information.
 * The only time such objects should be used is for encoding maps as object literals to allow for developer ergonomics or JSON compatibility.
 * Even those two use-cases need to be carefully considered as using objects as maps can have a lot of issues
 * (including but not limited to unintended access to __proto__ and other non-owned keys).
 * This function helps these few cases get into using an actual map in as safe of was as is practical.
 */
export declare function objectToMap<MapKey extends string | number | symbol, MapValue>(objectMap: Record<MapKey, MapValue>): Map<MapKey, MapValue>;
/**
 * Returns the value from `set` if it contains exactly one item, otherwise `undefined`.
 */
export declare function oneFromSet<T>(set: ReadonlySet<T> | undefined): T | undefined;
//# sourceMappingURL=utils.d.ts.map