Skip to content

Commit 659fede

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/structural-sharing-cache
2 parents ec005f6 + 29b7061 commit 659fede

File tree

10 files changed

+4910
-4213
lines changed

10 files changed

+4910
-4213
lines changed

.github/actions/javascript/validateReassureOutput/index.js

Lines changed: 4898 additions & 4137 deletions
Large diffs are not rendered by default.

.github/actions/javascript/validateReassureOutput/validateReassureOutput.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async function run() {
3232
const regressionOutput: CompareResult = JSON.parse(fs.readFileSync('.reassure/output.json', 'utf8'));
3333
const allowedDurationDeviation = Number(getInputOrEnv('ALLOWED_DURATION_DEVIATION'));
3434
const durationDeviationPercentage = Number(getInputOrEnv('ALLOWED_RELATIVE_DURATION_DEVIATION'));
35-
const isValidatingStability = Boolean(getInputOrEnv('IS_VALIDATING_STABILITY'));
35+
const isValidatingStability = getInputOrEnv('IS_VALIDATING_STABILITY') === 'true';
3636

3737
if (regressionOutput.significant === undefined || regressionOutput.significant.length === 0) {
3838
console.log('No significant data available. Exiting...');

.github/workflows/reassurePerfTests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,6 @@ jobs:
6363
id: validateReassureResults
6464
uses: ./.github/actions/javascript/validateReassureOutput
6565
with:
66-
ALLOWED_DURATION_DEVIATION: 10
67-
ALLOWED_RELATIVE_DURATION_DEVIATION: 20
66+
ALLOWED_DURATION_DEVIATION: 20
67+
ALLOWED_RELATIVE_DURATION_DEVIATION: 40
6868
IS_VALIDATING_STABILITY: false

lib/OnyxSnapshotCache.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,16 @@ class OnyxSnapshotCache {
5959
*
6060
* - `selector`: Different selectors produce different results, so each selector needs its own cache entry
6161
* - `initWithStoredValues`: This flag changes the initial loading behavior and affects the returned fetch status
62-
* - `allowStaleData`: Controls whether stale data can be returned during pending merges, affecting result timing
6362
*
6463
* Other options like `canEvict`, `reuseConnection`, and `allowDynamicKey` don't affect the data transformation
6564
* or timing behavior of getSnapshot, so they're excluded from the cache key for better cache hit rates.
6665
*/
67-
registerConsumer<TKey extends OnyxKey, TReturnValue>(options: Pick<UseOnyxOptions<TKey, TReturnValue>, 'selector' | 'initWithStoredValues' | 'allowStaleData'>): string {
66+
registerConsumer<TKey extends OnyxKey, TReturnValue>(options: Pick<UseOnyxOptions<TKey, TReturnValue>, 'selector' | 'initWithStoredValues'>): string {
6867
const selectorID = options?.selector ? this.getSelectorID(options.selector) : 'no_selector';
6968

7069
// Create options hash without expensive JSON.stringify
7170
const initWithStoredValues = options?.initWithStoredValues ?? true;
72-
const allowStaleData = options?.allowStaleData ?? false;
73-
const cacheKey = `${selectorID}_${initWithStoredValues}_${allowStaleData}`;
71+
const cacheKey = `${selectorID}_${initWithStoredValues}`;
7472

7573
// Increment reference count for this cache key
7674
const currentCount = this.cacheKeyRefCounts.get(cacheKey) || 0;

lib/useOnyx.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = {
2727
*/
2828
initWithStoredValues?: boolean;
2929

30-
/**
31-
* If set to `true`, data will be retrieved from cache during the first render even if there is a pending merge for the key.
32-
*/
33-
allowStaleData?: boolean;
34-
3530
/**
3631
* If set to `false`, the connection won't be reused between other subscribers that are listening to the same Onyx key
3732
* with the same connect configurations.
@@ -147,9 +142,8 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
147142
onyxSnapshotCache.registerConsumer({
148143
selector: options?.selector,
149144
initWithStoredValues: options?.initWithStoredValues,
150-
allowStaleData: options?.allowStaleData,
151145
}),
152-
[options?.selector, options?.initWithStoredValues, options?.allowStaleData],
146+
[options?.selector, options?.initWithStoredValues],
153147
);
154148

155149
useEffect(() => () => onyxSnapshotCache.deregisterConsumer(key, cacheKey), [key, cacheKey]);
@@ -270,8 +264,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
270264

271265
// If we have pending merge operations for the key during the first connection, we set the new value to `undefined`
272266
// and fetch status to `loading` to simulate that it is still being loaded until we have the most updated data.
273-
// If `allowStaleData` is `true` this logic will be ignored and cached value will be used, even if it's stale data.
274-
if (isFirstConnectionRef.current && OnyxUtils.hasPendingMergeForKey(key) && !options?.allowStaleData) {
267+
if (isFirstConnectionRef.current && OnyxUtils.hasPendingMergeForKey(key)) {
275268
newValueRef.current = undefined;
276269
newFetchStatus = 'loading';
277270
}
@@ -310,7 +303,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
310303
}
311304

312305
return resultRef.current;
313-
}, [options?.initWithStoredValues, options?.allowStaleData, key, memoizedSelector, cacheKey, previousKey]);
306+
}, [options?.initWithStoredValues, key, memoizedSelector, cacheKey, previousKey]);
314307

315308
const subscribe = useCallback(
316309
(onStoreChange: () => void) => {

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-onyx",
3-
"version": "3.0.43",
3+
"version": "3.0.45",
44
"author": "Expensify, Inc.",
55
"homepage": "https://expensify.com",
66
"description": "State management for React Native",

tests/perf-test/OnyxSnapshotCache.perf-test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,11 @@ const complexSelector: UseOnyxSelector<OnyxKey, ComplexSelectorResult> = (data)
3838
const selectorOptions: UseOnyxOptions<string, number | undefined> = {
3939
selector: simpleSelector,
4040
initWithStoredValues: true,
41-
allowStaleData: false,
4241
};
4342

4443
const complexSelectorOptions: UseOnyxOptions<string, ComplexSelectorResult> = {
4544
selector: complexSelector,
4645
initWithStoredValues: true,
47-
allowStaleData: false,
4846
};
4947

5048
// Mock results

tests/unit/OnyxSnapshotCacheTest.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ describe('OnyxSnapshotCache', () => {
4242
const optionsWithSelector: UseOnyxOptions<OnyxKey, string> = {
4343
selector,
4444
initWithStoredValues: true,
45-
allowStaleData: false,
4645
};
4746
const optionsWithoutSelector: UseOnyxOptions<OnyxKey, string> = {
4847
initWithStoredValues: false,
49-
allowStaleData: true,
5048
};
5149
const keyWithSelector = cache.registerConsumer(optionsWithSelector);
5250
const keyWithoutSelector = cache.registerConsumer(optionsWithoutSelector);

tests/unit/useOnyxTest.ts

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ describe('useOnyx', () => {
737737
});
738738
});
739739

740-
describe('allowStaleData', () => {
740+
describe('pending merges', () => {
741741
it('should return undefined and loading state while we have pending merges for the key, and then return updated value and loaded state', async () => {
742742
Onyx.set(ONYXKEYS.TEST_KEY, 'test1');
743743

@@ -777,24 +777,6 @@ describe('useOnyx', () => {
777777
expect(result.current[0]).toEqual('test4_changed');
778778
expect(result.current[1].status).toEqual('loaded');
779779
});
780-
781-
it('should return stale value and loaded state if allowStaleData is true, and then return updated value and loaded state', async () => {
782-
Onyx.set(ONYXKEYS.TEST_KEY, 'test1');
783-
784-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test2');
785-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test3');
786-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test4');
787-
788-
const {result} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {allowStaleData: true}));
789-
790-
expect(result.current[0]).toEqual('test1');
791-
expect(result.current[1].status).toEqual('loaded');
792-
793-
await act(async () => waitForPromisesToResolve());
794-
795-
expect(result.current[0]).toEqual('test4');
796-
expect(result.current[1].status).toEqual('loaded');
797-
});
798780
});
799781

800782
describe('initWithStoredValues', () => {
@@ -877,39 +859,6 @@ describe('useOnyx', () => {
877859
expect(result2.current[1].status).toEqual('loaded');
878860
});
879861

880-
it('"allowStaleData" should work correctly for the same key if more than one hook is using it', async () => {
881-
Onyx.set(ONYXKEYS.TEST_KEY, 'test1');
882-
883-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test2');
884-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test3');
885-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test4');
886-
887-
const {result: result1} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {allowStaleData: true}));
888-
889-
expect(result1.current[0]).toEqual('test1');
890-
expect(result1.current[1].status).toEqual('loaded');
891-
892-
await act(async () => waitForPromisesToResolve());
893-
894-
expect(result1.current[0]).toEqual('test4');
895-
expect(result1.current[1].status).toEqual('loaded');
896-
897-
// Second hook
898-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test5');
899-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test6');
900-
Onyx.merge(ONYXKEYS.TEST_KEY, 'test7');
901-
902-
const {result: result2} = renderHook(() => useOnyx(ONYXKEYS.TEST_KEY, {allowStaleData: true}));
903-
904-
expect(result2.current[0]).toEqual('test4');
905-
expect(result2.current[1].status).toEqual('loaded');
906-
907-
await act(async () => waitForPromisesToResolve());
908-
909-
expect(result2.current[0]).toEqual('test7');
910-
expect(result2.current[1].status).toEqual('loaded');
911-
});
912-
913862
it('"initWithStoredValues" should work correctly for the same key if more than one hook is using it', async () => {
914863
await StorageMock.setItem(ONYXKEYS.TEST_KEY, 'test1');
915864

0 commit comments

Comments
 (0)