react-native-onyx 2.0.141 → 3.0.1
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 +2 -8
- package/README.md +2 -62
- package/dist/Onyx.d.ts +7 -13
- package/dist/Onyx.js +8 -20
- package/dist/OnyxConnectionManager.d.ts +1 -1
- package/dist/OnyxConnectionManager.js +14 -22
- package/dist/OnyxUtils.d.ts +10 -13
- package/dist/OnyxUtils.js +28 -247
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -3
- package/dist/types.d.ts +6 -75
- package/dist/useOnyx.js +0 -1
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +0 -7
- package/package.json +1 -1
- package/dist/PerformanceUtils.d.ts +0 -8
- package/dist/PerformanceUtils.js +0 -52
- package/dist/withOnyx/index.d.ts +0 -15
- package/dist/withOnyx/index.js +0 -322
- package/dist/withOnyx/types.d.ts +0 -129
- package/dist/withOnyx/types.js +0 -2
package/dist/OnyxUtils.js
CHANGED
|
@@ -39,13 +39,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.clearOnyxUtilsInternals = clearOnyxUtilsInternals;
|
|
40
40
|
/* eslint-disable no-continue */
|
|
41
41
|
const fast_equals_1 = require("fast-equals");
|
|
42
|
-
const clone_1 = __importDefault(require("lodash/clone"));
|
|
43
42
|
const pick_1 = __importDefault(require("lodash/pick"));
|
|
44
43
|
const underscore_1 = __importDefault(require("underscore"));
|
|
45
44
|
const DevTools_1 = __importDefault(require("./DevTools"));
|
|
46
45
|
const Logger = __importStar(require("./Logger"));
|
|
47
46
|
const OnyxCache_1 = __importStar(require("./OnyxCache"));
|
|
48
|
-
const PerformanceUtils = __importStar(require("./PerformanceUtils"));
|
|
49
47
|
const Str = __importStar(require("./Str"));
|
|
50
48
|
const batch_1 = __importDefault(require("./batch"));
|
|
51
49
|
const storage_1 = __importDefault(require("./storage"));
|
|
@@ -192,10 +190,10 @@ function batchUpdates(updates) {
|
|
|
192
190
|
* and runs it through a reducer function to return a subset of the data according to a selector.
|
|
193
191
|
* The resulting collection will only contain items that are returned by the selector.
|
|
194
192
|
*/
|
|
195
|
-
function reduceCollectionWithSelector(collection, selector
|
|
193
|
+
function reduceCollectionWithSelector(collection, selector) {
|
|
196
194
|
return Object.entries(collection !== null && collection !== void 0 ? collection : {}).reduce((finalCollection, [key, item]) => {
|
|
197
195
|
// eslint-disable-next-line no-param-reassign
|
|
198
|
-
finalCollection[key] = selector(item
|
|
196
|
+
finalCollection[key] = selector(item);
|
|
199
197
|
return finalCollection;
|
|
200
198
|
}, {});
|
|
201
199
|
}
|
|
@@ -436,7 +434,7 @@ function getCollectionKey(key) {
|
|
|
436
434
|
* Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
|
|
437
435
|
* If the requested key is a collection, it will return an object with all the collection members.
|
|
438
436
|
*/
|
|
439
|
-
function tryGetCachedValue(key
|
|
437
|
+
function tryGetCachedValue(key) {
|
|
440
438
|
let val = OnyxCache_1.default.get(key);
|
|
441
439
|
if (isCollectionKey(key)) {
|
|
442
440
|
const collectionData = OnyxCache_1.default.getCollectionData(key);
|
|
@@ -452,13 +450,6 @@ function tryGetCachedValue(key, mapping) {
|
|
|
452
450
|
val = {};
|
|
453
451
|
}
|
|
454
452
|
}
|
|
455
|
-
if (mapping === null || mapping === void 0 ? void 0 : mapping.selector) {
|
|
456
|
-
const state = mapping.withOnyxInstance ? mapping.withOnyxInstance.state : undefined;
|
|
457
|
-
if (isCollectionKey(key)) {
|
|
458
|
-
return reduceCollectionWithSelector(val, mapping.selector, state);
|
|
459
|
-
}
|
|
460
|
-
return mapping.selector(val, state);
|
|
461
|
-
}
|
|
462
453
|
return val;
|
|
463
454
|
}
|
|
464
455
|
function getCachedCollection(collectionKey, collectionMemberKeys) {
|
|
@@ -503,7 +494,7 @@ function getCachedCollection(collectionKey, collectionMemberKeys) {
|
|
|
503
494
|
/**
|
|
504
495
|
* When a collection of keys change, search for any callbacks matching the collection key and trigger those callbacks
|
|
505
496
|
*/
|
|
506
|
-
function keysChanged(collectionKey, partialCollection, partialPreviousCollection, notifyConnectSubscribers = true
|
|
497
|
+
function keysChanged(collectionKey, partialCollection, partialPreviousCollection, notifyConnectSubscribers = true) {
|
|
507
498
|
// We prepare the "cached collection" which is the entire collection + the new partial data that
|
|
508
499
|
// was merged in via mergeCollection().
|
|
509
500
|
const cachedCollection = getCachedCollection(collectionKey);
|
|
@@ -565,94 +556,6 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
565
556
|
}
|
|
566
557
|
continue;
|
|
567
558
|
}
|
|
568
|
-
// React component subscriber found.
|
|
569
|
-
if (utils_1.default.hasWithOnyxInstance(subscriber)) {
|
|
570
|
-
if (!notifyWithOnyxSubscribers) {
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
// We are subscribed to a collection key so we must update the data in state with the new
|
|
574
|
-
// collection member key values from the partial update.
|
|
575
|
-
if (isSubscribedToCollectionKey) {
|
|
576
|
-
// If the subscriber has a selector, then the component's state must only be updated with the data
|
|
577
|
-
// returned by the selector.
|
|
578
|
-
const collectionSelector = subscriber.selector;
|
|
579
|
-
if (collectionSelector) {
|
|
580
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
581
|
-
const previousData = prevState[subscriber.statePropertyName];
|
|
582
|
-
const newData = reduceCollectionWithSelector(cachedCollection, collectionSelector, subscriber.withOnyxInstance.state);
|
|
583
|
-
if ((0, fast_equals_1.deepEqual)(previousData, newData)) {
|
|
584
|
-
return null;
|
|
585
|
-
}
|
|
586
|
-
return {
|
|
587
|
-
[subscriber.statePropertyName]: newData,
|
|
588
|
-
};
|
|
589
|
-
});
|
|
590
|
-
continue;
|
|
591
|
-
}
|
|
592
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
593
|
-
var _a;
|
|
594
|
-
const prevCollection = (_a = prevState === null || prevState === void 0 ? void 0 : prevState[subscriber.statePropertyName]) !== null && _a !== void 0 ? _a : {};
|
|
595
|
-
const finalCollection = (0, clone_1.default)(prevCollection);
|
|
596
|
-
const dataKeys = Object.keys(partialCollection !== null && partialCollection !== void 0 ? partialCollection : {});
|
|
597
|
-
for (const dataKey of dataKeys) {
|
|
598
|
-
finalCollection[dataKey] = cachedCollection[dataKey];
|
|
599
|
-
}
|
|
600
|
-
if ((0, fast_equals_1.deepEqual)(prevCollection, finalCollection)) {
|
|
601
|
-
return null;
|
|
602
|
-
}
|
|
603
|
-
PerformanceUtils.logSetStateCall(subscriber, prevState === null || prevState === void 0 ? void 0 : prevState[subscriber.statePropertyName], finalCollection, 'keysChanged', collectionKey);
|
|
604
|
-
return {
|
|
605
|
-
[subscriber.statePropertyName]: finalCollection,
|
|
606
|
-
};
|
|
607
|
-
});
|
|
608
|
-
continue;
|
|
609
|
-
}
|
|
610
|
-
// If a React component is only interested in a single key then we can set the cached value directly to the state name.
|
|
611
|
-
if (isSubscribedToCollectionMemberKey) {
|
|
612
|
-
if ((0, fast_equals_1.deepEqual)(cachedCollection[subscriber.key], previousCollection[subscriber.key])) {
|
|
613
|
-
continue;
|
|
614
|
-
}
|
|
615
|
-
// However, we only want to update this subscriber if the partial data contains a change.
|
|
616
|
-
// Otherwise, we would update them with a value they already have and trigger an unnecessary re-render.
|
|
617
|
-
const dataFromCollection = partialCollection === null || partialCollection === void 0 ? void 0 : partialCollection[subscriber.key];
|
|
618
|
-
if (dataFromCollection === undefined) {
|
|
619
|
-
continue;
|
|
620
|
-
}
|
|
621
|
-
// If the subscriber has a selector, then the component's state must only be updated with the data
|
|
622
|
-
// returned by the selector and the state should only change when the subset of data changes from what
|
|
623
|
-
// it was previously.
|
|
624
|
-
const selector = subscriber.selector;
|
|
625
|
-
if (selector) {
|
|
626
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
627
|
-
const prevData = prevState[subscriber.statePropertyName];
|
|
628
|
-
const newData = selector(cachedCollection[subscriber.key], subscriber.withOnyxInstance.state);
|
|
629
|
-
if ((0, fast_equals_1.deepEqual)(prevData, newData)) {
|
|
630
|
-
return null;
|
|
631
|
-
}
|
|
632
|
-
PerformanceUtils.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
|
|
633
|
-
return {
|
|
634
|
-
[subscriber.statePropertyName]: newData,
|
|
635
|
-
};
|
|
636
|
-
});
|
|
637
|
-
continue;
|
|
638
|
-
}
|
|
639
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
640
|
-
const prevData = prevState[subscriber.statePropertyName];
|
|
641
|
-
const newData = cachedCollection[subscriber.key];
|
|
642
|
-
// Avoids triggering unnecessary re-renders when feeding empty objects
|
|
643
|
-
if (utils_1.default.isEmptyObject(newData) && utils_1.default.isEmptyObject(prevData)) {
|
|
644
|
-
return null;
|
|
645
|
-
}
|
|
646
|
-
if ((0, fast_equals_1.deepEqual)(prevData, newData)) {
|
|
647
|
-
return null;
|
|
648
|
-
}
|
|
649
|
-
PerformanceUtils.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
|
|
650
|
-
return {
|
|
651
|
-
[subscriber.statePropertyName]: newData,
|
|
652
|
-
};
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
559
|
}
|
|
657
560
|
}
|
|
658
561
|
/**
|
|
@@ -661,7 +564,7 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
661
564
|
* @example
|
|
662
565
|
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
663
566
|
*/
|
|
664
|
-
function keyChanged(key, value,
|
|
567
|
+
function keyChanged(key, value, canUpdateSubscriber = () => true, notifyConnectSubscribers = true) {
|
|
665
568
|
var _a, _b;
|
|
666
569
|
// Add or remove this key from the recentlyAccessedKeys lists
|
|
667
570
|
if (value !== null) {
|
|
@@ -671,8 +574,7 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
|
|
|
671
574
|
OnyxCache_1.default.removeLastAccessedKey(key);
|
|
672
575
|
}
|
|
673
576
|
// We get the subscribers interested in the key that has just changed. If the subscriber's key is a collection key then we will
|
|
674
|
-
// notify them if the key that changed is a collection member. Or if it is a regular key notify them when there is an exact match.
|
|
675
|
-
// was connected via withOnyx we will call setState() directly on the withOnyx instance. If it is a regular connection we will pass the data to the provided callback.
|
|
577
|
+
// notify them if the key that changed is a collection member. Or if it is a regular key notify them when there is an exact match.
|
|
676
578
|
// Given the amount of times this function is called we need to make sure we are not iterating over all subscribers every time. On the other hand, we don't need to
|
|
677
579
|
// do the same in keysChanged, because we only call that function when a collection key changes, and it doesn't happen that often.
|
|
678
580
|
// For performance reason, we look for the given key and later if don't find it we look for the collection key, instead of checking if it is a collection key first.
|
|
@@ -721,119 +623,19 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
|
|
|
721
623
|
lastConnectionCallbackData.set(subscriber.subscriptionID, value);
|
|
722
624
|
continue;
|
|
723
625
|
}
|
|
724
|
-
|
|
725
|
-
if (utils_1.default.hasWithOnyxInstance(subscriber)) {
|
|
726
|
-
if (!notifyWithOnyxSubscribers) {
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
|
-
const selector = subscriber.selector;
|
|
730
|
-
// Check if we are subscribing to a collection key and overwrite the collection member key value in state
|
|
731
|
-
if (isCollectionKey(subscriber.key)) {
|
|
732
|
-
// If the subscriber has a selector, then the consumer of this data must only be given the data
|
|
733
|
-
// returned by the selector and only when the selected data has changed.
|
|
734
|
-
if (selector) {
|
|
735
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
736
|
-
const prevWithOnyxData = prevState[subscriber.statePropertyName];
|
|
737
|
-
const newWithOnyxData = {
|
|
738
|
-
[key]: selector(value, subscriber.withOnyxInstance.state),
|
|
739
|
-
};
|
|
740
|
-
const prevDataWithNewData = Object.assign(Object.assign({}, prevWithOnyxData), newWithOnyxData);
|
|
741
|
-
if ((0, fast_equals_1.deepEqual)(prevWithOnyxData, prevDataWithNewData)) {
|
|
742
|
-
return null;
|
|
743
|
-
}
|
|
744
|
-
PerformanceUtils.logSetStateCall(subscriber, prevWithOnyxData, newWithOnyxData, 'keyChanged', key);
|
|
745
|
-
return {
|
|
746
|
-
[subscriber.statePropertyName]: prevDataWithNewData,
|
|
747
|
-
};
|
|
748
|
-
});
|
|
749
|
-
continue;
|
|
750
|
-
}
|
|
751
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
752
|
-
const prevCollection = prevState[subscriber.statePropertyName] || {};
|
|
753
|
-
const newCollection = Object.assign(Object.assign({}, prevCollection), { [key]: value });
|
|
754
|
-
if ((0, fast_equals_1.deepEqual)(prevCollection, newCollection)) {
|
|
755
|
-
return null;
|
|
756
|
-
}
|
|
757
|
-
PerformanceUtils.logSetStateCall(subscriber, prevCollection, newCollection, 'keyChanged', key);
|
|
758
|
-
return {
|
|
759
|
-
[subscriber.statePropertyName]: newCollection,
|
|
760
|
-
};
|
|
761
|
-
});
|
|
762
|
-
continue;
|
|
763
|
-
}
|
|
764
|
-
// If the subscriber has a selector, then the component's state must only be updated with the data
|
|
765
|
-
// returned by the selector and only if the selected data has changed.
|
|
766
|
-
if (selector) {
|
|
767
|
-
subscriber.withOnyxInstance.setStateProxy(() => {
|
|
768
|
-
const prevValue = selector(previousValue, subscriber.withOnyxInstance.state);
|
|
769
|
-
const newValue = selector(value, subscriber.withOnyxInstance.state);
|
|
770
|
-
if ((0, fast_equals_1.deepEqual)(prevValue, newValue)) {
|
|
771
|
-
return null;
|
|
772
|
-
}
|
|
773
|
-
return {
|
|
774
|
-
[subscriber.statePropertyName]: newValue,
|
|
775
|
-
};
|
|
776
|
-
});
|
|
777
|
-
continue;
|
|
778
|
-
}
|
|
779
|
-
// If we did not match on a collection key then we just set the new data to the state property
|
|
780
|
-
subscriber.withOnyxInstance.setStateProxy((prevState) => {
|
|
781
|
-
const prevWithOnyxValue = prevState[subscriber.statePropertyName];
|
|
782
|
-
// Avoids triggering unnecessary re-renders when feeding empty objects
|
|
783
|
-
if (utils_1.default.isEmptyObject(value) && utils_1.default.isEmptyObject(prevWithOnyxValue)) {
|
|
784
|
-
return null;
|
|
785
|
-
}
|
|
786
|
-
if (prevWithOnyxValue === value) {
|
|
787
|
-
return null;
|
|
788
|
-
}
|
|
789
|
-
PerformanceUtils.logSetStateCall(subscriber, previousValue, value, 'keyChanged', key);
|
|
790
|
-
return {
|
|
791
|
-
[subscriber.statePropertyName]: value,
|
|
792
|
-
};
|
|
793
|
-
});
|
|
794
|
-
continue;
|
|
795
|
-
}
|
|
796
|
-
console.error('Warning: Found a matching subscriber to a key that changed, but no callback or withOnyxInstance could be found.');
|
|
626
|
+
console.error('Warning: Found a matching subscriber to a key that changed, but no callback could be found.');
|
|
797
627
|
}
|
|
798
628
|
}
|
|
799
629
|
/**
|
|
800
|
-
* Sends the data obtained from the keys to the connection.
|
|
801
|
-
* - sets state on the withOnyxInstances
|
|
802
|
-
* - triggers the callback function
|
|
630
|
+
* Sends the data obtained from the keys to the connection.
|
|
803
631
|
*/
|
|
804
|
-
function sendDataToConnection(mapping, value, matchedKey
|
|
632
|
+
function sendDataToConnection(mapping, value, matchedKey) {
|
|
805
633
|
var _a, _b;
|
|
806
634
|
// If the mapping no longer exists then we should not send any data.
|
|
807
|
-
// This means our subscriber disconnected
|
|
635
|
+
// This means our subscriber was disconnected.
|
|
808
636
|
if (!callbackToStateMapping[mapping.subscriptionID]) {
|
|
809
637
|
return;
|
|
810
638
|
}
|
|
811
|
-
if (utils_1.default.hasWithOnyxInstance(mapping)) {
|
|
812
|
-
let newData = value;
|
|
813
|
-
// If the mapping has a selector, then the component's state must only be updated with the data
|
|
814
|
-
// returned by the selector.
|
|
815
|
-
if (mapping.selector) {
|
|
816
|
-
if (isCollectionKey(mapping.key)) {
|
|
817
|
-
newData = reduceCollectionWithSelector(value, mapping.selector, mapping.withOnyxInstance.state);
|
|
818
|
-
}
|
|
819
|
-
else {
|
|
820
|
-
newData = mapping.selector(value, mapping.withOnyxInstance.state);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
PerformanceUtils.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
|
|
824
|
-
if (isBatched) {
|
|
825
|
-
batchUpdates(() => mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData));
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
|
|
829
|
-
}
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
832
|
-
// When there are no matching keys in "Onyx.connect", we pass null to "sendDataToConnection" explicitly,
|
|
833
|
-
// to allow the withOnyx instance to set the value in the state initially and therefore stop the loading state once all
|
|
834
|
-
// required keys have been set.
|
|
835
|
-
// If we would pass undefined to setWithOnyxInstance instead, withOnyx would not set the value in the state.
|
|
836
|
-
// withOnyx will internally replace null values with undefined and never pass null values to wrapped components.
|
|
837
639
|
// For regular callbacks, we never want to pass null values, but always just undefined if a value is not set in cache or storage.
|
|
838
640
|
const valueToPass = value === null ? undefined : value;
|
|
839
641
|
const lastValue = lastConnectionCallbackData.get(mapping.subscriptionID);
|
|
@@ -848,21 +650,14 @@ function sendDataToConnection(mapping, value, matchedKey, isBatched) {
|
|
|
848
650
|
* We check to see if this key is flagged as safe for eviction and add it to the recentlyAccessedKeys list so that when we
|
|
849
651
|
* run out of storage the least recently accessed key can be removed.
|
|
850
652
|
*/
|
|
851
|
-
function addKeyToRecentlyAccessedIfNeeded(
|
|
852
|
-
if (!OnyxCache_1.default.isEvictableKey(
|
|
653
|
+
function addKeyToRecentlyAccessedIfNeeded(key) {
|
|
654
|
+
if (!OnyxCache_1.default.isEvictableKey(key)) {
|
|
853
655
|
return;
|
|
854
656
|
}
|
|
855
657
|
// Add the key to recentKeys first (this makes it the most recent key)
|
|
856
|
-
OnyxCache_1.default.addToAccessedKeys(
|
|
658
|
+
OnyxCache_1.default.addToAccessedKeys(key);
|
|
857
659
|
// Try to free some cache whenever we connect to a safe eviction key
|
|
858
660
|
OnyxCache_1.default.removeLeastRecentlyUsedKeys();
|
|
859
|
-
if (utils_1.default.hasWithOnyxInstance(mapping) && !isCollectionKey(mapping.key)) {
|
|
860
|
-
// All React components subscribing to a key flagged as a safe eviction key must implement the canEvict property.
|
|
861
|
-
if (mapping.canEvict === undefined) {
|
|
862
|
-
throw new Error(`Cannot subscribe to safe eviction key '${mapping.key}' without providing a canEvict value.`);
|
|
863
|
-
}
|
|
864
|
-
OnyxCache_1.default.addLastAccessedKey(mapping.key, isCollectionKey(mapping.key));
|
|
865
|
-
}
|
|
866
661
|
}
|
|
867
662
|
/**
|
|
868
663
|
* Gets the data for a given an array of matching keys, combines them into an object, and sends the result back to the subscriber.
|
|
@@ -870,7 +665,7 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
870
665
|
function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
871
666
|
multiGet(matchingKeys).then((dataMap) => {
|
|
872
667
|
const data = Object.fromEntries(dataMap.entries());
|
|
873
|
-
sendDataToConnection(mapping, data, undefined
|
|
668
|
+
sendDataToConnection(mapping, data, undefined);
|
|
874
669
|
});
|
|
875
670
|
}
|
|
876
671
|
/**
|
|
@@ -879,9 +674,9 @@ function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
|
879
674
|
* @example
|
|
880
675
|
* scheduleSubscriberUpdate(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
881
676
|
*/
|
|
882
|
-
function scheduleSubscriberUpdate(key, value,
|
|
883
|
-
const promise = Promise.resolve().then(() => keyChanged(key, value,
|
|
884
|
-
batchUpdates(() => keyChanged(key, value,
|
|
677
|
+
function scheduleSubscriberUpdate(key, value, canUpdateSubscriber = () => true) {
|
|
678
|
+
const promise = Promise.resolve().then(() => keyChanged(key, value, canUpdateSubscriber, true));
|
|
679
|
+
batchUpdates(() => keyChanged(key, value, canUpdateSubscriber, false));
|
|
885
680
|
return Promise.all([maybeFlushBatchUpdates(), promise]).then(() => undefined);
|
|
886
681
|
}
|
|
887
682
|
/**
|
|
@@ -890,17 +685,16 @@ function scheduleSubscriberUpdate(key, value, previousValue, canUpdateSubscriber
|
|
|
890
685
|
* subscriber callbacks receive the data in a different format than they normally expect and it breaks code.
|
|
891
686
|
*/
|
|
892
687
|
function scheduleNotifyCollectionSubscribers(key, value, previousValue) {
|
|
893
|
-
const promise = Promise.resolve().then(() => keysChanged(key, value, previousValue, true
|
|
894
|
-
batchUpdates(() => keysChanged(key, value, previousValue, false
|
|
688
|
+
const promise = Promise.resolve().then(() => keysChanged(key, value, previousValue, true));
|
|
689
|
+
batchUpdates(() => keysChanged(key, value, previousValue, false));
|
|
895
690
|
return Promise.all([maybeFlushBatchUpdates(), promise]).then(() => undefined);
|
|
896
691
|
}
|
|
897
692
|
/**
|
|
898
693
|
* Remove a key from Onyx and update the subscribers
|
|
899
694
|
*/
|
|
900
695
|
function remove(key) {
|
|
901
|
-
const prevValue = OnyxCache_1.default.get(key, false);
|
|
902
696
|
OnyxCache_1.default.drop(key);
|
|
903
|
-
scheduleSubscriberUpdate(key, undefined
|
|
697
|
+
scheduleSubscriberUpdate(key, undefined);
|
|
904
698
|
return storage_1.default.removeItem(key).then(() => undefined);
|
|
905
699
|
}
|
|
906
700
|
function reportStorageQuota() {
|
|
@@ -942,7 +736,6 @@ function evictStorageAndRetry(error, onyxMethod, ...args) {
|
|
|
942
736
|
* Notifies subscribers and writes current value to cache
|
|
943
737
|
*/
|
|
944
738
|
function broadcastUpdate(key, value, hasChanged) {
|
|
945
|
-
const prevValue = OnyxCache_1.default.get(key, false);
|
|
946
739
|
// Update subscribers if the cached value has changed, or when the subscriber specifically requires
|
|
947
740
|
// all updates regardless of value changes (indicated by initWithStoredValues set to false).
|
|
948
741
|
if (hasChanged) {
|
|
@@ -951,7 +744,7 @@ function broadcastUpdate(key, value, hasChanged) {
|
|
|
951
744
|
else {
|
|
952
745
|
OnyxCache_1.default.addToAccessedKeys(key);
|
|
953
746
|
}
|
|
954
|
-
return scheduleSubscriberUpdate(key, value,
|
|
747
|
+
return scheduleSubscriberUpdate(key, value, (subscriber) => hasChanged || (subscriber === null || subscriber === void 0 ? void 0 : subscriber.initWithStoredValues) === false).then(() => undefined);
|
|
955
748
|
}
|
|
956
749
|
function hasPendingMergeForKey(key) {
|
|
957
750
|
return !!mergeQueue[key];
|
|
@@ -1036,7 +829,7 @@ function initializeWithDefaultKeyStates() {
|
|
|
1036
829
|
shouldRemoveNestedNulls: true,
|
|
1037
830
|
}).result;
|
|
1038
831
|
OnyxCache_1.default.merge(merged !== null && merged !== void 0 ? merged : {});
|
|
1039
|
-
Object.entries(merged !== null && merged !== void 0 ? merged : {}).forEach(([key, value]) => keyChanged(key, value
|
|
832
|
+
Object.entries(merged !== null && merged !== void 0 ? merged : {}).forEach(([key, value]) => keyChanged(key, value));
|
|
1040
833
|
});
|
|
1041
834
|
}
|
|
1042
835
|
/**
|
|
@@ -1082,7 +875,7 @@ function subscribeToKey(connectOptions) {
|
|
|
1082
875
|
}
|
|
1083
876
|
// Commit connection only after init passes
|
|
1084
877
|
deferredInitTask.promise
|
|
1085
|
-
.then(() => addKeyToRecentlyAccessedIfNeeded(mapping))
|
|
878
|
+
.then(() => addKeyToRecentlyAccessedIfNeeded(mapping.key))
|
|
1086
879
|
.then(() => {
|
|
1087
880
|
// Performance improvement
|
|
1088
881
|
// If the mapping is connected to an onyx key that is not a collection
|
|
@@ -1114,15 +907,14 @@ function subscribeToKey(connectOptions) {
|
|
|
1114
907
|
}
|
|
1115
908
|
// If the key being connected to does not exist we initialize the value with null. For subscribers that connected
|
|
1116
909
|
// directly via connect() they will simply get a null value sent to them without any information about which key matched
|
|
1117
|
-
// since there are none matched.
|
|
1118
|
-
// component. This null value will be filtered out so that the connected component can utilize defaultProps.
|
|
910
|
+
// since there are none matched.
|
|
1119
911
|
if (matchingKeys.length === 0) {
|
|
1120
912
|
if (mapping.key) {
|
|
1121
913
|
OnyxCache_1.default.addNullishStorageKey(mapping.key);
|
|
1122
914
|
}
|
|
1123
915
|
// Here we cannot use batching because the nullish value is expected to be set immediately for default props
|
|
1124
916
|
// or they will be undefined.
|
|
1125
|
-
sendDataToConnection(mapping, null, undefined
|
|
917
|
+
sendDataToConnection(mapping, null, undefined);
|
|
1126
918
|
return;
|
|
1127
919
|
}
|
|
1128
920
|
// When using a callback subscriber we will either trigger the provided callback for each key we find or combine all values
|
|
@@ -1137,27 +929,16 @@ function subscribeToKey(connectOptions) {
|
|
|
1137
929
|
// We did not opt into using waitForCollectionCallback mode so the callback is called for every matching key.
|
|
1138
930
|
multiGet(matchingKeys).then((values) => {
|
|
1139
931
|
values.forEach((val, key) => {
|
|
1140
|
-
sendDataToConnection(mapping, val, key
|
|
932
|
+
sendDataToConnection(mapping, val, key);
|
|
1141
933
|
});
|
|
1142
934
|
});
|
|
1143
935
|
return;
|
|
1144
936
|
}
|
|
1145
937
|
// If we are not subscribed to a collection key then there's only a single key to send an update for.
|
|
1146
|
-
get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
// If we have a withOnyxInstance that means a React component has subscribed via the withOnyx() HOC and we need to
|
|
1150
|
-
// group collection key member data into an object.
|
|
1151
|
-
if (utils_1.default.hasWithOnyxInstance(mapping)) {
|
|
1152
|
-
if (isCollectionKey(mapping.key)) {
|
|
1153
|
-
getCollectionDataAndSendAsObject(matchingKeys, mapping);
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
// If the subscriber is not using a collection key then we just send a single value back to the subscriber
|
|
1157
|
-
get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key, true));
|
|
938
|
+
get(mapping.key).then((val) => sendDataToConnection(mapping, val, mapping.key));
|
|
1158
939
|
return;
|
|
1159
940
|
}
|
|
1160
|
-
console.error('Warning: Onyx.connect() was found without a callback
|
|
941
|
+
console.error('Warning: Onyx.connect() was found without a callback');
|
|
1161
942
|
});
|
|
1162
943
|
// The subscriptionID is returned back to the caller so that it can be used to clean up the connection when it's no longer needed
|
|
1163
944
|
// by calling OnyxUtils.unsubscribeFromKey(subscriptionID).
|
package/dist/index.d.ts
CHANGED
|
@@ -4,9 +4,7 @@ import type { CustomTypeOptions, KeyValueMapping, NullishDeep, OnyxCollection, O
|
|
|
4
4
|
import type { FetchStatus, ResultMetadata, UseOnyxResult, UseOnyxOptions } from './useOnyx';
|
|
5
5
|
import type { Connection } from './OnyxConnectionManager';
|
|
6
6
|
import useOnyx from './useOnyx';
|
|
7
|
-
import withOnyx from './withOnyx';
|
|
8
|
-
import type { WithOnyxState } from './withOnyx/types';
|
|
9
7
|
import type { OnyxSQLiteKeyValuePair } from './storage/providers/SQLiteProvider';
|
|
10
8
|
export default Onyx;
|
|
11
|
-
export { useOnyx
|
|
12
|
-
export type { ConnectOptions, CustomTypeOptions, FetchStatus, KeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey, OnyxInputValue, OnyxCollectionInputValue, OnyxInput, OnyxSetInput, OnyxMultiSetInput, OnyxMergeInput, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, ResultMetadata, Selector, UseOnyxResult,
|
|
9
|
+
export { useOnyx };
|
|
10
|
+
export type { ConnectOptions, CustomTypeOptions, FetchStatus, KeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey, OnyxInputValue, OnyxCollectionInputValue, OnyxInput, OnyxSetInput, OnyxMultiSetInput, OnyxMergeInput, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, ResultMetadata, Selector, UseOnyxResult, Connection, UseOnyxOptions, OnyxSQLiteKeyValuePair, };
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.useOnyx = void 0;
|
|
7
7
|
const Onyx_1 = __importDefault(require("./Onyx"));
|
|
8
8
|
const useOnyx_1 = __importDefault(require("./useOnyx"));
|
|
9
9
|
exports.useOnyx = useOnyx_1.default;
|
|
10
|
-
const withOnyx_1 = __importDefault(require("./withOnyx"));
|
|
11
|
-
exports.withOnyx = withOnyx_1.default;
|
|
12
10
|
exports.default = Onyx_1.default;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Merge } from 'type-fest';
|
|
2
2
|
import type { BuiltIns } from 'type-fest/source/internal';
|
|
3
3
|
import type OnyxUtils from './OnyxUtils';
|
|
4
|
-
import type { WithOnyxInstance, WithOnyxState } from './withOnyx/types';
|
|
5
4
|
import type { OnyxMethod } from './OnyxUtils';
|
|
6
5
|
import type { FastMergeReplaceNullPatch } from './utils';
|
|
7
6
|
/**
|
|
@@ -104,69 +103,21 @@ type OnyxKey = Key | CollectionKey;
|
|
|
104
103
|
/**
|
|
105
104
|
* Represents a selector function type which operates based on the provided `TKey` and `ReturnType`.
|
|
106
105
|
*
|
|
107
|
-
* A `Selector` is a function that accepts a value
|
|
106
|
+
* A `Selector` is a function that accepts a value and returns a processed value.
|
|
108
107
|
* This type accepts two type parameters: `TKey` and `TReturnType`.
|
|
109
108
|
*
|
|
110
109
|
* The type `TKey` extends `OnyxKey` and it is the key used to access a value in `KeyValueMapping`.
|
|
111
110
|
* `TReturnType` is the type of the returned value from the selector function.
|
|
112
111
|
*/
|
|
113
|
-
type Selector<TKey extends OnyxKey,
|
|
112
|
+
type Selector<TKey extends OnyxKey, TReturnType> = (value: OnyxEntry<KeyValueMapping[TKey]>) => TReturnType;
|
|
114
113
|
/**
|
|
115
114
|
* Represents a single Onyx entry, that can be either `TOnyxValue` or `undefined` if it doesn't exist.
|
|
116
|
-
*
|
|
117
|
-
* It can be used to specify data retrieved from Onyx e.g. `withOnyx` HOC mappings.
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```ts
|
|
121
|
-
* import Onyx, {OnyxEntry, withOnyx} from 'react-native-onyx';
|
|
122
|
-
*
|
|
123
|
-
* type OnyxProps = {
|
|
124
|
-
* userAccount: OnyxEntry<Account>;
|
|
125
|
-
* };
|
|
126
|
-
*
|
|
127
|
-
* type Props = OnyxProps & {
|
|
128
|
-
* prop1: string;
|
|
129
|
-
* };
|
|
130
|
-
*
|
|
131
|
-
* function Component({prop1, userAccount}: Props) {
|
|
132
|
-
* // ...
|
|
133
|
-
* }
|
|
134
|
-
*
|
|
135
|
-
* export default withOnyx<Props, OnyxProps>({
|
|
136
|
-
* userAccount: {
|
|
137
|
-
* key: ONYXKEYS.ACCOUNT,
|
|
138
|
-
* },
|
|
139
|
-
* })(Component);
|
|
140
|
-
* ```
|
|
115
|
+
* It can be used to specify data retrieved from Onyx.
|
|
141
116
|
*/
|
|
142
117
|
type OnyxEntry<TOnyxValue> = TOnyxValue | undefined;
|
|
143
118
|
/**
|
|
144
119
|
* Represents an Onyx collection of entries, that can be either a record of `TOnyxValue`s or `undefined` if it is empty or doesn't exist.
|
|
145
|
-
*
|
|
146
|
-
* It can be used to specify collection data retrieved from Onyx e.g. `withOnyx` HOC mappings.
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```ts
|
|
150
|
-
* import Onyx, {OnyxCollection, withOnyx} from 'react-native-onyx';
|
|
151
|
-
*
|
|
152
|
-
* type OnyxProps = {
|
|
153
|
-
* reports: OnyxCollection<Report>;
|
|
154
|
-
* };
|
|
155
|
-
*
|
|
156
|
-
* type Props = OnyxProps & {
|
|
157
|
-
* prop1: string;
|
|
158
|
-
* };
|
|
159
|
-
*
|
|
160
|
-
* function Component({prop1, reports}: Props) {
|
|
161
|
-
* // ...
|
|
162
|
-
* }
|
|
163
|
-
*
|
|
164
|
-
* export default withOnyx<Props, OnyxProps>({
|
|
165
|
-
* reports: {
|
|
166
|
-
* key: ONYXKEYS.COLLECTION.REPORT,
|
|
167
|
-
* },
|
|
168
|
-
* })(Component);
|
|
169
|
-
* ```
|
|
120
|
+
* It can be used to specify collection data retrieved from Onyx.
|
|
170
121
|
*/
|
|
171
122
|
type OnyxCollection<TOnyxValue> = OnyxEntry<Record<string, TOnyxValue | undefined>>;
|
|
172
123
|
/**
|
|
@@ -270,25 +221,7 @@ type CollectionConnectOptions<TKey extends OnyxKey> = BaseConnectOptions & {
|
|
|
270
221
|
* and will pass `value` as an `OnyxEntry`.
|
|
271
222
|
*/
|
|
272
223
|
type ConnectOptions<TKey extends OnyxKey> = DefaultConnectOptions<TKey> | CollectionConnectOptions<TKey>;
|
|
273
|
-
|
|
274
|
-
type WithOnyxConnectOptions<TKey extends OnyxKey> = ConnectOptions<TKey> & {
|
|
275
|
-
/** The `withOnyx` class instance to be internally passed. */
|
|
276
|
-
withOnyxInstance: WithOnyxInstance;
|
|
277
|
-
/** The name of the component's prop that is connected to the Onyx key. */
|
|
278
|
-
statePropertyName: string;
|
|
279
|
-
/** The component's display name. */
|
|
280
|
-
displayName: string;
|
|
281
|
-
/**
|
|
282
|
-
* This will be used to subscribe to a subset of an Onyx key's data.
|
|
283
|
-
* Using this setting on `withOnyx` can have very positive performance benefits because the component will only re-render
|
|
284
|
-
* when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
285
|
-
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
286
|
-
*/
|
|
287
|
-
selector?: Selector<TKey, unknown, unknown>;
|
|
288
|
-
/** Determines if this key in this subscription is safe to be evicted. */
|
|
289
|
-
canEvict?: boolean;
|
|
290
|
-
};
|
|
291
|
-
type Mapping<TKey extends OnyxKey> = WithOnyxConnectOptions<TKey> & {
|
|
224
|
+
type CallbackToStateMapping<TKey extends OnyxKey> = ConnectOptions<TKey> & {
|
|
292
225
|
subscriptionID: number;
|
|
293
226
|
};
|
|
294
227
|
/**
|
|
@@ -399,8 +332,6 @@ type InitOptions = {
|
|
|
399
332
|
* of Onyx running in different tabs/windows. Defaults to true for platforms that support local storage (web/desktop)
|
|
400
333
|
*/
|
|
401
334
|
shouldSyncMultipleInstances?: boolean;
|
|
402
|
-
/** Enables debugging setState() calls to connected components */
|
|
403
|
-
debugSetState?: boolean;
|
|
404
335
|
/**
|
|
405
336
|
* If enabled it will use the performance API to measure the time taken by Onyx operations.
|
|
406
337
|
* @default false
|
|
@@ -428,4 +359,4 @@ type MixedOperationsQueue = {
|
|
|
428
359
|
mergeReplaceNullPatches: MultiMergeReplaceNullPatches;
|
|
429
360
|
set: OnyxInputKeyValueMapping;
|
|
430
361
|
};
|
|
431
|
-
export type { BaseConnectOptions, Collection, CollectionConnectCallback, CollectionConnectOptions, CollectionKey, CollectionKeyBase, ConnectOptions, CustomTypeOptions, DeepRecord, DefaultConnectCallback, DefaultConnectOptions, ExtractOnyxCollectionValue, GenericFunction, InitOptions, Key, KeyValueMapping,
|
|
362
|
+
export type { BaseConnectOptions, Collection, CollectionConnectCallback, CollectionConnectOptions, CollectionKey, CollectionKeyBase, ConnectOptions, CustomTypeOptions, DeepRecord, DefaultConnectCallback, DefaultConnectOptions, ExtractOnyxCollectionValue, GenericFunction, InitOptions, Key, KeyValueMapping, CallbackToStateMapping, NonNull, NonUndefined, OnyxInputKeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey, OnyxInputValue, OnyxCollectionInputValue, OnyxInput, OnyxSetInput, OnyxMultiSetInput, OnyxMergeInput, OnyxMergeCollectionInput, OnyxMethod, OnyxMethodMap, OnyxUpdate, OnyxValue, Selector, SetOptions, MultiMergeReplaceNullPatches, MixedOperationsQueue, };
|
package/dist/useOnyx.js
CHANGED
|
@@ -152,7 +152,6 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
152
152
|
onStoreChangeFnRef.current();
|
|
153
153
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
154
154
|
}, [...dependencies]);
|
|
155
|
-
// Mimics withOnyx's checkEvictableKeys() behavior.
|
|
156
155
|
const checkEvictableKey = (0, react_1.useCallback)(() => {
|
|
157
156
|
if ((options === null || options === void 0 ? void 0 : options.canEvict) === undefined || !connectionRef.current) {
|
|
158
157
|
return;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OnyxInput, OnyxKey } from './types';
|
|
2
2
|
type EmptyObject = Record<string, never>;
|
|
3
3
|
type EmptyValue = EmptyObject | null | undefined;
|
|
4
4
|
/**
|
|
@@ -63,10 +63,6 @@ declare function pick<TValue>(obj: Record<string, TValue>, condition: string | s
|
|
|
63
63
|
* @returns The object containing only the remaining entries after omission.
|
|
64
64
|
*/
|
|
65
65
|
declare function omit<TValue>(obj: Record<string, TValue>, condition: string | string[] | ((entry: [string, TValue]) => boolean)): Record<string, TValue>;
|
|
66
|
-
/**
|
|
67
|
-
* Whether the connect options has the `withOnyxInstance` property defined, that is, it's used by the `withOnyx()` HOC.
|
|
68
|
-
*/
|
|
69
|
-
declare function hasWithOnyxInstance<TKey extends OnyxKey>(mapping: ConnectOptions<TKey>): unknown;
|
|
70
66
|
declare const _default: {
|
|
71
67
|
fastMerge: typeof fastMerge;
|
|
72
68
|
isEmptyObject: typeof isEmptyObject;
|
|
@@ -75,7 +71,6 @@ declare const _default: {
|
|
|
75
71
|
checkCompatibilityWithExistingValue: typeof checkCompatibilityWithExistingValue;
|
|
76
72
|
pick: typeof pick;
|
|
77
73
|
omit: typeof omit;
|
|
78
|
-
hasWithOnyxInstance: typeof hasWithOnyxInstance;
|
|
79
74
|
ONYX_INTERNALS__REPLACE_OBJECT_MARK: string;
|
|
80
75
|
};
|
|
81
76
|
export default _default;
|
package/dist/utils.js
CHANGED
|
@@ -204,12 +204,6 @@ function pick(obj, condition) {
|
|
|
204
204
|
function omit(obj, condition) {
|
|
205
205
|
return filterObject(obj, condition, false);
|
|
206
206
|
}
|
|
207
|
-
/**
|
|
208
|
-
* Whether the connect options has the `withOnyxInstance` property defined, that is, it's used by the `withOnyx()` HOC.
|
|
209
|
-
*/
|
|
210
|
-
function hasWithOnyxInstance(mapping) {
|
|
211
|
-
return 'withOnyxInstance' in mapping && mapping.withOnyxInstance;
|
|
212
|
-
}
|
|
213
207
|
exports.default = {
|
|
214
208
|
fastMerge,
|
|
215
209
|
isEmptyObject,
|
|
@@ -218,6 +212,5 @@ exports.default = {
|
|
|
218
212
|
checkCompatibilityWithExistingValue,
|
|
219
213
|
pick,
|
|
220
214
|
omit,
|
|
221
|
-
hasWithOnyxInstance,
|
|
222
215
|
ONYX_INTERNALS__REPLACE_OBJECT_MARK,
|
|
223
216
|
};
|