react-native-onyx 2.0.3 → 2.0.4

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
@@ -510,11 +510,12 @@ function keysChanged(collectionKey, partialCollection, notifyRegularSubscibers =
510
510
  * @private
511
511
  * @param {String} key
512
512
  * @param {*} data
513
+ * @param {*} prevData
513
514
  * @param {Function} [canUpdateSubscriber] only subscribers that pass this truth test will be updated
514
515
  * @param {boolean} [notifyRegularSubscibers=true]
515
516
  * @param {boolean} [notifyWithOnyxSubscibers=true]
516
517
  */
517
- function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = true, notifyWithOnyxSubscibers = true) {
518
+ function keyChanged(key, data, prevData, canUpdateSubscriber = () => true, notifyRegularSubscibers = true, notifyWithOnyxSubscibers = true) {
518
519
  // Add or remove this key from the recentlyAccessedKeys lists
519
520
  if (!underscore_1.default.isNull(data)) {
520
521
  addLastAccessedKey(key);
@@ -528,7 +529,7 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
528
529
  const stateMappingKeys = underscore_1.default.keys(callbackToStateMapping);
529
530
  for (let i = 0; i < stateMappingKeys.length; i++) {
530
531
  const subscriber = callbackToStateMapping[stateMappingKeys[i]];
531
- if (!subscriber || !isKeyMatch(subscriber.key, key) || (underscore_1.default.isFunction(canUpdateSubscriber) && !canUpdateSubscriber(subscriber))) {
532
+ if (!subscriber || !isKeyMatch(subscriber.key, key) || !canUpdateSubscriber(subscriber)) {
532
533
  continue;
533
534
  }
534
535
  // Subscriber is a regular call to connect() and provided a callback
@@ -556,13 +557,13 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
556
557
  // returned by the selector and only when the selected data has changed.
557
558
  if (subscriber.selector) {
558
559
  subscriber.withOnyxInstance.setStateProxy((prevState) => {
559
- const prevData = prevState[subscriber.statePropertyName];
560
- const newData = {
560
+ const prevWithOnyxData = prevState[subscriber.statePropertyName];
561
+ const newWithOnyxData = {
561
562
  [key]: getSubsetOfData(data, subscriber.selector, subscriber.withOnyxInstance.state),
562
563
  };
563
- const prevDataWithNewData = Object.assign(Object.assign({}, prevData), newData);
564
- if (!(0, fast_equals_1.deepEqual)(prevData, prevDataWithNewData)) {
565
- PerformanceUtils.logSetStateCall(subscriber, prevData, newData, 'keyChanged', key);
564
+ const prevDataWithNewData = Object.assign(Object.assign({}, prevWithOnyxData), newWithOnyxData);
565
+ if (!(0, fast_equals_1.deepEqual)(prevWithOnyxData, prevDataWithNewData)) {
566
+ PerformanceUtils.logSetStateCall(subscriber, prevWithOnyxData, newWithOnyxData, 'keyChanged', key);
566
567
  return {
567
568
  [subscriber.statePropertyName]: prevDataWithNewData,
568
569
  };
@@ -584,8 +585,8 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
584
585
  // If the subscriber has a selector, then the component's state must only be updated with the data
585
586
  // returned by the selector and only if the selected data has changed.
586
587
  if (subscriber.selector) {
587
- subscriber.withOnyxInstance.setStateProxy((prevState) => {
588
- const previousValue = getSubsetOfData(prevState[subscriber.statePropertyName], subscriber.selector, subscriber.withOnyxInstance.state);
588
+ subscriber.withOnyxInstance.setStateProxy(() => {
589
+ const previousValue = getSubsetOfData(prevData, subscriber.selector, subscriber.withOnyxInstance.state);
589
590
  const newValue = getSubsetOfData(data, subscriber.selector, subscriber.withOnyxInstance.state);
590
591
  if (!(0, fast_equals_1.deepEqual)(previousValue, newValue)) {
591
592
  return {
@@ -598,15 +599,15 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
598
599
  }
599
600
  // If we did not match on a collection key then we just set the new data to the state property
600
601
  subscriber.withOnyxInstance.setStateProxy((prevState) => {
601
- const previousData = prevState[subscriber.statePropertyName];
602
+ const prevWithOnyxData = prevState[subscriber.statePropertyName];
602
603
  // Avoids triggering unnecessary re-renders when feeding empty objects
603
- if (utils_1.default.areObjectsEmpty(data, previousData)) {
604
+ if (utils_1.default.areObjectsEmpty(data, prevWithOnyxData)) {
604
605
  return null;
605
606
  }
606
- if (previousData === data) {
607
+ if (prevWithOnyxData === data) {
607
608
  return null;
608
609
  }
609
- PerformanceUtils.logSetStateCall(subscriber, previousData, data, 'keyChanged', key);
610
+ PerformanceUtils.logSetStateCall(subscriber, prevData, data, 'keyChanged', key);
610
611
  return {
611
612
  [subscriber.statePropertyName]: data,
612
613
  };
@@ -829,12 +830,13 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
829
830
  *
830
831
  * @param {String} key
831
832
  * @param {*} value
833
+ * @param {*} prevValue
832
834
  * @param {Function} [canUpdateSubscriber] only subscribers that pass this truth test will be updated
833
835
  * @returns {Promise}
834
836
  */
835
- function scheduleSubscriberUpdate(key, value, canUpdateSubscriber) {
836
- const promise = Promise.resolve().then(() => keyChanged(key, value, canUpdateSubscriber, true, false));
837
- batchUpdates(() => keyChanged(key, value, canUpdateSubscriber, false, true));
837
+ function scheduleSubscriberUpdate(key, value, prevValue, canUpdateSubscriber = () => true) {
838
+ const promise = Promise.resolve().then(() => keyChanged(key, value, prevValue, canUpdateSubscriber, true, false));
839
+ batchUpdates(() => keyChanged(key, value, prevValue, canUpdateSubscriber, false, true));
838
840
  return Promise.all([maybeFlushBatchUpdates(), promise]);
839
841
  }
840
842
  /**
@@ -859,8 +861,9 @@ function scheduleNotifyCollectionSubscribers(key, value) {
859
861
  * @return {Promise}
860
862
  */
861
863
  function remove(key) {
864
+ const prevValue = OnyxCache_1.default.getValue(key, false);
862
865
  OnyxCache_1.default.drop(key);
863
- scheduleSubscriberUpdate(key, null);
866
+ scheduleSubscriberUpdate(key, null, prevValue);
864
867
  return storage_1.default.removeItem(key);
865
868
  }
866
869
  /**
@@ -920,6 +923,7 @@ function evictStorageAndRetry(error, onyxMethod, ...args) {
920
923
  function broadcastUpdate(key, value, method, hasChanged, wasRemoved = false) {
921
924
  // Logging properties only since values could be sensitive things we don't want to log
922
925
  Logger.logInfo(`${method}() called for key: ${key}${underscore_1.default.isObject(value) ? ` properties: ${underscore_1.default.keys(value).join(',')}` : ''}`);
926
+ const prevValue = OnyxCache_1.default.getValue(key, false);
923
927
  // Update subscribers if the cached value has changed, or when the subscriber specifically requires
924
928
  // all updates regardless of value changes (indicated by initWithStoredValues set to false).
925
929
  if (hasChanged && !wasRemoved) {
@@ -928,7 +932,7 @@ function broadcastUpdate(key, value, method, hasChanged, wasRemoved = false) {
928
932
  else {
929
933
  OnyxCache_1.default.addToAccessedKeys(key);
930
934
  }
931
- return scheduleSubscriberUpdate(key, value, (subscriber) => hasChanged || subscriber.initWithStoredValues === false);
935
+ return scheduleSubscriberUpdate(key, value, prevValue, (subscriber) => hasChanged || subscriber.initWithStoredValues === false);
932
936
  }
933
937
  /**
934
938
  * @param {String} key
@@ -1011,9 +1015,10 @@ function prepareKeyValuePairsForStorage(data) {
1011
1015
  function multiSet(data) {
1012
1016
  const keyValuePairs = prepareKeyValuePairsForStorage(data);
1013
1017
  const updatePromises = underscore_1.default.map(keyValuePairs, ([key, value]) => {
1018
+ const prevValue = OnyxCache_1.default.getValue(key, false);
1014
1019
  // Update cache and optimistically inform subscribers on the next tick
1015
1020
  OnyxCache_1.default.set(key, value);
1016
- return scheduleSubscriberUpdate(key, value);
1021
+ return scheduleSubscriberUpdate(key, value, prevValue);
1017
1022
  });
1018
1023
  return storage_1.default.multiSet(keyValuePairs)
1019
1024
  .catch((error) => evictStorageAndRetry(error, multiSet, data))
@@ -1130,10 +1135,10 @@ function merge(key, changes) {
1130
1135
  */
1131
1136
  function initializeWithDefaultKeyStates() {
1132
1137
  return storage_1.default.multiGet(underscore_1.default.keys(defaultKeyStates)).then((pairs) => {
1133
- const asObject = underscore_1.default.object(pairs);
1134
- const merged = utils_1.default.fastMerge(asObject, defaultKeyStates);
1138
+ const existingDataAsObject = underscore_1.default.object(pairs);
1139
+ const merged = utils_1.default.fastMerge(existingDataAsObject, defaultKeyStates);
1135
1140
  OnyxCache_1.default.merge(merged);
1136
- underscore_1.default.each(merged, (val, key) => keyChanged(key, val));
1141
+ underscore_1.default.each(merged, (val, key) => keyChanged(key, val, existingDataAsObject));
1137
1142
  });
1138
1143
  }
1139
1144
  /**
@@ -1201,7 +1206,7 @@ function clear(keysToPreserve = []) {
1201
1206
  const updatePromises = [];
1202
1207
  // Notify the subscribers for each key/value group so they can receive the new values
1203
1208
  underscore_1.default.each(keyValuesToResetIndividually, (value, key) => {
1204
- updatePromises.push(scheduleSubscriberUpdate(key, value));
1209
+ updatePromises.push(scheduleSubscriberUpdate(key, value, OnyxCache_1.default.getValue(key, false)));
1205
1210
  });
1206
1211
  underscore_1.default.each(keyValuesToResetAsCollection, (value, key) => {
1207
1212
  updatePromises.push(scheduleNotifyCollectionSubscribers(key, value));
@@ -1401,8 +1406,9 @@ function init({ keys = {}, initialKeyStates = {}, safeEvictionKeys = [], maxCach
1401
1406
  Promise.all([addAllSafeEvictionKeysToRecentlyAccessedList(), initializeWithDefaultKeyStates()]).then(deferredInitTask.resolve);
1402
1407
  if (shouldSyncMultipleInstances && underscore_1.default.isFunction(storage_1.default.keepInstancesSync)) {
1403
1408
  storage_1.default.keepInstancesSync((key, value) => {
1409
+ const prevValue = OnyxCache_1.default.getValue(key, false);
1404
1410
  OnyxCache_1.default.set(key, value);
1405
- keyChanged(key, value);
1411
+ keyChanged(key, value, prevValue);
1406
1412
  });
1407
1413
  }
1408
1414
  }
@@ -39,9 +39,10 @@ declare class OnyxCache {
39
39
  /**
40
40
  * Get a cached value from storage
41
41
  * @param {string} key
42
+ * @param {Boolean} [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.
42
43
  * @returns {*}
43
44
  */
44
- getValue(key: string): any;
45
+ getValue(key: string, shouldReindexCache?: boolean | undefined): any;
45
46
  /**
46
47
  * Check whether cache has data for the given key
47
48
  * @param {string} key
package/dist/OnyxCache.js CHANGED
@@ -52,10 +52,13 @@ class OnyxCache {
52
52
  /**
53
53
  * Get a cached value from storage
54
54
  * @param {string} key
55
+ * @param {Boolean} [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.
55
56
  * @returns {*}
56
57
  */
57
- getValue(key) {
58
- this.addToAccessedKeys(key);
58
+ getValue(key, shouldReindexCache = true) {
59
+ if (shouldReindexCache) {
60
+ this.addToAccessedKeys(key);
61
+ }
59
62
  return this.storageMap[key];
60
63
  }
61
64
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",