react-native-onyx 2.0.41 → 2.0.43

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.
package/dist/Onyx.js CHANGED
@@ -47,7 +47,7 @@ function init({ keys = {}, initialKeyStates = {}, safeEvictionKeys = [], maxCach
47
47
  storage_1.default.init();
48
48
  if (shouldSyncMultipleInstances) {
49
49
  (_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
50
- const prevValue = OnyxCache_1.default.getValue(key, false);
50
+ const prevValue = OnyxCache_1.default.get(key, false);
51
51
  OnyxCache_1.default.set(key, value);
52
52
  OnyxUtils_1.default.keyChanged(key, value, prevValue);
53
53
  });
@@ -106,7 +106,7 @@ function connect(connectOptions) {
106
106
  // Performance improvement
107
107
  // If the mapping is connected to an onyx key that is not a collection
108
108
  // we can skip the call to getAllKeys() and return an array with a single item
109
- if (Boolean(mapping.key) && typeof mapping.key === 'string' && !mapping.key.endsWith('_') && OnyxCache_1.default.storageKeys.has(mapping.key)) {
109
+ if (Boolean(mapping.key) && typeof mapping.key === 'string' && !mapping.key.endsWith('_') && OnyxCache_1.default.getAllKeys().has(mapping.key)) {
110
110
  return new Set([mapping.key]);
111
111
  }
112
112
  return OnyxUtils_1.default.getAllKeys();
@@ -122,9 +122,9 @@ function connect(connectOptions) {
122
122
  // component. This null value will be filtered out so that the connected component can utilize defaultProps.
123
123
  if (matchingKeys.length === 0) {
124
124
  if (mapping.key && !OnyxUtils_1.default.isCollectionKey(mapping.key)) {
125
- OnyxCache_1.default.set(mapping.key, null);
125
+ OnyxCache_1.default.addNullishStorageKey(mapping.key);
126
126
  }
127
- // Here we cannot use batching because the null value is expected to be set immediately for default props
127
+ // Here we cannot use batching because the nullish value is expected to be set immediately for default props
128
128
  // or they will be undefined.
129
129
  OnyxUtils_1.default.sendDataToConnection(mapping, null, undefined, false);
130
130
  return;
@@ -192,8 +192,17 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
192
192
  * @param value value to store
193
193
  */
194
194
  function set(key, value) {
195
- // check if the value is compatible with the existing value in the storage
196
- const existingValue = OnyxCache_1.default.getValue(key, false);
195
+ // When we use Onyx.set to set a key we want to clear the current delta changes from Onyx.merge that were queued
196
+ // before the value was set. If Onyx.merge is currently reading the old value from storage, it will then not apply the changes.
197
+ if (OnyxUtils_1.default.hasPendingMergeForKey(key)) {
198
+ delete OnyxUtils_1.default.getMergeQueue()[key];
199
+ }
200
+ const existingValue = OnyxCache_1.default.get(key, false);
201
+ // If the existing value as well as the new value are null, we can return early.
202
+ if (value === null && existingValue === null) {
203
+ return Promise.resolve();
204
+ }
205
+ // Check if the value is compatible with the existing value in the storage
197
206
  const { isCompatible, existingValueType, newValueType } = utils_1.default.checkCompatibilityWithExistingValue(value, existingValue);
198
207
  if (!isCompatible) {
199
208
  Logger.logAlert(logMessages_1.default.incompatibleUpdateAlert(key, 'set', existingValueType, newValueType));
@@ -201,17 +210,23 @@ function set(key, value) {
201
210
  }
202
211
  // If the value is null, we remove the key from storage
203
212
  const { value: valueAfterRemoving, wasRemoved } = OnyxUtils_1.default.removeNullValues(key, value);
204
- const valueWithoutNullValues = valueAfterRemoving;
205
- if (OnyxUtils_1.default.hasPendingMergeForKey(key)) {
206
- delete OnyxUtils_1.default.getMergeQueue()[key];
213
+ const logSetCall = (hasChanged = true) => {
214
+ // Logging properties only since values could be sensitive things we don't want to log
215
+ Logger.logInfo(`set called for key: ${key}${underscore_1.default.isObject(value) ? ` properties: ${underscore_1.default.keys(value).join(',')}` : ''} hasChanged: ${hasChanged}`);
216
+ };
217
+ // Calling "OnyxUtils.removeNullValues" removes the key from storage and cache and updates the subscriber.
218
+ // Therefore, we don't need to further broadcast and update the value so we can return early.
219
+ if (wasRemoved) {
220
+ logSetCall();
221
+ return Promise.resolve();
207
222
  }
223
+ const valueWithoutNullValues = valueAfterRemoving;
208
224
  const hasChanged = OnyxCache_1.default.hasValueChanged(key, valueWithoutNullValues);
209
- // Logging properties only since values could be sensitive things we don't want to log
210
- Logger.logInfo(`set called for key: ${key}${underscore_1.default.isObject(value) ? ` properties: ${underscore_1.default.keys(value).join(',')}` : ''} hasChanged: ${hasChanged}`);
225
+ logSetCall(hasChanged);
211
226
  // This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
212
- const updatePromise = OnyxUtils_1.default.broadcastUpdate(key, valueWithoutNullValues, hasChanged, wasRemoved);
227
+ const updatePromise = OnyxUtils_1.default.broadcastUpdate(key, valueWithoutNullValues, hasChanged);
213
228
  // If the value has not changed or the key got removed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
214
- if (!hasChanged || wasRemoved) {
229
+ if (!hasChanged) {
215
230
  return updatePromise;
216
231
  }
217
232
  return storage_1.default.setItem(key, valueWithoutNullValues)
@@ -229,18 +244,28 @@ function set(key, value) {
229
244
  * @param data object keyed by ONYXKEYS and the values to set
230
245
  */
231
246
  function multiSet(data) {
232
- const keyValuePairs = OnyxUtils_1.default.prepareKeyValuePairsForStorage(data, true);
233
- const updatePromises = keyValuePairs.map(([key, value]) => {
234
- const prevValue = OnyxCache_1.default.getValue(key, false);
247
+ const allKeyValuePairs = OnyxUtils_1.default.prepareKeyValuePairsForStorage(data, true);
248
+ // When a key is set to null, we need to remove the remove the key from storage using "OnyxUtils.remove".
249
+ // Therefore, we filter the key value pairs to exclude null values and remove those keys explicitly.
250
+ const removePromises = [];
251
+ const keyValuePairsToUpdate = allKeyValuePairs.filter(([key, value]) => {
252
+ if (value === null) {
253
+ removePromises.push(OnyxUtils_1.default.remove(key));
254
+ return false;
255
+ }
256
+ return true;
257
+ });
258
+ const updatePromises = keyValuePairsToUpdate.map(([key, value]) => {
259
+ const prevValue = OnyxCache_1.default.get(key, false);
235
260
  // Update cache and optimistically inform subscribers on the next tick
236
261
  OnyxCache_1.default.set(key, value);
237
262
  return OnyxUtils_1.default.scheduleSubscriberUpdate(key, value, prevValue);
238
263
  });
239
- return storage_1.default.multiSet(keyValuePairs)
264
+ return storage_1.default.multiSet(allKeyValuePairs)
240
265
  .catch((error) => OnyxUtils_1.default.evictStorageAndRetry(error, multiSet, data))
241
266
  .then(() => {
242
267
  OnyxUtils_1.default.sendActionToDevTools(OnyxUtils_1.default.METHOD.MULTI_SET, undefined, data);
243
- return Promise.all(updatePromises);
268
+ return Promise.all([removePromises, updatePromises]);
244
269
  })
245
270
  .then(() => undefined);
246
271
  }
@@ -278,7 +303,7 @@ function merge(key, changes) {
278
303
  mergeQueuePromise[key] = OnyxUtils_1.default.get(key).then((existingValue) => {
279
304
  // Calls to Onyx.set after a merge will terminate the current merge process and clear the merge queue
280
305
  if (mergeQueue[key] == null) {
281
- return undefined;
306
+ return Promise.resolve();
282
307
  }
283
308
  try {
284
309
  // We first only merge the changes, so we can provide these to the native implementation (SQLite uses only delta changes in "JSON_PATCH" to merge)
@@ -291,7 +316,7 @@ function merge(key, changes) {
291
316
  return isCompatible;
292
317
  });
293
318
  if (!validChanges.length) {
294
- return undefined;
319
+ return Promise.resolve();
295
320
  }
296
321
  const batchedDeltaChanges = OnyxUtils_1.default.applyMerge(undefined, validChanges, false);
297
322
  // Case (1): When there is no existing value in storage, we want to set the value instead of merge it.
@@ -301,8 +326,18 @@ function merge(key, changes) {
301
326
  // Clean up the write queue, so we don't apply these changes again
302
327
  delete mergeQueue[key];
303
328
  delete mergeQueuePromise[key];
329
+ const logMergeCall = (hasChanged = true) => {
330
+ // Logging properties only since values could be sensitive things we don't want to log
331
+ Logger.logInfo(`merge called for key: ${key}${underscore_1.default.isObject(batchedDeltaChanges) ? ` properties: ${underscore_1.default.keys(batchedDeltaChanges).join(',')}` : ''} hasChanged: ${hasChanged}`);
332
+ };
304
333
  // If the batched changes equal null, we want to remove the key from storage, to reduce storage size
305
334
  const { wasRemoved } = OnyxUtils_1.default.removeNullValues(key, batchedDeltaChanges);
335
+ // Calling "OnyxUtils.removeNullValues" removes the key from storage and cache and updates the subscriber.
336
+ // Therefore, we don't need to further broadcast and update the value so we can return early.
337
+ if (wasRemoved) {
338
+ logMergeCall();
339
+ return Promise.resolve();
340
+ }
306
341
  // For providers that can't handle delta changes, we need to merge the batched changes with the existing value beforehand.
307
342
  // The "preMergedValue" will be directly "set" in storage instead of being merged
308
343
  // Therefore we merge the batched changes with the existing value to get the final merged value that will be stored.
@@ -310,12 +345,11 @@ function merge(key, changes) {
310
345
  const preMergedValue = OnyxUtils_1.default.applyMerge(shouldSetValue ? undefined : existingValue, [batchedDeltaChanges], true);
311
346
  // In cache, we don't want to remove the key if it's null to improve performance and speed up the next merge.
312
347
  const hasChanged = OnyxCache_1.default.hasValueChanged(key, preMergedValue);
313
- // Logging properties only since values could be sensitive things we don't want to log
314
- Logger.logInfo(`merge called for key: ${key}${underscore_1.default.isObject(batchedDeltaChanges) ? ` properties: ${underscore_1.default.keys(batchedDeltaChanges).join(',')}` : ''} hasChanged: ${hasChanged}`);
348
+ logMergeCall(hasChanged);
315
349
  // This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
316
- const updatePromise = OnyxUtils_1.default.broadcastUpdate(key, preMergedValue, hasChanged, wasRemoved);
350
+ const updatePromise = OnyxUtils_1.default.broadcastUpdate(key, preMergedValue, hasChanged);
317
351
  // If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
318
- if (!hasChanged || wasRemoved) {
352
+ if (!hasChanged) {
319
353
  return updatePromise;
320
354
  }
321
355
  return storage_1.default.mergeItem(key, batchedDeltaChanges, preMergedValue, shouldSetValue).then(() => {
@@ -453,6 +487,7 @@ function mergeCollection(collectionKey, collection) {
453
487
  function clear(keysToPreserve = []) {
454
488
  return OnyxUtils_1.default.getAllKeys()
455
489
  .then((keys) => {
490
+ OnyxCache_1.default.clearNullishStorageKeys();
456
491
  const keysToBeClearedFromStorage = [];
457
492
  const keyValuesToResetAsCollection = {};
458
493
  const keyValuesToResetIndividually = {};
@@ -471,7 +506,7 @@ function clear(keysToPreserve = []) {
471
506
  // 2. Figure out whether it is a collection key or not,
472
507
  // since collection key subscribers need to be updated differently
473
508
  if (!isKeyToPreserve) {
474
- const oldValue = OnyxCache_1.default.getValue(key);
509
+ const oldValue = OnyxCache_1.default.get(key);
475
510
  const newValue = (_a = defaultKeyStates[key]) !== null && _a !== void 0 ? _a : null;
476
511
  if (newValue !== oldValue) {
477
512
  OnyxCache_1.default.set(key, newValue);
@@ -496,7 +531,7 @@ function clear(keysToPreserve = []) {
496
531
  const updatePromises = [];
497
532
  // Notify the subscribers for each key/value group so they can receive the new values
498
533
  Object.entries(keyValuesToResetIndividually).forEach(([key, value]) => {
499
- updatePromises.push(OnyxUtils_1.default.scheduleSubscriberUpdate(key, value, OnyxCache_1.default.getValue(key, false)));
534
+ updatePromises.push(OnyxUtils_1.default.scheduleSubscriberUpdate(key, value, OnyxCache_1.default.get(key, false)));
500
535
  });
501
536
  Object.entries(keyValuesToResetAsCollection).forEach(([key, value]) => {
502
537
  updatePromises.push(OnyxUtils_1.default.scheduleNotifyCollectionSubscribers(key, value));
@@ -5,7 +5,9 @@ import type { OnyxKey, OnyxValue } from './types';
5
5
  */
6
6
  declare class OnyxCache {
7
7
  /** Cache of all the storage keys available in persistent storage */
8
- storageKeys: Set<OnyxKey>;
8
+ private storageKeys;
9
+ /** A list of keys where a nullish value has been fetched from storage before, but the key still exists in cache */
10
+ private nullishStorageKeys;
9
11
  /** Unique list of keys maintained in access order (most recent at the end) */
10
12
  private recentKeys;
11
13
  /** A map of cached values */
@@ -21,16 +23,32 @@ declare class OnyxCache {
21
23
  /** Get all the storage keys */
22
24
  getAllKeys(): Set<OnyxKey>;
23
25
  /**
24
- * Get a cached value from storage
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.
26
+ * Allows to set all the keys at once.
27
+ * This is useful when we are getting
28
+ * all the keys from the storage provider
29
+ * and we want to keep the cache in sync.
30
+ *
31
+ * Previously, we had to call `addKey` in a loop
32
+ * to achieve the same result.
33
+ *
34
+ * @param keys - an array of keys
26
35
  */
27
- getValue(key: OnyxKey, shouldReindexCache?: boolean): OnyxValue<OnyxKey>;
28
- /** Check whether cache has data for the given key */
29
- hasCacheForKey(key: OnyxKey): boolean;
36
+ setAllKeys(keys: OnyxKey[]): void;
30
37
  /** Saves a key in the storage keys list
31
38
  * Serves to keep the result of `getAllKeys` up to date
32
39
  */
33
40
  addKey(key: OnyxKey): void;
41
+ /** Used to set keys that are null/undefined in storage without adding null to the storage map */
42
+ addNullishStorageKey(key: OnyxKey): void;
43
+ /** Used to clear keys that are null/undefined in cache */
44
+ clearNullishStorageKeys(): void;
45
+ /** Check whether cache has data for the given key */
46
+ hasCacheForKey(key: OnyxKey): boolean;
47
+ /**
48
+ * Get a cached value from storage
49
+ * @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.
50
+ */
51
+ get(key: OnyxKey, shouldReindexCache?: boolean): OnyxValue<OnyxKey>;
34
52
  /**
35
53
  * Set's a key value in cache
36
54
  * Adds the key to the storage keys list as well
@@ -43,18 +61,6 @@ declare class OnyxCache {
43
61
  * @param data - a map of (cache) key - values
44
62
  */
45
63
  merge(data: Record<OnyxKey, OnyxValue<OnyxKey>>): void;
46
- /**
47
- * Allows to set all the keys at once.
48
- * This is useful when we are getting
49
- * all the keys from the storage provider
50
- * and we want to keep the cache in sync.
51
- *
52
- * Previously, we had to call `addKey` in a loop
53
- * to achieve the same result.
54
- *
55
- * @param keys - an array of keys
56
- */
57
- setAllKeys(keys: OnyxKey[]): void;
58
64
  /**
59
65
  * Check whether the given task is already running
60
66
  * @param taskName - unique name given for the task
package/dist/OnyxCache.js CHANGED
@@ -15,29 +15,30 @@ class OnyxCache {
15
15
  /** Maximum size of the keys store din cache */
16
16
  this.maxRecentKeysSize = 0;
17
17
  this.storageKeys = new Set();
18
+ this.nullishStorageKeys = new Set();
18
19
  this.recentKeys = new Set();
19
20
  this.storageMap = {};
20
21
  this.pendingPromises = new Map();
21
22
  // bind all public methods to prevent problems with `this`
22
- (0, bindAll_1.default)(this, 'getAllKeys', 'getValue', 'hasCacheForKey', 'addKey', 'set', 'drop', 'merge', 'hasPendingTask', 'getTaskPromise', 'captureTask', 'removeLeastRecentlyUsedKeys', 'setRecentKeysLimit', 'setAllKeys');
23
+ (0, bindAll_1.default)(this, 'getAllKeys', 'get', 'hasCacheForKey', 'addKey', 'addNullishStorageKey', 'clearNullishStorageKeys', 'set', 'drop', 'merge', 'hasPendingTask', 'getTaskPromise', 'captureTask', 'removeLeastRecentlyUsedKeys', 'setRecentKeysLimit', 'setAllKeys');
23
24
  }
24
25
  /** Get all the storage keys */
25
26
  getAllKeys() {
26
27
  return this.storageKeys;
27
28
  }
28
29
  /**
29
- * Get a cached value from storage
30
- * @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.
30
+ * Allows to set all the keys at once.
31
+ * This is useful when we are getting
32
+ * all the keys from the storage provider
33
+ * and we want to keep the cache in sync.
34
+ *
35
+ * Previously, we had to call `addKey` in a loop
36
+ * to achieve the same result.
37
+ *
38
+ * @param keys - an array of keys
31
39
  */
32
- getValue(key, shouldReindexCache = true) {
33
- if (shouldReindexCache) {
34
- this.addToAccessedKeys(key);
35
- }
36
- return this.storageMap[key];
37
- }
38
- /** Check whether cache has data for the given key */
39
- hasCacheForKey(key) {
40
- return this.storageMap[key] !== undefined;
40
+ setAllKeys(keys) {
41
+ this.storageKeys = new Set(keys);
41
42
  }
42
43
  /** Saves a key in the storage keys list
43
44
  * Serves to keep the result of `getAllKeys` up to date
@@ -45,6 +46,28 @@ class OnyxCache {
45
46
  addKey(key) {
46
47
  this.storageKeys.add(key);
47
48
  }
49
+ /** Used to set keys that are null/undefined in storage without adding null to the storage map */
50
+ addNullishStorageKey(key) {
51
+ this.nullishStorageKeys.add(key);
52
+ }
53
+ /** Used to clear keys that are null/undefined in cache */
54
+ clearNullishStorageKeys() {
55
+ this.nullishStorageKeys = new Set();
56
+ }
57
+ /** Check whether cache has data for the given key */
58
+ hasCacheForKey(key) {
59
+ return this.storageMap[key] !== undefined || this.nullishStorageKeys.has(key);
60
+ }
61
+ /**
62
+ * Get a cached value from storage
63
+ * @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.
64
+ */
65
+ get(key, shouldReindexCache = true) {
66
+ if (shouldReindexCache) {
67
+ this.addToAccessedKeys(key);
68
+ }
69
+ return this.storageMap[key];
70
+ }
48
71
  /**
49
72
  * Set's a key value in cache
50
73
  * Adds the key to the storage keys list as well
@@ -52,6 +75,13 @@ class OnyxCache {
52
75
  set(key, value) {
53
76
  this.addKey(key);
54
77
  this.addToAccessedKeys(key);
78
+ // When a key is explicitly set in cache, we can remove it from the list of nullish keys,
79
+ // since it will either be set to a non nullish value or removed from the cache completely.
80
+ this.nullishStorageKeys.delete(key);
81
+ if (value === null || value === undefined) {
82
+ delete this.storageMap[key];
83
+ return undefined;
84
+ }
55
85
  this.storageMap[key] = value;
56
86
  return value;
57
87
  }
@@ -69,25 +99,17 @@ class OnyxCache {
69
99
  if (typeof data !== 'object' || Array.isArray(data)) {
70
100
  throw new Error('data passed to cache.merge() must be an Object of onyx key/value pairs');
71
101
  }
72
- this.storageMap = Object.assign({}, utils_1.default.fastMerge(this.storageMap, data, false));
73
- const storageKeys = this.getAllKeys();
74
- const mergedKeys = Object.keys(data);
75
- this.storageKeys = new Set([...storageKeys, ...mergedKeys]);
76
- mergedKeys.forEach((key) => this.addToAccessedKeys(key));
77
- }
78
- /**
79
- * Allows to set all the keys at once.
80
- * This is useful when we are getting
81
- * all the keys from the storage provider
82
- * and we want to keep the cache in sync.
83
- *
84
- * Previously, we had to call `addKey` in a loop
85
- * to achieve the same result.
86
- *
87
- * @param keys - an array of keys
88
- */
89
- setAllKeys(keys) {
90
- this.storageKeys = new Set(keys);
102
+ this.storageMap = Object.assign({}, utils_1.default.fastMerge(this.storageMap, data));
103
+ Object.entries(data).forEach(([key, value]) => {
104
+ this.addKey(key);
105
+ this.addToAccessedKeys(key);
106
+ if (value === null || value === undefined) {
107
+ this.addNullishStorageKey(key);
108
+ }
109
+ else {
110
+ this.nullishStorageKeys.delete(key);
111
+ }
112
+ });
91
113
  }
92
114
  /**
93
115
  * Check whether the given task is already running
@@ -1,6 +1,6 @@
1
1
  import type { ValueOf } from 'type-fest';
2
- import type { DeepRecord, Mapping, CollectionKey, CollectionKeyBase, NullableKeyValueMapping, OnyxKey, OnyxValue, OnyxCollection, WithOnyxConnectOptions, OnyxEntry, KeyValueMapping } from './types';
3
2
  import type Onyx from './Onyx';
3
+ import type { CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, Mapping, NullableKeyValueMapping, OnyxCollection, OnyxEntry, OnyxKey, OnyxValue, WithOnyxConnectOptions } from './types';
4
4
  declare const METHOD: {
5
5
  readonly SET: "set";
6
6
  readonly MERGE: "merge";
@@ -107,7 +107,7 @@ declare function getCachedCollection<TKey extends CollectionKeyBase>(collectionK
107
107
  /**
108
108
  * When a collection of keys change, search for any callbacks matching the collection key and trigger those callbacks
109
109
  */
110
- declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, previousPartialCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined, notifyRegularSubscibers?: boolean, notifyWithOnyxSubscibers?: boolean): void;
110
+ declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, partialPreviousCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined, notifyRegularSubscibers?: boolean, notifyWithOnyxSubscibers?: boolean): void;
111
111
  /**
112
112
  * When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
113
113
  *
@@ -120,7 +120,7 @@ declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TK
120
120
  * - sets state on the withOnyxInstances
121
121
  * - triggers the callback function
122
122
  */
123
- declare function sendDataToConnection<TKey extends OnyxKey>(mapping: Mapping<TKey>, val: OnyxValue<TKey>, matchedKey: TKey | undefined, isBatched: boolean): void;
123
+ declare function sendDataToConnection<TKey extends OnyxKey>(mapping: Mapping<TKey>, value: OnyxValue<TKey> | null, matchedKey: TKey | undefined, isBatched: boolean): void;
124
124
  /**
125
125
  * We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
126
126
  * run out of storage the least recently accessed key can be removed.
@@ -157,10 +157,10 @@ declare function evictStorageAndRetry<TMethod extends typeof Onyx.set | typeof O
157
157
  /**
158
158
  * Notifies subscribers and writes current value to cache
159
159
  */
160
- declare function broadcastUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, hasChanged?: boolean, wasRemoved?: boolean): Promise<void>;
160
+ declare function broadcastUpdate<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, hasChanged?: boolean): Promise<void>;
161
161
  declare function hasPendingMergeForKey(key: OnyxKey): boolean;
162
- type RemoveNullValuesOutput = {
163
- value: Record<string, unknown> | unknown[] | null;
162
+ type RemoveNullValuesOutput<Value extends OnyxValue<OnyxKey> | null> = {
163
+ value: Value | null;
164
164
  wasRemoved: boolean;
165
165
  };
166
166
  /**
@@ -170,7 +170,7 @@ type RemoveNullValuesOutput = {
170
170
  *
171
171
  * @returns The value without null values and a boolean "wasRemoved", which indicates if the key got removed completely
172
172
  */
173
- declare function removeNullValues(key: OnyxKey, value: OnyxValue<OnyxKey>, shouldRemoveNestedNulls?: boolean): RemoveNullValuesOutput;
173
+ declare function removeNullValues<Value extends OnyxValue<OnyxKey>>(key: OnyxKey, value: Value | null, shouldRemoveNestedNulls?: boolean): RemoveNullValuesOutput<Value>;
174
174
  /**
175
175
  * Storage expects array like: [["@MyApp_user", value_1], ["@MyApp_key", value_2]]
176
176
  * This method transforms an object like {'@MyApp_user': myUserValue, '@MyApp_key': myKeyValue}