react-native-onyx 1.0.87 → 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.
- package/dist/web.development.js +147 -138
- 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 +58 -49
- package/package.json +1 -1
package/lib/Onyx.js
CHANGED
|
@@ -49,6 +49,47 @@ let defaultKeyStates = {};
|
|
|
49
49
|
// Connections can be made before `Onyx.init`. They would wait for this task before resolving
|
|
50
50
|
const deferredInitTask = createDeferredTask();
|
|
51
51
|
|
|
52
|
+
let batchUpdatesPromise = null;
|
|
53
|
+
let batchUpdatesQueue = [];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
|
|
57
|
+
* This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
|
|
58
|
+
* update operations. Instead of calling the subscribers for each update operation, we batch them together which will
|
|
59
|
+
* cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
|
|
60
|
+
* @returns {Promise}
|
|
61
|
+
*/
|
|
62
|
+
function maybeFlushBatchUpdates() {
|
|
63
|
+
if (batchUpdatesPromise) {
|
|
64
|
+
return batchUpdatesPromise;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
batchUpdatesPromise = new Promise((resolve) => {
|
|
68
|
+
/* We use (setTimeout, 0) here which should be called once native module calls are flushed (usually at the end of the frame)
|
|
69
|
+
* We may investigate if (setTimeout, 1) (which in React Native is equal to requestAnimationFrame) works even better
|
|
70
|
+
* then the batch will be flushed on next frame.
|
|
71
|
+
*/
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
const updatesCopy = batchUpdatesQueue;
|
|
74
|
+
batchUpdatesQueue = [];
|
|
75
|
+
batchUpdatesPromise = null;
|
|
76
|
+
unstable_batchedUpdates(() => {
|
|
77
|
+
updatesCopy.forEach((applyUpdates) => {
|
|
78
|
+
applyUpdates();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
resolve();
|
|
83
|
+
}, 0);
|
|
84
|
+
});
|
|
85
|
+
return batchUpdatesPromise;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function batchUpdates(updates) {
|
|
89
|
+
batchUpdatesQueue.push(updates);
|
|
90
|
+
return maybeFlushBatchUpdates();
|
|
91
|
+
}
|
|
92
|
+
|
|
52
93
|
/**
|
|
53
94
|
* Uses a selector function to return a simplified version of sourceData
|
|
54
95
|
* @param {Mixed} sourceData
|
|
@@ -638,9 +679,10 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
|
|
|
638
679
|
* @param {Function} [mapping.callback]
|
|
639
680
|
* @param {String} [mapping.selector]
|
|
640
681
|
* @param {*|null} val
|
|
641
|
-
* @param {String} matchedKey
|
|
682
|
+
* @param {String|undefined} matchedKey
|
|
683
|
+
* @param {Boolean} isBatched
|
|
642
684
|
*/
|
|
643
|
-
function sendDataToConnection(mapping, val, matchedKey) {
|
|
685
|
+
function sendDataToConnection(mapping, val, matchedKey, isBatched) {
|
|
644
686
|
// If the mapping no longer exists then we should not send any data.
|
|
645
687
|
// This means our subscriber disconnected or withOnyx wrapped component unmounted.
|
|
646
688
|
if (!callbackToStateMapping[mapping.connectionID]) {
|
|
@@ -661,7 +703,13 @@ function sendDataToConnection(mapping, val, matchedKey) {
|
|
|
661
703
|
}
|
|
662
704
|
|
|
663
705
|
PerformanceUtils.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
|
|
664
|
-
|
|
706
|
+
if (isBatched) {
|
|
707
|
+
batchUpdates(() => {
|
|
708
|
+
mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
|
|
709
|
+
});
|
|
710
|
+
} else {
|
|
711
|
+
mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
|
|
712
|
+
}
|
|
665
713
|
return;
|
|
666
714
|
}
|
|
667
715
|
|
|
@@ -711,7 +759,7 @@ function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
|
711
759
|
finalObject[matchingKeys[i]] = value;
|
|
712
760
|
return finalObject;
|
|
713
761
|
}, {}))
|
|
714
|
-
.then(val => sendDataToConnection(mapping, val));
|
|
762
|
+
.then(val => sendDataToConnection(mapping, val, undefined, true));
|
|
715
763
|
}
|
|
716
764
|
|
|
717
765
|
/**
|
|
@@ -766,7 +814,9 @@ function connect(mapping) {
|
|
|
766
814
|
// since there are none matched. In withOnyx() we wait for all connected keys to return a value before rendering the child
|
|
767
815
|
// component. This null value will be filtered out so that the connected component can utilize defaultProps.
|
|
768
816
|
if (matchingKeys.length === 0) {
|
|
769
|
-
|
|
817
|
+
// Here we cannot use batching because the null value is expected to be set immediately for default props
|
|
818
|
+
// or they will be undefined.
|
|
819
|
+
sendDataToConnection(mapping, null, undefined, false);
|
|
770
820
|
return;
|
|
771
821
|
}
|
|
772
822
|
|
|
@@ -782,13 +832,13 @@ function connect(mapping) {
|
|
|
782
832
|
|
|
783
833
|
// We did not opt into using waitForCollectionCallback mode so the callback is called for every matching key.
|
|
784
834
|
for (let i = 0; i < matchingKeys.length; i++) {
|
|
785
|
-
get(matchingKeys[i]).then(val => sendDataToConnection(mapping, val, matchingKeys[i]));
|
|
835
|
+
get(matchingKeys[i]).then(val => sendDataToConnection(mapping, val, matchingKeys[i], true));
|
|
786
836
|
}
|
|
787
837
|
return;
|
|
788
838
|
}
|
|
789
839
|
|
|
790
840
|
// If we are not subscribed to a collection key then there's only a single key to send an update for.
|
|
791
|
-
get(mapping.key).then(val => sendDataToConnection(mapping, val, mapping.key));
|
|
841
|
+
get(mapping.key).then(val => sendDataToConnection(mapping, val, mapping.key, true));
|
|
792
842
|
return;
|
|
793
843
|
}
|
|
794
844
|
|
|
@@ -801,7 +851,7 @@ function connect(mapping) {
|
|
|
801
851
|
}
|
|
802
852
|
|
|
803
853
|
// If the subscriber is not using a collection key then we just send a single value back to the subscriber
|
|
804
|
-
get(mapping.key).then(val => sendDataToConnection(mapping, val, mapping.key));
|
|
854
|
+
get(mapping.key).then(val => sendDataToConnection(mapping, val, mapping.key, true));
|
|
805
855
|
return;
|
|
806
856
|
}
|
|
807
857
|
|
|
@@ -835,47 +885,6 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
|
|
|
835
885
|
delete callbackToStateMapping[connectionID];
|
|
836
886
|
}
|
|
837
887
|
|
|
838
|
-
let batchUpdatesPromise = null;
|
|
839
|
-
let batchUpdatesQueue = [];
|
|
840
|
-
|
|
841
|
-
/**
|
|
842
|
-
* We are batching together onyx updates. This helps with use cases where we schedule onyx updates after each other.
|
|
843
|
-
* This happens for example in the Onyx.update function, where we process API responses that might contain a lot of
|
|
844
|
-
* update operations. Instead of calling the subscribers for each update operation, we batch them together which will
|
|
845
|
-
* cause react to schedule the updates at once instead of after each other. This is mainly a performance optimization.
|
|
846
|
-
* @returns {Promise}
|
|
847
|
-
*/
|
|
848
|
-
function maybeFlushBatchUpdates() {
|
|
849
|
-
if (batchUpdatesPromise) {
|
|
850
|
-
return batchUpdatesPromise;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
batchUpdatesPromise = new Promise((resolve) => {
|
|
854
|
-
/* We use (setTimeout, 0) here which should be called once native module calls are flushed (usually at the end of the frame)
|
|
855
|
-
* We may investigate if (setTimeout, 1) (which in React Native is equal to requestAnimationFrame) works even better
|
|
856
|
-
* then the batch will be flushed on next frame.
|
|
857
|
-
*/
|
|
858
|
-
setTimeout(() => {
|
|
859
|
-
const updatesCopy = batchUpdatesQueue;
|
|
860
|
-
batchUpdatesQueue = [];
|
|
861
|
-
batchUpdatesPromise = null;
|
|
862
|
-
unstable_batchedUpdates(() => {
|
|
863
|
-
updatesCopy.forEach((applyUpdates) => {
|
|
864
|
-
applyUpdates();
|
|
865
|
-
});
|
|
866
|
-
});
|
|
867
|
-
|
|
868
|
-
resolve();
|
|
869
|
-
}, 0);
|
|
870
|
-
});
|
|
871
|
-
return batchUpdatesPromise;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function batchUpdates(updates) {
|
|
875
|
-
batchUpdatesQueue.push(updates);
|
|
876
|
-
return maybeFlushBatchUpdates();
|
|
877
|
-
}
|
|
878
|
-
|
|
879
888
|
/**
|
|
880
889
|
* Schedules an update that will be appended to the macro task queue (so it doesn't update the subscribers immediately).
|
|
881
890
|
*
|