diff --git a/API-INTERNAL.md b/API-INTERNAL.md
index a31fa6135..34ec4bf37 100644
--- a/API-INTERNAL.md
+++ b/API-INTERNAL.md
@@ -20,9 +20,15 @@
getSkippableCollectionMemberIDs()
Getter - returns the skippable collection member IDs.
+getSnapshotMergeKeys()
+Getter - returns the snapshot merge keys allowlist.
+
setSkippableCollectionMemberIDs()
Setter - sets the skippable collection member IDs.
+setSnapshotMergeKeys()
+Setter - sets the snapshot merge keys allowlist.
+
initStoreValues(keys, initialKeyStates, evictableKeys)
Sets the initial values for the Onyx store
@@ -222,12 +228,24 @@ Getter - returns the deffered init task.
## getSkippableCollectionMemberIDs()
Getter - returns the skippable collection member IDs.
+**Kind**: global function
+
+
+## getSnapshotMergeKeys()
+Getter - returns the snapshot merge keys allowlist.
+
**Kind**: global function
## setSkippableCollectionMemberIDs()
Setter - sets the skippable collection member IDs.
+**Kind**: global function
+
+
+## setSnapshotMergeKeys()
+Setter - sets the snapshot merge keys allowlist.
+
**Kind**: global function
diff --git a/README.md b/README.md
index e5384e8dc..dd32a0e66 100644
--- a/README.md
+++ b/README.md
@@ -206,21 +206,6 @@ export default App;
It's also beneficial to use a [selector](https://github.com/Expensify/react-native-onyx/blob/main/API.md#connectmapping--number) with the mapping in case you need to grab a single item in a collection (like a single report action).
-### useOnyx()'s `canBeMissing` option
-
-You must pass the `canBeMissing` configuration flag to `useOnyx` if you want the hook to log an alert when data is missing from Onyx store. Regarding usage in `Expensify/App` repo, if the component calling this is the one loading the data by calling an action, then you should set this to `true`. If the component calling this does not load the data then you should set it to `false`, which means that if the data is not there, it will log an alert, as it means we are using data that no one loaded and that's most probably a bug.
-
-```javascript
-const Component = ({reportID}) => {
- // This hook will log an alert (via `Logger.logAlert()`) if `report` is `undefined`.
- const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: false});
-
- // rest of the component's code.
-};
-
-export default Component;
-```
-
## Collections
Collections allow keys with similar value types to be subscribed together by subscribing to the collection key. To define one, it must be included in the `ONYXKEYS.COLLECTION` object and it must be suffixed with an underscore. Member keys should use a unique identifier or index after the collection key prefix (e.g. `report_42`).
diff --git a/lib/OnyxSnapshotCache.ts b/lib/OnyxSnapshotCache.ts
index 0d6871c96..b277163b4 100644
--- a/lib/OnyxSnapshotCache.ts
+++ b/lib/OnyxSnapshotCache.ts
@@ -60,19 +60,17 @@ class OnyxSnapshotCache {
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
* - `allowStaleData`: Controls whether stale data can be returned during pending merges, affecting result timing
- * - `canBeMissing`: Determines logging behavior for missing data, but doesn't affect the actual data returned
*
* Other options like `canEvict`, `reuseConnection`, and `allowDynamicKey` don't affect the data transformation
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
*/
- registerConsumer(options: Pick, 'selector' | 'initWithStoredValues' | 'allowStaleData' | 'canBeMissing'>): string {
+ registerConsumer(options: Pick, 'selector' | 'initWithStoredValues' | 'allowStaleData'>): string {
const selectorID = options?.selector ? this.getSelectorID(options.selector) : 'no_selector';
// Create options hash without expensive JSON.stringify
const initWithStoredValues = options?.initWithStoredValues ?? true;
const allowStaleData = options?.allowStaleData ?? false;
- const canBeMissing = options?.canBeMissing ?? true;
- const cacheKey = `${selectorID}_${initWithStoredValues}_${allowStaleData}_${canBeMissing}`;
+ const cacheKey = `${selectorID}_${initWithStoredValues}_${allowStaleData}`;
// Increment reference count for this cache key
const currentCount = this.cacheKeyRefCounts.get(cacheKey) || 0;
diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts
index 0b28a450b..8428e27d3 100644
--- a/lib/useOnyx.ts
+++ b/lib/useOnyx.ts
@@ -9,7 +9,6 @@ import * as GlobalSettings from './GlobalSettings';
import type {CollectionKeyBase, OnyxKey, OnyxValue} from './types';
import usePrevious from './usePrevious';
import decorateWithMetrics from './metrics';
-import * as Logger from './Logger';
import onyxSnapshotCache from './OnyxSnapshotCache';
import useLiveRef from './useLiveRef';
@@ -43,14 +42,6 @@ type UseOnyxOptions = {
*/
allowDynamicKey?: boolean;
- /**
- * If the component calling this is the one loading the data by calling an action, then you should set this to `true`.
- *
- * If the component calling this does not load the data then you should set it to `false`, which means that if the data
- * is not there, it will log an alert, as it means we are using data that no one loaded and that's most probably a bug.
- */
- canBeMissing?: boolean;
-
/**
* This will be used to subscribe to a subset of an Onyx key's data.
* Using this setting on `useOnyx` can have very positive performance benefits because the component will only re-render
@@ -156,9 +147,8 @@ function useOnyx>(
selector: options?.selector,
initWithStoredValues: options?.initWithStoredValues,
allowStaleData: options?.allowStaleData,
- canBeMissing: options?.canBeMissing,
}),
- [options?.selector, options?.initWithStoredValues, options?.allowStaleData, options?.canBeMissing],
+ [options?.selector, options?.initWithStoredValues, options?.allowStaleData],
);
useEffect(() => () => onyxSnapshotCache.deregisterConsumer(key, cacheKey), [key, cacheKey]);
@@ -242,8 +232,6 @@ function useOnyx>(
}
}
- let isOnyxValueDefined = true;
-
// We return the initial result right away during the first connection if `initWithStoredValues` is set to `false`.
if (isFirstConnectionRef.current && options?.initWithStoredValues === false) {
const result = resultRef.current;
@@ -262,10 +250,6 @@ function useOnyx>(
const selectedValue = memoizedSelector ? memoizedSelector(value) : value;
newValueRef.current = (selectedValue ?? undefined) as TReturnValue | undefined;
- // This flag is `false` when the original Onyx value (without selector) is not defined yet.
- // It will be used later to check if we need to log an alert that the value is missing.
- isOnyxValueDefined = value !== null && value !== undefined;
-
// We set this flag to `false` again since we don't want to get the newest cached value every time `getSnapshot()` is executed,
// and only when `Onyx.connect()` callback is fired.
shouldGetCachedValueRef.current = false;
@@ -317,13 +301,6 @@ function useOnyx>(
sourceValue: sourceValueRef.current,
},
];
-
- // If `canBeMissing` is set to `false` and the Onyx value of that key is not defined,
- // we log an alert so it can be acknowledged by the consumer. Additionally, we won't log alerts
- // if there's a `Onyx.clear()` task in progress.
- if (options?.canBeMissing === false && newFetchStatus === 'loaded' && !isOnyxValueDefined && !OnyxCache.hasPendingTask(TASK.CLEAR)) {
- Logger.logAlert(`useOnyx returned no data for key with canBeMissing set to false for key ${key}`, {showAlert: true});
- }
}
if (newFetchStatus !== 'loading') {
@@ -331,7 +308,7 @@ function useOnyx>(
}
return resultRef.current;
- }, [options?.initWithStoredValues, options?.allowStaleData, options?.canBeMissing, key, memoizedSelector, cacheKey, previousKey]);
+ }, [options?.initWithStoredValues, options?.allowStaleData, key, memoizedSelector, cacheKey, previousKey]);
const subscribe = useCallback(
(onStoreChange: () => void) => {
diff --git a/package-lock.json b/package-lock.json
index 0b86abad8..d333c70fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -211,6 +211,7 @@
"integrity": "sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
"eslint-visitor-keys": "^2.1.0",
@@ -538,7 +539,6 @@
"integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/traverse": "^7.28.5"
@@ -556,7 +556,6 @@
"integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -573,7 +572,6 @@
"integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -590,7 +588,6 @@
"integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
@@ -609,7 +606,6 @@
"integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/traverse": "^7.28.3"
@@ -698,7 +694,6 @@
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.9.0"
},
@@ -812,7 +807,6 @@
"integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1013,7 +1007,6 @@
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
"@babel/helper-plugin-utils": "^7.18.6"
@@ -1083,7 +1076,6 @@
"integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1133,7 +1125,6 @@
"integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.28.3",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1206,7 +1197,6 @@
"integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1224,7 +1214,6 @@
"integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1241,7 +1230,6 @@
"integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1259,7 +1247,6 @@
"integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1276,7 +1263,6 @@
"integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/plugin-transform-destructuring": "^7.28.0"
@@ -1294,7 +1280,6 @@
"integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1311,7 +1296,6 @@
"integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1380,7 +1364,6 @@
"integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1429,7 +1412,6 @@
"integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1446,7 +1428,6 @@
"integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1481,7 +1462,6 @@
"integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.28.3",
"@babel/helper-plugin-utils": "^7.27.1",
@@ -1501,7 +1481,6 @@
"integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1536,7 +1515,6 @@
"integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1605,7 +1583,6 @@
"integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1",
"@babel/helper-replace-supers": "^7.27.1"
@@ -1707,7 +1684,6 @@
"integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1808,7 +1784,6 @@
"integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -1826,7 +1801,6 @@
"integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1913,7 +1887,6 @@
"integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1930,7 +1903,6 @@
"integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1967,7 +1939,6 @@
"integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.27.1"
},
@@ -1984,7 +1955,6 @@
"integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -2019,7 +1989,6 @@
"integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
"@babel/helper-plugin-utils": "^7.27.1"
@@ -2141,7 +2110,6 @@
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/types": "^7.4.4",
@@ -3457,6 +3425,7 @@
"integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.62.0",
@@ -3492,6 +3461,7 @@
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
"dev": true,
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.62.0",
"@typescript-eslint/types": "5.62.0",
@@ -4251,6 +4221,7 @@
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/linkify-it": "^5",
"@types/mdurl": "^2"
@@ -4269,6 +4240,7 @@
"integrity": "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -4401,6 +4373,7 @@
"integrity": "sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.51.0",
"@typescript-eslint/types": "8.51.0",
@@ -4932,6 +4905,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -5735,6 +5709,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001726",
"electron-to-chromium": "^1.5.173",
@@ -7351,6 +7326,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -10343,6 +10319,7 @@
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -11623,6 +11600,7 @@
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
@@ -13081,6 +13059,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -13213,6 +13192,7 @@
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"prettier": "bin-prettier.js"
},
@@ -13418,6 +13398,7 @@
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -13471,6 +13452,7 @@
"integrity": "sha512-0TUhgmlouRNf6yuDIIAdbQl0g1VsONgCMsLs7Et64hjj5VLMCA7np+4dMrZvGZ3wRNqzgeyT9oWJsUm49AcwSQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/create-cache-key-function": "^29.6.3",
"@react-native/assets-registry": "0.76.3",
@@ -13544,6 +13526,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -13671,6 +13654,7 @@
"integrity": "sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"react-is": "^18.2.0",
"react-shallow-renderer": "^16.15.0",
@@ -15472,6 +15456,7 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -15884,6 +15869,7 @@
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -16043,6 +16029,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"napi-postinstall": "^0.3.0"
},
diff --git a/tests/perf-test/OnyxSnapshotCache.perf-test.ts b/tests/perf-test/OnyxSnapshotCache.perf-test.ts
index 7c1e5ed8e..a160d6eb9 100644
--- a/tests/perf-test/OnyxSnapshotCache.perf-test.ts
+++ b/tests/perf-test/OnyxSnapshotCache.perf-test.ts
@@ -39,14 +39,12 @@ const selectorOptions: UseOnyxOptions = {
selector: simpleSelector,
initWithStoredValues: true,
allowStaleData: false,
- canBeMissing: true,
};
const complexSelectorOptions: UseOnyxOptions = {
selector: complexSelector,
initWithStoredValues: true,
allowStaleData: false,
- canBeMissing: true,
};
// Mock results
diff --git a/tests/unit/OnyxSnapshotCacheTest.ts b/tests/unit/OnyxSnapshotCacheTest.ts
index daaf5fcd4..de1ce2d89 100644
--- a/tests/unit/OnyxSnapshotCacheTest.ts
+++ b/tests/unit/OnyxSnapshotCacheTest.ts
@@ -40,12 +40,10 @@ describe('OnyxSnapshotCache', () => {
selector,
initWithStoredValues: true,
allowStaleData: false,
- canBeMissing: true,
};
const optionsWithoutSelector: UseOnyxOptions = {
initWithStoredValues: false,
allowStaleData: true,
- canBeMissing: false,
};
const keyWithSelector = cache.registerConsumer(optionsWithSelector);
const keyWithoutSelector = cache.registerConsumer(optionsWithoutSelector);
diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts
index 19fe2cd09..80176e58c 100644
--- a/tests/unit/useOnyxTest.ts
+++ b/tests/unit/useOnyxTest.ts
@@ -5,7 +5,6 @@ import OnyxCache from '../../lib/OnyxCache';
import StorageMock from '../../lib/storage';
import type GenericCollection from '../utils/GenericCollection';
import waitForPromisesToResolve from '../utils/waitForPromisesToResolve';
-import * as Logger from '../../lib/Logger';
import onyxSnapshotCache from '../../lib/OnyxSnapshotCache';
import type {UseOnyxSelector} from '../../lib/useOnyx';
@@ -1019,158 +1018,6 @@ describe('useOnyx', () => {
});
});
- describe('canBeMissing', () => {
- let logAlertFn = jest.fn();
- const alertMessage = 'useOnyx returned no data for key with canBeMissing set to false for key test';
-
- beforeEach(() => {
- logAlertFn = jest.fn();
- jest.spyOn(Logger, 'logAlert').mockImplementation(logAlertFn);
- });
-
- afterEach(() => {
- (Logger.logAlert as unknown as jest.SpyInstance>).mockRestore();
- });
-
- it('should not log an alert if Onyx doesn\'t return data in loaded state and "canBeMissing" property is not provided', async () => {
- const {result: result1} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY));
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loading');
-
- await act(async () => waitForPromisesToResolve());
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loaded');
- expect(logAlertFn).not.toBeCalled();
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, 'test'));
-
- expect(result1.current[0]).toBe('test');
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, null));
-
- expect(result1.current[0]).toBeUndefined();
- expect(logAlertFn).not.toBeCalled();
- });
-
- it('should not log an alert if Onyx doesn\'t return data, "canBeMissing" property is false but "initWithStoredValues" is also false', async () => {
- const {result: result1} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {canBeMissing: false, initWithStoredValues: false}));
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loaded');
-
- expect(logAlertFn).not.toBeCalled();
- });
-
- it('should log an alert if Onyx doesn\'t return data in loaded state and "canBeMissing" property is false', async () => {
- const {result: result1} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {canBeMissing: false}));
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loading');
- expect(logAlertFn).not.toBeCalled();
-
- await act(async () => waitForPromisesToResolve());
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loaded');
- expect(logAlertFn).toHaveBeenCalledTimes(1);
- expect(logAlertFn).toHaveBeenNthCalledWith(1, alertMessage, {showAlert: true});
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, 'test'));
-
- expect(result1.current[0]).toBe('test');
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, null));
-
- expect(result1.current[0]).toBeUndefined();
- expect(logAlertFn).toHaveBeenCalledTimes(2);
- expect(logAlertFn).toHaveBeenNthCalledWith(2, alertMessage, {showAlert: true});
- });
-
- it('should log an alert if Onyx doesn\'t return selected data in loaded state and "canBeMissing" property is false', async () => {
- const {result: result1} = renderHook(() =>
- useOnyx(ONYXKEYS.TEST_KEY, {
- selector: ((entry: OnyxEntry) => (entry ? `${entry}_changed` : undefined)) as UseOnyxSelector,
- canBeMissing: false,
- }),
- );
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loading');
- expect(logAlertFn).not.toBeCalled();
-
- await act(async () => waitForPromisesToResolve());
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loaded');
- expect(logAlertFn).toHaveBeenCalledTimes(1);
- expect(logAlertFn).toHaveBeenNthCalledWith(1, alertMessage, {showAlert: true});
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, 'test'));
-
- expect(result1.current[0]).toBe('test_changed');
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, null));
-
- expect(result1.current[0]).toBeUndefined();
- expect(logAlertFn).toHaveBeenCalledTimes(2);
- expect(logAlertFn).toHaveBeenNthCalledWith(2, alertMessage, {showAlert: true});
- });
-
- it('should log an alert if Onyx doesn\'t return data but there is a selector that always return something and "canBeMissing" property is false', async () => {
- const {result: result1} = renderHook(() =>
- useOnyx(ONYXKEYS.TEST_KEY, {
- // This selector will always return a value, even if the Onyx data is missing.
- selector: ((entry: OnyxEntry) => `${entry}_changed`) as UseOnyxSelector,
- canBeMissing: false,
- }),
- );
-
- await act(async () => waitForPromisesToResolve());
-
- expect(result1.current[0]).toBe('undefined_changed');
- expect(result1.current[1].status).toEqual('loaded');
- expect(logAlertFn).toHaveBeenCalledTimes(1);
- expect(logAlertFn).toHaveBeenNthCalledWith(1, alertMessage, {showAlert: true});
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, 'test'));
-
- expect(result1.current[0]).toBe('test_changed');
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, null));
-
- expect(result1.current[0]).toBe('undefined_changed');
- expect(logAlertFn).toHaveBeenCalledTimes(2);
- expect(logAlertFn).toHaveBeenNthCalledWith(2, alertMessage, {showAlert: true});
- });
-
- it('should not log an alert if "canBeMissing" property is false but there is a Onyx.clear() task in progress', async () => {
- const {result: result1} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {canBeMissing: false}));
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loading');
- expect(logAlertFn).not.toBeCalled();
-
- await act(async () => waitForPromisesToResolve());
-
- expect(result1.current[0]).toBeUndefined();
- expect(result1.current[1].status).toEqual('loaded');
- expect(logAlertFn).toHaveBeenCalledTimes(1);
- expect(logAlertFn).toHaveBeenNthCalledWith(1, alertMessage, {showAlert: true});
-
- await act(async () => Onyx.set(ONYXKEYS.TEST_KEY, 'test'));
-
- expect(result1.current[0]).toBe('test');
-
- logAlertFn.mockReset();
- await act(async () => Onyx.clear());
-
- expect(result1.current[0]).toBeUndefined();
- expect(logAlertFn).not.toBeCalled();
- });
- });
-
// This test suite must be the last one to avoid problems when running the other tests here.
describe('canEvict', () => {
const error = (key: string) => `canEvict can't be used on key '${key}'. This key must explicitly be flagged as safe for removal by adding it to Onyx.init({evictableKeys: []}).`;