react-native-onyx 3.0.70 → 3.0.72
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/OnyxUtils.js +51 -5
- package/dist/useOnyx.js +15 -4
- package/package.json +1 -1
package/dist/OnyxUtils.js
CHANGED
|
@@ -454,6 +454,16 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
454
454
|
const cachedCollection = getCachedCollection(collectionKey);
|
|
455
455
|
const previousCollection = partialPreviousCollection !== null && partialPreviousCollection !== void 0 ? partialPreviousCollection : {};
|
|
456
456
|
const changedMemberKeys = Object.keys(partialCollection !== null && partialCollection !== void 0 ? partialCollection : {});
|
|
457
|
+
// Add or remove the keys from the recentlyAccessedKeys list
|
|
458
|
+
for (const memberKey of changedMemberKeys) {
|
|
459
|
+
const value = partialCollection === null || partialCollection === void 0 ? void 0 : partialCollection[memberKey];
|
|
460
|
+
if (value !== null && value !== undefined) {
|
|
461
|
+
OnyxCache_1.default.addLastAccessedKey(memberKey, false);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
OnyxCache_1.default.removeLastAccessedKey(memberKey);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
457
467
|
// Use indexed lookup instead of scanning all subscribers.
|
|
458
468
|
// We need subscribers for: (1) the collection key itself, and (2) individual changed member keys.
|
|
459
469
|
const collectionSubscriberIDs = (_a = onyxKeyToSubscriptionIDs.get(collectionKey)) !== null && _a !== void 0 ? _a : [];
|
|
@@ -478,12 +488,20 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
478
488
|
subscriber.callback(cachedCollection, subscriber.key, partialCollection);
|
|
479
489
|
continue;
|
|
480
490
|
}
|
|
481
|
-
// Not using waitForCollectionCallback — notify per changed key
|
|
491
|
+
// Not using waitForCollectionCallback — notify per changed key.
|
|
492
|
+
// Re-check the subscription on each iteration because the callback may
|
|
493
|
+
// synchronously disconnect itself (removing it from callbackToStateMapping),
|
|
494
|
+
// in which case we must stop firing further callbacks for this subscriber.
|
|
482
495
|
for (const dataKey of changedMemberKeys) {
|
|
496
|
+
const currentSubscriber = callbackToStateMapping[subID];
|
|
497
|
+
if (!currentSubscriber || typeof currentSubscriber.callback !== 'function') {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
483
500
|
if (cachedCollection[dataKey] === previousCollection[dataKey]) {
|
|
484
501
|
continue;
|
|
485
502
|
}
|
|
486
|
-
|
|
503
|
+
const currentSubscriberCallback = currentSubscriber.callback;
|
|
504
|
+
currentSubscriberCallback(cachedCollection[dataKey], dataKey);
|
|
487
505
|
}
|
|
488
506
|
}
|
|
489
507
|
catch (error) {
|
|
@@ -1135,15 +1153,43 @@ function multiSetWithRetry(data, retryAttempt) {
|
|
|
1135
1153
|
}, {});
|
|
1136
1154
|
}
|
|
1137
1155
|
const keyValuePairsToSet = OnyxUtils.prepareKeyValuePairsForStorage(newData, true);
|
|
1156
|
+
// Group collection members by their parent collection key so each collection can be notified
|
|
1157
|
+
// via a single batched keysChanged() call instead of one keyChanged() per member. For each
|
|
1158
|
+
// collection, `partial` holds the new values being set and `previous` holds the cached values
|
|
1159
|
+
// from before the set, which keysChanged() uses to skip subscribers whose value didn't change.
|
|
1160
|
+
const collectionBatches = new Map();
|
|
1138
1161
|
for (const [key, value] of keyValuePairsToSet) {
|
|
1139
1162
|
// When we use multiSet to set a key we want to clear the current delta changes from Onyx.merge that were queued
|
|
1140
1163
|
// before the value was set. If Onyx.merge is currently reading the old value from storage, it will then not apply the changes.
|
|
1141
1164
|
if (OnyxUtils.hasPendingMergeForKey(key)) {
|
|
1142
1165
|
delete OnyxUtils.getMergeQueue()[key];
|
|
1143
1166
|
}
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1167
|
+
const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
|
|
1168
|
+
if (collectionKey && OnyxKeys_1.default.isCollectionMemberKey(collectionKey, key)) {
|
|
1169
|
+
// Capture the previous cached value BEFORE calling cache.set() so keysChanged()
|
|
1170
|
+
// can diff old vs new per-member.
|
|
1171
|
+
const previousValue = OnyxCache_1.default.get(key);
|
|
1172
|
+
OnyxCache_1.default.set(key, value);
|
|
1173
|
+
let batch = collectionBatches.get(collectionKey);
|
|
1174
|
+
if (!batch) {
|
|
1175
|
+
batch = { partial: {}, previous: {} };
|
|
1176
|
+
collectionBatches.set(collectionKey, batch);
|
|
1177
|
+
}
|
|
1178
|
+
batch.partial[key] = value;
|
|
1179
|
+
batch.previous[key] = previousValue;
|
|
1180
|
+
}
|
|
1181
|
+
else {
|
|
1182
|
+
// Non-collection keys are notified inline (cache.set + keyChanged in iteration order)
|
|
1183
|
+
// so re-entrant callbacks (e.g. Onyx.set inside a callback) see consistent cache
|
|
1184
|
+
// and subscriber state, matching the original per-key notification semantics.
|
|
1185
|
+
OnyxCache_1.default.set(key, value);
|
|
1186
|
+
keyChanged(key, value);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
// One keysChanged() per collection — fires each collection-level subscriber once and lets
|
|
1190
|
+
// keysChanged() internally decide which individual member subscribers need notification.
|
|
1191
|
+
for (const [collectionKey, batch] of collectionBatches) {
|
|
1192
|
+
keysChanged(collectionKey, batch.partial, batch.previous);
|
|
1147
1193
|
}
|
|
1148
1194
|
const keyValuePairsToStore = keyValuePairsToSet.filter((keyValuePair) => {
|
|
1149
1195
|
const [key] = keyValuePair;
|
package/dist/useOnyx.js
CHANGED
|
@@ -96,6 +96,9 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
96
96
|
// after cleanup), so the hook automatically enters first-connection mode for the new key without any
|
|
97
97
|
// explicit reset logic — eliminating the race condition where cleanup could clobber a boolean flag.
|
|
98
98
|
const connectedKeyRef = (0, react_1.useRef)(null);
|
|
99
|
+
// Tracks whether the hook has completed its initial mount subscription.
|
|
100
|
+
// Unlike connectedKeyRef (which gets nulled by cleanup), this persists across re-subscriptions.
|
|
101
|
+
const hasMountedRef = (0, react_1.useRef)(false);
|
|
99
102
|
// Indicates if the hook is connecting to an Onyx key.
|
|
100
103
|
const isConnectingRef = (0, react_1.useRef)(false);
|
|
101
104
|
// Stores the `onStoreChange()` function, which can be used to trigger a `getSnapshot()` update when desired.
|
|
@@ -211,11 +214,19 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
211
214
|
const subscribe = (0, react_1.useCallback)((onStoreChange) => {
|
|
212
215
|
// Reset internal state so the hook properly transitions through loading
|
|
213
216
|
// for the new key instead of preserving stale state from the previous one.
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
// Only reset when the key has actually changed (not on initial mount).
|
|
218
|
+
if (hasMountedRef.current) {
|
|
219
|
+
previousValueRef.current = null;
|
|
220
|
+
newValueRef.current = null;
|
|
221
|
+
sourceValueRef.current = undefined;
|
|
222
|
+
resultRef.current = [undefined, { status: (options === null || options === void 0 ? void 0 : options.initWithStoredValues) === false ? 'loaded' : 'loading' }];
|
|
223
|
+
}
|
|
224
|
+
// Force a cache re-read on every (re)subscription so any side effects from
|
|
225
|
+
// subscribeToKey (e.g. addNullishStorageKey for skippable collection member ids)
|
|
226
|
+
// are reflected in the next getSnapshot. Resetting this flag does not change
|
|
227
|
+
// resultRef by itself, so it doesn't cause an extra mount render.
|
|
216
228
|
shouldGetCachedValueRef.current = true;
|
|
217
|
-
|
|
218
|
-
resultRef.current = [undefined, { status: (options === null || options === void 0 ? void 0 : options.initWithStoredValues) === false ? 'loaded' : 'loading' }];
|
|
229
|
+
hasMountedRef.current = true;
|
|
219
230
|
isConnectingRef.current = true;
|
|
220
231
|
onStoreChangeFnRef.current = onStoreChange;
|
|
221
232
|
connectionRef.current = OnyxConnectionManager_1.default.connect({
|