Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
aeb9457
add RAM-only key support, store in cache
JKobrynski Jan 26, 2026
d89ec4f
add RAM-only support to multiSetWithRetry method
JKobrynski Jan 27, 2026
d91820a
add RAM-only support to merge method
JKobrynski Jan 27, 2026
ab3dd88
add RAM-only support to clear method
JKobrynski Jan 28, 2026
d4e975e
add ramOnlyKeys parameter to the init function, remove RAM-only logic…
JKobrynski Jan 28, 2026
4889a47
add RAM-only support to the clear method
JKobrynski Jan 28, 2026
17ecd78
add RAM-only support to methods that use Storage.multiSet
JKobrynski Jan 28, 2026
3ff81f7
add RAM-only support to methods that use Storage.multiMerge
JKobrynski Jan 28, 2026
df07112
send RAM-only set actions to dev tools
JKobrynski Jan 28, 2026
3296a6f
add RAM-only support to setWithRetry for collection child keys
JKobrynski Jan 28, 2026
30fd1f3
add RAM-only support to multiSetWithRetry for collection members
JKobrynski Jan 29, 2026
ddfc694
cleanup the code
JKobrynski Jan 29, 2026
a492c41
update the docs
JKobrynski Jan 29, 2026
aa5f13b
add unit tests to newly added logic
JKobrynski Jan 30, 2026
091bf1b
address review comments
JKobrynski Jan 30, 2026
3b25980
prettier
JKobrynski Jan 30, 2026
61b21fb
address review comments
JKobrynski Feb 2, 2026
2edcd51
apply feedback
JKobrynski Feb 2, 2026
2824d57
clean up pre-existing RAM-only keys from storage
JKobrynski Feb 3, 2026
c07c7a2
add missing unit tests
JKobrynski Feb 3, 2026
eea4af1
add a missing test case for a RAM-only key with default value
JKobrynski Feb 3, 2026
ab32044
update readme
JKobrynski Feb 3, 2026
f62fd74
skip storage operations for RAM-only keys in the remove function
JKobrynski Feb 3, 2026
b69c214
update isRamOnlyKey comments
JKobrynski Feb 3, 2026
2b78c25
run automated documentation script
JKobrynski Feb 4, 2026
0c09ac1
Merge branch 'main' into JKobrynski/feat/80091-implement-ramonly-key-…
JKobrynski Feb 4, 2026
0f12047
Merge remote-tracking branch 'upstream/main' into JKobrynski/feat/800…
JKobrynski Feb 4, 2026
1fde270
add RAM-only keys to OnyxUtils perf tests
JKobrynski Feb 5, 2026
bead3d3
remove logic that removes pre-existing RAM-only keys
JKobrynski Feb 5, 2026
0848187
add explaining comment
JKobrynski Feb 5, 2026
94ece5a
add RAM-only keys to perf tests
JKobrynski Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions API-INTERNAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ is associated with a collection of keys.</p>
<dt><a href="#isCollectionMember">isCollectionMember(key)</a> ⇒</dt>
<dd><p>Checks if a given key is a collection member key (not just a collection key).</p>
</dd>
<dt><a href="#isRamOnlyKey">isRamOnlyKey(key)</a> ⇒</dt>
<dd><p>Checks if a given key is a RAM-only key, RAM-only collection key, or a RAM-only collection member</p>
<p>For example:</p>
<p>For the following Onyx setup</p>
<p>ramOnlyKeys: [&quot;ramOnlyKey&quot;, &quot;ramOnlyCollection_&quot;]</p>
<ul>
<li><code>isRamOnlyKey(&quot;ramOnlyKey&quot;)</code> would return true</li>
<li><code>isRamOnlyKey(&quot;ramOnlyCollection_&quot;)</code> would return true</li>
<li><code>isRamOnlyKey(&quot;ramOnlyCollection_1&quot;)</code> would return true</li>
<li><code>isRamOnlyKey(&quot;someOtherKey&quot;)</code> would return false</li>
</ul>
</dd>
<dt><a href="#splitCollectionMemberKey">splitCollectionMemberKey(key, collectionKey)</a> ⇒</dt>
<dd><p>Splits a collection member key into the collection key part and the ID part.</p>
</dd>
Expand Down Expand Up @@ -307,6 +319,29 @@ Checks if a given key is a collection member key (not just a collection key).
| --- | --- |
| key | The key to check |

<a name="isRamOnlyKey"></a>

## isRamOnlyKey(key) ⇒
Checks if a given key is a RAM-only key, RAM-only collection key, or a RAM-only collection member

For example:

For the following Onyx setup

ramOnlyKeys: ["ramOnlyKey", "ramOnlyCollection_"]

- `isRamOnlyKey("ramOnlyKey")` would return true
- `isRamOnlyKey("ramOnlyCollection_")` would return true
- `isRamOnlyKey("ramOnlyCollection_1")` would return true
- `isRamOnlyKey("someOtherKey")` would return false

**Kind**: global function
**Returns**: true if key is a RAM-only key, RAM-only collection key, or a RAM-only collection member

| Param | Description |
| --- | --- |
| key | The key to check |

<a name="splitCollectionMemberKey"></a>

## splitCollectionMemberKey(key, collectionKey) ⇒
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,25 @@ Onyx.init({
});
```

### Using RAM-only keys

You can choose not to save certain keys on disk and keep them RAM-only, that way their values will reset with each session. You just have to pass an array of `ramOnlyKeys` to the `Onyx.init` method. You can mark entire collections as RAM-only by including the collection key (e.g., `ONYXKEYS.COLLECTION.TEMP_DATA`). This will make all members of that collection RAM-only. Individual collection member keys cannot be selectively marked as RAM-only.

```javascript
import Onyx from 'react-native-onyx';

Onyx.init({
keys: ONYXKEYS,
ramOnlyKeys: [
ONYXKEYS.RAM_ONLY_KEY_1,
ONYXKEYS.RAM_ONLY_KEY_2,
ONYXKEYS.COLLECTION.TEMP_DATA,
],
});
```

> Note: RAM-only keys still consume memory and will remain in cache until explicitly cleared or until Onyx.clear() is called. Use them judiciously for truly ephemeral data.

### Usage

The extension interface is pretty simple, on the left sidebar you can see all the updates made to the local storage, in ascending order, and on the right pane you can see the whole the current state, payload of an action and the diff between the previous state and the current state after the action was triggered.
Expand Down
6 changes: 5 additions & 1 deletion lib/Onyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function init({
enablePerformanceMetrics = false,
enableDevTools = true,
skippableCollectionMemberIDs = [],
ramOnlyKeys = [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be sure to run the automated documentation script. I expected the docs to be updated with this parameter. It would also be great to give it some comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I ran the script and pushed the changes. I added this comment in the lib/types.ts file, do you think we should add anything else?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that looks good. Thanks!

snapshotMergeKeys = [],
}: InitOptions): void {
if (enablePerformanceMetrics) {
Expand All @@ -54,6 +55,8 @@ function init({
OnyxUtils.setSkippableCollectionMemberIDs(new Set(skippableCollectionMemberIDs));
OnyxUtils.setSnapshotMergeKeys(new Set(snapshotMergeKeys));

cache.setRamOnlyKeys(new Set<OnyxKey>(ramOnlyKeys));

if (shouldSyncMultipleInstances) {
Storage.keepInstancesSync?.((key, value) => {
cache.set(key, value);
Expand Down Expand Up @@ -378,9 +381,10 @@ function clear(keysToPreserve: OnyxKey[] = []): Promise<void> {
updatePromises.push(OnyxUtils.scheduleNotifyCollectionSubscribers(key, value.newValues, value.oldValues));
}

// Exclude RAM-only keys to prevent them from being saved to storage
const defaultKeyValuePairs = Object.entries(
Object.keys(defaultKeyStates)
.filter((key) => !keysToPreserve.includes(key))
.filter((key) => !keysToPreserve.includes(key) && !OnyxUtils.isRamOnlyKey(key))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why exclude the RAM only keys here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because defaultKeyValuePairs are passed to Storage.multiSet(defaultKeyValuePairs) couple of lines below, we want to avoid saving RAM-only keys to storage.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Would you mind adding that as a code comment so that it's obvious to others?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

.reduce((obj: KeyValueMapping, key) => {
// eslint-disable-next-line no-param-reassign
obj[key] = defaultKeyStates[key];
Expand Down
19 changes: 19 additions & 0 deletions lib/OnyxCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class OnyxCache {
/** Set of collection keys for fast lookup */
private collectionKeys = new Set<OnyxKey>();

/** Set of RAM-only keys for fast lookup */
private ramOnlyKeys = new Set<OnyxKey>();

constructor() {
this.storageKeys = new Set();
this.nullishStorageKeys = new Set();
Expand Down Expand Up @@ -94,6 +97,8 @@ class OnyxCache {
'isCollectionKey',
'getCollectionKey',
'getCollectionData',
'setRamOnlyKeys',
'isRamOnlyKey',
);
}

Expand Down Expand Up @@ -474,6 +479,20 @@ class OnyxCache {
// Return a shallow copy to ensure React detects changes when items are added/removed
return {...cachedCollection};
}

/**
* Set the RAM-only keys for optimized storage
*/
setRamOnlyKeys(ramOnlyKeys: Set<OnyxKey>): void {
this.ramOnlyKeys = ramOnlyKeys;
}

/**
* Check if a key is a RAM-only key
*/
isRamOnlyKey(key: OnyxKey): boolean {
return this.ramOnlyKeys.has(key);
}
}

const instance = new OnyxCache();
Expand Down
5 changes: 4 additions & 1 deletion lib/OnyxMerge/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ const applyMerge: ApplyMerge = <TKey extends OnyxKey, TValue extends OnyxInput<T
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
const updatePromise = OnyxUtils.broadcastUpdate(key, mergedValue as OnyxValue<TKey>, hasChanged);

const shouldSkipStorageOperations = !hasChanged || OnyxUtils.isRamOnlyKey(key);

// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
if (!hasChanged) {
// If the key is marked as RAM-only, it should not be saved nor updated in the storage.
if (shouldSkipStorageOperations) {
return Promise.resolve({mergedValue, updatePromise});
}

Expand Down
5 changes: 4 additions & 1 deletion lib/OnyxMerge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ const applyMerge: ApplyMerge = <TKey extends OnyxKey, TValue extends OnyxInput<T
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
const updatePromise = OnyxUtils.broadcastUpdate(key, mergedValue as OnyxValue<TKey>, hasChanged);

const shouldSkipStorageOperations = !hasChanged || OnyxUtils.isRamOnlyKey(key);

// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
if (!hasChanged) {
// If the key is marked as RAM-only, it should not be saved nor updated in the storage.
if (shouldSkipStorageOperations) {
return Promise.resolve({mergedValue, updatePromise});
}

Expand Down
66 changes: 63 additions & 3 deletions lib/OnyxUtils.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue 4: O(n) filtering on every multiSet call

The new filter in multiSetWithRetry runs on every multiSet call, iterating through all key-value pairs. Each isRamOnlyKey call may also iterate through collection keys via getCollectionKey.

For large batch operations (e.g., syncing many reports), this compounds. While acceptable for now since RAM-only keys are expected to be rare, if performance becomes an issue in the future, consider:

  1. Caching a Set of collection key prefixes for O(1) prefix matching
  2. Or doing a single pass that both filters and builds the storage array

Low priority - just flagging for awareness.


Issue 5: Consider adding RAM-only check to remove()

When a RAM-only key is set to null (e.g., via Onyx.set(RAMONLY_KEY, null)), the code path goes through remove() which calls Storage.removeItem(). This attempts to remove a key from storage that was never stored there - it's wasteful though not incorrect.

Consider adding a RAM-only check in remove():

function remove<TKey extends OnyxKey>(key: TKey, isProcessingCollectionUpdate?: boolean): Promise<void> {
    cache.drop(key);
    scheduleSubscriberUpdate(key, undefined as OnyxValue<TKey>, undefined, isProcessingCollectionUpdate);
    
    if (isRamOnlyKey(key)) {
        return Promise.resolve();
    }
    
    return Storage.removeItem(key).then(() => undefined);
}

Low priority since the storage operation will just be a no-op.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added that additional condition to remove. About the multiSetWithRetry optimisation, do you think we should do it in this PR? If so, I can address it. If we'd be ok with doing this as a followup improvement, I can assign myself to it and take care of it as soon as I finish working on the higher priority Onyx issues. What would you prefer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can confirm Issue 4 with Reassure – we already have a test for multiSet and it didn't report regressions, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct! However, the perf tests don't include RAM-only keys, we should probably add them right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to add those tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests added!

Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,35 @@ function isCollectionMember(key: OnyxKey): boolean {
}
}

/**
* Checks if a given key is a RAM-only key, RAM-only collection key, or a RAM-only collection member
*
* For example:
*
* For the following Onyx setup
*
* ramOnlyKeys: ["ramOnlyKey", "ramOnlyCollection_"]
*
* - `isRamOnlyKey("ramOnlyKey")` would return true
* - `isRamOnlyKey("ramOnlyCollection_")` would return true
* - `isRamOnlyKey("ramOnlyCollection_1")` would return true
* - `isRamOnlyKey("someOtherKey")` would return false
*
* @param key - The key to check
* @returns true if key is a RAM-only key, RAM-only collection key, or a RAM-only collection member
*/
function isRamOnlyKey(key: OnyxKey): boolean {
try {
const collectionKey = getCollectionKey(key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of using try/catch for flow control. Claude put it elegantly:

Problems with the current pattern:

  • Hidden contract: It's not obvious from reading this code that getCollectionKey throws for non-collection keys. You have to go read its implementation to understand the flow.
  • Expensive error path: If many keys aren't collection members, you're creating exception objects frequently (though JS/TS exceptions are cheaper than some languages)
  • Empty catch: The silent catch with just a comment is a code smell—what if getCollectionKey throws for a different reason? You'd swallow that error too.

Its proposed solution is to change the signature of getCollectionKey to return null instead of throw when the provided key is not a collection key or collection member.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this suggestion any concerns with that? @JKobrynski @fabioh8010 ?

Copy link
Contributor

@fabioh8010 fabioh8010 Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont see immediate concerns and I agree with the comment, but I would make it return undefined instead of null – from the usage I saw it would be simpler to refactor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Do you think we could do that in a follow-up issue? That change would also affect some existing logic so it might be safer to do it separately.

CC: @mountiny @roryabraham

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do it in a separate PR. I agree with the change and I have commented about this in past PRs as well.

// If collectionKey exists for a given key, check if it's a RAM-only key
return cache.isRamOnlyKey(collectionKey);
} catch {
Comment on lines +490 to +495

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor RAM-only collection members, not just collection keys

The new isRamOnlyKey only checks the collection key when the input is a collection member. If a caller includes a specific member key in ramOnlyKeys (as implied by the docstring “RAM-only collection member”), getCollectionKey succeeds and the function returns cache.isRamOnlyKey(collectionKey), ignoring the member entry. In that scenario, the member will still be persisted to storage, which violates the RAM-only contract for that key. Consider checking cache.isRamOnlyKey(key) as well when the key is a collection member so explicitly marked members are honored.

Useful? React with 👍 / 👎.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense to clarify @JKobrynski , either the docs should be updated or the individual keys should be updated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand this problem correctly, this function is tested and should work correctly for RAM-only keys, RAM-only collection keys, and RAM-only collection member keys, the tests pass for all cases listed above. I updated the comment so every supported key is listed and added some examples. Let me know if that's what you meant, if not I will change it, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @JKobrynski , I don't understand the comment because tests are actually covering all possible scenarios.

// If getCollectionKey throws, the key is not a collection member
}

return cache.isRamOnlyKey(key);
}

/**
* Splits a collection member key into the collection key part and the ID part.
* @param key - The collection member key to split.
Expand Down Expand Up @@ -869,6 +898,11 @@ function scheduleNotifyCollectionSubscribers<TKey extends OnyxKey>(
function remove<TKey extends OnyxKey>(key: TKey, isProcessingCollectionUpdate?: boolean): Promise<void> {
cache.drop(key);
scheduleSubscriberUpdate(key, undefined as OnyxValue<TKey>, undefined, isProcessingCollectionUpdate);

if (isRamOnlyKey(key)) {
return Promise.resolve();
}

return Storage.removeItem(key).then(() => undefined);
}

Expand Down Expand Up @@ -1344,6 +1378,12 @@ function setWithRetry<TKey extends OnyxKey>({key, value, options}: SetParams<TKe
return updatePromise;
}

// If a key is a RAM-only key or a member of RAM-only collection, we skip the step that modifies the storage
if (isRamOnlyKey(key)) {
OnyxUtils.sendActionToDevTools(OnyxUtils.METHOD.SET, key, valueWithoutNestedNullValues);
return updatePromise;
}

return Storage.setItem(key, valueWithoutNestedNullValues)
.catch((error) => OnyxUtils.retryOperation(error, setWithRetry, {key, value: valueWithoutNestedNullValues, options}, retryAttempt))
.then(() => {
Expand Down Expand Up @@ -1394,7 +1434,13 @@ function multiSetWithRetry(data: OnyxMultiSetInput, retryAttempt?: number): Prom
return OnyxUtils.scheduleSubscriberUpdate(key, value);
});

return Storage.multiSet(keyValuePairsToSet)
const keyValuePairsToStore = keyValuePairsToSet.filter((keyValuePair) => {
const [key] = keyValuePair;
// Filter out the RAM-only key value pairs, as they should not be saved to storage
return !isRamOnlyKey(key);
});

return Storage.multiSet(keyValuePairsToStore)
.catch((error) => OnyxUtils.retryOperation(error, multiSetWithRetry, newData, retryAttempt))
.then(() => {
OnyxUtils.sendActionToDevTools(OnyxUtils.METHOD.MULTI_SET, undefined, newData);
Expand Down Expand Up @@ -1463,6 +1509,12 @@ function setCollectionWithRetry<TKey extends CollectionKeyBase>({collectionKey,

const updatePromise = OnyxUtils.scheduleNotifyCollectionSubscribers(collectionKey, mutableCollection, previousCollection);

// RAM-only keys are not supposed to be saved to storage
if (isRamOnlyKey(collectionKey)) {
OnyxUtils.sendActionToDevTools(OnyxUtils.METHOD.SET_COLLECTION, undefined, mutableCollection);
return updatePromise;
}

return Storage.multiSet(keyValuePairs)
.catch((error) => OnyxUtils.retryOperation(error, setCollectionWithRetry, {collectionKey, collection}, retryAttempt))
.then(() => {
Expand Down Expand Up @@ -1573,11 +1625,13 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(

// New keys will be added via multiSet while existing keys will be updated using multiMerge
// This is because setting a key that doesn't exist yet with multiMerge will throw errors
if (keyValuePairsForExistingCollection.length > 0) {
// We can skip this step for RAM-only keys as they should never be saved to storage
if (!isRamOnlyKey(collectionKey) && keyValuePairsForExistingCollection.length > 0) {
promises.push(Storage.multiMerge(keyValuePairsForExistingCollection));
}

if (keyValuePairsForNewCollection.length > 0) {
// We can skip this step for RAM-only keys as they should never be saved to storage
if (!isRamOnlyKey(collectionKey) && keyValuePairsForNewCollection.length > 0) {
promises.push(Storage.multiSet(keyValuePairsForNewCollection));
}

Expand Down Expand Up @@ -1656,6 +1710,11 @@ function partialSetCollection<TKey extends CollectionKeyBase>({collectionKey, co

const updatePromise = scheduleNotifyCollectionSubscribers(collectionKey, mutableCollection, previousCollection);

if (isRamOnlyKey(collectionKey)) {
sendActionToDevTools(METHOD.SET_COLLECTION, undefined, mutableCollection);
return updatePromise;
}

return Storage.multiSet(keyValuePairs)
.catch((error) => retryOperation(error, partialSetCollection, {collectionKey, collection}, retryAttempt))
.then(() => {
Expand Down Expand Up @@ -1741,6 +1800,7 @@ const OnyxUtils = {
setWithRetry,
multiSetWithRetry,
setCollectionWithRetry,
isRamOnlyKey,
};

GlobalSettings.addGlobalSettingsChangeListener(({enablePerformanceMetrics}) => {
Expand Down
5 changes: 5 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,11 @@ type InitOptions = {
*/
skippableCollectionMemberIDs?: string[];

/**
* Array of keys that when provided to Onyx are flagged as RAM-only keys, and thus are not saved to disk.
*/
ramOnlyKeys?: OnyxKey[];

/**
* A list of field names that should always be merged into snapshot entries even if those fields are
* missing in the snapshot. Snapshots are saved "views" of a key's data used to populate read-only
Expand Down
1 change: 1 addition & 0 deletions lib/useOnyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type UseOnyxOptions<TKey extends OnyxKey, TReturnValue> = {

/**
* If set to `false`, then no data will be prefilled into the component.
* @deprecated This param is going to be removed soon. Use RAM-only keys instead.
*/
initWithStoredValues?: boolean;

Expand Down
3 changes: 3 additions & 0 deletions tests/perf-test/OnyxConnectionManager.perf-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {getRandomReportActions} from '../utils/collections/reportActions';
const ONYXKEYS = {
TEST_KEY: 'test',
TEST_KEY_2: 'test2',
RAM_ONLY_TEST_KEY: 'ramOnlyTestKey',
COLLECTION: {
TEST_KEY: 'test_',
TEST_NESTED_KEY: 'test_nested_',
Expand All @@ -18,6 +19,7 @@ const ONYXKEYS = {
TEST_KEY_5: 'test5_',
EVICTABLE_TEST_KEY: 'evictable_test_',
SNAPSHOT: 'snapshot_',
RAM_ONLY_TEST_COLLECTION: 'ramOnlyTestCollection_',
},
};

Expand Down Expand Up @@ -47,6 +49,7 @@ describe('OnyxConnectionManager', () => {
maxCachedKeysCount: 100000,
evictableKeys: [ONYXKEYS.COLLECTION.EVICTABLE_TEST_KEY],
skippableCollectionMemberIDs: ['skippable-id'],
ramOnlyKeys: [ONYXKEYS.RAM_ONLY_TEST_KEY, ONYXKEYS.COLLECTION.RAM_ONLY_TEST_COLLECTION],
});
});

Expand Down
17 changes: 17 additions & 0 deletions tests/perf-test/OnyxUtils.perf-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {OnyxEntry, OnyxInputKeyValueMapping, OnyxKey, RetriableOnyxOperatio
const ONYXKEYS = {
TEST_KEY: 'test',
TEST_KEY_2: 'test2',
RAM_ONLY_TEST_KEY: 'ramOnlyTestKey',
COLLECTION: {
TEST_KEY: 'test_',
TEST_NESTED_KEY: 'test_nested_',
Expand All @@ -24,6 +25,7 @@ const ONYXKEYS = {
TEST_KEY_5: 'test5_',
EVICTABLE_TEST_KEY: 'evictable_test_',
SNAPSHOT: 'snapshot_',
RAM_ONLY_TEST_COLLECTION: 'ramOnlyTestCollection_',
},
};

Expand Down Expand Up @@ -54,6 +56,7 @@ describe('OnyxUtils', () => {
evictableKeys,
initialKeyStates,
skippableCollectionMemberIDs: ['skippable-id'],
ramOnlyKeys: [ONYXKEYS.RAM_ONLY_TEST_KEY, ONYXKEYS.COLLECTION.RAM_ONLY_TEST_COLLECTION],
});
});

Expand Down Expand Up @@ -144,6 +147,20 @@ describe('OnyxUtils', () => {
});
});

describe('isRamOnlyKey', () => {
test('one call for RAM-only key', async () => {
await measureFunction(() => OnyxUtils.isRamOnlyKey(ONYXKEYS.RAM_ONLY_TEST_KEY));
});

test('one call for RAM-only collection key', async () => {
await measureFunction(() => OnyxUtils.isRamOnlyKey(ONYXKEYS.COLLECTION.RAM_ONLY_TEST_COLLECTION));
});

test('one call for RAM-only collection member key', async () => {
await measureFunction(() => OnyxUtils.isRamOnlyKey(`${ONYXKEYS.COLLECTION.RAM_ONLY_TEST_COLLECTION}1`));
});
});

describe('isCollectionMemberKey', () => {
test('one call with correct key', async () => {
await measureFunction(() => OnyxUtils.isCollectionMemberKey(collectionKey, `${collectionKey}entry1`));
Expand Down
2 changes: 2 additions & 0 deletions tests/perf-test/useOnyx.perf-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const ONYXKEYS = {
TEST_KEY: 'test',
TEST_KEY_2: 'test2',
TEST_KEY_3: 'test3',
RAM_ONLY_TEST_KEY: 'ramOnlyTestKey',
};

const dataMatcher = (onyxKey: OnyxKey, expected: unknown) => `data: ${onyxKey}_${JSON.stringify(expected)}`;
Expand Down Expand Up @@ -57,6 +58,7 @@ describe('useOnyx', () => {
Onyx.init({
keys: ONYXKEYS,
maxCachedKeysCount: 100000,
ramOnlyKeys: [ONYXKEYS.RAM_ONLY_TEST_KEY],
});
});

Expand Down
Loading
Loading