react-native-onyx 2.0.57 → 2.0.59

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.d.ts CHANGED
@@ -19,7 +19,7 @@ declare function init({ keys, initialKeyStates, safeEvictionKeys, maxCachedKeysC
19
19
  * @param [mapping.callback] a method that will be called with changed data
20
20
  * This is used by any non-React code to connect to Onyx
21
21
  * @param [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
22
- * component
22
+ * component. Default is true.
23
23
  * @param [mapping.waitForCollectionCallback] If set to true, it will return the entire collection to the callback as a single object
24
24
  * @param [mapping.selector] THIS PARAM IS ONLY USED WITH withOnyx(). If included, this will be used to subscribe to a subset of an Onyx key's data.
25
25
  * The sourceData and withOnyx state are passed to the selector and should return the simplified data. Using this setting on `withOnyx` can have very positive
package/dist/Onyx.js CHANGED
@@ -80,7 +80,7 @@ function init({ keys = {}, initialKeyStates = {}, safeEvictionKeys = [], maxCach
80
80
  * @param [mapping.callback] a method that will be called with changed data
81
81
  * This is used by any non-React code to connect to Onyx
82
82
  * @param [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
83
- * component
83
+ * component. Default is true.
84
84
  * @param [mapping.waitForCollectionCallback] If set to true, it will return the entire collection to the callback as a single object
85
85
  * @param [mapping.selector] THIS PARAM IS ONLY USED WITH withOnyx(). If included, this will be used to subscribe to a subset of an Onyx key's data.
86
86
  * The sourceData and withOnyx state are passed to the selector and should return the simplified data. Using this setting on `withOnyx` can have very positive
@@ -482,21 +482,24 @@ function mergeCollection(collectionKey, collection) {
482
482
  * @param keysToPreserve is a list of ONYXKEYS that should not be cleared with the rest of the data
483
483
  */
484
484
  function clear(keysToPreserve = []) {
485
+ const defaultKeyStates = OnyxUtils_1.default.getDefaultKeyStates();
486
+ const initialKeys = Object.keys(defaultKeyStates);
485
487
  return OnyxUtils_1.default.getAllKeys()
486
- .then((keys) => {
488
+ .then((cachedKeys) => {
487
489
  OnyxCache_1.default.clearNullishStorageKeys();
488
490
  const keysToBeClearedFromStorage = [];
489
491
  const keyValuesToResetAsCollection = {};
490
492
  const keyValuesToResetIndividually = {};
493
+ const allKeys = new Set([...cachedKeys, ...initialKeys]);
491
494
  // The only keys that should not be cleared are:
492
495
  // 1. Anything specifically passed in keysToPreserve (because some keys like language preferences, offline
493
496
  // status, or activeClients need to remain in Onyx even when signed out)
494
497
  // 2. Any keys with a default state (because they need to remain in Onyx as their default, and setting them
495
498
  // to null would cause unknown behavior)
496
- keys.forEach((key) => {
499
+ // 2.1 However, if a default key was explicitly set to null, we need to reset it to the default value
500
+ allKeys.forEach((key) => {
497
501
  var _a;
498
502
  const isKeyToPreserve = keysToPreserve.includes(key);
499
- const defaultKeyStates = OnyxUtils_1.default.getDefaultKeyStates();
500
503
  const isDefaultKey = key in defaultKeyStates;
501
504
  // If the key is being removed or reset to default:
502
505
  // 1. Update it in the cache
@@ -533,7 +536,6 @@ function clear(keysToPreserve = []) {
533
536
  Object.entries(keyValuesToResetAsCollection).forEach(([key, value]) => {
534
537
  updatePromises.push(OnyxUtils_1.default.scheduleNotifyCollectionSubscribers(key, value));
535
538
  });
536
- const defaultKeyStates = OnyxUtils_1.default.getDefaultKeyStates();
537
539
  const defaultKeyValuePairs = Object.entries(Object.keys(defaultKeyStates)
538
540
  .filter((key) => !keysToPreserve.includes(key))
539
541
  .reduce((obj, key) => {
@@ -145,7 +145,7 @@ declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey
145
145
  * @example
146
146
  * keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
147
147
  */
148
- declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, previousValue: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: Mapping<OnyxKey>) => boolean, notifyRegularSubscibers?: boolean, notifyWithOnyxSubscibers?: boolean): void;
148
+ declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, previousValue: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: Mapping<OnyxKey>) => boolean, notifyConnectSubscribers?: boolean, notifyWithOnyxSubscribers?: boolean): void;
149
149
  /**
150
150
  * Sends the data obtained from the keys to the connection. It either:
151
151
  * - sets state on the withOnyxInstances
package/dist/OnyxUtils.js CHANGED
@@ -67,6 +67,8 @@ const evictionBlocklist = {};
67
67
  let defaultKeyStates = {};
68
68
  let batchUpdatesPromise = null;
69
69
  let batchUpdatesQueue = [];
70
+ // Used for comparison with a new update to avoid invoking the Onyx.connect callback with the same data.
71
+ const lastConnectionCallbackData = new Map();
70
72
  let snapshotKey = null;
71
73
  function getSnapshotKey() {
72
74
  return snapshotKey;
@@ -625,7 +627,7 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
625
627
  * @example
626
628
  * keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
627
629
  */
628
- function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true, notifyRegularSubscibers = true, notifyWithOnyxSubscibers = true) {
630
+ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true, notifyConnectSubscribers = true, notifyWithOnyxSubscribers = true) {
629
631
  var _a, _b;
630
632
  // Add or remove this key from the recentlyAccessedKeys lists
631
633
  if (value !== null) {
@@ -657,7 +659,10 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
657
659
  }
658
660
  // Subscriber is a regular call to connect() and provided a callback
659
661
  if (typeof subscriber.callback === 'function') {
660
- if (!notifyRegularSubscibers) {
662
+ if (!notifyConnectSubscribers) {
663
+ continue;
664
+ }
665
+ if (lastConnectionCallbackData.has(subscriber.connectionID) && lastConnectionCallbackData.get(subscriber.connectionID) === value) {
661
666
  continue;
662
667
  }
663
668
  if (isCollectionKey(subscriber.key) && subscriber.waitForCollectionCallback) {
@@ -668,11 +673,12 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
668
673
  }
669
674
  const subscriberCallback = subscriber.callback;
670
675
  subscriberCallback(value, key);
676
+ lastConnectionCallbackData.set(subscriber.connectionID, value);
671
677
  continue;
672
678
  }
673
679
  // Subscriber connected via withOnyx() HOC
674
680
  if ('withOnyxInstance' in subscriber && subscriber.withOnyxInstance) {
675
- if (!notifyWithOnyxSubscibers) {
681
+ if (!notifyWithOnyxSubscribers) {
676
682
  continue;
677
683
  }
678
684
  const selector = subscriber.selector;
@@ -784,7 +790,14 @@ function sendDataToConnection(mapping, value, matchedKey, isBatched) {
784
790
  // If we would pass undefined to setWithOnyxInstance instead, withOnyx would not set the value in the state.
785
791
  // withOnyx will internally replace null values with undefined and never pass null values to wrapped components.
786
792
  // For regular callbacks, we never want to pass null values, but always just undefined if a value is not set in cache or storage.
787
- (_b = (_a = mapping).callback) === null || _b === void 0 ? void 0 : _b.call(_a, value === null ? undefined : value, matchedKey);
793
+ const valueToPass = value === null ? undefined : value;
794
+ const lastValue = lastConnectionCallbackData.get(mapping.connectionID);
795
+ lastConnectionCallbackData.get(mapping.connectionID);
796
+ // If the value has not changed we do not need to trigger the callback
797
+ if (lastConnectionCallbackData.has(mapping.connectionID) && valueToPass === lastValue) {
798
+ return;
799
+ }
800
+ (_b = (_a = mapping).callback) === null || _b === void 0 ? void 0 : _b.call(_a, valueToPass, matchedKey);
788
801
  }
789
802
  /**
790
803
  * We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "2.0.57",
3
+ "version": "2.0.59",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",