import type { ValueOf } from 'type-fest';
import type Onyx from './Onyx';
import type { CollectionKey, CollectionKeyBase, ConnectOptions, DeepRecord, KeyValueMapping, Mapping, OnyxCollection, OnyxEntry, OnyxInput, OnyxKey, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, Selector } from './types';
import type { WithOnyxState } from './withOnyx/types';
import type { DeferredTask } from './createDeferredTask';
declare const METHOD: {
    readonly SET: "set";
    readonly MERGE: "merge";
    readonly MERGE_COLLECTION: "mergecollection";
    readonly SET_COLLECTION: "setcollection";
    readonly MULTI_SET: "multiset";
    readonly CLEAR: "clear";
};
type OnyxMethod = ValueOf<typeof METHOD>;
declare function getSnapshotKey(): OnyxKey | null;
/**
 * Getter - returns the merge queue.
 */
declare function getMergeQueue(): Record<OnyxKey, Array<OnyxValue<OnyxKey>>>;
/**
 * Getter - returns the merge queue promise.
 */
declare function getMergeQueuePromise(): Record<OnyxKey, Promise<void>>;
/**
 * Getter - returns the default key states.
 */
declare function getDefaultKeyStates(): Record<OnyxKey, OnyxValue<OnyxKey>>;
/**
 * Getter - returns the deffered init task.
 */
declare function getDeferredInitTask(): DeferredTask;
/**
 * Getter - returns the skippable collection member IDs.
 */
declare function getSkippableCollectionMemberIDs(): Set<string>;
/**
 * Setter - sets the skippable collection member IDs.
 */
declare function setSkippableCollectionMemberIDs(ids: Set<string>): void;
/**
 * Sets the initial values for the Onyx store
 *
 * @param keys - `ONYXKEYS` constants object from Onyx.init()
 * @param initialKeyStates - initial data to set when `init()` and `clear()` are called
 * @param evictableKeys - This is an array of keys (individual or collection patterns) that when provided to Onyx are flagged as "safe" for removal.
 */
declare function initStoreValues(keys: DeepRecord<string, OnyxKey>, initialKeyStates: Partial<KeyValueMapping>, evictableKeys: OnyxKey[]): void;
/**
 * Sends an action to DevTools extension
 *
 * @param method - Onyx method from METHOD
 * @param key - Onyx key that was changed
 * @param value - contains the change that was made by the method
 * @param mergedValue - (optional) value that was written in the storage after a merge method was executed.
 */
declare function sendActionToDevTools(method: typeof METHOD.MERGE_COLLECTION | typeof METHOD.MULTI_SET | typeof METHOD.SET_COLLECTION, key: undefined, value: OnyxCollection<KeyValueMapping[OnyxKey]>, mergedValue?: undefined): void;
declare function sendActionToDevTools(method: Exclude<OnyxMethod, typeof METHOD.MERGE_COLLECTION | typeof METHOD.MULTI_SET | typeof METHOD.SET_COLLECTION>, key: OnyxKey, value: OnyxEntry<KeyValueMapping[OnyxKey]>, mergedValue?: OnyxEntry<KeyValueMapping[OnyxKey]>): void;
/**
 * We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
 * This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
 * update operations. Instead of calling the subscribers for each update operation, we batch them together which will
 * cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
 */
declare function maybeFlushBatchUpdates(): Promise<void>;
declare function batchUpdates(updates: () => void): Promise<void>;
/**
 * Takes a collection of items (eg. {testKey_1:{a:'a'}, testKey_2:{b:'b'}})
 * and runs it through a reducer function to return a subset of the data according to a selector.
 * The resulting collection will only contain items that are returned by the selector.
 */
declare function reduceCollectionWithSelector<TKey extends CollectionKeyBase, TMap, TReturn>(collection: OnyxCollection<KeyValueMapping[TKey]>, selector: Selector<TKey, TMap, TReturn>, withOnyxInstanceState: WithOnyxState<TMap> | undefined): Record<string, TReturn>;
/** Get some data from the store */
declare function get<TKey extends OnyxKey, TValue extends OnyxValue<TKey>>(key: TKey): Promise<TValue>;
declare function multiGet<TKey extends OnyxKey>(keys: CollectionKeyBase[]): Promise<Map<OnyxKey, OnyxValue<TKey>>>;
/**
 * This helper exists to map an array of Onyx keys such as `['report_', 'conciergeReportID']`
 * to the values for those keys (correctly typed) such as `[OnyxCollection<Report>, OnyxEntry<string>]`
 *
 * Note: just using `.map`, you'd end up with `Array<OnyxCollection<Report>|OnyxEntry<string>>`, which is not what we want. This preserves the order of the keys provided.
 */
declare function tupleGet<Keys extends readonly OnyxKey[]>(keys: Keys): Promise<{
    [Index in keyof Keys]: OnyxValue<Keys[Index]>;
}>;
/**
 * Stores a subscription ID associated with a given key.
 *
 * @param subscriptionID - A subscription ID of the subscriber.
 * @param key - A key that the subscriber is subscribed to.
 */
declare function storeKeyBySubscriptions(key: OnyxKey, subscriptionID: number): void;
/**
 * Deletes a subscription ID associated with its corresponding key.
 *
 * @param subscriptionID - The subscription ID to be deleted.
 */
declare function deleteKeyBySubscriptions(subscriptionID: number): void;
/** Returns current key names stored in persisted storage */
declare function getAllKeys(): Promise<Set<OnyxKey>>;
/**
 * Returns set of all registered collection keys
 */
declare function getCollectionKeys(): Set<OnyxKey>;
/**
 * Checks to see if the subscriber's supplied key
 * is associated with a collection of keys.
 */
declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string, collectionKeyLength: number): key is `${TCollectionKey}${string}`;
/**
 * Splits a collection member key into the collection key part and the ID part.
 * @param key - The collection member key to split.
 * @param collectionKey - The collection key of the `key` param that can be passed in advance to optimize the function.
 * @returns A tuple where the first element is the collection part and the second element is the ID part,
 * or throws an Error if the key is not a collection one.
 */
declare function splitCollectionMemberKey<TKey extends CollectionKey, CollectionKeyType = TKey extends `${infer Prefix}_${string}` ? `${Prefix}_` : never>(key: TKey, collectionKey?: string): [CollectionKeyType, string];
/**
 * Checks to see if a provided key is the exact configured key of our connected subscriber
 * or if the provided key is a collection member key (in case our configured key is a "collection key")
 */
declare function isKeyMatch(configKey: OnyxKey, key: OnyxKey): boolean;
/**
 * Extracts the collection identifier of a given collection member key.
 *
 * For example:
 * - `getCollectionKey("report_123")` would return "report_"
 * - `getCollectionKey("report_")` would return "report_"
 * - `getCollectionKey("report_-1_something")` would return "report_"
 * - `getCollectionKey("sharedNVP_user_-1_something")` would return "sharedNVP_user_"
 *
 * @param key - The collection key to process.
 * @returns The plain collection key or throws an Error if the key is not a collection one.
 */
declare function getCollectionKey(key: CollectionKey): string;
/**
 * Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
 * If the requested key is a collection, it will return an object with all the collection members.
 */
declare function tryGetCachedValue<TKey extends OnyxKey>(key: TKey, mapping?: Partial<Mapping<TKey>>): OnyxValue<OnyxKey>;
declare function getCachedCollection<TKey extends CollectionKeyBase>(collectionKey: TKey, collectionMemberKeys?: string[]): NonNullable<OnyxCollection<KeyValueMapping[TKey]>>;
/**
 * When a collection of keys change, search for any callbacks matching the collection key and trigger those callbacks
 */
declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, partialPreviousCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined, notifyConnectSubscribers?: boolean, notifyWithOnyxSubscribers?: boolean): void;
/**
 * When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
 *
 * @example
 * keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
 */
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, previousValue: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: Mapping<OnyxKey>) => boolean, notifyConnectSubscribers?: boolean, notifyWithOnyxSubscribers?: boolean): void;
/**
 * Sends the data obtained from the keys to the connection. It either:
 *     - sets state on the withOnyxInstances
 *     - triggers the callback function
 */
declare function sendDataToConnection<TKey extends OnyxKey>(mapping: Mapping<TKey>, value: OnyxValue<TKey> | null, matchedKey: TKey | undefined, isBatched: boolean): void;
/**
 * We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
 * run out of storage the least recently accessed key can be removed.
 */
declare function addKeyToRecentlyAccessedIfNeeded<TKey extends OnyxKey>(mapping: Mapping<TKey>): void;
/**
 * Gets the data for a given an array of matching keys, combines them into an object, and sends the result back to the subscriber.
 */
declare function getCollectionDataAndSendAsObject<TKey extends OnyxKey>(matchingKeys: CollectionKeyBase[], mapping: Mapping<TKey>): void;
/**
 * Schedules an update that will be appended to the macro task queue (so it doesn't update the subscribers immediately).
 *
 * @example
 * scheduleSubscriberUpdate(key, value, subscriber => subscriber.initWithStoredValues === false)
 */
declare function scheduleSubscriberUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, previousValue: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: Mapping<OnyxKey>) => boolean): Promise<void>;
/**
 * This method is similar to notifySubscribersOnNextTick but it is built for working specifically with collections
 * so that keysChanged() is triggered for the collection and not keyChanged(). If this was not done, then the
 * subscriber callbacks receive the data in a different format than they normally expect and it breaks code.
 */
declare function scheduleNotifyCollectionSubscribers<TKey extends OnyxKey>(key: TKey, value: OnyxCollection<KeyValueMapping[TKey]>, previousValue?: OnyxCollection<KeyValueMapping[TKey]>): Promise<void>;
/**
 * Remove a key from Onyx and update the subscribers
 */
declare function remove<TKey extends OnyxKey>(key: TKey): Promise<void>;
declare function reportStorageQuota(): Promise<void>;
/**
 * If we fail to set or merge we must handle this by
 * evicting some data from Onyx and then retrying to do
 * whatever it is we attempted to do.
 */
declare function evictStorageAndRetry<TMethod extends typeof Onyx.set | typeof Onyx.multiSet | typeof Onyx.mergeCollection | typeof Onyx.setCollection>(error: Error, onyxMethod: TMethod, ...args: Parameters<TMethod>): Promise<void>;
/**
 * Notifies subscribers and writes current value to cache
 */
declare function broadcastUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, hasChanged?: boolean): Promise<void>;
declare function hasPendingMergeForKey(key: OnyxKey): boolean;
type RemoveNullValuesOutput<Value extends OnyxInput<OnyxKey> | undefined> = {
    value: Value;
    wasRemoved: boolean;
};
/**
 * Removes a key from storage if the value is null.
 * Otherwise removes all nested null values in objects,
 * if shouldRemoveNestedNulls is true and returns the object.
 *
 * @returns The value without null values and a boolean "wasRemoved", which indicates if the key got removed completely
 */
declare function removeNullValues<Value extends OnyxInput<OnyxKey> | undefined>(key: OnyxKey, value: Value, shouldRemoveNestedNulls?: boolean): RemoveNullValuesOutput<Value>;
/**
 * Storage expects array like: [["@MyApp_user", value_1], ["@MyApp_key", value_2]]
 * This method transforms an object like {'@MyApp_user': myUserValue, '@MyApp_key': myKeyValue}
 * to an array of key-value pairs in the above format and removes key-value pairs that are being set to null

* @return an array of key - value pairs <[key, value]>
 */
declare function prepareKeyValuePairsForStorage(data: Record<OnyxKey, OnyxInput<OnyxKey>>, shouldRemoveNestedNulls: boolean): Array<[OnyxKey, OnyxInput<OnyxKey>]>;
/**
 * Merges an array of changes with an existing value
 *
 * @param changes Array of changes that should be applied to the existing value
 */
declare function applyMerge<TValue extends OnyxInput<OnyxKey> | undefined, TChange extends OnyxInput<OnyxKey> | undefined>(existingValue: TValue, changes: TChange[], shouldRemoveNestedNulls: boolean): TChange;
/**
 * Merge user provided default key value pairs.
 */
declare function initializeWithDefaultKeyStates(): Promise<void>;
/**
 * Validate the collection is not empty and has a correct type before applying mergeCollection()
 */
declare function isValidNonEmptyCollectionForMerge<TKey extends CollectionKeyBase, TMap>(collection: OnyxMergeCollectionInput<TKey, TMap>): boolean;
/**
 * Verify if all the collection keys belong to the same parent
 */
declare function doAllCollectionItemsBelongToSameParent<TKey extends CollectionKeyBase>(collectionKey: TKey, collectionKeys: string[]): boolean;
/**
 * Subscribes to an Onyx key and listens to its changes.
 *
 * @param connectOptions The options object that will define the behavior of the connection.
 * @returns The subscription ID to use when calling `OnyxUtils.unsubscribeFromKey()`.
 */
declare function subscribeToKey<TKey extends OnyxKey>(connectOptions: ConnectOptions<TKey>): number;
/**
 * Disconnects and removes the listener from the Onyx key.
 *
 * @param subscriptionID Subscription ID returned by calling `OnyxUtils.subscribeToKey()`.
 */
declare function unsubscribeFromKey(subscriptionID: number): void;
declare function updateSnapshots(data: OnyxUpdate[], mergeFn: typeof Onyx.merge): Array<() => Promise<void>>;
declare const OnyxUtils: {
    METHOD: {
        readonly SET: "set";
        readonly MERGE: "merge";
        readonly MERGE_COLLECTION: "mergecollection";
        readonly SET_COLLECTION: "setcollection";
        readonly MULTI_SET: "multiset";
        readonly CLEAR: "clear";
    };
    getMergeQueue: typeof getMergeQueue;
    getMergeQueuePromise: typeof getMergeQueuePromise;
    getDefaultKeyStates: typeof getDefaultKeyStates;
    getDeferredInitTask: typeof getDeferredInitTask;
    initStoreValues: typeof initStoreValues;
    sendActionToDevTools: typeof sendActionToDevTools;
    maybeFlushBatchUpdates: typeof maybeFlushBatchUpdates;
    batchUpdates: typeof batchUpdates;
    get: typeof get;
    getAllKeys: typeof getAllKeys;
    getCollectionKeys: typeof getCollectionKeys;
    isCollectionKey: typeof isCollectionKey;
    isCollectionMemberKey: typeof isCollectionMemberKey;
    splitCollectionMemberKey: typeof splitCollectionMemberKey;
    isKeyMatch: typeof isKeyMatch;
    tryGetCachedValue: typeof tryGetCachedValue;
    getCachedCollection: typeof getCachedCollection;
    keysChanged: typeof keysChanged;
    keyChanged: typeof keyChanged;
    sendDataToConnection: typeof sendDataToConnection;
    getCollectionKey: typeof getCollectionKey;
    getCollectionDataAndSendAsObject: typeof getCollectionDataAndSendAsObject;
    scheduleSubscriberUpdate: typeof scheduleSubscriberUpdate;
    scheduleNotifyCollectionSubscribers: typeof scheduleNotifyCollectionSubscribers;
    remove: typeof remove;
    reportStorageQuota: typeof reportStorageQuota;
    evictStorageAndRetry: typeof evictStorageAndRetry;
    broadcastUpdate: typeof broadcastUpdate;
    hasPendingMergeForKey: typeof hasPendingMergeForKey;
    removeNullValues: typeof removeNullValues;
    prepareKeyValuePairsForStorage: typeof prepareKeyValuePairsForStorage;
    applyMerge: typeof applyMerge;
    initializeWithDefaultKeyStates: typeof initializeWithDefaultKeyStates;
    getSnapshotKey: typeof getSnapshotKey;
    multiGet: typeof multiGet;
    tupleGet: typeof tupleGet;
    isValidNonEmptyCollectionForMerge: typeof isValidNonEmptyCollectionForMerge;
    doAllCollectionItemsBelongToSameParent: typeof doAllCollectionItemsBelongToSameParent;
    subscribeToKey: typeof subscribeToKey;
    unsubscribeFromKey: typeof unsubscribeFromKey;
    getSkippableCollectionMemberIDs: typeof getSkippableCollectionMemberIDs;
    setSkippableCollectionMemberIDs: typeof setSkippableCollectionMemberIDs;
    storeKeyBySubscriptions: typeof storeKeyBySubscriptions;
    deleteKeyBySubscriptions: typeof deleteKeyBySubscriptions;
    addKeyToRecentlyAccessedIfNeeded: typeof addKeyToRecentlyAccessedIfNeeded;
    reduceCollectionWithSelector: typeof reduceCollectionWithSelector;
    updateSnapshots: typeof updateSnapshots;
};
export type { OnyxMethod };
export default OnyxUtils;
