react-native-onyx 3.0.47 → 3.0.49
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 +7 -1
- package/dist/OnyxSnapshotCache.d.ts +1 -1
- package/dist/OnyxSnapshotCache.js +1 -1
- package/dist/OnyxUtils.js +14 -2
- package/dist/useOnyx.d.ts +0 -4
- package/dist/useOnyx.js +0 -17
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +10 -0
- package/package.json +1 -1
package/dist/Onyx.js
CHANGED
|
@@ -221,7 +221,13 @@ function merge(key, changes) {
|
|
|
221
221
|
}
|
|
222
222
|
try {
|
|
223
223
|
const validChanges = mergeQueue[key].filter((change) => {
|
|
224
|
-
const { isCompatible, existingValueType, newValueType } = utils_1.default.checkCompatibilityWithExistingValue(change, existingValue);
|
|
224
|
+
const { isCompatible, existingValueType, newValueType, isEmptyArrayCoercion } = utils_1.default.checkCompatibilityWithExistingValue(change, existingValue);
|
|
225
|
+
if (isEmptyArrayCoercion) {
|
|
226
|
+
// Merging an object into an empty array isn't semantically correct, but we allow it
|
|
227
|
+
// in case we accidentally encoded an empty object as an empty array in PHP. If you're
|
|
228
|
+
// looking at a bugbot from this message, we're probably missing that key in OnyxKeys::KEYS_REQUIRING_EMPTY_OBJECT
|
|
229
|
+
Logger.logAlert(`[ENSURE_BUGBOT] Onyx merge called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
|
|
230
|
+
}
|
|
225
231
|
if (!isCompatible) {
|
|
226
232
|
Logger.logAlert(logMessages_1.default.incompatibleUpdateAlert(key, 'merge', existingValueType, newValueType));
|
|
227
233
|
}
|
|
@@ -40,7 +40,7 @@ declare class OnyxSnapshotCache {
|
|
|
40
40
|
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
|
|
41
41
|
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
|
|
42
42
|
*
|
|
43
|
-
* Other options like `canEvict
|
|
43
|
+
* Other options like `canEvict` and `reuseConnection` don't affect the data transformation
|
|
44
44
|
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
|
|
45
45
|
*/
|
|
46
46
|
registerConsumer<TKey extends OnyxKey, TReturnValue>(options: Pick<UseOnyxOptions<TKey, TReturnValue>, 'selector' | 'initWithStoredValues'>): string;
|
|
@@ -37,7 +37,7 @@ class OnyxSnapshotCache {
|
|
|
37
37
|
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
|
|
38
38
|
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
|
|
39
39
|
*
|
|
40
|
-
* Other options like `canEvict
|
|
40
|
+
* Other options like `canEvict` and `reuseConnection` don't affect the data transformation
|
|
41
41
|
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
|
|
42
42
|
*/
|
|
43
43
|
registerConsumer(options) {
|
package/dist/OnyxUtils.js
CHANGED
|
@@ -1111,7 +1111,13 @@ function setWithRetry({ key, value, options }, retryAttempt) {
|
|
|
1111
1111
|
return Promise.resolve();
|
|
1112
1112
|
}
|
|
1113
1113
|
// Check if the value is compatible with the existing value in the storage
|
|
1114
|
-
const { isCompatible, existingValueType, newValueType } = utils_1.default.checkCompatibilityWithExistingValue(value, existingValue);
|
|
1114
|
+
const { isCompatible, existingValueType, newValueType, isEmptyArrayCoercion } = utils_1.default.checkCompatibilityWithExistingValue(value, existingValue);
|
|
1115
|
+
if (isEmptyArrayCoercion) {
|
|
1116
|
+
// Setting an object over empty array isn't semantically correct, but we allow it
|
|
1117
|
+
// in case we accidentally encoded an empty object as an empty array in PHP. If you're
|
|
1118
|
+
// looking at a bugbot from this message, we're probably missing that key in OnyxKeys::KEYS_REQUIRING_EMPTY_OBJECT
|
|
1119
|
+
Logger.logAlert(`[ENSURE_BUGBOT] Onyx setWithRetry called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
|
|
1120
|
+
}
|
|
1115
1121
|
if (!isCompatible) {
|
|
1116
1122
|
Logger.logAlert(logMessages_1.default.incompatibleUpdateAlert(key, 'set', existingValueType, newValueType));
|
|
1117
1123
|
return Promise.resolve();
|
|
@@ -1309,7 +1315,13 @@ function mergeCollectionWithPatches({ collectionKey, collection, mergeReplaceNul
|
|
|
1309
1315
|
const existingKeys = keys.filter((key) => persistedKeys.has(key));
|
|
1310
1316
|
const cachedCollectionForExistingKeys = getCachedCollection(collectionKey, existingKeys);
|
|
1311
1317
|
const existingKeyCollection = existingKeys.reduce((obj, key) => {
|
|
1312
|
-
const { isCompatible, existingValueType, newValueType } = utils_1.default.checkCompatibilityWithExistingValue(resultCollection[key], cachedCollectionForExistingKeys[key]);
|
|
1318
|
+
const { isCompatible, existingValueType, newValueType, isEmptyArrayCoercion } = utils_1.default.checkCompatibilityWithExistingValue(resultCollection[key], cachedCollectionForExistingKeys[key]);
|
|
1319
|
+
if (isEmptyArrayCoercion) {
|
|
1320
|
+
// Merging an object into an empty array isn't semantically correct, but we allow it
|
|
1321
|
+
// in case we accidentally encoded an empty object as an empty array in PHP. If you're
|
|
1322
|
+
// looking at a bugbot from this message, we're probably missing that key in OnyxKeys::KEYS_REQUIRING_EMPTY_OBJECT
|
|
1323
|
+
Logger.logAlert(`[ENSURE_BUGBOT] Onyx mergeCollection called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
|
|
1324
|
+
}
|
|
1313
1325
|
if (!isCompatible) {
|
|
1314
1326
|
Logger.logAlert(logMessages_1.default.incompatibleUpdateAlert(key, 'mergeCollection', existingValueType, newValueType));
|
|
1315
1327
|
return obj;
|
package/dist/useOnyx.d.ts
CHANGED
|
@@ -16,10 +16,6 @@ type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = {
|
|
|
16
16
|
* with the same connect configurations.
|
|
17
17
|
*/
|
|
18
18
|
reuseConnection?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* If set to `true`, the key can be changed dynamically during the component lifecycle.
|
|
21
|
-
*/
|
|
22
|
-
allowDynamicKey?: boolean;
|
|
23
19
|
/**
|
|
24
20
|
* This will be used to subscribe to a subset of an Onyx key's data.
|
|
25
21
|
* Using this setting on `useOnyx` can have very positive performance benefits because the component will only re-render
|
package/dist/useOnyx.js
CHANGED
|
@@ -111,23 +111,6 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
111
111
|
initWithStoredValues: options === null || options === void 0 ? void 0 : options.initWithStoredValues,
|
|
112
112
|
}), [options === null || options === void 0 ? void 0 : options.selector, options === null || options === void 0 ? void 0 : options.initWithStoredValues]);
|
|
113
113
|
(0, react_1.useEffect)(() => () => OnyxSnapshotCache_1.default.deregisterConsumer(key, cacheKey), [key, cacheKey]);
|
|
114
|
-
(0, react_1.useEffect)(() => {
|
|
115
|
-
// These conditions will ensure we can only handle dynamic collection member keys from the same collection.
|
|
116
|
-
if ((options === null || options === void 0 ? void 0 : options.allowDynamicKey) || previousKey === key) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
try {
|
|
120
|
-
const previousCollectionKey = OnyxUtils_1.default.splitCollectionMemberKey(previousKey)[0];
|
|
121
|
-
const collectionKey = OnyxUtils_1.default.splitCollectionMemberKey(key)[0];
|
|
122
|
-
if (OnyxUtils_1.default.isCollectionMemberKey(previousCollectionKey, previousKey) && OnyxUtils_1.default.isCollectionMemberKey(collectionKey, key) && previousCollectionKey === collectionKey) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
catch (e) {
|
|
127
|
-
throw new Error(`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`);
|
|
128
|
-
}
|
|
129
|
-
throw new Error(`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`);
|
|
130
|
-
}, [previousKey, key, options === null || options === void 0 ? void 0 : options.allowDynamicKey]);
|
|
131
114
|
// Track previous dependencies to prevent infinite loops
|
|
132
115
|
const previousDependenciesRef = (0, react_1.useRef)([]);
|
|
133
116
|
(0, react_1.useEffect)(() => {
|
package/dist/utils.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ declare function checkCompatibilityWithExistingValue(value: unknown, existingVal
|
|
|
46
46
|
isCompatible: boolean;
|
|
47
47
|
existingValueType?: string;
|
|
48
48
|
newValueType?: string;
|
|
49
|
+
isEmptyArrayCoercion?: boolean;
|
|
49
50
|
};
|
|
50
51
|
/**
|
|
51
52
|
* Picks entries from an object based on a condition.
|
package/dist/utils.js
CHANGED
|
@@ -142,6 +142,16 @@ function checkCompatibilityWithExistingValue(value, existingValue) {
|
|
|
142
142
|
isCompatible: true,
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
|
+
// PHP's associative arrays cannot distinguish between an empty list and an
|
|
146
|
+
// empty object, so it encodes both as []. A key that should hold an
|
|
147
|
+
// object may arrive from the server as [] and be stored that way. If
|
|
148
|
+
// we then try to MERGE an object into that key, the array-vs-object type check
|
|
149
|
+
// would normally block it. Since an empty array carries no data worth
|
|
150
|
+
// preserving, we treat it as compatible with an object update and coerce it.
|
|
151
|
+
const isObjectValue = typeof value === 'object' && !Array.isArray(value);
|
|
152
|
+
if (Array.isArray(existingValue) && existingValue.length === 0 && isObjectValue) {
|
|
153
|
+
return { isCompatible: true, isEmptyArrayCoercion: true };
|
|
154
|
+
}
|
|
145
155
|
const existingValueType = Array.isArray(existingValue) ? 'array' : 'non-array';
|
|
146
156
|
const newValueType = Array.isArray(value) ? 'array' : 'non-array';
|
|
147
157
|
if (existingValueType !== newValueType) {
|