react-native-onyx 1.0.86 → 1.0.88

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.
@@ -1,13 +1,13 @@
1
1
  (function webpackUniversalModuleDefinition(root, factory) {
2
2
  if(typeof exports === 'object' && typeof module === 'object')
3
- module.exports = factory(require("fast-equals"), require("underscore"), require("idb-keyval"), require("lodash/transform"), require("react-dom"), require("react"));
3
+ module.exports = factory(require("fast-equals"), require("underscore"), require("react-dom"), require("idb-keyval"), require("lodash/transform"), require("react"));
4
4
  else if(typeof define === 'function' && define.amd)
5
- define(["fast-equals", "underscore", "idb-keyval", "lodash/transform", "react-dom", "react"], factory);
5
+ define(["fast-equals", "underscore", "react-dom", "idb-keyval", "lodash/transform", "react"], factory);
6
6
  else if(typeof exports === 'object')
7
- exports["react-native-onyx/web"] = factory(require("fast-equals"), require("underscore"), require("idb-keyval"), require("lodash/transform"), require("react-dom"), require("react"));
7
+ exports["react-native-onyx/web"] = factory(require("fast-equals"), require("underscore"), require("react-dom"), require("idb-keyval"), require("lodash/transform"), require("react"));
8
8
  else
9
- root["react-native-onyx/web"] = factory(root["fast-equals"], root["underscore"], root["idb-keyval"], root["lodash/transform"], root["react-dom"], root["react"]);
10
- })(self, (__WEBPACK_EXTERNAL_MODULE_fast_equals__, __WEBPACK_EXTERNAL_MODULE_underscore__, __WEBPACK_EXTERNAL_MODULE_idb_keyval__, __WEBPACK_EXTERNAL_MODULE_lodash_transform__, __WEBPACK_EXTERNAL_MODULE_react_dom__, __WEBPACK_EXTERNAL_MODULE_react__) => {
9
+ root["react-native-onyx/web"] = factory(root["fast-equals"], root["underscore"], root["react-dom"], root["idb-keyval"], root["lodash/transform"], root["react"]);
10
+ })(self, (__WEBPACK_EXTERNAL_MODULE_fast_equals__, __WEBPACK_EXTERNAL_MODULE_underscore__, __WEBPACK_EXTERNAL_MODULE_react_dom__, __WEBPACK_EXTERNAL_MODULE_idb_keyval__, __WEBPACK_EXTERNAL_MODULE_lodash_transform__, __WEBPACK_EXTERNAL_MODULE_react__) => {
11
11
  return /******/ (() => { // webpackBootstrap
12
12
  /******/ var __webpack_modules__ = ({
13
13
 
@@ -73,14 +73,14 @@ __webpack_require__.r(__webpack_exports__);
73
73
  /* harmony import */ var fast_equals__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fast_equals__WEBPACK_IMPORTED_MODULE_0__);
74
74
  /* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! underscore */ "underscore");
75
75
  /* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_1__);
76
- /* harmony import */ var _Logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Logger */ "./lib/Logger.js");
77
- /* harmony import */ var _OnyxCache__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./OnyxCache */ "./lib/OnyxCache.js");
78
- /* harmony import */ var _Str__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Str */ "./lib/Str.js");
76
+ /* harmony import */ var _Logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Logger */ "./lib/Logger.js");
77
+ /* harmony import */ var _OnyxCache__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./OnyxCache */ "./lib/OnyxCache.js");
78
+ /* harmony import */ var _Str__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Str */ "./lib/Str.js");
79
79
  /* harmony import */ var _createDeferredTask__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./createDeferredTask */ "./lib/createDeferredTask.js");
80
- /* harmony import */ var _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./metrics/PerformanceUtils */ "./lib/metrics/PerformanceUtils.js");
81
- /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./storage */ "./lib/storage/index.web.js");
82
- /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils */ "./lib/utils.js");
83
- /* harmony import */ var _batch__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./batch */ "./lib/batch.js");
80
+ /* harmony import */ var _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./metrics/PerformanceUtils */ "./lib/metrics/PerformanceUtils.js");
81
+ /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./storage */ "./lib/storage/index.web.js");
82
+ /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils */ "./lib/utils.js");
83
+ /* harmony import */ var _batch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./batch */ "./lib/batch.js");
84
84
  /* eslint-disable no-continue */
85
85
 
86
86
 
@@ -132,6 +132,47 @@ let defaultKeyStates = {};
132
132
  // Connections can be made before `Onyx.init`. They would wait for this task before resolving
133
133
  const deferredInitTask = (0,_createDeferredTask__WEBPACK_IMPORTED_MODULE_2__["default"])();
134
134
 
135
+ let batchUpdatesPromise = null;
136
+ let batchUpdatesQueue = [];
137
+
138
+ /**
139
+ * We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
140
+ * This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
141
+ * update operations. Instead of calling the subscribers for each update operation, we batch them together which will
142
+ * cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
143
+ * @returns {Promise}
144
+ */
145
+ function maybeFlushBatchUpdates() {
146
+ if (batchUpdatesPromise) {
147
+ return batchUpdatesPromise;
148
+ }
149
+
150
+ batchUpdatesPromise = new Promise((resolve) => {
151
+ /* We use (setTimeout, 0) here which should be called once native module calls are flushed (usually at the end of the frame)
152
+ * We may investigate if (setTimeout, 1) (which in React Native is equal to requestAnimationFrame) works even better
153
+ * then the batch will be flushed on next frame.
154
+ */
155
+ setTimeout(() => {
156
+ const updatesCopy = batchUpdatesQueue;
157
+ batchUpdatesQueue = [];
158
+ batchUpdatesPromise = null;
159
+ (0,_batch__WEBPACK_IMPORTED_MODULE_3__["default"])(() => {
160
+ updatesCopy.forEach((applyUpdates) => {
161
+ applyUpdates();
162
+ });
163
+ });
164
+
165
+ resolve();
166
+ }, 0);
167
+ });
168
+ return batchUpdatesPromise;
169
+ }
170
+
171
+ function batchUpdates(updates) {
172
+ batchUpdatesQueue.push(updates);
173
+ return maybeFlushBatchUpdates();
174
+ }
175
+
135
176
  /**
136
177
  * Uses a selector function to return a simplified version of sourceData
137
178
  * @param {Mixed} sourceData
@@ -166,26 +207,26 @@ const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceStat
166
207
  */
167
208
  function get(key) {
168
209
  // When we already have the value in cache - resolve right away
169
- if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasCacheForKey(key)) {
170
- return Promise.resolve(_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key));
210
+ if (_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasCacheForKey(key)) {
211
+ return Promise.resolve(_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(key));
171
212
  }
172
213
 
173
214
  const taskName = `get:${key}`;
174
215
 
175
216
  // When a value retrieving task for this key is still running hook to it
176
- if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasPendingTask(taskName)) {
177
- return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getTaskPromise(taskName);
217
+ if (_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasPendingTask(taskName)) {
218
+ return _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getTaskPromise(taskName);
178
219
  }
179
220
 
180
221
  // Otherwise retrieve the value from storage and capture a promise to aid concurrent usages
181
- const promise = _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getItem(key).
222
+ const promise = _storage__WEBPACK_IMPORTED_MODULE_5__["default"].getItem(key).
182
223
  then((val) => {
183
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, val);
224
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, val);
184
225
  return val;
185
226
  }).
186
- catch((err) => _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Unable to get item from persistent storage. Key: ${key} Error: ${err}`));
227
+ catch((err) => _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Unable to get item from persistent storage. Key: ${key} Error: ${err}`));
187
228
 
188
- return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].captureTask(taskName, promise);
229
+ return _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].captureTask(taskName, promise);
189
230
  }
190
231
 
191
232
  /**
@@ -195,7 +236,7 @@ function get(key) {
195
236
  */
196
237
  function getAllKeys() {
197
238
  // When we've already read stored keys, resolve right away
198
- const storedKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys();
239
+ const storedKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys();
199
240
  if (storedKeys.length > 0) {
200
241
  return Promise.resolve(storedKeys);
201
242
  }
@@ -203,18 +244,18 @@ function getAllKeys() {
203
244
  const taskName = 'getAllKeys';
204
245
 
205
246
  // When a value retrieving task for all keys is still running hook to it
206
- if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasPendingTask(taskName)) {
207
- return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getTaskPromise(taskName);
247
+ if (_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasPendingTask(taskName)) {
248
+ return _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getTaskPromise(taskName);
208
249
  }
209
250
 
210
251
  // Otherwise retrieve the keys from storage and capture a promise to aid concurrent usages
211
- const promise = _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys().
252
+ const promise = _storage__WEBPACK_IMPORTED_MODULE_5__["default"].getAllKeys().
212
253
  then((keys) => {
213
- underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].addKey(key));
254
+ underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].addKey(key));
214
255
  return keys;
215
256
  });
216
257
 
217
- return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].captureTask(taskName, promise);
258
+ return _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].captureTask(taskName, promise);
218
259
  }
219
260
 
220
261
  /**
@@ -235,7 +276,7 @@ function isCollectionKey(key) {
235
276
  * @returns {Boolean}
236
277
  */
237
278
  function isCollectionMemberKey(collectionKey, key) {
238
- return _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(key, collectionKey) && key.length > collectionKey.length;
279
+ return _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(key, collectionKey) && key.length > collectionKey.length;
239
280
  }
240
281
 
241
282
  /**
@@ -249,7 +290,7 @@ function isCollectionMemberKey(collectionKey, key) {
249
290
  */
250
291
  function isKeyMatch(configKey, key) {
251
292
  return isCollectionKey(configKey) ?
252
- _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(key, configKey) :
293
+ _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(key, configKey) :
253
294
  configKey === key;
254
295
  }
255
296
 
@@ -274,13 +315,13 @@ function isSafeEvictionKey(testKey) {
274
315
  * @returns {Mixed}
275
316
  */
276
317
  function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
277
- let val = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
318
+ let val = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(key);
278
319
 
279
320
  if (isCollectionKey(key)) {
280
- const allKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys();
321
+ const allKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys();
281
322
  const matchingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(allKeys, (k) => k.startsWith(key));
282
323
  const values = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(matchingKeys, (finalObject, matchedKey) => {
283
- const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(matchedKey);
324
+ const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(matchedKey);
284
325
  if (cachedValue) {
285
326
  // This is permissible because we're in the process of constructing the final object in a reduce function.
286
327
  // eslint-disable-next-line no-param-reassign
@@ -396,12 +437,12 @@ function addAllSafeEvictionKeysToRecentlyAccessedList() {
396
437
  * @returns {Object}
397
438
  */
398
439
  function getCachedCollection(collectionKey) {
399
- const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys(),
440
+ const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys(),
400
441
  (storedKey) => isCollectionMemberKey(collectionKey, storedKey));
401
442
 
402
443
 
403
444
  return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(collectionMemberKeys, (prev, curr) => {
404
- const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(curr);
445
+ const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(curr);
405
446
  if (!cachedValue) {
406
447
  return prev;
407
448
  }
@@ -433,7 +474,7 @@ function keysChanged(collectionKey, partialCollection) {let notifyRegularSubscib
433
474
  }
434
475
 
435
476
  // Skip iteration if we do not have a collection key or a collection member key on this subscriber
436
- if (!_Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(subscriber.key, collectionKey)) {
477
+ if (!_Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(subscriber.key, collectionKey)) {
437
478
  continue;
438
479
  }
439
480
 
@@ -519,7 +560,7 @@ function keysChanged(collectionKey, partialCollection) {let notifyRegularSubscib
519
560
  finalCollection[dataKey] = cachedCollection[dataKey];
520
561
  }
521
562
 
522
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevState[subscriber.statePropertyName], finalCollection, 'keysChanged', collectionKey);
563
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, prevState[subscriber.statePropertyName], finalCollection, 'keysChanged', collectionKey);
523
564
  return {
524
565
  [subscriber.statePropertyName]: finalCollection
525
566
  };
@@ -544,7 +585,7 @@ function keysChanged(collectionKey, partialCollection) {let notifyRegularSubscib
544
585
  const prevData = prevState[subscriber.statePropertyName];
545
586
  const newData = getSubsetOfData(cachedCollection[subscriber.key], subscriber.selector, subscriber.withOnyxInstance.state);
546
587
  if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, newData)) {
547
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
588
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
548
589
  return {
549
590
  [subscriber.statePropertyName]: newData
550
591
  };
@@ -560,14 +601,14 @@ function keysChanged(collectionKey, partialCollection) {let notifyRegularSubscib
560
601
  const previousData = prevState[subscriber.statePropertyName];
561
602
 
562
603
  // Avoids triggering unnecessary re-renders when feeding empty objects
563
- if (_utils__WEBPACK_IMPORTED_MODULE_8__["default"].areObjectsEmpty(data, previousData)) {
604
+ if (_utils__WEBPACK_IMPORTED_MODULE_9__["default"].areObjectsEmpty(data, previousData)) {
564
605
  return null;
565
606
  }
566
607
  if (data === previousData) {
567
608
  return null;
568
609
  }
569
610
 
570
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keysChanged', collectionKey);
611
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, previousData, data, 'keysChanged', collectionKey);
571
612
  return {
572
613
  [subscriber.statePropertyName]: data
573
614
  };
@@ -645,7 +686,7 @@ function keyChanged(key, data, canUpdateSubscriber) {let notifyRegularSubscibers
645
686
  ...newData
646
687
  };
647
688
  if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, prevDataWithNewData)) {
648
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keyChanged', key);
689
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, prevData, newData, 'keyChanged', key);
649
690
  return {
650
691
  [subscriber.statePropertyName]: prevDataWithNewData
651
692
  };
@@ -661,7 +702,7 @@ function keyChanged(key, data, canUpdateSubscriber) {let notifyRegularSubscibers
661
702
  ...collection,
662
703
  [key]: data
663
704
  };
664
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, collection, newCollection, 'keyChanged', key);
705
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, collection, newCollection, 'keyChanged', key);
665
706
  return {
666
707
  [subscriber.statePropertyName]: newCollection
667
708
  };
@@ -690,14 +731,14 @@ function keyChanged(key, data, canUpdateSubscriber) {let notifyRegularSubscibers
690
731
  const previousData = prevState[subscriber.statePropertyName];
691
732
 
692
733
  // Avoids triggering unnecessary re-renders when feeding empty objects
693
- if (_utils__WEBPACK_IMPORTED_MODULE_8__["default"].areObjectsEmpty(data, previousData)) {
734
+ if (_utils__WEBPACK_IMPORTED_MODULE_9__["default"].areObjectsEmpty(data, previousData)) {
694
735
  return null;
695
736
  }
696
737
  if (previousData === data) {
697
738
  return null;
698
739
  }
699
740
 
700
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keyChanged', key);
741
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(subscriber, previousData, data, 'keyChanged', key);
701
742
  return {
702
743
  [subscriber.statePropertyName]: data
703
744
  };
@@ -721,9 +762,10 @@ function keyChanged(key, data, canUpdateSubscriber) {let notifyRegularSubscibers
721
762
  * @param {Function} [mapping.callback]
722
763
  * @param {String} [mapping.selector]
723
764
  * @param {*|null} val
724
- * @param {String} matchedKey
765
+ * @param {String|undefined} matchedKey
766
+ * @param {Boolean} isBatched
725
767
  */
726
- function sendDataToConnection(mapping, val, matchedKey) {
768
+ function sendDataToConnection(mapping, val, matchedKey, isBatched) {
727
769
  // If the mapping no longer exists then we should not send any data.
728
770
  // This means our subscriber disconnected or withOnyx wrapped component unmounted.
729
771
  if (!callbackToStateMapping[mapping.connectionID]) {
@@ -743,8 +785,14 @@ function sendDataToConnection(mapping, val, matchedKey) {
743
785
  }
744
786
  }
745
787
 
746
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
747
- mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
788
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
789
+ if (isBatched) {
790
+ batchUpdates(() => {
791
+ mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
792
+ });
793
+ } else {
794
+ mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
795
+ }
748
796
  return;
749
797
  }
750
798
 
@@ -766,7 +814,7 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
766
814
  }
767
815
 
768
816
  // Try to free some cache whenever we connect to a safe eviction key
769
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].removeLeastRecentlyUsedKeys();
817
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].removeLeastRecentlyUsedKeys();
770
818
 
771
819
  if (mapping.withOnyxInstance && !isCollectionKey(mapping.key)) {
772
820
  // All React components subscribing to a key flagged as a safe eviction key must implement the canEvict property.
@@ -794,7 +842,7 @@ function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
794
842
  finalObject[matchingKeys[i]] = value;
795
843
  return finalObject;
796
844
  }, {})).
797
- then((val) => sendDataToConnection(mapping, val));
845
+ then((val) => sendDataToConnection(mapping, val, undefined, true));
798
846
  }
799
847
 
800
848
  /**
@@ -849,7 +897,9 @@ function connect(mapping) {
849
897
  // since there are none matched. In withOnyx() we wait for all connected keys to return a value before rendering the child
850
898
  // component. This null value will be filtered out so that the connected component can utilize defaultProps.
851
899
  if (matchingKeys.length === 0) {
852
- sendDataToConnection(mapping, null);
900
+ // Here we cannot use batching because the null value is expected to be set immediately for default props
901
+ // or they will be undefined.
902
+ sendDataToConnection(mapping, null, undefined, false);
853
903
  return;
854
904
  }
855
905
 
@@ -865,13 +915,13 @@ function connect(mapping) {
865
915
 
866
916
  // We did not opt into using waitForCollectionCallback mode so the callback is called for every matching key.
867
917
  for (let i = 0; i < matchingKeys.length; i++) {
868
- get(matchingKeys[i]).then((val) => sendDataToConnection(mapping, val, matchingKeys[i]));
918
+ get(matchingKeys[i]).then((val) => sendDataToConnection(mapping, val, matchingKeys[i], true));
869
919
  }
870
920
  return;
871
921
  }
872
922
 
873
923
  // If we are not subscribed to a collection key then there's only a single key to send an update for.
874
- get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key));
924
+ get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key, true));
875
925
  return;
876
926
  }
877
927
 
@@ -884,7 +934,7 @@ function connect(mapping) {
884
934
  }
885
935
 
886
936
  // If the subscriber is not using a collection key then we just send a single value back to the subscriber
887
- get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key));
937
+ get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key, true));
888
938
  return;
889
939
  }
890
940
 
@@ -918,47 +968,6 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
918
968
  delete callbackToStateMapping[connectionID];
919
969
  }
920
970
 
921
- let batchUpdatesPromise = null;
922
- let batchUpdatesQueue = [];
923
-
924
- /**
925
- * We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
926
- * This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
927
- * update operations. Instead of calling the subscribers for each update operation, we batch them together which will
928
- * cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
929
- * @returns {Promise}
930
- */
931
- function maybeFlushBatchUpdates() {
932
- if (batchUpdatesPromise) {
933
- return batchUpdatesPromise;
934
- }
935
-
936
- batchUpdatesPromise = new Promise((resolve) => {
937
- /* We use (setTimeout, 0) here which should be called once native module calls are flushed (usually at the end of the frame)
938
- * We may investigate if (setTimeout, 1) (which in React Native is equal to requestAnimationFrame) works even better
939
- * then the batch will be flushed on next frame.
940
- */
941
- setTimeout(() => {
942
- const updatesCopy = batchUpdatesQueue;
943
- batchUpdatesQueue = [];
944
- batchUpdatesPromise = null;
945
- (0,_batch__WEBPACK_IMPORTED_MODULE_9__["default"])(() => {
946
- updatesCopy.forEach((applyUpdates) => {
947
- applyUpdates();
948
- });
949
- });
950
-
951
- resolve();
952
- }, 0);
953
- });
954
- return batchUpdatesPromise;
955
- }
956
-
957
- function batchUpdates(updates) {
958
- batchUpdatesQueue.push(updates);
959
- return maybeFlushBatchUpdates();
960
- }
961
-
962
971
  /**
963
972
  * Schedules an update that will be appended to the macro task queue (so it doesn't update the subscribers immediately).
964
973
  *
@@ -999,9 +1008,9 @@ function scheduleNotifyCollectionSubscribers(key, value) {
999
1008
  * @return {Promise}
1000
1009
  */
1001
1010
  function remove(key) {
1002
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key);
1011
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].drop(key);
1003
1012
  scheduleSubscriberUpdate(key, null);
1004
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItem(key);
1013
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].removeItem(key);
1005
1014
  }
1006
1015
 
1007
1016
  /**
@@ -1009,12 +1018,12 @@ function remove(key) {
1009
1018
  * @returns {Promise<void>}
1010
1019
  */
1011
1020
  function reportStorageQuota() {
1012
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getDatabaseSize().
1021
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].getDatabaseSize().
1013
1022
  then((_ref) => {let { bytesUsed, bytesRemaining } = _ref;
1014
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Storage Quota Check -- bytesUsed: ${bytesUsed} bytesRemaining: ${bytesRemaining}`);
1023
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Storage Quota Check -- bytesUsed: ${bytesUsed} bytesRemaining: ${bytesRemaining}`);
1015
1024
  }).
1016
1025
  catch((dbSizeError) => {
1017
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Unable to get database size. Error: ${dbSizeError}`);
1026
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`Unable to get database size. Error: ${dbSizeError}`);
1018
1027
  });
1019
1028
  }
1020
1029
 
@@ -1030,10 +1039,10 @@ function reportStorageQuota() {
1030
1039
  * @return {Promise}
1031
1040
  */
1032
1041
  function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {args[_key - 2] = arguments[_key];}
1033
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Failed to save to storage. Error: ${error}. onyxMethod: ${onyxMethod.name}`);
1042
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Failed to save to storage. Error: ${error}. onyxMethod: ${onyxMethod.name}`);
1034
1043
 
1035
- if (error && _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(error.message, 'Failed to execute \'put\' on \'IDBObjectStore\'')) {
1036
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Attempted to set invalid data set in Onyx. Please ensure all data is serializable.');
1044
+ if (error && _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(error.message, 'Failed to execute \'put\' on \'IDBObjectStore\'')) {
1045
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert('Attempted to set invalid data set in Onyx. Please ensure all data is serializable.');
1037
1046
  throw error;
1038
1047
  }
1039
1048
 
@@ -1043,12 +1052,12 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
1043
1052
  // If we have no acceptable keys to remove then we are possibly trying to save mission critical data. If this is the case,
1044
1053
  // then we should stop retrying as there is not much the user can do to fix this. Instead of getting them stuck in an infinite loop we
1045
1054
  // will allow this write to be skipped.
1046
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Out of storage. But found no acceptable keys to remove.');
1055
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert('Out of storage. But found no acceptable keys to remove.');
1047
1056
  return reportStorageQuota();
1048
1057
  }
1049
1058
 
1050
1059
  // Remove the least recently viewed key that is not currently being accessed and retry.
1051
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
1060
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
1052
1061
  reportStorageQuota();
1053
1062
  return remove(keyForRemoval).
1054
1063
  then(() => onyxMethod(...args));
@@ -1065,14 +1074,14 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
1065
1074
  */
1066
1075
  function broadcastUpdate(key, value, hasChanged, method) {
1067
1076
  // Logging properties only since values could be sensitive things we don't want to log
1068
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`${method}() called for key: ${key}${underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) ? ` properties: ${underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(value).join(',')}` : ''}`);
1077
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`${method}() called for key: ${key}${underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) ? ` properties: ${underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(value).join(',')}` : ''}`);
1069
1078
 
1070
1079
  // Update subscribers if the cached value has changed, or when the subscriber specifically requires
1071
1080
  // all updates regardless of value changes (indicated by initWithStoredValues set to false).
1072
1081
  if (hasChanged) {
1073
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
1082
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, value);
1074
1083
  } else {
1075
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].addToAccessedKeys(key);
1084
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].addToAccessedKeys(key);
1076
1085
  }
1077
1086
 
1078
1087
  return scheduleSubscriberUpdate(key, value, (subscriber) => hasChanged || subscriber.initWithStoredValues === false);
@@ -1100,12 +1109,12 @@ function set(key, value) {
1100
1109
  }
1101
1110
 
1102
1111
  if (hasPendingMergeForKey(key)) {
1103
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Onyx.set() called after Onyx.merge() for key: ${key}. It is recommended to use set() or merge() not both.`);
1112
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`Onyx.set() called after Onyx.merge() for key: ${key}. It is recommended to use set() or merge() not both.`);
1104
1113
  }
1105
1114
 
1106
- const valueWithNullRemoved = _utils__WEBPACK_IMPORTED_MODULE_8__["default"].removeNullObjectValues(value);
1115
+ const valueWithNullRemoved = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].removeNullObjectValues(value);
1107
1116
 
1108
- const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, valueWithNullRemoved);
1117
+ const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, valueWithNullRemoved);
1109
1118
 
1110
1119
  // This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
1111
1120
  const updatePromise = broadcastUpdate(key, valueWithNullRemoved, hasChanged, 'set');
@@ -1115,7 +1124,7 @@ function set(key, value) {
1115
1124
  return updatePromise;
1116
1125
  }
1117
1126
 
1118
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].setItem(key, valueWithNullRemoved).
1127
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].setItem(key, valueWithNullRemoved).
1119
1128
  catch((error) => evictStorageAndRetry(error, set, key, valueWithNullRemoved)).
1120
1129
  then(() => updatePromise);
1121
1130
  }
@@ -1145,11 +1154,11 @@ function multiSet(data) {
1145
1154
 
1146
1155
  const updatePromises = underscore__WEBPACK_IMPORTED_MODULE_1___default().map(data, (val, key) => {
1147
1156
  // Update cache and optimistically inform subscribers on the next tick
1148
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, val);
1157
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, val);
1149
1158
  return scheduleSubscriberUpdate(key, val);
1150
1159
  });
1151
1160
 
1152
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairs).
1161
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(keyValuePairs).
1153
1162
  catch((error) => evictStorageAndRetry(error, multiSet, data)).
1154
1163
  then(() => Promise.all(updatePromises));
1155
1164
  }
@@ -1173,7 +1182,7 @@ function applyMerge(existingValue, changes) {
1173
1182
  // Object values are merged one after the other
1174
1183
  // lodash adds a small overhead so we don't use it here
1175
1184
  // eslint-disable-next-line prefer-object-spread, rulesdir/prefer-underscore-method
1176
- return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_8__["default"].fastMerge(modifiedData, change),
1185
+ return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(modifiedData, change),
1177
1186
  existingValue || {});
1178
1187
  }
1179
1188
 
@@ -1222,17 +1231,17 @@ function merge(key, changes) {
1222
1231
  delete mergeQueuePromise[key];
1223
1232
 
1224
1233
  // After that we merge the batched changes with the existing value
1225
- const modifiedData = _utils__WEBPACK_IMPORTED_MODULE_8__["default"].removeNullObjectValues(applyMerge(existingValue, [batchedChanges]));
1234
+ const modifiedData = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].removeNullObjectValues(applyMerge(existingValue, [batchedChanges]));
1226
1235
 
1227
1236
  // On native platforms we use SQLite which utilises JSON_PATCH to merge changes.
1228
1237
  // JSON_PATCH generally removes top-level nullish values from the stored object.
1229
1238
  // When there is no existing value though, SQLite will just insert the changes as a new value and thus the top-level nullish values won't be removed.
1230
1239
  // Therefore we need to remove nullish values from the `batchedChanges` which are sent to the SQLite, if no existing value is present.
1231
1240
  if (!existingValue) {
1232
- batchedChanges = _utils__WEBPACK_IMPORTED_MODULE_8__["default"].removeNullObjectValues(batchedChanges);
1241
+ batchedChanges = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].removeNullObjectValues(batchedChanges);
1233
1242
  }
1234
1243
 
1235
- const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, modifiedData);
1244
+ const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, modifiedData);
1236
1245
 
1237
1246
  // This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
1238
1247
  const updatePromise = broadcastUpdate(key, modifiedData, hasChanged, 'merge');
@@ -1242,10 +1251,10 @@ function merge(key, changes) {
1242
1251
  return updatePromise;
1243
1252
  }
1244
1253
 
1245
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].mergeItem(key, batchedChanges, modifiedData).
1254
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].mergeItem(key, batchedChanges, modifiedData).
1246
1255
  then(() => updatePromise);
1247
1256
  } catch (error) {
1248
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`An error occurred while applying merge for key: ${key}, Error: ${error}`);
1257
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`An error occurred while applying merge for key: ${key}, Error: ${error}`);
1249
1258
  return Promise.resolve();
1250
1259
  }
1251
1260
  });
@@ -1259,12 +1268,12 @@ function merge(key, changes) {
1259
1268
  * @returns {Promise}
1260
1269
  */
1261
1270
  function initializeWithDefaultKeyStates() {
1262
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).
1271
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).
1263
1272
  then((pairs) => {
1264
1273
  const asObject = underscore__WEBPACK_IMPORTED_MODULE_1___default().object(pairs);
1265
1274
 
1266
- const merged = _utils__WEBPACK_IMPORTED_MODULE_8__["default"].fastMerge(asObject, defaultKeyStates);
1267
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(merged);
1275
+ const merged = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(asObject, defaultKeyStates);
1276
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].merge(merged);
1268
1277
  underscore__WEBPACK_IMPORTED_MODULE_1___default().each(merged, (val, key) => keyChanged(key, val));
1269
1278
  });
1270
1279
  }
@@ -1312,10 +1321,10 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
1312
1321
  // 2. Figure out whether it is a collection key or not,
1313
1322
  // since collection key subscribers need to be updated differently
1314
1323
  if (!isKeyToPreserve) {
1315
- const oldValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
1324
+ const oldValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(key);
1316
1325
  const newValue = underscore__WEBPACK_IMPORTED_MODULE_1___default().get(defaultKeyStates, key, null);
1317
1326
  if (newValue !== oldValue) {
1318
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, newValue);
1327
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, newValue);
1319
1328
  const collectionKey = key.substring(0, key.indexOf('_') + 1);
1320
1329
  if (collectionKey) {
1321
1330
  if (!keyValuesToResetAsCollection[collectionKey]) {
@@ -1349,8 +1358,8 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
1349
1358
  const defaultKeyValuePairs = underscore__WEBPACK_IMPORTED_MODULE_1___default().pairs(underscore__WEBPACK_IMPORTED_MODULE_1___default().omit(defaultKeyStates, keysToPreserve));
1350
1359
 
1351
1360
  // Remove only the items that we want cleared from storage, and reset others to default
1352
- underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keysToBeClearedFromStorage, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key));
1353
- return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItems(keysToBeClearedFromStorage).then(() => _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(defaultKeyValuePairs)).then(() => Promise.all(updatePromises));
1361
+ underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keysToBeClearedFromStorage, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].drop(key));
1362
+ return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].removeItems(keysToBeClearedFromStorage).then(() => _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(defaultKeyValuePairs)).then(() => Promise.all(updatePromises));
1354
1363
  });
1355
1364
  }
1356
1365
 
@@ -1370,7 +1379,7 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
1370
1379
  */
1371
1380
  function mergeCollection(collectionKey, collection) {
1372
1381
  if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(collection) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(collection) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isEmpty(collection)) {
1373
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo('mergeCollection() called with invalid or empty value. Skipping this update.');
1382
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo('mergeCollection() called with invalid or empty value. Skipping this update.');
1374
1383
  return Promise.resolve();
1375
1384
  }
1376
1385
 
@@ -1386,7 +1395,7 @@ function mergeCollection(collectionKey, collection) {
1386
1395
  }
1387
1396
 
1388
1397
  hasCollectionKeyCheckFailed = true;
1389
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
1398
+ _Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
1390
1399
  });
1391
1400
 
1392
1401
  // Gracefully handle bad mergeCollection updates so it doesn't block the merge queue
@@ -1412,17 +1421,17 @@ function mergeCollection(collectionKey, collection) {
1412
1421
  // New keys will be added via multiSet while existing keys will be updated using multiMerge
1413
1422
  // This is because setting a key that doesn't exist yet with multiMerge will throw errors
1414
1423
  if (keyValuePairsForExistingCollection.length > 0) {
1415
- promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiMerge(keyValuePairsForExistingCollection));
1424
+ promises.push(_storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiMerge(keyValuePairsForExistingCollection));
1416
1425
  }
1417
1426
 
1418
1427
  if (keyValuePairsForNewCollection.length > 0) {
1419
- promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairsForNewCollection));
1428
+ promises.push(_storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(keyValuePairsForNewCollection));
1420
1429
  }
1421
1430
 
1422
1431
  // Prefill cache if necessary by calling get() on any existing keys and then merge original data to cache
1423
1432
  // and update all subscribers
1424
1433
  const promiseUpdate = Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(existingKeys, get)).then(() => {
1425
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(collection);
1434
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].merge(collection);
1426
1435
  return scheduleNotifyCollectionSubscribers(collectionKey, collection);
1427
1436
  });
1428
1437
 
@@ -1487,10 +1496,10 @@ function update(data) {
1487
1496
  * @param {string[]} keyList
1488
1497
  */
1489
1498
  function setMemoryOnlyKeys(keyList) {
1490
- _storage__WEBPACK_IMPORTED_MODULE_4__["default"].setMemoryOnlyKeys(keyList);
1499
+ _storage__WEBPACK_IMPORTED_MODULE_5__["default"].setMemoryOnlyKeys(keyList);
1491
1500
 
1492
1501
  // When in memory only mode for certain keys we do not want to ever drop items from the cache as the user will have no way to recover them again via storage.
1493
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(Infinity);
1502
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].setRecentKeysLimit(Infinity);
1494
1503
  }
1495
1504
 
1496
1505
  /**
@@ -1534,11 +1543,11 @@ function init()
1534
1543
  }
1535
1544
 
1536
1545
  if (debugSetState) {
1537
- _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.setShouldDebugSetState(true);
1546
+ _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__.setShouldDebugSetState(true);
1538
1547
  }
1539
1548
 
1540
1549
  if (maxCachedKeysCount > 0) {
1541
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(maxCachedKeysCount);
1550
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].setRecentKeysLimit(maxCachedKeysCount);
1542
1551
  }
1543
1552
 
1544
1553
  // We need the value of the collection keys later for checking if a
@@ -1562,9 +1571,9 @@ function init()
1562
1571
 
1563
1572
  then(deferredInitTask.resolve);
1564
1573
 
1565
- if (shouldSyncMultipleInstances && underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync)) {
1566
- _storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync((key, value) => {
1567
- _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
1574
+ if (shouldSyncMultipleInstances && underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(_storage__WEBPACK_IMPORTED_MODULE_5__["default"].keepInstancesSync)) {
1575
+ _storage__WEBPACK_IMPORTED_MODULE_5__["default"].keepInstancesSync((key, value) => {
1576
+ _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, value);
1568
1577
  keyChanged(key, value);
1569
1578
  });
1570
1579
  }
@@ -1581,7 +1590,7 @@ const Onyx = {
1581
1590
  clear,
1582
1591
  getAllKeys,
1583
1592
  init,
1584
- registerLogger: _Logger__WEBPACK_IMPORTED_MODULE_5__.registerLogger,
1593
+ registerLogger: _Logger__WEBPACK_IMPORTED_MODULE_6__.registerLogger,
1585
1594
  addToEvictionBlockList,
1586
1595
  removeFromEvictionBlockList,
1587
1596
  isSafeEvictionKey,
@@ -1830,16 +1839,13 @@ class OnyxCache {
1830
1839
  * Remove keys that don't fall into the range of recently used keys
1831
1840
  */
1832
1841
  removeLeastRecentlyUsedKeys() {
1833
- if (this.recentKeys.size <= this.maxRecentKeysSize) {
1834
- return;
1842
+ while (this.recentKeys.size > this.maxRecentKeysSize) {
1843
+ const iterator = this.recentKeys.values();
1844
+ const value = iterator.next().value;
1845
+ if (value !== undefined) {
1846
+ this.drop(value);
1847
+ }
1835
1848
  }
1836
-
1837
- // Get the last N keys by doing a negative slice
1838
- const recentlyAccessed = [...this.recentKeys].slice(-this.maxRecentKeysSize);
1839
- const storageKeys = underscore__WEBPACK_IMPORTED_MODULE_0___default().keys(this.storageMap);
1840
- const keysToRemove = underscore__WEBPACK_IMPORTED_MODULE_0___default().difference(storageKeys, recentlyAccessed);
1841
-
1842
- underscore__WEBPACK_IMPORTED_MODULE_0___default().each(keysToRemove, this.drop);
1843
1849
  }
1844
1850
 
1845
1851
  /**