react-native-onyx 2.0.21 → 2.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/API.md +49 -64
  2. package/dist/DevTools.js +0 -1
  3. package/dist/Onyx.d.ts +49 -258
  4. package/dist/Onyx.js +192 -1165
  5. package/dist/OnyxCache.d.ts +14 -15
  6. package/dist/OnyxUtils.d.ts +320 -0
  7. package/dist/OnyxUtils.js +1061 -0
  8. package/dist/PerformanceUtils.d.ts +3 -5
  9. package/dist/index.d.ts +3 -2
  10. package/dist/storage/InstanceSync/index.d.ts +14 -0
  11. package/dist/storage/InstanceSync/index.js +20 -0
  12. package/dist/storage/InstanceSync/index.web.d.ts +27 -0
  13. package/dist/storage/InstanceSync/index.web.js +59 -0
  14. package/dist/storage/__mocks__/index.d.ts +15 -13
  15. package/dist/storage/__mocks__/index.js +43 -81
  16. package/dist/storage/index.d.ts +6 -2
  17. package/dist/storage/index.js +170 -2
  18. package/dist/storage/platforms/index.d.ts +2 -0
  19. package/dist/storage/{NativeStorage.js → platforms/index.js} +2 -2
  20. package/dist/storage/platforms/index.native.d.ts +2 -0
  21. package/dist/storage/{index.native.js → platforms/index.native.js} +2 -2
  22. package/dist/storage/providers/{IDBKeyVal.js → IDBKeyValProvider.js} +23 -19
  23. package/dist/storage/providers/MemoryOnlyProvider.d.ts +9 -0
  24. package/dist/storage/providers/MemoryOnlyProvider.js +124 -0
  25. package/dist/storage/providers/NoopProvider.js +85 -0
  26. package/dist/storage/providers/SQLiteProvider.d.ts +3 -0
  27. package/dist/storage/providers/{SQLiteStorage.js → SQLiteProvider.js} +17 -11
  28. package/dist/storage/providers/types.d.ts +17 -14
  29. package/dist/types.d.ts +128 -55
  30. package/dist/types.js +2 -0
  31. package/dist/useOnyx.js +11 -10
  32. package/dist/utils.d.ts +2 -2
  33. package/dist/utils.js +29 -16
  34. package/dist/withOnyx.js +6 -5
  35. package/package.json +1 -1
  36. package/dist/storage/NativeStorage.d.ts +0 -2
  37. package/dist/storage/WebStorage.d.ts +0 -3
  38. package/dist/storage/WebStorage.js +0 -62
  39. package/dist/storage/index.native.d.ts +0 -2
  40. /package/dist/storage/providers/{IDBKeyVal.d.ts → IDBKeyValProvider.d.ts} +0 -0
  41. /package/dist/storage/providers/{SQLiteStorage.d.ts → NoopProvider.d.ts} +0 -0
@@ -1,12 +1,11 @@
1
- import type { Key, Value } from './storage/providers/types';
2
- type StorageMap = Record<Key, Value>;
1
+ import type { OnyxKey, OnyxValue } from './types';
3
2
  /**
4
3
  * In memory cache providing data by reference
5
4
  * Encapsulates Onyx cache related functionality
6
5
  */
7
6
  declare class OnyxCache {
8
7
  /** Cache of all the storage keys available in persistent storage */
9
- private storageKeys;
8
+ storageKeys: Set<OnyxKey>;
10
9
  /** Unique list of keys maintained in access order (most recent at the end) */
11
10
  private recentKeys;
12
11
  /** A map of cached values */
@@ -20,30 +19,30 @@ declare class OnyxCache {
20
19
  private maxRecentKeysSize;
21
20
  constructor();
22
21
  /** Get all the storage keys */
23
- getAllKeys(): Set<Key>;
22
+ getAllKeys(): Set<OnyxKey>;
24
23
  /**
25
24
  * Get a cached value from storage
26
25
  * @param [shouldReindexCache] – This is an LRU cache, and by default accessing a value will make it become last in line to be evicted. This flag can be used to skip that and just access the value directly without side-effects.
27
26
  */
28
- getValue(key: Key, shouldReindexCache?: boolean): Value;
27
+ getValue(key: OnyxKey, shouldReindexCache?: boolean): OnyxValue<OnyxKey>;
29
28
  /** Check whether cache has data for the given key */
30
- hasCacheForKey(key: Key): boolean;
29
+ hasCacheForKey(key: OnyxKey): boolean;
31
30
  /** Saves a key in the storage keys list
32
31
  * Serves to keep the result of `getAllKeys` up to date
33
32
  */
34
- addKey(key: Key): void;
33
+ addKey(key: OnyxKey): void;
35
34
  /**
36
35
  * Set's a key value in cache
37
36
  * Adds the key to the storage keys list as well
38
37
  */
39
- set(key: Key, value: Value): Value;
38
+ set(key: OnyxKey, value: OnyxValue<OnyxKey>): OnyxValue<OnyxKey>;
40
39
  /** Forget the cached value for the given key */
41
- drop(key: Key): void;
40
+ drop(key: OnyxKey): void;
42
41
  /**
43
42
  * Deep merge data to cache, any non existing keys will be created
44
43
  * @param data - a map of (cache) key - values
45
44
  */
46
- merge(data: StorageMap): void;
45
+ merge(data: Record<OnyxKey, OnyxValue<OnyxKey>>): void;
47
46
  /**
48
47
  * Allows to set all the keys at once.
49
48
  * This is useful when we are getting
@@ -55,7 +54,7 @@ declare class OnyxCache {
55
54
  *
56
55
  * @param keys - an array of keys
57
56
  */
58
- setAllKeys(keys: Key[]): void;
57
+ setAllKeys(keys: OnyxKey[]): void;
59
58
  /**
60
59
  * Check whether the given task is already running
61
60
  * @param taskName - unique name given for the task
@@ -67,21 +66,21 @@ declare class OnyxCache {
67
66
  * provided from this function
68
67
  * @param taskName - unique name given for the task
69
68
  */
70
- getTaskPromise(taskName: string): Promise<unknown> | undefined;
69
+ getTaskPromise(taskName: string): Promise<OnyxValue<OnyxKey> | OnyxKey[]> | undefined;
71
70
  /**
72
71
  * Capture a promise for a given task so other caller can
73
72
  * hook up to the promise if it's still pending
74
73
  * @param taskName - unique name for the task
75
74
  */
76
- captureTask(taskName: string, promise: Promise<unknown>): Promise<unknown>;
75
+ captureTask(taskName: string, promise: Promise<OnyxValue<OnyxKey>>): Promise<OnyxValue<OnyxKey>>;
77
76
  /** Adds a key to the top of the recently accessed keys */
78
- private addToAccessedKeys;
77
+ addToAccessedKeys(key: OnyxKey): void;
79
78
  /** Remove keys that don't fall into the range of recently used keys */
80
79
  removeLeastRecentlyUsedKeys(): void;
81
80
  /** Set the recent keys list size */
82
81
  setRecentKeysLimit(limit: number): void;
83
82
  /** Check if the value has changed */
84
- hasValueChanged(key: Key, value: Value): boolean;
83
+ hasValueChanged(key: OnyxKey, value: OnyxValue<OnyxKey>): boolean;
85
84
  }
86
85
  declare const instance: OnyxCache;
87
86
  export default instance;
@@ -0,0 +1,320 @@
1
+ import {Component} from 'react';
2
+ import * as Logger from './Logger';
3
+ import {CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey, Selector} from './types';
4
+
5
+ declare const METHOD: {
6
+ readonly SET: 'set';
7
+ readonly MERGE: 'merge';
8
+ readonly MERGE_COLLECTION: 'mergecollection';
9
+ readonly MULTI_SET: 'multiset';
10
+ readonly CLEAR: 'clear';
11
+ };
12
+
13
+ type OnyxMethod = ValueOf<typeof METHOD>;
14
+
15
+ // Key/value store of Onyx key and arrays of values to merge
16
+ declare const mergeQueue: Record<OnyxKey, OnyxValue<OnyxKey>[]>;
17
+ declare const mergeQueuePromise: Record<OnyxKey, Promise<void | void[]>>;
18
+
19
+ // Holds a mapping of all the react components that want their state subscribed to a store key
20
+ declare const callbackToStateMapping: Record<string, Mapping<OnyxKey>>;
21
+
22
+ // Keeps a copy of the values of the onyx collection keys as a map for faster lookups
23
+ declare let onyxCollectionKeyMap: Map<OnyxKey, OnyxValue<OnyxKey>>;
24
+
25
+ // Holds a list of keys that have been directly subscribed to or recently modified from least to most recent
26
+ declare let recentlyAccessedKeys: OnyxKey[];
27
+
28
+ // Holds a list of keys that are safe to remove when we reach max storage. If a key does not match with
29
+ // whatever appears in this list it will NEVER be a candidate for eviction.
30
+ declare let evictionAllowList: OnyxKey[];
31
+
32
+ // Holds a map of keys and connectionID arrays whose keys will never be automatically evicted as
33
+ // long as we have at least one subscriber that returns false for the canEvict property.
34
+ declare const evictionBlocklist: Record<OnyxKey, number[]>;
35
+
36
+ // Optional user-provided key value states set when Onyx initializes or clears
37
+ declare let defaultKeyStates: Record<OnyxKey, OnyxValue<OnyxKey>>;
38
+
39
+ declare let batchUpdatesPromise: Promise<void> | null;
40
+ declare let batchUpdatesQueue: Array<() => void>;
41
+
42
+ /** Getter - returns the merge queue. */
43
+ declare function getMergeQueue(): Record<string, OnyxValue<string>[]>;
44
+
45
+ /** Getter - returns the merge queue promise. */
46
+ declare function getMergeQueuePromise(): Record<string, Promise<void | void[]>>;
47
+
48
+ /** Getter - returns the callback to state mapping. */
49
+ declare function getCallbackToStateMapping(): Record<string, Mapping<string>>;
50
+
51
+ /** Getter - returns the default key states. */
52
+ declare function getDefaultKeyStates(): Record<string, OnyxValue<string>>;
53
+
54
+ /**
55
+ * Sets the initial values for the Onyx store
56
+ *
57
+ * @param keys - `ONYXKEYS` constants object from Onyx.init()
58
+ * @param initialKeyStates - initial data to set when `init()` and `clear()` are called
59
+ * @param safeEvictionKeys - This is an array of keys (individual or collection patterns) that when provided to Onyx are flagged as "safe" for removal.
60
+ */
61
+ declare function initStoreValues(keys: DeepRecord<string, OnyxKey>, initialKeyStates: Partial<NullableKeyValueMapping>, safeEvictionKeys: OnyxKey[]): void;
62
+
63
+ /**
64
+ * Sends an action to DevTools extension
65
+ *
66
+ * @param method - Onyx method from METHOD
67
+ * @param key - Onyx key that was changed
68
+ * @param value - contains the change that was made by the method
69
+ * @param mergedValue - (optional) value that was written in the storage after a merge method was executed.
70
+ */
71
+ declare function sendActionToDevTools(method: OnyxMethod, key: undefined, value: Record<OnyxKey, OnyxValue<OnyxKey>>, mergedValue?: OnyxValue<OnyxKey>): void;
72
+ declare function sendActionToDevTools(method: OnyxMethod, key: OnyxKey, value: OnyxValue<OnyxKey>, mergedValue?: OnyxValue<OnyxKey>): void;
73
+
74
+ /**
75
+ * We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
76
+ * This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
77
+ * update operations. Instead of calling the subscribers for each update operation, we batch them together which will
78
+ * cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
79
+ */
80
+ declare function maybeFlushBatchUpdates(): Promise<void>;
81
+
82
+ declare function batchUpdates(updates: () => void): Promise<void>;
83
+
84
+ /** Get some data from the store */
85
+ declare function get(key: OnyxKey): Promise<OnyxValue<OnyxKey>>;
86
+
87
+ /**
88
+ * Returns current key names stored in persisted storage
89
+ */
90
+ declare function getAllKeys(): Promise<Set<string>>;
91
+
92
+ /**
93
+ * Checks to see if the a subscriber's supplied key
94
+ * is associated with a collection of keys.
95
+ */
96
+ declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
97
+
98
+ declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string): key is `${TCollectionKey}${string}`;
99
+
100
+ /**
101
+ * Splits a collection member key into the collection key part and the ID part.
102
+ * @param key - The collection member key to split.
103
+ * @returns A tuple where the first element is the collection part and the second element is the ID part.
104
+ */
105
+ declare function splitCollectionMemberKey<TKey extends CollectionKey>(key: TKey): [TKey extends `${infer Prefix}_${string}` ? `${Prefix}_` : never, string];
106
+
107
+ /**
108
+ * Checks to see if a provided key is the exact configured key of our connected subscriber
109
+ * or if the provided key is a collection member key (in case our configured key is a "collection key")
110
+ */
111
+ declare function isKeyMatch(configKey: OnyxKey, key: OnyxKey): boolean;
112
+
113
+ /**
114
+ * Checks to see if this key has been flagged as
115
+ * safe for removal.
116
+ */
117
+ declare function isSafeEvictionKey(testKey: OnyxKey): boolean;
118
+
119
+ /**
120
+ * Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
121
+ * If the requested key is a collection, it will return an object with all the collection members.
122
+ */
123
+ declare function tryGetCachedValue<TKey extends OnyxKey>(key: TKey, mapping: Mapping<TKey>): OnyxValue<OnyxKey>;
124
+
125
+ /** Remove a key from the recently accessed key list. */
126
+ declare function removeLastAccessedKey(key: OnyxKey): void;
127
+
128
+ /**
129
+ * Add a key to the list of recently accessed keys.
130
+ * The least recently accessed key should be at the head and the most recently accessed key at the tail.
131
+ */
132
+ declare function addLastAccessedKey(key: OnyxKey): void;
133
+
134
+ /**
135
+ * Removes a key previously added to this list
136
+ * which will enable it to be deleted again.
137
+ */
138
+ declare function removeFromEvictionBlockList(key: OnyxKey, connectionID: number): void;
139
+
140
+ /**
141
+ * Keys added to this list can never be deleted.
142
+ */
143
+ declare function addToEvictionBlockList(key: OnyxKey, connectionID: number): void;
144
+
145
+ /**
146
+ * Take all the keys that are safe to evict and add them to
147
+ * the recently accessed list when initializing the app. This
148
+ * enables keys that have not recently been accessed to be removed.
149
+ */
150
+ declare function addAllSafeEvictionKeysToRecentlyAccessedList(): Promise<void>;
151
+
152
+ declare function getCachedCollection<TKey extends CollectionKeyBase>(collectionKey: TKey): Record<OnyxKey, OnyxValue<OnyxKey>>;
153
+
154
+ /** When a collection of keys change, search for any callbacks matching the collection key and trigger those callbacks */
155
+ declare function keysChanged<TKey extends CollectionKeyBase>(
156
+ collectionKey: TKey,
157
+ partialCollection: OnyxCollection<OnyxValue<OnyxKey>>,
158
+ notifyRegularSubscibers?: boolean,
159
+ notifyWithOnyxSubscibers?: boolean,
160
+ ): void;
161
+ /**
162
+ * When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
163
+ *
164
+ * @example
165
+ * keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
166
+ *
167
+ * @param [canUpdateSubscriber] only subscribers that pass this truth test will be updated
168
+ */
169
+ declare function keyChanged(
170
+ key: OnyxKey,
171
+ data: OnyxValue<OnyxKey>,
172
+ prevData: OnyxValue<OnyxKey>,
173
+ canUpdateSubscriber?: (_subscriber: Mapping<OnyxKey>) => boolean,
174
+ notifyRegularSubscibers?: boolean,
175
+ notifyWithOnyxSubscibers?: boolean,
176
+ ): void;
177
+
178
+ /**
179
+ * Sends the data obtained from the keys to the connection. It either:
180
+ * - sets state on the withOnyxInstances
181
+ * - triggers the callback function
182
+ */
183
+ declare function sendDataToConnection<TKey extends OnyxKey>(
184
+ mapping: Mapping<TKey>,
185
+ val: OnyxValue<OnyxKey> | Record<OnyxKey, OnyxValue<OnyxKey>>,
186
+ matchedKey: TKey | undefined,
187
+ isBatched: boolean,
188
+ ): void;
189
+
190
+ /**
191
+ * We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
192
+ * run out of storage the least recently accessed key can be removed.
193
+ */
194
+ declare function addKeyToRecentlyAccessedIfNeeded<TKey extends OnyxKey>(mapping: Mapping<TKey>): void;
195
+
196
+ /**
197
+ * Gets the data for a given an array of matching keys, combines them into an object, and sends the result back to the subscriber.
198
+ */
199
+ declare function getCollectionDataAndSendAsObject<TKey extends OnyxKey>(matchingKeys: CollectionKeyBase[], mapping: Mapping<TKey>): void;
200
+
201
+ /**
202
+ * Schedules an update that will be appended to the macro task queue (so it doesn't update the subscribers immediately).
203
+ *
204
+ * @example
205
+ * scheduleSubscriberUpdate(key, value, subscriber => subscriber.initWithStoredValues === false)
206
+ */
207
+ declare function scheduleSubscriberUpdate<TKey extends OnyxKey>(
208
+ key: TKey,
209
+ value: KeyValueMapping[TKey],
210
+ prevValue: KeyValueMapping[TKey],
211
+ canUpdateSubscriber?: (_subscriber: Mapping<OnyxKey>) => boolean,
212
+ ): Promise<void>;
213
+
214
+ /**
215
+ * This method is similar to notifySubscribersOnNextTick but it is built for working specifically with collections
216
+ * so that keysChanged() is triggered for the collection and not keyChanged(). If this was not done, then the
217
+ * subscriber callbacks receive the data in a different format than they normally expect and it breaks code.
218
+ */
219
+ declare function scheduleNotifyCollectionSubscribers(key: OnyxKey, value: OnyxCollection<OnyxValue<OnyxKey>>): Promise<void>;
220
+
221
+ /**
222
+ * Remove a key from Onyx and update the subscribers
223
+ */
224
+ declare function remove<TKey extends OnyxKey>(key: TKey): Promise<void>;
225
+
226
+ declare function reportStorageQuota(): Promise<void>;
227
+
228
+ /**
229
+ * If we fail to set or merge we must handle this by
230
+ * evicting some data from Onyx and then retrying to do
231
+ * whatever it is we attempted to do.
232
+ */
233
+ declare function evictStorageAndRetry<TMethod extends typeof Onyx.set | typeof Onyx.multiSet | typeof Onyx.mergeCollection>(
234
+ error: Error,
235
+ onyxMethod: TMethod,
236
+ ...args: Parameters<TMethod>
237
+ ): Promise<void>;
238
+
239
+ /** Notifies subscribers and writes current value to cache */
240
+ declare function broadcastUpdate<TKey extends OnyxKey>(key: TKey, value: KeyValueMapping[TKey], hasChanged: boolean, wasRemoved?: boolean): Promise<void[]>;
241
+
242
+ /**
243
+ * @private
244
+ */
245
+ declare function hasPendingMergeForKey(key: OnyxKey): boolean;
246
+
247
+ /**
248
+ * Removes a key from storage if the value is null.
249
+ * Otherwise removes all nested null values in objects and returns the object
250
+ * @returns The value without null values and a boolean "wasRemoved", which indicates if the key got removed completely
251
+ */
252
+ declare function removeNullValues<TKey extends OnyxKey>(
253
+ key: TKey,
254
+ value: OnyxValue<TKey>,
255
+ ): {
256
+ value: OnyxValue<TKey>;
257
+ wasRemoved: boolean;
258
+ };
259
+ /**
260
+ * Storage expects array like: [["@MyApp_user", value_1], ["@MyApp_key", value_2]]
261
+ * This method transforms an object like {'@MyApp_user': myUserValue, '@MyApp_key': myKeyValue}
262
+ * to an array of key-value pairs in the above format and removes key-value pairs that are being set to null
263
+ *
264
+ * @return an array of key - value pairs <[key, value]>
265
+ */
266
+ declare function prepareKeyValuePairsForStorage(data: Record<OnyxKey, OnyxValue<OnyxKey>>): Array<[OnyxKey, OnyxValue<OnyxKey>]>;
267
+ /**
268
+ * Merges an array of changes with an existing value
269
+ *
270
+ * @param changes Array of changes that should be applied to the existing value
271
+ */
272
+ declare function applyMerge(existingValue: OnyxValue<OnyxKey>, changes: Array<OnyxValue<OnyxKey>>, shouldRemoveNullObjectValues: boolean): any;
273
+ /**
274
+ * Merge user provided default key value pairs.
275
+ */
276
+ declare function initializeWithDefaultKeyStates(): Promise<void>;
277
+
278
+ const OnyxUtils = {
279
+ METHOD,
280
+ getMergeQueue,
281
+ getMergeQueuePromise,
282
+ getCallbackToStateMapping,
283
+ getDefaultKeyStates,
284
+ initStoreValues,
285
+ sendActionToDevTools,
286
+ maybeFlushBatchUpdates,
287
+ batchUpdates,
288
+ get,
289
+ getAllKeys,
290
+ isCollectionKey,
291
+ isCollectionMemberKey,
292
+ splitCollectionMemberKey,
293
+ isKeyMatch,
294
+ isSafeEvictionKey,
295
+ tryGetCachedValue,
296
+ removeLastAccessedKey,
297
+ addLastAccessedKey,
298
+ removeFromEvictionBlockList,
299
+ addToEvictionBlockList,
300
+ addAllSafeEvictionKeysToRecentlyAccessedList,
301
+ getCachedCollection,
302
+ keysChanged,
303
+ keyChanged,
304
+ sendDataToConnection,
305
+ addKeyToRecentlyAccessedIfNeeded,
306
+ getCollectionDataAndSendAsObject,
307
+ scheduleSubscriberUpdate,
308
+ scheduleNotifyCollectionSubscribers,
309
+ remove,
310
+ reportStorageQuota,
311
+ evictStorageAndRetry,
312
+ broadcastUpdate,
313
+ hasPendingMergeForKey,
314
+ removeNullValues,
315
+ prepareKeyValuePairsForStorage,
316
+ applyMerge,
317
+ initializeWithDefaultKeyStates,
318
+ } as const;
319
+
320
+ export default OnyxUtils;