react-native-onyx
Version:
State management for React Native
307 lines (305 loc) • 17.1 kB
TypeScript
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;