react-native-onyx 3.0.21 → 3.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/dist/Onyx.js +5 -1
- package/dist/OnyxUtils.d.ts +7 -0
- package/dist/OnyxUtils.js +23 -96
- package/package.json +1 -1
package/dist/Onyx.js
CHANGED
|
@@ -60,7 +60,11 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
|
|
|
60
60
|
if (shouldSyncMultipleInstances) {
|
|
61
61
|
(_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
|
|
62
62
|
OnyxCache_1.default.set(key, value);
|
|
63
|
-
|
|
63
|
+
// Check if this is a collection member key to prevent duplicate callbacks
|
|
64
|
+
// When a collection is updated, individual members sync separately to other tabs
|
|
65
|
+
// Setting isProcessingCollectionUpdate=true prevents triggering collection callbacks for each individual update
|
|
66
|
+
const isKeyCollectionMember = OnyxUtils_1.default.isCollectionMember(key);
|
|
67
|
+
OnyxUtils_1.default.keyChanged(key, value, undefined, true, isKeyCollectionMember);
|
|
64
68
|
});
|
|
65
69
|
}
|
|
66
70
|
if (maxCachedKeysCount > 0) {
|
package/dist/OnyxUtils.d.ts
CHANGED
|
@@ -107,6 +107,12 @@ declare function getCollectionKeys(): Set<OnyxKey>;
|
|
|
107
107
|
*/
|
|
108
108
|
declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
|
|
109
109
|
declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string): key is `${TCollectionKey}${string}`;
|
|
110
|
+
/**
|
|
111
|
+
* Checks if a given key is a collection member key (not just a collection key).
|
|
112
|
+
* @param key - The key to check
|
|
113
|
+
* @returns true if the key is a collection member, false otherwise
|
|
114
|
+
*/
|
|
115
|
+
declare function isCollectionMember(key: OnyxKey): boolean;
|
|
110
116
|
/**
|
|
111
117
|
* Splits a collection member key into the collection key part and the ID part.
|
|
112
118
|
* @param key - The collection member key to split.
|
|
@@ -328,6 +334,7 @@ declare const OnyxUtils: {
|
|
|
328
334
|
getCollectionKeys: typeof getCollectionKeys;
|
|
329
335
|
isCollectionKey: typeof isCollectionKey;
|
|
330
336
|
isCollectionMemberKey: typeof isCollectionMemberKey;
|
|
337
|
+
isCollectionMember: typeof isCollectionMember;
|
|
331
338
|
splitCollectionMemberKey: typeof splitCollectionMemberKey;
|
|
332
339
|
isKeyMatch: typeof isKeyMatch;
|
|
333
340
|
tryGetCachedValue: typeof tryGetCachedValue;
|
package/dist/OnyxUtils.js
CHANGED
|
@@ -391,6 +391,22 @@ function isCollectionKey(key) {
|
|
|
391
391
|
function isCollectionMemberKey(collectionKey, key) {
|
|
392
392
|
return key.startsWith(collectionKey) && key.length > collectionKey.length;
|
|
393
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Checks if a given key is a collection member key (not just a collection key).
|
|
396
|
+
* @param key - The key to check
|
|
397
|
+
* @returns true if the key is a collection member, false otherwise
|
|
398
|
+
*/
|
|
399
|
+
function isCollectionMember(key) {
|
|
400
|
+
try {
|
|
401
|
+
const collectionKey = getCollectionKey(key);
|
|
402
|
+
// If the key is longer than the collection key, it's a collection member
|
|
403
|
+
return key.length > collectionKey.length;
|
|
404
|
+
}
|
|
405
|
+
catch (e) {
|
|
406
|
+
// If getCollectionKey throws, the key is not a collection member
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
394
410
|
/**
|
|
395
411
|
* Splits a collection member key into the collection key part and the ID part.
|
|
396
412
|
* @param key - The collection member key to split.
|
|
@@ -465,81 +481,6 @@ function tryGetCachedValue(key) {
|
|
|
465
481
|
}
|
|
466
482
|
return val;
|
|
467
483
|
}
|
|
468
|
-
/**
|
|
469
|
-
* Marks items that existed in previousCollection but not in preservedCollection as null.
|
|
470
|
-
* This ensures subscribers are properly notified about item removals.
|
|
471
|
-
* @param preservedCollection - The collection to mark removed items in (mutated in place)
|
|
472
|
-
* @param previousCollection - The previous collection state to compare against
|
|
473
|
-
*/
|
|
474
|
-
function markRemovedItemsAsNull(preservedCollection, previousCollection) {
|
|
475
|
-
if (!previousCollection) {
|
|
476
|
-
return preservedCollection;
|
|
477
|
-
}
|
|
478
|
-
const mutablePreservedCollection = Object.assign({}, preservedCollection);
|
|
479
|
-
Object.keys(previousCollection).forEach((key) => {
|
|
480
|
-
if (key in preservedCollection) {
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
mutablePreservedCollection[key] = null;
|
|
484
|
-
});
|
|
485
|
-
return mutablePreservedCollection;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* Utility function to preserve object references for unchanged items in collection operations.
|
|
489
|
-
* Compares new values with cached values using deep equality and preserves references when data is identical.
|
|
490
|
-
* @param keyValuePairs - Array of key-value pairs to process
|
|
491
|
-
* @param previousCollection - Optional previous collection state. If provided, removed items will be included as null
|
|
492
|
-
* @returns The preserved collection with unchanged references maintained and removed items marked as null
|
|
493
|
-
*/
|
|
494
|
-
function preserveCollectionReferences(keyValuePairs, previousCollection) {
|
|
495
|
-
const preservedCollection = {};
|
|
496
|
-
keyValuePairs.forEach(([key, value]) => {
|
|
497
|
-
const cachedValue = OnyxCache_1.default.get(key, false);
|
|
498
|
-
// If no cached value exists, we need to add the new value (skip expensive deep equality check)
|
|
499
|
-
// Use deep equality check to preserve references for unchanged items
|
|
500
|
-
if (cachedValue !== undefined && (0, fast_equals_1.deepEqual)(value, cachedValue)) {
|
|
501
|
-
// Keep the existing reference
|
|
502
|
-
preservedCollection[key] = cachedValue;
|
|
503
|
-
}
|
|
504
|
-
else {
|
|
505
|
-
// Update cache only for changed items
|
|
506
|
-
OnyxCache_1.default.set(key, value);
|
|
507
|
-
preservedCollection[key] = value;
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
if (previousCollection) {
|
|
511
|
-
return markRemovedItemsAsNull(preservedCollection, previousCollection);
|
|
512
|
-
}
|
|
513
|
-
return preservedCollection;
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Utility function for merge operations that preserves references after cache merge has been performed.
|
|
517
|
-
* Compares merged values with original cached values and preserves references when data is unchanged.
|
|
518
|
-
* @param collection - Collection of merged data
|
|
519
|
-
* @param originalCachedValues - Original cached values before merge
|
|
520
|
-
* @param previousCollection - Optional previous collection state. If provided, removed items will be included as null
|
|
521
|
-
* @returns The preserved collection with unchanged references maintained and removed items marked as null
|
|
522
|
-
*/
|
|
523
|
-
function preserveCollectionReferencesAfterMerge(collection, originalCachedValues, previousCollection) {
|
|
524
|
-
const preservedCollection = {};
|
|
525
|
-
Object.keys(collection).forEach((key) => {
|
|
526
|
-
const newMergedValue = OnyxCache_1.default.get(key, false);
|
|
527
|
-
const originalValue = originalCachedValues[key];
|
|
528
|
-
// Use deep equality check to preserve references for unchanged items
|
|
529
|
-
if (originalValue !== undefined && (0, fast_equals_1.deepEqual)(newMergedValue, originalValue)) {
|
|
530
|
-
// Keep the existing reference and update cache
|
|
531
|
-
preservedCollection[key] = originalValue;
|
|
532
|
-
OnyxCache_1.default.set(key, originalValue);
|
|
533
|
-
}
|
|
534
|
-
else {
|
|
535
|
-
preservedCollection[key] = newMergedValue;
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
if (previousCollection) {
|
|
539
|
-
return markRemovedItemsAsNull(preservedCollection, previousCollection);
|
|
540
|
-
}
|
|
541
|
-
return preservedCollection;
|
|
542
|
-
}
|
|
543
484
|
function getCachedCollection(collectionKey, collectionMemberKeys) {
|
|
544
485
|
// Use optimized collection data retrieval when cache is populated
|
|
545
486
|
const collectionData = OnyxCache_1.default.getCollectionData(collectionKey);
|
|
@@ -1270,9 +1211,8 @@ function setCollectionWithRetry({ collectionKey, collection }, retryAttempt) {
|
|
|
1270
1211
|
});
|
|
1271
1212
|
const keyValuePairs = OnyxUtils.prepareKeyValuePairsForStorage(mutableCollection, true, undefined, true);
|
|
1272
1213
|
const previousCollection = OnyxUtils.getCachedCollection(collectionKey);
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1275
|
-
const updatePromise = OnyxUtils.scheduleNotifyCollectionSubscribers(collectionKey, preservedCollection, previousCollection);
|
|
1214
|
+
keyValuePairs.forEach(([key, value]) => OnyxCache_1.default.set(key, value));
|
|
1215
|
+
const updatePromise = OnyxUtils.scheduleNotifyCollectionSubscribers(collectionKey, mutableCollection, previousCollection);
|
|
1276
1216
|
return storage_1.default.multiSet(keyValuePairs)
|
|
1277
1217
|
.catch((error) => OnyxUtils.retryOperation(error, setCollectionWithRetry, { collectionKey, collection }, retryAttempt))
|
|
1278
1218
|
.then(() => {
|
|
@@ -1324,8 +1264,6 @@ function mergeCollectionWithPatches({ collectionKey, collection, mergeReplaceNul
|
|
|
1324
1264
|
resultCollectionKeys = Object.keys(resultCollection);
|
|
1325
1265
|
return getAllKeys()
|
|
1326
1266
|
.then((persistedKeys) => {
|
|
1327
|
-
// Capture keys that will be removed (before calling remove())
|
|
1328
|
-
const keysToRemove = resultCollectionKeys.filter((key) => resultCollection[key] === null && persistedKeys.has(key));
|
|
1329
1267
|
// Split to keys that exist in storage and keys that don't
|
|
1330
1268
|
const keys = resultCollectionKeys.filter((key) => {
|
|
1331
1269
|
if (resultCollection[key] === null) {
|
|
@@ -1335,8 +1273,6 @@ function mergeCollectionWithPatches({ collectionKey, collection, mergeReplaceNul
|
|
|
1335
1273
|
return true;
|
|
1336
1274
|
});
|
|
1337
1275
|
const existingKeys = keys.filter((key) => persistedKeys.has(key));
|
|
1338
|
-
// Get previous values for both existing keys and keys that will be removed
|
|
1339
|
-
const allAffectedKeys = [...existingKeys, ...keysToRemove];
|
|
1340
1276
|
const cachedCollectionForExistingKeys = getCachedCollection(collectionKey, existingKeys);
|
|
1341
1277
|
const existingKeyCollection = existingKeys.reduce((obj, key) => {
|
|
1342
1278
|
const { isCompatible, existingValueType, newValueType } = utils_1.default.checkCompatibilityWithExistingValue(resultCollection[key], cachedCollectionForExistingKeys[key]);
|
|
@@ -1365,8 +1301,7 @@ function mergeCollectionWithPatches({ collectionKey, collection, mergeReplaceNul
|
|
|
1365
1301
|
const promises = [];
|
|
1366
1302
|
// We need to get the previously existing values so we can compare the new ones
|
|
1367
1303
|
// against them, to avoid unnecessary subscriber updates.
|
|
1368
|
-
|
|
1369
|
-
const previousCollectionPromise = Promise.all(allAffectedKeys.map((key) => get(key).then((value) => [key, value]))).then(Object.fromEntries);
|
|
1304
|
+
const previousCollectionPromise = Promise.all(existingKeys.map((key) => get(key).then((value) => [key, value]))).then(Object.fromEntries);
|
|
1370
1305
|
// New keys will be added via multiSet while existing keys will be updated using multiMerge
|
|
1371
1306
|
// This is because setting a key that doesn't exist yet with multiMerge will throw errors
|
|
1372
1307
|
if (keyValuePairsForExistingCollection.length > 0) {
|
|
@@ -1380,16 +1315,8 @@ function mergeCollectionWithPatches({ collectionKey, collection, mergeReplaceNul
|
|
|
1380
1315
|
// Prefill cache if necessary by calling get() on any existing keys and then merge original data to cache
|
|
1381
1316
|
// and update all subscribers
|
|
1382
1317
|
const promiseUpdate = previousCollectionPromise.then((previousCollection) => {
|
|
1383
|
-
// Capture the original cached values before merging
|
|
1384
|
-
const originalCachedValues = {};
|
|
1385
|
-
Object.keys(finalMergedCollection).forEach((key) => {
|
|
1386
|
-
originalCachedValues[key] = OnyxCache_1.default.get(key, false);
|
|
1387
|
-
});
|
|
1388
|
-
// Then merge all the data into cache as normal
|
|
1389
1318
|
OnyxCache_1.default.merge(finalMergedCollection);
|
|
1390
|
-
|
|
1391
|
-
const preservedCollection = preserveCollectionReferencesAfterMerge(finalMergedCollection, originalCachedValues, previousCollection);
|
|
1392
|
-
return scheduleNotifyCollectionSubscribers(collectionKey, preservedCollection, previousCollection);
|
|
1319
|
+
return scheduleNotifyCollectionSubscribers(collectionKey, finalMergedCollection, previousCollection);
|
|
1393
1320
|
});
|
|
1394
1321
|
return Promise.all(promises)
|
|
1395
1322
|
.catch((error) => retryOperation(error, mergeCollectionWithPatches, { collectionKey, collection: resultCollection, mergeReplaceNullPatches, isProcessingCollectionUpdate }, retryAttempt))
|
|
@@ -1440,9 +1367,8 @@ function partialSetCollection({ collectionKey, collection }, retryAttempt) {
|
|
|
1440
1367
|
const existingKeys = resultCollectionKeys.filter((key) => persistedKeys.has(key));
|
|
1441
1368
|
const previousCollection = getCachedCollection(collectionKey, existingKeys);
|
|
1442
1369
|
const keyValuePairs = prepareKeyValuePairsForStorage(mutableCollection, true, undefined, true);
|
|
1443
|
-
|
|
1444
|
-
const
|
|
1445
|
-
const updatePromise = scheduleNotifyCollectionSubscribers(collectionKey, preservedCollection, previousCollection);
|
|
1370
|
+
keyValuePairs.forEach(([key, value]) => OnyxCache_1.default.set(key, value));
|
|
1371
|
+
const updatePromise = scheduleNotifyCollectionSubscribers(collectionKey, mutableCollection, previousCollection);
|
|
1446
1372
|
return storage_1.default.multiSet(keyValuePairs)
|
|
1447
1373
|
.catch((error) => retryOperation(error, partialSetCollection, { collectionKey, collection }, retryAttempt))
|
|
1448
1374
|
.then(() => {
|
|
@@ -1483,6 +1409,7 @@ const OnyxUtils = {
|
|
|
1483
1409
|
getCollectionKeys,
|
|
1484
1410
|
isCollectionKey,
|
|
1485
1411
|
isCollectionMemberKey,
|
|
1412
|
+
isCollectionMember,
|
|
1486
1413
|
splitCollectionMemberKey,
|
|
1487
1414
|
isKeyMatch,
|
|
1488
1415
|
tryGetCachedValue,
|