react-native-onyx 1.0.21 → 1.0.22

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/lib/Onyx.js CHANGED
@@ -367,11 +367,15 @@ function keysChanged(collectionKey, partialCollection) {
367
367
  /**
368
368
  * When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
369
369
  *
370
+ * @example
371
+ * keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
372
+ *
370
373
  * @private
371
374
  * @param {String} key
372
375
  * @param {*} data
376
+ * @param {Function} [canUpdateSubscriber] only subscribers that pass this truth test will be updated
373
377
  */
374
- function keyChanged(key, data) {
378
+ function keyChanged(key, data, canUpdateSubscriber) {
375
379
  // Add or remove this key from the recentlyAccessedKeys lists
376
380
  if (!_.isNull(data)) {
377
381
  addLastAccessedKey(key);
@@ -385,7 +389,7 @@ function keyChanged(key, data) {
385
389
  const stateMappingKeys = _.keys(callbackToStateMapping);
386
390
  for (let i = 0; i < stateMappingKeys.length; i++) {
387
391
  const subscriber = callbackToStateMapping[stateMappingKeys[i]];
388
- if (!subscriber || !isKeyMatch(subscriber.key, key)) {
392
+ if (!subscriber || !isKeyMatch(subscriber.key, key) || (_.isFunction(canUpdateSubscriber) && !canUpdateSubscriber(subscriber))) {
389
393
  continue;
390
394
  }
391
395
 
@@ -631,12 +635,16 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
631
635
  * available async. Since we have code in our main applications that might expect things to work this way it's not safe to change this
632
636
  * behavior just yet.
633
637
  *
638
+ * @example
639
+ * notifySubscribersOnNextTick(key, value, subscriber => subscriber.initWithStoredValues === false)
640
+ *
634
641
  * @param {String} key
635
642
  * @param {*} value
643
+ * @param {Function} [canUpdateSubscriber] only subscribers that pass this truth test will be updated
636
644
  */
637
645
  // eslint-disable-next-line rulesdir/no-negated-variables
638
- function notifySubscribersOnNextTick(key, value) {
639
- Promise.resolve().then(() => keyChanged(key, value));
646
+ function notifySubscribersOnNextTick(key, value, canUpdateSubscriber) {
647
+ Promise.resolve().then(() => keyChanged(key, value, canUpdateSubscriber));
640
648
  }
641
649
 
642
650
  /**
@@ -703,6 +711,14 @@ function set(key, value) {
703
711
  Logger.logAlert(`Onyx.set() called after Onyx.merge() for key: ${key}. It is recommended to use set() or merge() not both.`);
704
712
  }
705
713
 
714
+ // If the value in the cache is the same as what we have then do not update subscribers unless they
715
+ // have initWithStoredValues: false then they MUST get all updates even if nothing has changed.
716
+ if (!cache.hasValueChanged(key, value)) {
717
+ cache.addToAccessedKeys(key);
718
+ notifySubscribersOnNextTick(key, value, subscriber => subscriber.initWithStoredValues === false);
719
+ return Promise.resolve();
720
+ }
721
+
706
722
  // Adds the key to cache when it's not available
707
723
  cache.set(key, value);
708
724
  notifySubscribersOnNextTick(key, value);
package/lib/OnyxCache.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import _ from 'underscore';
2
+ import {deepEqual} from 'fast-equals';
2
3
  import fastMerge from './fastMerge';
3
4
 
4
5
  const isDefined = _.negate(_.isUndefined);
@@ -191,6 +192,15 @@ class OnyxCache {
191
192
  setRecentKeysLimit(limit) {
192
193
  this.maxRecentKeysSize = limit;
193
194
  }
195
+
196
+ /**
197
+ * @param {String} key
198
+ * @param {*} value
199
+ * @returns {Boolean}
200
+ */
201
+ hasValueChanged(key, value) {
202
+ return !deepEqual(this.storageMap[key], value);
203
+ }
194
204
  }
195
205
 
196
206
  const instance = new OnyxCache();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",
@@ -40,6 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "ascii-table": "0.0.9",
43
+ "fast-equals": "^4.0.3",
43
44
  "lodash": "^4.17.21",
44
45
  "underscore": "^1.13.1"
45
46
  },