react-native-onyx 2.0.56 → 2.0.58
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 +1 -1
- package/dist/Onyx.js +84 -21
- package/dist/OnyxUtils.d.ts +18 -3
- package/dist/OnyxUtils.js +56 -11
- package/dist/types.d.ts +8 -1
- package/package.json +1 -1
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
|
|
@@ -385,26 +385,14 @@ function merge(key, changes) {
|
|
|
385
385
|
* @param collection Object collection keyed by individual collection member keys and values
|
|
386
386
|
*/
|
|
387
387
|
function mergeCollection(collectionKey, collection) {
|
|
388
|
-
if (
|
|
388
|
+
if (!OnyxUtils_1.default.isValidNonEmptyCollectionForMerge(collection)) {
|
|
389
389
|
Logger.logInfo('mergeCollection() called with invalid or empty value. Skipping this update.');
|
|
390
390
|
return Promise.resolve();
|
|
391
391
|
}
|
|
392
392
|
const mergedCollection = collection;
|
|
393
393
|
// Confirm all the collection keys belong to the same parent
|
|
394
|
-
let hasCollectionKeyCheckFailed = false;
|
|
395
394
|
const mergedCollectionKeys = Object.keys(mergedCollection);
|
|
396
|
-
|
|
397
|
-
if (OnyxUtils_1.default.isKeyMatch(collectionKey, dataKey)) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
if (process.env.NODE_ENV === 'development') {
|
|
401
|
-
throw new Error(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
402
|
-
}
|
|
403
|
-
hasCollectionKeyCheckFailed = true;
|
|
404
|
-
Logger.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
405
|
-
});
|
|
406
|
-
// Gracefully handle bad mergeCollection updates so it doesn't block the merge queue
|
|
407
|
-
if (hasCollectionKeyCheckFailed) {
|
|
395
|
+
if (!OnyxUtils_1.default.doAllCollectionItemsBelongToSameParent(collectionKey, mergedCollectionKeys)) {
|
|
408
396
|
return Promise.resolve();
|
|
409
397
|
}
|
|
410
398
|
return OnyxUtils_1.default.getAllKeys()
|
|
@@ -620,22 +608,53 @@ function update(data) {
|
|
|
620
608
|
throw new Error(`Invalid ${typeof key} key provided in Onyx update. Onyx key must be of type string.`);
|
|
621
609
|
}
|
|
622
610
|
});
|
|
611
|
+
// The queue of operations within a single `update` call in the format of <item key - list of operations updating the item>.
|
|
612
|
+
// This allows us to batch the operations per item and merge them into one operation in the order they were requested.
|
|
613
|
+
const updateQueue = {};
|
|
614
|
+
const enqueueSetOperation = (key, value) => {
|
|
615
|
+
// If a `set` operation is enqueued, we should clear the whole queue.
|
|
616
|
+
// Since the `set` operation replaces the value entirely, there's no need to perform any previous operations.
|
|
617
|
+
// To do this, we first put `null` in the queue, which removes the existing value, and then merge the new value.
|
|
618
|
+
updateQueue[key] = [null, value];
|
|
619
|
+
};
|
|
620
|
+
const enqueueMergeOperation = (key, value) => {
|
|
621
|
+
if (value === null) {
|
|
622
|
+
// If we merge `null`, the value is removed and all the previous operations are discarded.
|
|
623
|
+
updateQueue[key] = [null];
|
|
624
|
+
}
|
|
625
|
+
else if (!updateQueue[key]) {
|
|
626
|
+
updateQueue[key] = [value];
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
updateQueue[key].push(value);
|
|
630
|
+
}
|
|
631
|
+
};
|
|
623
632
|
const promises = [];
|
|
624
633
|
let clearPromise = Promise.resolve();
|
|
625
634
|
data.forEach(({ onyxMethod, key, value }) => {
|
|
626
635
|
switch (onyxMethod) {
|
|
627
636
|
case OnyxUtils_1.default.METHOD.SET:
|
|
628
|
-
|
|
637
|
+
enqueueSetOperation(key, value);
|
|
629
638
|
break;
|
|
630
639
|
case OnyxUtils_1.default.METHOD.MERGE:
|
|
631
|
-
|
|
640
|
+
enqueueMergeOperation(key, value);
|
|
632
641
|
break;
|
|
633
|
-
case OnyxUtils_1.default.METHOD.MERGE_COLLECTION:
|
|
634
|
-
|
|
635
|
-
|
|
642
|
+
case OnyxUtils_1.default.METHOD.MERGE_COLLECTION: {
|
|
643
|
+
const collection = value;
|
|
644
|
+
if (!OnyxUtils_1.default.isValidNonEmptyCollectionForMerge(collection)) {
|
|
645
|
+
Logger.logInfo('mergeCollection enqueued within update() with invalid or empty value. Skipping this operation.');
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
// Confirm all the collection keys belong to the same parent
|
|
649
|
+
const collectionKeys = Object.keys(collection);
|
|
650
|
+
if (OnyxUtils_1.default.doAllCollectionItemsBelongToSameParent(key, collectionKeys)) {
|
|
651
|
+
const mergedCollection = collection;
|
|
652
|
+
collectionKeys.forEach((collectionKey) => enqueueMergeOperation(collectionKey, mergedCollection[collectionKey]));
|
|
653
|
+
}
|
|
636
654
|
break;
|
|
655
|
+
}
|
|
637
656
|
case OnyxUtils_1.default.METHOD.MULTI_SET:
|
|
638
|
-
|
|
657
|
+
Object.entries(value).forEach(([entryKey, entryValue]) => enqueueSetOperation(entryKey, entryValue));
|
|
639
658
|
break;
|
|
640
659
|
case OnyxUtils_1.default.METHOD.CLEAR:
|
|
641
660
|
clearPromise = clear();
|
|
@@ -644,6 +663,50 @@ function update(data) {
|
|
|
644
663
|
break;
|
|
645
664
|
}
|
|
646
665
|
});
|
|
666
|
+
// Group all the collection-related keys and update each collection in a single `mergeCollection` call.
|
|
667
|
+
// This is needed to prevent multiple `mergeCollection` calls for the same collection and `merge` calls for the individual items of the said collection.
|
|
668
|
+
// This way, we ensure there is no race condition in the queued updates of the same key.
|
|
669
|
+
OnyxUtils_1.default.getCollectionKeys().forEach((collectionKey) => {
|
|
670
|
+
const collectionItemKeys = Object.keys(updateQueue).filter((key) => OnyxUtils_1.default.isKeyMatch(collectionKey, key));
|
|
671
|
+
if (collectionItemKeys.length <= 1) {
|
|
672
|
+
// If there are no items of this collection in the updateQueue, we should skip it.
|
|
673
|
+
// If there is only one item, we should update it individually, therefore retain it in the updateQueue.
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
const batchedCollectionUpdates = collectionItemKeys.reduce((queue, key) => {
|
|
677
|
+
const operations = updateQueue[key];
|
|
678
|
+
// Remove the collection-related key from the updateQueue so that it won't be processed individually.
|
|
679
|
+
delete updateQueue[key];
|
|
680
|
+
const updatedValue = OnyxUtils_1.default.applyMerge(undefined, operations, false);
|
|
681
|
+
if (operations[0] === null) {
|
|
682
|
+
// eslint-disable-next-line no-param-reassign
|
|
683
|
+
queue.set[key] = updatedValue;
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
// eslint-disable-next-line no-param-reassign
|
|
687
|
+
queue.merge[key] = updatedValue;
|
|
688
|
+
}
|
|
689
|
+
return queue;
|
|
690
|
+
}, {
|
|
691
|
+
merge: {},
|
|
692
|
+
set: {},
|
|
693
|
+
});
|
|
694
|
+
if (!utils_1.default.isEmptyObject(batchedCollectionUpdates.merge)) {
|
|
695
|
+
promises.push(() => mergeCollection(collectionKey, batchedCollectionUpdates.merge));
|
|
696
|
+
}
|
|
697
|
+
if (!utils_1.default.isEmptyObject(batchedCollectionUpdates.set)) {
|
|
698
|
+
promises.push(() => multiSet(batchedCollectionUpdates.set));
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
Object.entries(updateQueue).forEach(([key, operations]) => {
|
|
702
|
+
const batchedChanges = OnyxUtils_1.default.applyMerge(undefined, operations, false);
|
|
703
|
+
if (operations[0] === null) {
|
|
704
|
+
promises.push(() => set(key, batchedChanges));
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
promises.push(() => merge(key, batchedChanges));
|
|
708
|
+
}
|
|
709
|
+
});
|
|
647
710
|
return clearPromise
|
|
648
711
|
.then(() => Promise.all(promises.map((p) => p())))
|
|
649
712
|
.then(() => updateSnapshots(data))
|
package/dist/OnyxUtils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ValueOf } from 'type-fest';
|
|
2
2
|
import type Onyx from './Onyx';
|
|
3
|
-
import type { CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, Mapping, OnyxCollection, OnyxEntry, OnyxInput, OnyxKey, OnyxValue, WithOnyxConnectOptions } from './types';
|
|
3
|
+
import type { CollectionKey, CollectionKeyBase, DeepRecord, KeyValueMapping, Mapping, OnyxCollection, OnyxEntry, OnyxInput, OnyxKey, OnyxMergeCollectionInput, OnyxValue, WithOnyxConnectOptions } from './types';
|
|
4
4
|
declare const METHOD: {
|
|
5
5
|
readonly SET: "set";
|
|
6
6
|
readonly MERGE: "merge";
|
|
@@ -71,7 +71,11 @@ declare function deleteKeyByConnections(connectionID: number): void;
|
|
|
71
71
|
/** Returns current key names stored in persisted storage */
|
|
72
72
|
declare function getAllKeys(): Promise<Set<OnyxKey>>;
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* Returns set of all registered collection keys
|
|
75
|
+
*/
|
|
76
|
+
declare function getCollectionKeys(): Set<OnyxKey>;
|
|
77
|
+
/**
|
|
78
|
+
* Checks to see if the subscriber's supplied key
|
|
75
79
|
* is associated with a collection of keys.
|
|
76
80
|
*/
|
|
77
81
|
declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
|
|
@@ -141,7 +145,7 @@ declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey
|
|
|
141
145
|
* @example
|
|
142
146
|
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
143
147
|
*/
|
|
144
|
-
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, previousValue: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: Mapping<OnyxKey>) => boolean,
|
|
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;
|
|
145
149
|
/**
|
|
146
150
|
* Sends the data obtained from the keys to the connection. It either:
|
|
147
151
|
* - sets state on the withOnyxInstances
|
|
@@ -216,6 +220,14 @@ declare function applyMerge<TValue extends OnyxInput<OnyxKey> | undefined, TChan
|
|
|
216
220
|
* Merge user provided default key value pairs.
|
|
217
221
|
*/
|
|
218
222
|
declare function initializeWithDefaultKeyStates(): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Validate the collection is not empty and has a correct type before applying mergeCollection()
|
|
225
|
+
*/
|
|
226
|
+
declare function isValidNonEmptyCollectionForMerge<TKey extends CollectionKeyBase, TMap>(collection: OnyxMergeCollectionInput<TKey, TMap>): boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Verify if all the collection keys belong to the same parent
|
|
229
|
+
*/
|
|
230
|
+
declare function doAllCollectionItemsBelongToSameParent<TKey extends CollectionKeyBase>(collectionKey: TKey, collectionKeys: string[]): boolean;
|
|
219
231
|
declare const OnyxUtils: {
|
|
220
232
|
METHOD: {
|
|
221
233
|
readonly SET: "set";
|
|
@@ -234,6 +246,7 @@ declare const OnyxUtils: {
|
|
|
234
246
|
batchUpdates: typeof batchUpdates;
|
|
235
247
|
get: typeof get;
|
|
236
248
|
getAllKeys: typeof getAllKeys;
|
|
249
|
+
getCollectionKeys: typeof getCollectionKeys;
|
|
237
250
|
isCollectionKey: typeof isCollectionKey;
|
|
238
251
|
isCollectionMemberKey: typeof isCollectionMemberKey;
|
|
239
252
|
splitCollectionMemberKey: typeof splitCollectionMemberKey;
|
|
@@ -267,5 +280,7 @@ declare const OnyxUtils: {
|
|
|
267
280
|
deleteKeyByConnections: typeof deleteKeyByConnections;
|
|
268
281
|
getSnapshotKey: typeof getSnapshotKey;
|
|
269
282
|
multiGet: typeof multiGet;
|
|
283
|
+
isValidNonEmptyCollectionForMerge: typeof isValidNonEmptyCollectionForMerge;
|
|
284
|
+
doAllCollectionItemsBelongToSameParent: typeof doAllCollectionItemsBelongToSameParent;
|
|
270
285
|
};
|
|
271
286
|
export default OnyxUtils;
|
package/dist/OnyxUtils.js
CHANGED
|
@@ -49,10 +49,10 @@ const METHOD = {
|
|
|
49
49
|
// Key/value store of Onyx key and arrays of values to merge
|
|
50
50
|
const mergeQueue = {};
|
|
51
51
|
const mergeQueuePromise = {};
|
|
52
|
-
// Holds a mapping of all the
|
|
52
|
+
// Holds a mapping of all the React components that want their state subscribed to a store key
|
|
53
53
|
const callbackToStateMapping = {};
|
|
54
54
|
// Keeps a copy of the values of the onyx collection keys as a map for faster lookups
|
|
55
|
-
let
|
|
55
|
+
let onyxCollectionKeySet = new Set();
|
|
56
56
|
// Holds a mapping of the connected key to the connectionID for faster lookups
|
|
57
57
|
const onyxKeyToConnectionIDs = new Map();
|
|
58
58
|
// Holds a list of keys that have been directly subscribed to or recently modified from least to most recent
|
|
@@ -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;
|
|
@@ -107,10 +109,10 @@ function initStoreValues(keys, initialKeyStates, safeEvictionKeys) {
|
|
|
107
109
|
// We need the value of the collection keys later for checking if a
|
|
108
110
|
// key is a collection. We store it in a map for faster lookup.
|
|
109
111
|
const collectionValues = Object.values((_a = keys.COLLECTION) !== null && _a !== void 0 ? _a : {});
|
|
110
|
-
|
|
111
|
-
acc.
|
|
112
|
+
onyxCollectionKeySet = collectionValues.reduce((acc, val) => {
|
|
113
|
+
acc.add(val);
|
|
112
114
|
return acc;
|
|
113
|
-
}, new
|
|
115
|
+
}, new Set());
|
|
114
116
|
// Set our default key states to use when initializing and clearing Onyx data
|
|
115
117
|
defaultKeyStates = initialKeyStates;
|
|
116
118
|
DevTools_1.default.initState(initialKeyStates);
|
|
@@ -300,11 +302,17 @@ function getAllKeys() {
|
|
|
300
302
|
return OnyxCache_1.default.captureTask(taskName, promise);
|
|
301
303
|
}
|
|
302
304
|
/**
|
|
303
|
-
*
|
|
305
|
+
* Returns set of all registered collection keys
|
|
306
|
+
*/
|
|
307
|
+
function getCollectionKeys() {
|
|
308
|
+
return onyxCollectionKeySet;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Checks to see if the subscriber's supplied key
|
|
304
312
|
* is associated with a collection of keys.
|
|
305
313
|
*/
|
|
306
314
|
function isCollectionKey(key) {
|
|
307
|
-
return
|
|
315
|
+
return onyxCollectionKeySet.has(key);
|
|
308
316
|
}
|
|
309
317
|
function isCollectionMemberKey(collectionKey, key) {
|
|
310
318
|
return Str.startsWith(key, collectionKey) && key.length > collectionKey.length;
|
|
@@ -619,7 +627,7 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
619
627
|
* @example
|
|
620
628
|
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
621
629
|
*/
|
|
622
|
-
function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
|
|
630
|
+
function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true, notifyConnectSubscribers = true, notifyWithOnyxSubscribers = true) {
|
|
623
631
|
var _a, _b;
|
|
624
632
|
// Add or remove this key from the recentlyAccessedKeys lists
|
|
625
633
|
if (value !== null) {
|
|
@@ -651,7 +659,10 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
|
|
|
651
659
|
}
|
|
652
660
|
// Subscriber is a regular call to connect() and provided a callback
|
|
653
661
|
if (typeof subscriber.callback === 'function') {
|
|
654
|
-
if (!
|
|
662
|
+
if (!notifyConnectSubscribers) {
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
if (lastConnectionCallbackData.has(subscriber.connectionID) && lastConnectionCallbackData.get(subscriber.connectionID) === value) {
|
|
655
666
|
continue;
|
|
656
667
|
}
|
|
657
668
|
if (isCollectionKey(subscriber.key) && subscriber.waitForCollectionCallback) {
|
|
@@ -662,11 +673,12 @@ function keyChanged(key, value, previousValue, canUpdateSubscriber = () => true,
|
|
|
662
673
|
}
|
|
663
674
|
const subscriberCallback = subscriber.callback;
|
|
664
675
|
subscriberCallback(value, key);
|
|
676
|
+
lastConnectionCallbackData.set(subscriber.connectionID, value);
|
|
665
677
|
continue;
|
|
666
678
|
}
|
|
667
679
|
// Subscriber connected via withOnyx() HOC
|
|
668
680
|
if ('withOnyxInstance' in subscriber && subscriber.withOnyxInstance) {
|
|
669
|
-
if (!
|
|
681
|
+
if (!notifyWithOnyxSubscribers) {
|
|
670
682
|
continue;
|
|
671
683
|
}
|
|
672
684
|
const selector = subscriber.selector;
|
|
@@ -778,7 +790,14 @@ function sendDataToConnection(mapping, value, matchedKey, isBatched) {
|
|
|
778
790
|
// If we would pass undefined to setWithOnyxInstance instead, withOnyx would not set the value in the state.
|
|
779
791
|
// withOnyx will internally replace null values with undefined and never pass null values to wrapped components.
|
|
780
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.
|
|
781
|
-
|
|
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);
|
|
782
801
|
}
|
|
783
802
|
/**
|
|
784
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
|
|
@@ -955,6 +974,29 @@ function initializeWithDefaultKeyStates() {
|
|
|
955
974
|
Object.entries(merged !== null && merged !== void 0 ? merged : {}).forEach(([key, value]) => keyChanged(key, value, existingDataAsObject));
|
|
956
975
|
});
|
|
957
976
|
}
|
|
977
|
+
/**
|
|
978
|
+
* Validate the collection is not empty and has a correct type before applying mergeCollection()
|
|
979
|
+
*/
|
|
980
|
+
function isValidNonEmptyCollectionForMerge(collection) {
|
|
981
|
+
return typeof collection === 'object' && !Array.isArray(collection) && !utils_1.default.isEmptyObject(collection);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Verify if all the collection keys belong to the same parent
|
|
985
|
+
*/
|
|
986
|
+
function doAllCollectionItemsBelongToSameParent(collectionKey, collectionKeys) {
|
|
987
|
+
let hasCollectionKeyCheckFailed = false;
|
|
988
|
+
collectionKeys.forEach((dataKey) => {
|
|
989
|
+
if (OnyxUtils.isKeyMatch(collectionKey, dataKey)) {
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (process.env.NODE_ENV === 'development') {
|
|
993
|
+
throw new Error(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
994
|
+
}
|
|
995
|
+
hasCollectionKeyCheckFailed = true;
|
|
996
|
+
Logger.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
997
|
+
});
|
|
998
|
+
return !hasCollectionKeyCheckFailed;
|
|
999
|
+
}
|
|
958
1000
|
const OnyxUtils = {
|
|
959
1001
|
METHOD,
|
|
960
1002
|
getMergeQueue,
|
|
@@ -967,6 +1009,7 @@ const OnyxUtils = {
|
|
|
967
1009
|
batchUpdates,
|
|
968
1010
|
get,
|
|
969
1011
|
getAllKeys,
|
|
1012
|
+
getCollectionKeys,
|
|
970
1013
|
isCollectionKey,
|
|
971
1014
|
isCollectionMemberKey,
|
|
972
1015
|
splitCollectionMemberKey,
|
|
@@ -1000,5 +1043,7 @@ const OnyxUtils = {
|
|
|
1000
1043
|
deleteKeyByConnections,
|
|
1001
1044
|
getSnapshotKey,
|
|
1002
1045
|
multiGet,
|
|
1046
|
+
isValidNonEmptyCollectionForMerge,
|
|
1047
|
+
doAllCollectionItemsBelongToSameParent,
|
|
1003
1048
|
};
|
|
1004
1049
|
exports.default = OnyxUtils;
|
package/dist/types.d.ts
CHANGED
|
@@ -365,4 +365,11 @@ type InitOptions = {
|
|
|
365
365
|
debugSetState?: boolean;
|
|
366
366
|
};
|
|
367
367
|
type GenericFunction = (...args: any[]) => any;
|
|
368
|
-
|
|
368
|
+
/**
|
|
369
|
+
* Represents a combination of Merge and Set operations that should be executed in Onyx
|
|
370
|
+
*/
|
|
371
|
+
type MixedOperationsQueue = {
|
|
372
|
+
merge: OnyxInputKeyValueMapping;
|
|
373
|
+
set: OnyxInputKeyValueMapping;
|
|
374
|
+
};
|
|
375
|
+
export type { BaseConnectOptions, Collection, CollectionConnectCallback, CollectionConnectOptions, CollectionKey, CollectionKeyBase, ConnectOptions, CustomTypeOptions, DeepRecord, DefaultConnectCallback, DefaultConnectOptions, ExtractOnyxCollectionValue, GenericFunction, InitOptions, Key, KeyValueMapping, Mapping, NonNull, NonUndefined, OnyxInputKeyValueMapping, NullishDeep, OnyxCollection, OnyxEntry, OnyxKey, OnyxInputValue, OnyxCollectionInputValue, OnyxInput, OnyxSetInput, OnyxMultiSetInput, OnyxMergeInput, OnyxMergeCollectionInput, OnyxUpdate, OnyxValue, Selector, WithOnyxConnectOptions, MixedOperationsQueue, };
|