react-native-onyx 1.0.21 → 1.0.23
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/API.md +12 -7
- package/dist/web.development.js +50 -23
- package/dist/web.development.js.map +1 -1
- package/dist/web.min.js +1 -1
- package/dist/web.min.js.map +1 -1
- package/lib/Onyx.js +21 -8
- package/lib/OnyxCache.js +10 -0
- package/lib/storage/WebStorage.js +2 -9
- package/package.json +2 -1
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);
|
|
@@ -1008,8 +1024,6 @@ function update(data) {
|
|
|
1008
1024
|
* @param {Boolean} [options.captureMetrics] Enables Onyx benchmarking and exposes the get/print/reset functions
|
|
1009
1025
|
* @param {Boolean} [options.shouldSyncMultipleInstances] Auto synchronize storage events between multiple instances
|
|
1010
1026
|
* of Onyx running in different tabs/windows. Defaults to true for platforms that support local storage (web/desktop)
|
|
1011
|
-
* @param {String[]} [option.keysToDisableSyncEvents=[]] Contains keys for which
|
|
1012
|
-
* we want to disable sync event across tabs.
|
|
1013
1027
|
* @param {Boolean} [options.debugSetState] Enables debugging setState() calls to connected components.
|
|
1014
1028
|
* @example
|
|
1015
1029
|
* Onyx.init({
|
|
@@ -1026,7 +1040,6 @@ function init({
|
|
|
1026
1040
|
maxCachedKeysCount = 1000,
|
|
1027
1041
|
captureMetrics = false,
|
|
1028
1042
|
shouldSyncMultipleInstances = Boolean(global.localStorage),
|
|
1029
|
-
keysToDisableSyncEvents = [],
|
|
1030
1043
|
debugSetState = false,
|
|
1031
1044
|
} = {}) {
|
|
1032
1045
|
if (captureMetrics) {
|
|
@@ -1060,7 +1073,7 @@ function init({
|
|
|
1060
1073
|
.then(deferredInitTask.resolve);
|
|
1061
1074
|
|
|
1062
1075
|
if (shouldSyncMultipleInstances && _.isFunction(Storage.keepInstancesSync)) {
|
|
1063
|
-
Storage.keepInstancesSync(
|
|
1076
|
+
Storage.keepInstancesSync((key, value) => {
|
|
1064
1077
|
cache.set(key, value);
|
|
1065
1078
|
keyChanged(key, value);
|
|
1066
1079
|
});
|
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();
|
|
@@ -16,12 +16,9 @@ const webStorage = {
|
|
|
16
16
|
...Storage,
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @param {String[]} keysToDisableSyncEvents
|
|
21
|
-
* Storage synchronization mechanism keeping all opened tabs in sync
|
|
22
|
-
* @param {function(key: String, data: *)} onStorageKeyChanged
|
|
19
|
+
* @param {Function} onStorageKeyChanged Storage synchronization mechanism keeping all opened tabs in sync
|
|
23
20
|
*/
|
|
24
|
-
keepInstancesSync(
|
|
21
|
+
keepInstancesSync(onStorageKeyChanged) {
|
|
25
22
|
// Override set, remove and clear to raise storage events that we intercept in other tabs
|
|
26
23
|
this.setItem = (key, value) => Storage.setItem(key, value)
|
|
27
24
|
.then(() => raiseStorageSyncEvent(key));
|
|
@@ -43,10 +40,6 @@ const webStorage = {
|
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
const onyxKey = event.newValue;
|
|
46
|
-
if (_.contains(keysToDisableSyncEvents, onyxKey)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
43
|
Storage.getItem(onyxKey)
|
|
51
44
|
.then(value => onStorageKeyChanged(onyxKey, value));
|
|
52
45
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-onyx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
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
|
},
|