react-native-onyx 3.0.73 → 3.0.75
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/OnyxConnectionManager.js +3 -6
- package/dist/OnyxSnapshotCache.d.ts +1 -2
- package/dist/OnyxSnapshotCache.js +1 -5
- package/dist/OnyxUtils.d.ts +0 -8
- package/dist/OnyxUtils.js +4 -36
- package/dist/types.d.ts +0 -2
- package/dist/useOnyx.d.ts +0 -5
- package/dist/useOnyx.js +8 -23
- package/package.json +1 -1
|
@@ -60,21 +60,18 @@ class OnyxConnectionManager {
|
|
|
60
60
|
* according to their purpose and effect they produce in the Onyx connection.
|
|
61
61
|
*/
|
|
62
62
|
generateConnectionID(connectOptions) {
|
|
63
|
-
const { key,
|
|
63
|
+
const { key, reuseConnection, waitForCollectionCallback } = connectOptions;
|
|
64
64
|
// The current session ID is appended to the connection ID so we can have different connections
|
|
65
65
|
// after an `Onyx.clear()` operation.
|
|
66
66
|
let suffix = `,sessionID=${this.sessionID}`;
|
|
67
67
|
// We will generate a unique ID in any of the following situations:
|
|
68
68
|
// - `reuseConnection` is `false`. That means the subscriber explicitly wants the connection to not be reused.
|
|
69
|
-
// - `initWithStoredValues` is `false`. This flag changes the subscription flow when set to `false`, so the connection can't be reused.
|
|
70
69
|
// - `key` is a collection key AND `waitForCollectionCallback` is `undefined/false`. This combination needs a new connection at every subscription
|
|
71
70
|
// in order to send all the collection entries, so the connection can't be reused.
|
|
72
|
-
if (reuseConnection === false ||
|
|
73
|
-
initWithStoredValues === false ||
|
|
74
|
-
(OnyxKeys_1.default.isCollectionKey(key) && (waitForCollectionCallback === undefined || waitForCollectionCallback === false))) {
|
|
71
|
+
if (reuseConnection === false || (OnyxKeys_1.default.isCollectionKey(key) && (waitForCollectionCallback === undefined || waitForCollectionCallback === false))) {
|
|
75
72
|
suffix += `,uniqueID=${Str.guid()}`;
|
|
76
73
|
}
|
|
77
|
-
return `onyxKey=${key},
|
|
74
|
+
return `onyxKey=${key},waitForCollectionCallback=${waitForCollectionCallback !== null && waitForCollectionCallback !== void 0 ? waitForCollectionCallback : false}${suffix}`;
|
|
78
75
|
}
|
|
79
76
|
/**
|
|
80
77
|
* Fires all the subscribers callbacks associated with that connection ID.
|
|
@@ -38,12 +38,11 @@ declare class OnyxSnapshotCache {
|
|
|
38
38
|
* according to their purpose and effect they produce in the useOnyx hook behavior:
|
|
39
39
|
*
|
|
40
40
|
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
|
|
41
|
-
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
|
|
42
41
|
*
|
|
43
42
|
* Other options like `reuseConnection` don't affect the data transformation
|
|
44
43
|
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
|
|
45
44
|
*/
|
|
46
|
-
registerConsumer<TKey extends OnyxKey, TReturnValue>(options: Pick<UseOnyxOptions<TKey, TReturnValue>, 'selector'
|
|
45
|
+
registerConsumer<TKey extends OnyxKey, TReturnValue>(options: Pick<UseOnyxOptions<TKey, TReturnValue>, 'selector'>): string;
|
|
47
46
|
/**
|
|
48
47
|
* Deregister a consumer for a cache key.
|
|
49
48
|
* Decrements reference counter and removes cache entry if no consumers remain.
|
|
@@ -35,17 +35,13 @@ class OnyxSnapshotCache {
|
|
|
35
35
|
* according to their purpose and effect they produce in the useOnyx hook behavior:
|
|
36
36
|
*
|
|
37
37
|
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
|
|
38
|
-
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
|
|
39
38
|
*
|
|
40
39
|
* Other options like `reuseConnection` don't affect the data transformation
|
|
41
40
|
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
|
|
42
41
|
*/
|
|
43
42
|
registerConsumer(options) {
|
|
44
|
-
var _a;
|
|
45
43
|
const selectorID = (options === null || options === void 0 ? void 0 : options.selector) ? this.getSelectorID(options.selector) : 'no_selector';
|
|
46
|
-
|
|
47
|
-
const initWithStoredValues = (_a = options === null || options === void 0 ? void 0 : options.initWithStoredValues) !== null && _a !== void 0 ? _a : true;
|
|
48
|
-
const cacheKey = `${selectorID}_${initWithStoredValues}`;
|
|
44
|
+
const cacheKey = String(selectorID);
|
|
49
45
|
// Increment reference count for this cache key
|
|
50
46
|
const currentCount = this.cacheKeyRefCounts.get(cacheKey) || 0;
|
|
51
47
|
this.cacheKeyRefCounts.set(cacheKey, currentCount + 1);
|
package/dist/OnyxUtils.d.ts
CHANGED
|
@@ -118,9 +118,6 @@ declare function getCachedCollection<TKey extends CollectionKeyBase>(collectionK
|
|
|
118
118
|
declare function keysChanged<TKey extends CollectionKeyBase>(collectionKey: TKey, partialCollection: OnyxCollection<KeyValueMapping[TKey]>, partialPreviousCollection: OnyxCollection<KeyValueMapping[TKey]> | undefined): void;
|
|
119
119
|
/**
|
|
120
120
|
* When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
124
121
|
*/
|
|
125
122
|
declare function keyChanged<TKey extends OnyxKey>(key: TKey, value: OnyxValue<TKey>, canUpdateSubscriber?: (subscriber?: CallbackToStateMapping<OnyxKey>) => boolean, isProcessingCollectionUpdate?: boolean): void;
|
|
126
123
|
/**
|
|
@@ -257,10 +254,6 @@ declare function mergeCollectionWithPatches<TKey extends CollectionKeyBase>({ co
|
|
|
257
254
|
declare function partialSetCollection<TKey extends CollectionKeyBase>({ collectionKey, collection }: SetCollectionParams<TKey>, retryAttempt?: number): Promise<void>;
|
|
258
255
|
declare function logKeyChanged(onyxMethod: Extract<OnyxMethod, 'set' | 'merge'>, key: OnyxKey, value: unknown, hasChanged: boolean): void;
|
|
259
256
|
declare function logKeyRemoved(onyxMethod: Extract<OnyxMethod, 'set' | 'merge'>, key: OnyxKey): void;
|
|
260
|
-
/**
|
|
261
|
-
* Getter - returns the callback to state mapping, useful in test environments.
|
|
262
|
-
*/
|
|
263
|
-
declare function getCallbackToStateMapping(): Record<number, CallbackToStateMapping<OnyxKey>>;
|
|
264
257
|
/**
|
|
265
258
|
* Clear internal variables used in this file, useful in test environments.
|
|
266
259
|
*/
|
|
@@ -320,7 +313,6 @@ declare const OnyxUtils: {
|
|
|
320
313
|
setWithRetry: typeof setWithRetry;
|
|
321
314
|
multiSetWithRetry: typeof multiSetWithRetry;
|
|
322
315
|
setCollectionWithRetry: typeof setCollectionWithRetry;
|
|
323
|
-
getCallbackToStateMapping: typeof getCallbackToStateMapping;
|
|
324
316
|
};
|
|
325
317
|
export type { OnyxMethod };
|
|
326
318
|
export default OnyxUtils;
|
package/dist/OnyxUtils.js
CHANGED
|
@@ -529,9 +529,6 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
529
529
|
}
|
|
530
530
|
/**
|
|
531
531
|
* When a key change happens, search for any callbacks matching the key or collection key and trigger those callbacks
|
|
532
|
-
*
|
|
533
|
-
* @example
|
|
534
|
-
* keyChanged(key, value, subscriber => subscriber.initWithStoredValues === false)
|
|
535
532
|
*/
|
|
536
533
|
function keyChanged(key, value, canUpdateSubscriber = () => true, isProcessingCollectionUpdate = false) {
|
|
537
534
|
var _a, _b;
|
|
@@ -707,12 +704,11 @@ function retryOperation(error, onyxMethod, defaultParams, retryAttempt) {
|
|
|
707
704
|
* Notifies subscribers and writes current value to cache
|
|
708
705
|
*/
|
|
709
706
|
function broadcastUpdate(key, value, hasChanged) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (hasChanged) {
|
|
713
|
-
OnyxCache_1.default.set(key, value);
|
|
707
|
+
if (!hasChanged) {
|
|
708
|
+
return;
|
|
714
709
|
}
|
|
715
|
-
|
|
710
|
+
OnyxCache_1.default.set(key, value);
|
|
711
|
+
keyChanged(key, value);
|
|
716
712
|
}
|
|
717
713
|
function hasPendingMergeForKey(key) {
|
|
718
714
|
return !!mergeQueue[key];
|
|
@@ -886,31 +882,10 @@ function subscribeToKey(connectOptions) {
|
|
|
886
882
|
const subscriptionID = lastSubscriptionID++;
|
|
887
883
|
callbackToStateMapping[subscriptionID] = mapping;
|
|
888
884
|
callbackToStateMapping[subscriptionID].subscriptionID = subscriptionID;
|
|
889
|
-
// If the subscriber is attempting to connect to a collection member whose ID is skippable (e.g. "undefined", "null", etc.)
|
|
890
|
-
// we suppress wiring the subscription fully to avoid unnecessary callback emissions such as for "report_undefined".
|
|
891
|
-
// We still return a valid subscriptionID so callers can disconnect safely.
|
|
892
|
-
try {
|
|
893
|
-
const skippableIDs = getSkippableCollectionMemberIDs();
|
|
894
|
-
if (skippableIDs.size) {
|
|
895
|
-
const [, collectionMemberID] = OnyxKeys_1.default.splitCollectionMemberKey(mapping.key);
|
|
896
|
-
if (skippableIDs.has(collectionMemberID)) {
|
|
897
|
-
// Clean up the provisional mapping to avoid retaining unused subscribers.
|
|
898
|
-
OnyxCache_1.default.addNullishStorageKey(mapping.key);
|
|
899
|
-
delete callbackToStateMapping[subscriptionID];
|
|
900
|
-
return subscriptionID;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
catch (e) {
|
|
905
|
-
// Not a collection member key, proceed as usual.
|
|
906
|
-
}
|
|
907
885
|
// When keyChanged is called, a key is passed and the method looks through all the Subscribers in callbackToStateMapping for the matching key to get the subscriptionID
|
|
908
886
|
// to avoid having to loop through all the Subscribers all the time (even when just one connection belongs to one key),
|
|
909
887
|
// We create a mapping from key to lists of subscriptionIDs to access the specific list of subscriptionIDs.
|
|
910
888
|
storeKeyBySubscriptions(mapping.key, callbackToStateMapping[subscriptionID].subscriptionID);
|
|
911
|
-
if (mapping.initWithStoredValues === false) {
|
|
912
|
-
return subscriptionID;
|
|
913
|
-
}
|
|
914
889
|
// Commit connection only after init passes
|
|
915
890
|
deferredInitTask.promise
|
|
916
891
|
// This first .then() adds a microtask tick for compatibility reasons and
|
|
@@ -1440,12 +1415,6 @@ function logKeyChanged(onyxMethod, key, value, hasChanged) {
|
|
|
1440
1415
|
function logKeyRemoved(onyxMethod, key) {
|
|
1441
1416
|
Logger.logInfo(`${onyxMethod} called for key: ${key} => null passed, so key was removed`);
|
|
1442
1417
|
}
|
|
1443
|
-
/**
|
|
1444
|
-
* Getter - returns the callback to state mapping, useful in test environments.
|
|
1445
|
-
*/
|
|
1446
|
-
function getCallbackToStateMapping() {
|
|
1447
|
-
return callbackToStateMapping;
|
|
1448
|
-
}
|
|
1449
1418
|
/**
|
|
1450
1419
|
* Clear internal variables used in this file, useful in test environments.
|
|
1451
1420
|
*/
|
|
@@ -1504,6 +1473,5 @@ const OnyxUtils = {
|
|
|
1504
1473
|
setWithRetry,
|
|
1505
1474
|
multiSetWithRetry,
|
|
1506
1475
|
setCollectionWithRetry,
|
|
1507
|
-
getCallbackToStateMapping,
|
|
1508
1476
|
};
|
|
1509
1477
|
exports.default = OnyxUtils;
|
package/dist/types.d.ts
CHANGED
|
@@ -178,8 +178,6 @@ type NullishObjectDeep<ObjectType extends object> = {
|
|
|
178
178
|
type Collection<TKey extends CollectionKeyBase, TValue> = Record<`${TKey}${string}`, TValue>;
|
|
179
179
|
/** Represents the base options used in `Onyx.connect()` method. */
|
|
180
180
|
type BaseConnectOptions = {
|
|
181
|
-
/** If set to `false`, then the initial data will be only sent to the callback function if it changes. */
|
|
182
|
-
initWithStoredValues?: boolean;
|
|
183
181
|
/**
|
|
184
182
|
* If set to `false`, the connection won't be reused between other subscribers that are listening to the same Onyx key
|
|
185
183
|
* with the same connect configurations.
|
package/dist/useOnyx.d.ts
CHANGED
|
@@ -2,11 +2,6 @@ import type { DependencyList } from 'react';
|
|
|
2
2
|
import type { OnyxKey, OnyxValue } from './types';
|
|
3
3
|
type UseOnyxSelector<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>> = (data: OnyxValue<TKey> | undefined) => TReturnValue;
|
|
4
4
|
type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = {
|
|
5
|
-
/**
|
|
6
|
-
* If set to `false`, then no data will be prefilled into the component.
|
|
7
|
-
* @deprecated This param is going to be removed soon. Use RAM-only keys instead.
|
|
8
|
-
*/
|
|
9
|
-
initWithStoredValues?: boolean;
|
|
10
5
|
/**
|
|
11
6
|
* If set to `false`, the connection won't be reused between other subscribers that are listening to the same Onyx key
|
|
12
7
|
* with the same connect configurations.
|
package/dist/useOnyx.js
CHANGED
|
@@ -83,11 +83,10 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
83
83
|
const newValueRef = (0, react_1.useRef)(null);
|
|
84
84
|
// Stores the previously result returned by the hook, containing the data from cache and the fetch status.
|
|
85
85
|
// We initialize it to `undefined` and `loading` fetch status to simulate the initial result when the hook is loading from the cache.
|
|
86
|
-
// However, if `initWithStoredValues` is `false` we set the fetch status to `loaded` since we want to signal that data is ready.
|
|
87
86
|
const resultRef = (0, react_1.useRef)([
|
|
88
87
|
undefined,
|
|
89
88
|
{
|
|
90
|
-
status:
|
|
89
|
+
status: 'loading',
|
|
91
90
|
},
|
|
92
91
|
]);
|
|
93
92
|
// Tracks which key has completed its first Onyx connection callback. When this doesn't match the
|
|
@@ -110,8 +109,7 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
110
109
|
// Cache the options key to avoid regenerating it every getSnapshot call
|
|
111
110
|
const cacheKey = (0, react_1.useMemo)(() => OnyxSnapshotCache_1.default.registerConsumer({
|
|
112
111
|
selector: options === null || options === void 0 ? void 0 : options.selector,
|
|
113
|
-
|
|
114
|
-
}), [options === null || options === void 0 ? void 0 : options.selector, options === null || options === void 0 ? void 0 : options.initWithStoredValues]);
|
|
112
|
+
}), [options === null || options === void 0 ? void 0 : options.selector]);
|
|
115
113
|
(0, react_1.useEffect)(() => () => OnyxSnapshotCache_1.default.deregisterConsumer(key, cacheKey), [key, cacheKey]);
|
|
116
114
|
// Track previous dependencies to prevent infinite loops
|
|
117
115
|
const previousDependenciesRef = (0, react_1.useRef)([]);
|
|
@@ -141,23 +139,15 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
141
139
|
const getSnapshot = (0, react_1.useCallback)(() => {
|
|
142
140
|
var _a, _b, _c;
|
|
143
141
|
// Check if we have any cache for this Onyx key
|
|
144
|
-
// Don't use cache
|
|
145
|
-
// Also don't use cache during active data updates (when shouldGetCachedValueRef is true)
|
|
142
|
+
// Don't use cache during active data updates (when shouldGetCachedValueRef is true)
|
|
146
143
|
const isFirstConnection = connectedKeyRef.current !== key;
|
|
147
|
-
if (!
|
|
144
|
+
if (!shouldGetCachedValueRef.current) {
|
|
148
145
|
const cachedResult = OnyxSnapshotCache_1.default.getCachedResult(key, cacheKey);
|
|
149
146
|
if (cachedResult !== undefined) {
|
|
150
147
|
resultRef.current = cachedResult;
|
|
151
148
|
return cachedResult;
|
|
152
149
|
}
|
|
153
150
|
}
|
|
154
|
-
// We return the initial result right away during the first connection if `initWithStoredValues` is set to `false`.
|
|
155
|
-
if (isFirstConnection && (options === null || options === void 0 ? void 0 : options.initWithStoredValues) === false) {
|
|
156
|
-
const result = resultRef.current;
|
|
157
|
-
// Store result in snapshot cache
|
|
158
|
-
OnyxSnapshotCache_1.default.setCachedResult(key, cacheKey, result);
|
|
159
|
-
return result;
|
|
160
|
-
}
|
|
161
151
|
// We get the value from cache while the first connection to Onyx is being made or if the key has changed,
|
|
162
152
|
// so we can return any cached value right away. For the case where the key has changed, If we don't return the cached value right away, then the UI will show the incorrect (previous) value for a brief period which looks like a UI glitch to the user. After the connection is made, we only
|
|
163
153
|
// update `newValueRef` when `Onyx.connect()` callback is fired.
|
|
@@ -210,7 +200,7 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
210
200
|
OnyxSnapshotCache_1.default.setCachedResult(key, cacheKey, resultRef.current);
|
|
211
201
|
}
|
|
212
202
|
return resultRef.current;
|
|
213
|
-
}, [
|
|
203
|
+
}, [key, memoizedSelector, cacheKey]);
|
|
214
204
|
const subscribe = (0, react_1.useCallback)((onStoreChange) => {
|
|
215
205
|
// Reset internal state so the hook properly transitions through loading
|
|
216
206
|
// for the new key instead of preserving stale state from the previous one.
|
|
@@ -219,13 +209,9 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
219
209
|
previousValueRef.current = null;
|
|
220
210
|
newValueRef.current = null;
|
|
221
211
|
sourceValueRef.current = undefined;
|
|
222
|
-
resultRef.current = [undefined, { status:
|
|
212
|
+
resultRef.current = [undefined, { status: 'loading' }];
|
|
213
|
+
shouldGetCachedValueRef.current = true;
|
|
223
214
|
}
|
|
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.
|
|
228
|
-
shouldGetCachedValueRef.current = true;
|
|
229
215
|
hasMountedRef.current = true;
|
|
230
216
|
isConnectingRef.current = true;
|
|
231
217
|
onStoreChangeFnRef.current = onStoreChange;
|
|
@@ -246,7 +232,6 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
246
232
|
// Finally, we signal that the store changed, making `getSnapshot()` be called again.
|
|
247
233
|
onStoreChange();
|
|
248
234
|
},
|
|
249
|
-
initWithStoredValues: options === null || options === void 0 ? void 0 : options.initWithStoredValues,
|
|
250
235
|
waitForCollectionCallback: OnyxKeys_1.default.isCollectionKey(key),
|
|
251
236
|
reuseConnection: options === null || options === void 0 ? void 0 : options.reuseConnection,
|
|
252
237
|
});
|
|
@@ -259,7 +244,7 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
259
244
|
isConnectingRef.current = false;
|
|
260
245
|
onStoreChangeFnRef.current = null;
|
|
261
246
|
};
|
|
262
|
-
}, [key, options === null || options === void 0 ? void 0 : options.
|
|
247
|
+
}, [key, options === null || options === void 0 ? void 0 : options.reuseConnection]);
|
|
263
248
|
const result = (0, react_1.useSyncExternalStore)(subscribe, getSnapshot);
|
|
264
249
|
return result;
|
|
265
250
|
}
|