import type { ValueOf } from 'type-fest';
import type Onyx from './Onyx';
import type { CollectionKeyBase, ConnectOptions, DeepRecord, KeyValueMapping, CallbackToStateMapping, MultiMergeReplaceNullPatches, OnyxCollection, OnyxEntry, OnyxInput, OnyxKey, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, Selector, MergeCollectionWithPatchesParams, SetCollectionParams, SetParams, OnyxMultiSetInput, RetriableOnyxOperation } from './types';
import type { FastMergeResult } from './utils';
import type { DeferredTask } from './createDeferredTask';
import type { StorageKeyValuePair } from './storage/providers/types';
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;
/**
 * Executes an action after Onyx has been initialized.
 * If Onyx is already initialized, the action is executed immediately.
 * Otherwise, it waits for initialization to complete before executing.
 *
 * @param action The action to execute after initialization
 * @returns The result of the action
 */
declare function afterInit<T>(action: () => Promise<T>): Promise<T>;
/**
 * Getter - returns the skippable collection member IDs.
 */
declare function getSkippableCollectionMemberIDs(): Set<string>;
/**
 * Getter - returns the snapshot merge keys allowlist.
 */
declare function getSnapshotMergeKeys(): Set<string>;
/**
 * Setter - sets the skippable collection member IDs.
 */
declare function setSkippableCollectionMemberIDs(ids: Set<string>): void;
/**
 * Setter - sets the snapshot merge keys allowlist.
 */
declare function setSnapshotMergeKeys(keys: 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;
/**
 * 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, TReturn>(collection: OnyxCollection<KeyValueMapping[TKey]>, selector: Selector<TKey, TReturn>): 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>>;
/**
 * 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): 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): void;
/**
 * When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
 */
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: CallbackToStateMapping<OnyxKey>) => boolean, isProcessingCollectionUpdate?: boolean): void;
/**
 * Sends the data obtained from the keys to the connection.
 */
declare function sendDataToConnection<TKey extends OnyxKey>(mapping: CallbackToStateMapping<TKey>, matchedKey: TKey | undefined): 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: CallbackToStateMapping<TKey>): void;
/**
 * Remove a key from Onyx and update the subscribers
 */
declare function remove<TKey extends OnyxKey>(key: TKey, isProcessingCollectionUpdate?: boolean): Promise<void>;
declare function reportStorageQuota(error?: Error): Promise<void>;
/**
 * Handles storage operation failures based on the error class (see lib/storage/errors.ts).
 * The connection layer (createStore) owns connection/transport recovery; this operation layer owns
 * capacity recovery (eviction) so that a given failure is retried by exactly one layer:
 * - INVALID_DATA: logs an alert and throws (the same data will always fail).
 * - TRANSIENT / FATAL: the connection layer already retried (transient) or exhausted its heal budget
 *   and alerted (fatal). Retrying here would only re-amplify, so we skip the write quietly.
 * - CAPACITY: evicts the least recently accessed evictable key and retries, under a session-level
 *   circuit breaker (see lib/StorageCircuitBreaker.ts) that halts the loop once eviction stops making
 *   progress or failures storm — the per-operation budget alone cannot stop a session-wide storm.
 * - UNKNOWN: the provider couldn't classify it — log the full error shape (name + message +
 *   provider) once so it's visible, then bounded retry without eviction.
 */
declare function retryOperation<TMethod extends RetriableOnyxOperation>(error: Error, onyxMethod: TMethod, defaultParams: Parameters<TMethod>[0], retryAttempt: number | undefined, inFlightKeys?: Set<OnyxKey>): Promise<void>;
/**
 * Notifies subscribers and writes current value to cache
 */
declare function broadcastUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, hasChanged?: boolean): void;
declare function hasPendingMergeForKey(key: OnyxKey): boolean;
/**
 * 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, replaceNullPatches?: MultiMergeReplaceNullPatches, isProcessingCollectionUpdate?: boolean): StorageKeyValuePair[];
/**
 * Merges an array of changes with an existing value or creates a single change.
 *
 * @param changes Array of changes that should be merged
 * @param existingValue The existing value that should be merged with the changes
 */
declare function mergeChanges<TValue extends OnyxInput<OnyxKey> | undefined, TChange extends OnyxInput<OnyxKey> | undefined>(changes: TChange[], existingValue?: TValue): FastMergeResult<TChange>;
/**
 * Merges an array of changes with an existing value or creates a single change.
 * It will also mark deep nested objects that need to be entirely replaced during the merge.
 *
 * @param changes Array of changes that should be merged
 * @param existingValue The existing value that should be merged with the changes
 */
declare function mergeAndMarkChanges<TValue extends OnyxInput<OnyxKey> | undefined, TChange extends OnyxInput<OnyxKey> | undefined>(changes: TChange[], existingValue?: TValue): FastMergeResult<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>(collection: OnyxMergeCollectionInput<TKey>): 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<TKey extends OnyxKey>(data: Array<OnyxUpdate<TKey>>, mergeFn: typeof Onyx.merge): Array<() => Promise<void>>;
/**
 * Writes a value to our store with the given key.
 * Serves as core implementation for `Onyx.set()` public function, the difference being
 * that this internal function allows passing an additional `retryAttempt` parameter to retry on failure.
 *
 * @param params - set parameters
 * @param params.key ONYXKEY to set
 * @param params.value value to store
 * @param params.options optional configuration object
 * @param retryAttempt retry attempt
 */
declare function setWithRetry<TKey extends OnyxKey>({ key, value, options }: SetParams<TKey>, retryAttempt?: number): Promise<void>;
/**
 * Sets multiple keys and values.
 * Serves as core implementation for `Onyx.multiSet()` public function, the difference being
 * that this internal function allows passing an additional `retryAttempt` parameter to retry on failure.
 *
 * @param data object keyed by ONYXKEYS and the values to set
 * @param retryAttempt retry attempt
 */
declare function multiSetWithRetry(data: OnyxMultiSetInput, retryAttempt?: number): Promise<void>;
/**
 * Sets a collection by replacing all existing collection members with new values.
 * Any existing collection members not included in the new data will be removed.
 * Serves as core implementation for `Onyx.setCollection()` public function, the difference being
 * that this internal function allows passing an additional `retryAttempt` parameter to retry on failure.
 *
 * @param params - collection parameters
 * @param params.collectionKey e.g. `ONYXKEYS.COLLECTION.REPORT`
 * @param params.collection Object collection keyed by individual collection member keys and values
 * @param retryAttempt retry attempt
 */
declare function setCollectionWithRetry<TKey extends CollectionKeyBase>({ collectionKey, collection }: SetCollectionParams<TKey>, retryAttempt?: number): Promise<void>;
/**
 * Merges a collection based on their keys.
 * Serves as core implementation for `Onyx.mergeCollection()` public function, the difference being
 * that this internal function allows passing an additional `mergeReplaceNullPatches` parameter and retries on failure.
 *
 * @param params - mergeCollection parameters
 * @param params.collectionKey e.g. `ONYXKEYS.COLLECTION.REPORT`
 * @param params.collection Object collection keyed by individual collection member keys and values
 * @param params.mergeReplaceNullPatches Record where the key is a collection member key and the value is a list of
 * tuples that we'll use to replace the nested objects of that collection member record with something else.
 * @param params.isProcessingCollectionUpdate whether this is part of a collection update operation.
 * @param retryAttempt retry attempt
 */
declare function mergeCollectionWithPatches<TKey extends CollectionKeyBase>({ collectionKey, collection, mergeReplaceNullPatches, isProcessingCollectionUpdate }: MergeCollectionWithPatchesParams<TKey>, retryAttempt?: number): Promise<void>;
/**
 * Sets keys in a collection by replacing all targeted collection members with new values.
 * Any existing collection members not included in the new data will not be removed.
 * Retries on failure.
 *
 * @param params - collection parameters
 * @param params.collectionKey e.g. `ONYXKEYS.COLLECTION.REPORT`
 * @param params.collection Object collection keyed by individual collection member keys and values
 * @param retryAttempt retry attempt
 */
declare function partialSetCollection<TKey extends CollectionKeyBase>({ collectionKey, collection }: SetCollectionParams<TKey>, retryAttempt?: number): Promise<void>;
declare function logKeyChanged(onyxMethod: Extract<OnyxMethod, 'set' | 'merge'>, key: OnyxKey, value: unknown, hasChanged: boolean): void;
declare function logKeyRemoved(onyxMethod: Extract<OnyxMethod, 'set' | 'merge'>, key: OnyxKey): void;
/**
 * Clear internal variables used in this file, useful in test environments.
 */
declare function clearOnyxUtilsInternals(): 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;
    afterInit: typeof afterInit;
    initStoreValues: typeof initStoreValues;
    sendActionToDevTools: typeof sendActionToDevTools;
    get: typeof get;
    getAllKeys: typeof getAllKeys;
    tryGetCachedValue: typeof tryGetCachedValue;
    getCachedCollection: typeof getCachedCollection;
    keysChanged: typeof keysChanged;
    keyChanged: typeof keyChanged;
    sendDataToConnection: typeof sendDataToConnection;
    getCollectionDataAndSendAsObject: typeof getCollectionDataAndSendAsObject;
    remove: typeof remove;
    reportStorageQuota: typeof reportStorageQuota;
    retryOperation: typeof retryOperation;
    broadcastUpdate: typeof broadcastUpdate;
    hasPendingMergeForKey: typeof hasPendingMergeForKey;
    prepareKeyValuePairsForStorage: typeof prepareKeyValuePairsForStorage;
    mergeChanges: typeof mergeChanges;
    mergeAndMarkChanges: typeof mergeAndMarkChanges;
    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;
    getSnapshotMergeKeys: typeof getSnapshotMergeKeys;
    setSnapshotMergeKeys: typeof setSnapshotMergeKeys;
    storeKeyBySubscriptions: typeof storeKeyBySubscriptions;
    deleteKeyBySubscriptions: typeof deleteKeyBySubscriptions;
    reduceCollectionWithSelector: typeof reduceCollectionWithSelector;
    updateSnapshots: typeof updateSnapshots;
    mergeCollectionWithPatches: typeof mergeCollectionWithPatches;
    partialSetCollection: typeof partialSetCollection;
    logKeyChanged: typeof logKeyChanged;
    logKeyRemoved: typeof logKeyRemoved;
    setWithRetry: typeof setWithRetry;
    multiSetWithRetry: typeof multiSetWithRetry;
    setCollectionWithRetry: typeof setCollectionWithRetry;
};
export type { OnyxMethod };
export default OnyxUtils;
export { clearOnyxUtilsInternals };
