Skip to content

Commit 1351565

Browse files
committed
Resolve member keys to the most specific collection prefix in registerMemberKey
1 parent cd7cbbb commit 1351565

2 files changed

Lines changed: 35 additions & 9 deletions

File tree

lib/OnyxKeys.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,28 @@ function registerMemberKey(key: OnyxKey): void {
115115
members.add(key);
116116
return;
117117
}
118+
// Find the longest (most specific) matching collection key.
119+
// e.g. for 'test_level_1', prefer 'test_level_' over 'test_'.
120+
let matchedCollectionKey: OnyxKey | undefined;
118121
for (const collectionKey of collectionKeySet) {
119122
if (isCollectionMemberKey(collectionKey, key)) {
120-
memberToCollectionKeyMap.set(key, collectionKey);
121-
122-
// Also register in the forward lookup (collection → members)
123-
let members = collectionToMembersMap.get(collectionKey);
124-
if (!members) {
125-
members = new Set();
126-
collectionToMembersMap.set(collectionKey, members);
123+
if (!matchedCollectionKey || collectionKey.length > matchedCollectionKey.length) {
124+
matchedCollectionKey = collectionKey;
127125
}
128-
members.add(key);
129-
return;
130126
}
131127
}
128+
129+
if (matchedCollectionKey) {
130+
memberToCollectionKeyMap.set(key, matchedCollectionKey);
131+
132+
// Also register in the forward lookup (collection → members)
133+
let members = collectionToMembersMap.get(matchedCollectionKey);
134+
if (!members) {
135+
members = new Set();
136+
collectionToMembersMap.set(matchedCollectionKey, members);
137+
}
138+
members.add(key);
139+
}
132140
}
133141

134142
/**

tests/unit/OnyxKeysTest.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,24 @@ describe('OnyxKeys', () => {
209209
OnyxKeys.deregisterMemberKey(memberKey);
210210
});
211211

212+
it('should resolve to the most specific (longest) collection key for overlapping prefixes', () => {
213+
// 'test_level_' and 'test_' both match 'test_level_1', but 'test_level_' is more specific
214+
const memberKey = `${ONYXKEYS.COLLECTION.TEST_LEVEL_KEY}1`;
215+
OnyxKeys.registerMemberKey(memberKey);
216+
217+
expect(OnyxKeys.getCollectionKey(memberKey)).toBe(ONYXKEYS.COLLECTION.TEST_LEVEL_KEY);
218+
219+
const testLevelMembers = OnyxKeys.getMembersOfCollection(ONYXKEYS.COLLECTION.TEST_LEVEL_KEY);
220+
expect(testLevelMembers?.has(memberKey)).toBe(true);
221+
222+
// Should NOT be registered under the shorter 'test_' collection
223+
const testMembers = OnyxKeys.getMembersOfCollection(ONYXKEYS.COLLECTION.TEST_KEY);
224+
expect(testMembers?.has(memberKey)).toBeFalsy();
225+
226+
// Clean up
227+
OnyxKeys.deregisterMemberKey(memberKey);
228+
});
229+
212230
it('should populate the reverse lookup so getCollectionKey returns O(1)', () => {
213231
const memberKey = `${ONYXKEYS.COLLECTION.ROUTES}xyz`;
214232
OnyxKeys.registerMemberKey(memberKey);

0 commit comments

Comments
 (0)