react-native-onyx 3.0.52 → 3.0.54

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.
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const OnyxUtils_1 = __importDefault(require("../OnyxUtils"));
6
+ const OnyxKeys_1 = __importDefault(require("../OnyxKeys"));
7
7
  const ERROR_LABEL = 'Onyx DevTools - Error: ';
8
8
  /**
9
9
  * Real implementation of DevTools that connects to Redux DevTools Extension
@@ -67,7 +67,7 @@ class RealDevTools {
67
67
  clearState(keysToPreserve = []) {
68
68
  const newState = Object.entries(this.state).reduce((obj, [key, value]) => {
69
69
  // eslint-disable-next-line no-param-reassign
70
- obj[key] = keysToPreserve.some((preserveKey) => OnyxUtils_1.default.isKeyMatch(preserveKey, key)) ? value : this.defaultState[key];
70
+ obj[key] = keysToPreserve.some((preserveKey) => OnyxKeys_1.default.isKeyMatch(preserveKey, key)) ? value : this.defaultState[key];
71
71
  return obj;
72
72
  }, {});
73
73
  this.registerAction('CLEAR', undefined, newState);
package/dist/Onyx.js CHANGED
@@ -42,6 +42,7 @@ const storage_1 = __importDefault(require("./storage"));
42
42
  const utils_1 = __importDefault(require("./utils"));
43
43
  const DevTools_1 = __importStar(require("./DevTools"));
44
44
  const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
45
+ const OnyxKeys_1 = __importDefault(require("./OnyxKeys"));
45
46
  const logMessages_1 = __importDefault(require("./logMessages"));
46
47
  const OnyxConnectionManager_1 = __importDefault(require("./OnyxConnectionManager"));
47
48
  const GlobalSettings = __importStar(require("./GlobalSettings"));
@@ -58,19 +59,19 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
58
59
  storage_1.default.init();
59
60
  OnyxUtils_1.default.setSkippableCollectionMemberIDs(new Set(skippableCollectionMemberIDs));
60
61
  OnyxUtils_1.default.setSnapshotMergeKeys(new Set(snapshotMergeKeys));
61
- OnyxCache_1.default.setRamOnlyKeys(new Set(ramOnlyKeys));
62
+ OnyxKeys_1.default.setRamOnlyKeys(new Set(ramOnlyKeys));
62
63
  if (shouldSyncMultipleInstances) {
63
64
  (_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
64
65
  // RAM-only keys should never sync from storage as they may have stale persisted data
65
66
  // from before the key was migrated to RAM-only.
66
- if (OnyxUtils_1.default.isRamOnlyKey(key)) {
67
+ if (OnyxKeys_1.default.isRamOnlyKey(key)) {
67
68
  return;
68
69
  }
69
70
  OnyxCache_1.default.set(key, value);
70
71
  // Check if this is a collection member key to prevent duplicate callbacks
71
72
  // When a collection is updated, individual members sync separately to other tabs
72
73
  // Setting isProcessingCollectionUpdate=true prevents triggering collection callbacks for each individual update
73
- const isKeyCollectionMember = OnyxUtils_1.default.isCollectionMember(key);
74
+ const isKeyCollectionMember = OnyxKeys_1.default.isCollectionMember(key);
74
75
  OnyxUtils_1.default.keyChanged(key, value, undefined, isKeyCollectionMember);
75
76
  });
76
77
  }
@@ -83,7 +84,7 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
83
84
  // eager cache loading populates the key index (cache.setAllKeys) inside initializeWithDefaultKeyStates,
84
85
  // and the evictable keys list depends on that index being populated.
85
86
  OnyxUtils_1.default.initializeWithDefaultKeyStates()
86
- .then(() => OnyxCache_1.default.addEvictableKeysToRecentlyAccessedList(OnyxUtils_1.default.isCollectionKey, OnyxUtils_1.default.getAllKeys))
87
+ .then(() => OnyxCache_1.default.addEvictableKeysToRecentlyAccessedList(OnyxKeys_1.default.isCollectionKey, OnyxUtils_1.default.getAllKeys))
87
88
  .then(OnyxUtils_1.default.getDeferredInitTask().resolve);
88
89
  }
89
90
  /**
@@ -194,7 +195,7 @@ function merge(key, changes) {
194
195
  const skippableCollectionMemberIDs = OnyxUtils_1.default.getSkippableCollectionMemberIDs();
195
196
  if (skippableCollectionMemberIDs.size) {
196
197
  try {
197
- const [, collectionMemberID] = OnyxUtils_1.default.splitCollectionMemberKey(key);
198
+ const [, collectionMemberID] = OnyxKeys_1.default.splitCollectionMemberKey(key);
198
199
  if (skippableCollectionMemberIDs.has(collectionMemberID)) {
199
200
  // The key is a skippable one, so we set the new changes to undefined.
200
201
  // eslint-disable-next-line no-param-reassign
@@ -322,7 +323,7 @@ function clear(keysToPreserve = []) {
322
323
  // to null would cause unknown behavior)
323
324
  // 2.1 However, if a default key was explicitly set to null, we need to reset it to the default value
324
325
  for (const key of allKeys) {
325
- const isKeyToPreserve = keysToPreserve.some((preserveKey) => OnyxUtils_1.default.isKeyMatch(preserveKey, key));
326
+ const isKeyToPreserve = keysToPreserve.some((preserveKey) => OnyxKeys_1.default.isKeyMatch(preserveKey, key));
326
327
  const isDefaultKey = key in defaultKeyStates;
327
328
  // If the key is being removed or reset to default:
328
329
  // 1. Update it in the cache
@@ -333,7 +334,7 @@ function clear(keysToPreserve = []) {
333
334
  const newValue = (_a = defaultKeyStates[key]) !== null && _a !== void 0 ? _a : null;
334
335
  if (newValue !== oldValue) {
335
336
  OnyxCache_1.default.set(key, newValue);
336
- const collectionKey = OnyxUtils_1.default.getCollectionKey(key);
337
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
337
338
  if (collectionKey) {
338
339
  if (!keyValuesToResetAsCollection[collectionKey]) {
339
340
  keyValuesToResetAsCollection[collectionKey] = { oldValues: {}, newValues: {} };
@@ -362,7 +363,7 @@ function clear(keysToPreserve = []) {
362
363
  }
363
364
  // Exclude RAM-only keys to prevent them from being saved to storage
364
365
  const defaultKeyValuePairs = Object.entries(Object.keys(defaultKeyStates)
365
- .filter((key) => !keysToPreserve.some((preserveKey) => OnyxUtils_1.default.isKeyMatch(preserveKey, key)) && !OnyxUtils_1.default.isRamOnlyKey(key))
366
+ .filter((key) => !keysToPreserve.some((preserveKey) => OnyxKeys_1.default.isKeyMatch(preserveKey, key)) && !OnyxKeys_1.default.isRamOnlyKey(key))
366
367
  .reduce((obj, key) => {
367
368
  // eslint-disable-next-line no-param-reassign
368
369
  obj[key] = defaultKeyStates[key];
@@ -459,8 +460,8 @@ function update(data) {
459
460
  // Group all the collection-related keys and update each collection in a single `mergeCollection` call.
460
461
  // This is needed to prevent multiple `mergeCollection` calls for the same collection and `merge` calls for the individual items of the said collection.
461
462
  // This way, we ensure there is no race condition in the queued updates of the same key.
462
- for (const collectionKey of OnyxUtils_1.default.getCollectionKeys()) {
463
- const collectionItemKeys = Object.keys(updateQueue).filter((key) => OnyxUtils_1.default.isKeyMatch(collectionKey, key));
463
+ for (const collectionKey of OnyxKeys_1.default.getCollectionKeys()) {
464
+ const collectionItemKeys = Object.keys(updateQueue).filter((key) => OnyxKeys_1.default.isKeyMatch(collectionKey, key));
464
465
  if (collectionItemKeys.length <= 1) {
465
466
  // If there are no items of this collection in the updateQueue, we should skip it.
466
467
  // If there is only one item, we should update it individually, therefore retain it in the updateQueue.
@@ -34,10 +34,6 @@ declare class OnyxCache {
34
34
  private evictionBlocklist;
35
35
  /** List of keys that have been directly subscribed to or recently modified from least to most recent */
36
36
  private recentlyAccessedKeys;
37
- /** Set of collection keys for fast lookup */
38
- private collectionKeys;
39
- /** Set of RAM-only keys for fast lookup */
40
- private ramOnlyKeys;
41
37
  constructor();
42
38
  /** Get all the storage keys */
43
39
  getAllKeys(): Set<OnyxKey>;
@@ -122,12 +118,6 @@ declare class OnyxCache {
122
118
  * @param testKey - Key to check
123
119
  */
124
120
  isEvictableKey(testKey: OnyxKey): boolean;
125
- /**
126
- * Check if a given key matches a pattern key
127
- * @param configKey - Pattern that may contain a wildcard
128
- * @param key - Key to test against the pattern
129
- */
130
- private isKeyMatch;
131
121
  /**
132
122
  * Remove a key from the recently accessed key list.
133
123
  */
@@ -155,26 +145,10 @@ declare class OnyxCache {
155
145
  * Set the collection keys for optimized storage
156
146
  */
157
147
  setCollectionKeys(collectionKeys: Set<OnyxKey>): void;
158
- /**
159
- * Check if a key is a collection key
160
- */
161
- isCollectionKey(key: OnyxKey): boolean;
162
- /**
163
- * Get the collection key for a given member key
164
- */
165
- getCollectionKey(key: OnyxKey): OnyxKey | undefined;
166
148
  /**
167
149
  * Get all data for a collection key
168
150
  */
169
151
  getCollectionData(collectionKey: OnyxKey): Record<OnyxKey, OnyxValue<OnyxKey>> | undefined;
170
- /**
171
- * Set the RAM-only keys for optimized storage
172
- */
173
- setRamOnlyKeys(ramOnlyKeys: Set<OnyxKey>): void;
174
- /**
175
- * Check if a key is a RAM-only key
176
- */
177
- isRamOnlyKey(key: OnyxKey): boolean;
178
152
  }
179
153
  declare const instance: OnyxCache;
180
154
  export default instance;
package/dist/OnyxCache.js CHANGED
@@ -1,37 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
@@ -40,7 +7,7 @@ exports.TASK = void 0;
40
7
  const fast_equals_1 = require("fast-equals");
41
8
  const bindAll_1 = __importDefault(require("lodash/bindAll"));
42
9
  const utils_1 = __importDefault(require("./utils"));
43
- const Str = __importStar(require("./Str"));
10
+ const OnyxKeys_1 = __importDefault(require("./OnyxKeys"));
44
11
  // Task constants
45
12
  const TASK = {
46
13
  GET: 'get',
@@ -62,10 +29,6 @@ class OnyxCache {
62
29
  this.evictionBlocklist = {};
63
30
  /** List of keys that have been directly subscribed to or recently modified from least to most recent */
64
31
  this.recentlyAccessedKeys = new Set();
65
- /** Set of collection keys for fast lookup */
66
- this.collectionKeys = new Set();
67
- /** Set of RAM-only keys for fast lookup */
68
- this.ramOnlyKeys = new Set();
69
32
  this.storageKeys = new Set();
70
33
  this.nullishStorageKeys = new Set();
71
34
  this.recentKeys = new Set();
@@ -73,7 +36,7 @@ class OnyxCache {
73
36
  this.collectionData = {};
74
37
  this.pendingPromises = new Map();
75
38
  // bind all public methods to prevent problems with `this`
76
- (0, bindAll_1.default)(this, 'getAllKeys', 'get', 'hasCacheForKey', 'addKey', 'addNullishStorageKey', 'hasNullishStorageKey', 'clearNullishStorageKeys', 'set', 'drop', 'merge', 'hasPendingTask', 'getTaskPromise', 'captureTask', 'addToAccessedKeys', 'removeLeastRecentlyUsedKeys', 'setRecentKeysLimit', 'setAllKeys', 'setEvictionAllowList', 'getEvictionBlocklist', 'isEvictableKey', 'removeLastAccessedKey', 'addLastAccessedKey', 'addEvictableKeysToRecentlyAccessedList', 'getKeyForEviction', 'setCollectionKeys', 'isCollectionKey', 'getCollectionKey', 'getCollectionData', 'setRamOnlyKeys', 'isRamOnlyKey');
39
+ (0, bindAll_1.default)(this, 'getAllKeys', 'get', 'hasCacheForKey', 'addKey', 'addNullishStorageKey', 'hasNullishStorageKey', 'clearNullishStorageKeys', 'set', 'drop', 'merge', 'hasPendingTask', 'getTaskPromise', 'captureTask', 'addToAccessedKeys', 'removeLeastRecentlyUsedKeys', 'setRecentKeysLimit', 'setAllKeys', 'setEvictionAllowList', 'getEvictionBlocklist', 'isEvictableKey', 'removeLastAccessedKey', 'addLastAccessedKey', 'addEvictableKeysToRecentlyAccessedList', 'getKeyForEviction', 'setCollectionKeys', 'getCollectionData', 'hasValueChanged');
77
40
  }
78
41
  /** Get all the storage keys */
79
42
  getAllKeys() {
@@ -92,12 +55,16 @@ class OnyxCache {
92
55
  */
93
56
  setAllKeys(keys) {
94
57
  this.storageKeys = new Set(keys);
58
+ for (const key of keys) {
59
+ OnyxKeys_1.default.registerMemberKey(key);
60
+ }
95
61
  }
96
62
  /** Saves a key in the storage keys list
97
63
  * Serves to keep the result of `getAllKeys` up to date
98
64
  */
99
65
  addKey(key) {
100
66
  this.storageKeys.add(key);
67
+ OnyxKeys_1.default.registerMemberKey(key);
101
68
  }
102
69
  /** Used to set keys that are null/undefined in storage without adding null to the storage map */
103
70
  addNullishStorageKey(key) {
@@ -135,7 +102,7 @@ class OnyxCache {
135
102
  // When a key is explicitly set in cache, we can remove it from the list of nullish keys,
136
103
  // since it will either be set to a non nullish value or removed from the cache completely.
137
104
  this.nullishStorageKeys.delete(key);
138
- const collectionKey = this.getCollectionKey(key);
105
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
139
106
  if (value === null || value === undefined) {
140
107
  delete this.storageMap[key];
141
108
  // Remove from collection data cache if it's a collection member
@@ -158,16 +125,17 @@ class OnyxCache {
158
125
  drop(key) {
159
126
  delete this.storageMap[key];
160
127
  // Remove from collection data cache if this is a collection member
161
- const collectionKey = this.getCollectionKey(key);
128
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
162
129
  if (collectionKey && this.collectionData[collectionKey]) {
163
130
  delete this.collectionData[collectionKey][key];
164
131
  }
165
132
  // If this is a collection key, clear its data
166
- if (this.isCollectionKey(key)) {
133
+ if (OnyxKeys_1.default.isCollectionKey(key)) {
167
134
  delete this.collectionData[key];
168
135
  }
169
136
  this.storageKeys.delete(key);
170
137
  this.recentKeys.delete(key);
138
+ OnyxKeys_1.default.deregisterMemberKey(key);
171
139
  }
172
140
  /**
173
141
  * Deep merge data to cache, any non existing keys will be created
@@ -184,7 +152,7 @@ class OnyxCache {
184
152
  for (const [key, value] of Object.entries(data)) {
185
153
  this.addKey(key);
186
154
  this.addToAccessedKeys(key);
187
- const collectionKey = this.getCollectionKey(key);
155
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
188
156
  if (value === null || value === undefined) {
189
157
  this.addNullishStorageKey(key);
190
158
  // Remove from collection data cache if it's a collection member
@@ -260,7 +228,7 @@ class OnyxCache {
260
228
  for (const key of keysToRemove) {
261
229
  delete this.storageMap[key];
262
230
  // Remove from collection data cache if this is a collection member
263
- const collectionKey = this.getCollectionKey(key);
231
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
264
232
  if (collectionKey && this.collectionData[collectionKey]) {
265
233
  delete this.collectionData[collectionKey][key];
266
234
  }
@@ -294,16 +262,7 @@ class OnyxCache {
294
262
  * @param testKey - Key to check
295
263
  */
296
264
  isEvictableKey(testKey) {
297
- return this.evictionAllowList.some((key) => this.isKeyMatch(key, testKey));
298
- }
299
- /**
300
- * Check if a given key matches a pattern key
301
- * @param configKey - Pattern that may contain a wildcard
302
- * @param key - Key to test against the pattern
303
- */
304
- isKeyMatch(configKey, key) {
305
- const isCollectionKey = configKey.endsWith('_');
306
- return isCollectionKey ? Str.startsWith(key, configKey) : configKey === key;
265
+ return this.evictionAllowList.some((key) => OnyxKeys_1.default.isKeyMatch(key, testKey));
307
266
  }
308
267
  /**
309
268
  * Remove a key from the recently accessed key list.
@@ -336,7 +295,7 @@ class OnyxCache {
336
295
  return getAllKeysFn().then((keys) => {
337
296
  for (const evictableKey of this.evictionAllowList) {
338
297
  for (const key of keys) {
339
- if (!this.isKeyMatch(evictableKey, key)) {
298
+ if (!OnyxKeys_1.default.isKeyMatch(evictableKey, key)) {
340
299
  continue;
341
300
  }
342
301
  this.addLastAccessedKey(key, isCollectionKeyFn(key));
@@ -359,7 +318,7 @@ class OnyxCache {
359
318
  * Set the collection keys for optimized storage
360
319
  */
361
320
  setCollectionKeys(collectionKeys) {
362
- this.collectionKeys = collectionKeys;
321
+ OnyxKeys_1.default.setCollectionKeys(collectionKeys);
363
322
  // Initialize collection data for existing collection keys
364
323
  for (const collectionKey of collectionKeys) {
365
324
  if (this.collectionData[collectionKey]) {
@@ -368,23 +327,6 @@ class OnyxCache {
368
327
  this.collectionData[collectionKey] = {};
369
328
  }
370
329
  }
371
- /**
372
- * Check if a key is a collection key
373
- */
374
- isCollectionKey(key) {
375
- return this.collectionKeys.has(key);
376
- }
377
- /**
378
- * Get the collection key for a given member key
379
- */
380
- getCollectionKey(key) {
381
- for (const collectionKey of this.collectionKeys) {
382
- if (key.startsWith(collectionKey) && key.length > collectionKey.length) {
383
- return collectionKey;
384
- }
385
- }
386
- return undefined;
387
- }
388
330
  /**
389
331
  * Get all data for a collection key
390
332
  */
@@ -396,18 +338,6 @@ class OnyxCache {
396
338
  // Return a shallow copy to ensure React detects changes when items are added/removed
397
339
  return Object.assign({}, cachedCollection);
398
340
  }
399
- /**
400
- * Set the RAM-only keys for optimized storage
401
- */
402
- setRamOnlyKeys(ramOnlyKeys) {
403
- this.ramOnlyKeys = ramOnlyKeys;
404
- }
405
- /**
406
- * Check if a key is a RAM-only key
407
- */
408
- isRamOnlyKey(key) {
409
- return this.ramOnlyKeys.has(key);
410
- }
411
341
  }
412
342
  const instance = new OnyxCache();
413
343
  exports.default = instance;
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const bindAll_1 = __importDefault(require("lodash/bindAll"));
40
40
  const Logger = __importStar(require("./Logger"));
41
41
  const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
42
+ const OnyxKeys_1 = __importDefault(require("./OnyxKeys"));
42
43
  const Str = __importStar(require("./Str"));
43
44
  const OnyxCache_1 = __importDefault(require("./OnyxCache"));
44
45
  const OnyxSnapshotCache_1 = __importDefault(require("./OnyxSnapshotCache"));
@@ -71,7 +72,7 @@ class OnyxConnectionManager {
71
72
  // in order to send all the collection entries, so the connection can't be reused.
72
73
  if (reuseConnection === false ||
73
74
  initWithStoredValues === false ||
74
- (OnyxUtils_1.default.isCollectionKey(key) && (waitForCollectionCallback === undefined || waitForCollectionCallback === false))) {
75
+ (OnyxKeys_1.default.isCollectionKey(key) && (waitForCollectionCallback === undefined || waitForCollectionCallback === false))) {
75
76
  suffix += `,uniqueID=${Str.guid()}`;
76
77
  }
77
78
  return `onyxKey=${key},initWithStoredValues=${initWithStoredValues !== null && initWithStoredValues !== void 0 ? initWithStoredValues : true},waitForCollectionCallback=${waitForCollectionCallback !== null && waitForCollectionCallback !== void 0 ? waitForCollectionCallback : false}${suffix}`;
@@ -0,0 +1,93 @@
1
+ import type { CollectionKeyBase, CollectionKey, OnyxKey } from './types';
2
+ /**
3
+ * Initializes the collection key set. Called once during Onyx.init().
4
+ */
5
+ declare function setCollectionKeys(keys: Set<OnyxKey>): void;
6
+ /**
7
+ * Returns the set of all registered collection keys.
8
+ */
9
+ declare function getCollectionKeys(): Set<OnyxKey>;
10
+ /**
11
+ * Checks if the given key is a registered collection key (e.g. "report_").
12
+ */
13
+ declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
14
+ /**
15
+ * Checks if the given key is a member of the specified collection key.
16
+ * e.g. isCollectionMemberKey("report_", "report_123") → true
17
+ */
18
+ declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string): key is `${TCollectionKey}${string}`;
19
+ /**
20
+ * Checks if a given key is a collection member key (not just a collection key).
21
+ */
22
+ declare function isCollectionMember(key: OnyxKey): boolean;
23
+ /**
24
+ * Checks if the provided key matches the config key — either an exact match
25
+ * or a collection prefix match.
26
+ */
27
+ declare function isKeyMatch(configKey: OnyxKey, key: OnyxKey): boolean;
28
+ /**
29
+ * Extracts the collection key from a collection member key.
30
+ *
31
+ * Uses a pre-computed Map for O(1) lookup. Falls back to string parsing
32
+ * for keys not yet in the map (e.g. before they're cached).
33
+ *
34
+ * Examples:
35
+ * - getCollectionKey("report_123") → "report_"
36
+ * - getCollectionKey("report_") → "report_"
37
+ * - getCollectionKey("sharedNVP_user_-1_something") → "sharedNVP_user_"
38
+ */
39
+ declare function getCollectionKey(key: CollectionKey | OnyxKey): string | undefined;
40
+ /**
41
+ * Pre-computes and caches the member → collection key mapping for a given key.
42
+ * Called from OnyxCache.addKey() to ensure the Map stays populated.
43
+ */
44
+ declare function registerMemberKey(key: OnyxKey): void;
45
+ /**
46
+ * Removes a member key from the reverse lookup map.
47
+ * Called when a key is dropped from cache.
48
+ */
49
+ declare function deregisterMemberKey(key: OnyxKey): void;
50
+ /**
51
+ * Returns the set of member keys for a given collection key.
52
+ * O(1) lookup using the forward index.
53
+ */
54
+ declare function getMembersOfCollection(collectionKey: OnyxKey): Set<OnyxKey> | undefined;
55
+ /**
56
+ * Splits a collection member key into the collection key part and the ID part.
57
+ *
58
+ * @param key - The collection member key to split
59
+ * @param collectionKey - Optional pre-resolved collection key for optimization
60
+ * @returns A tuple of [collectionKey, memberId]
61
+ * @throws If the key is not a valid collection member key
62
+ */
63
+ declare function splitCollectionMemberKey<TKey extends CollectionKey, CollectionKeyType = TKey extends `${infer Prefix}_${string}` ? `${Prefix}_` : never>(key: TKey, collectionKey?: string): [CollectionKeyType, string];
64
+ /**
65
+ * Initializes the RAM-only key set. Called once during Onyx.init().
66
+ */
67
+ declare function setRamOnlyKeys(keys: Set<OnyxKey>): void;
68
+ /**
69
+ * Checks if a given key is a RAM-only key, RAM-only collection key, or a RAM-only collection member.
70
+ *
71
+ * For example, given ramOnlyKeys: ["ramOnlyKey", "ramOnlyCollection_"]:
72
+ * - isRamOnlyKey("ramOnlyKey") → true
73
+ * - isRamOnlyKey("ramOnlyCollection_") → true
74
+ * - isRamOnlyKey("ramOnlyCollection_1") → true
75
+ * - isRamOnlyKey("someOtherKey") → false
76
+ */
77
+ declare function isRamOnlyKey(key: OnyxKey): boolean;
78
+ declare const _default: {
79
+ setCollectionKeys: typeof setCollectionKeys;
80
+ getCollectionKeys: typeof getCollectionKeys;
81
+ isCollectionKey: typeof isCollectionKey;
82
+ isCollectionMemberKey: typeof isCollectionMemberKey;
83
+ isCollectionMember: typeof isCollectionMember;
84
+ isKeyMatch: typeof isKeyMatch;
85
+ getCollectionKey: typeof getCollectionKey;
86
+ registerMemberKey: typeof registerMemberKey;
87
+ deregisterMemberKey: typeof deregisterMemberKey;
88
+ getMembersOfCollection: typeof getMembersOfCollection;
89
+ splitCollectionMemberKey: typeof splitCollectionMemberKey;
90
+ setRamOnlyKeys: typeof setRamOnlyKeys;
91
+ isRamOnlyKey: typeof isRamOnlyKey;
92
+ };
93
+ export default _default;
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /** Single source of truth for the set of registered collection keys */
4
+ let collectionKeySet = new Set();
5
+ /** Reverse lookup: member key → collection key for O(1) access */
6
+ const memberToCollectionKeyMap = new Map();
7
+ /** Forward lookup: collection key → set of member keys for O(collectionMembers) iteration */
8
+ const collectionToMembersMap = new Map();
9
+ /** Set of keys that should only be stored in RAM, not persisted to storage */
10
+ let ramOnlyKeySet = new Set();
11
+ /**
12
+ * Initializes the collection key set. Called once during Onyx.init().
13
+ */
14
+ function setCollectionKeys(keys) {
15
+ collectionKeySet = keys;
16
+ }
17
+ /**
18
+ * Returns the set of all registered collection keys.
19
+ */
20
+ function getCollectionKeys() {
21
+ return collectionKeySet;
22
+ }
23
+ /**
24
+ * Checks if the given key is a registered collection key (e.g. "report_").
25
+ */
26
+ function isCollectionKey(key) {
27
+ return collectionKeySet.has(key);
28
+ }
29
+ /**
30
+ * Checks if the given key is a member of the specified collection key.
31
+ * e.g. isCollectionMemberKey("report_", "report_123") → true
32
+ */
33
+ function isCollectionMemberKey(collectionKey, key) {
34
+ return key.startsWith(collectionKey) && key.length > collectionKey.length;
35
+ }
36
+ /**
37
+ * Checks if a given key is a collection member key (not just a collection key).
38
+ */
39
+ function isCollectionMember(key) {
40
+ const collectionKey = getCollectionKey(key);
41
+ return !!collectionKey && key.length > collectionKey.length;
42
+ }
43
+ /**
44
+ * Checks if the provided key matches the config key — either an exact match
45
+ * or a collection prefix match.
46
+ */
47
+ function isKeyMatch(configKey, key) {
48
+ return isCollectionKey(configKey) ? key.startsWith(configKey) : configKey === key;
49
+ }
50
+ /**
51
+ * Extracts the collection key from a collection member key.
52
+ *
53
+ * Uses a pre-computed Map for O(1) lookup. Falls back to string parsing
54
+ * for keys not yet in the map (e.g. before they're cached).
55
+ *
56
+ * Examples:
57
+ * - getCollectionKey("report_123") → "report_"
58
+ * - getCollectionKey("report_") → "report_"
59
+ * - getCollectionKey("sharedNVP_user_-1_something") → "sharedNVP_user_"
60
+ */
61
+ function getCollectionKey(key) {
62
+ // Fast path: O(1) Map lookup for known member keys
63
+ const cached = memberToCollectionKeyMap.get(key);
64
+ if (cached !== undefined) {
65
+ return cached;
66
+ }
67
+ // If the key itself is a collection key, return it directly
68
+ if (isCollectionKey(key)) {
69
+ return key;
70
+ }
71
+ // Slow path: string parsing — use a `string` variable to avoid
72
+ // TypeScript narrowing `key` to `never` after the isCollectionKey guard.
73
+ const keyStr = key;
74
+ let lastUnderscoreIndex = keyStr.lastIndexOf('_');
75
+ while (lastUnderscoreIndex > 0) {
76
+ const possibleKey = keyStr.slice(0, lastUnderscoreIndex + 1);
77
+ if (isCollectionKey(possibleKey)) {
78
+ // Cache for future O(1) lookups
79
+ memberToCollectionKeyMap.set(key, possibleKey);
80
+ return possibleKey;
81
+ }
82
+ lastUnderscoreIndex = keyStr.lastIndexOf('_', lastUnderscoreIndex - 1);
83
+ }
84
+ return undefined;
85
+ }
86
+ /**
87
+ * Pre-computes and caches the member → collection key mapping for a given key.
88
+ * Called from OnyxCache.addKey() to ensure the Map stays populated.
89
+ */
90
+ function registerMemberKey(key) {
91
+ const existingCollectionKey = memberToCollectionKeyMap.get(key);
92
+ if (existingCollectionKey !== undefined) {
93
+ // Already in reverse map — ensure forward map is also populated.
94
+ // getCollectionKey() can populate memberToCollectionKeyMap without
95
+ // updating collectionToMembersMap, so we must sync here.
96
+ let members = collectionToMembersMap.get(existingCollectionKey);
97
+ if (!members) {
98
+ members = new Set();
99
+ collectionToMembersMap.set(existingCollectionKey, members);
100
+ }
101
+ members.add(key);
102
+ return;
103
+ }
104
+ // Find the longest (most specific) matching collection key.
105
+ // e.g. for 'test_level_1', prefer 'test_level_' over 'test_'.
106
+ let matchedCollectionKey;
107
+ for (const collectionKey of collectionKeySet) {
108
+ if (isCollectionMemberKey(collectionKey, key)) {
109
+ if (!matchedCollectionKey || collectionKey.length > matchedCollectionKey.length) {
110
+ matchedCollectionKey = collectionKey;
111
+ }
112
+ }
113
+ }
114
+ if (matchedCollectionKey) {
115
+ memberToCollectionKeyMap.set(key, matchedCollectionKey);
116
+ // Also register in the forward lookup (collection → members)
117
+ let members = collectionToMembersMap.get(matchedCollectionKey);
118
+ if (!members) {
119
+ members = new Set();
120
+ collectionToMembersMap.set(matchedCollectionKey, members);
121
+ }
122
+ members.add(key);
123
+ }
124
+ }
125
+ /**
126
+ * Removes a member key from the reverse lookup map.
127
+ * Called when a key is dropped from cache.
128
+ */
129
+ function deregisterMemberKey(key) {
130
+ const collectionKey = memberToCollectionKeyMap.get(key);
131
+ if (collectionKey) {
132
+ const members = collectionToMembersMap.get(collectionKey);
133
+ if (members) {
134
+ members.delete(key);
135
+ if (members.size === 0) {
136
+ collectionToMembersMap.delete(collectionKey);
137
+ }
138
+ }
139
+ }
140
+ memberToCollectionKeyMap.delete(key);
141
+ }
142
+ /**
143
+ * Returns the set of member keys for a given collection key.
144
+ * O(1) lookup using the forward index.
145
+ */
146
+ function getMembersOfCollection(collectionKey) {
147
+ return collectionToMembersMap.get(collectionKey);
148
+ }
149
+ /**
150
+ * Splits a collection member key into the collection key part and the ID part.
151
+ *
152
+ * @param key - The collection member key to split
153
+ * @param collectionKey - Optional pre-resolved collection key for optimization
154
+ * @returns A tuple of [collectionKey, memberId]
155
+ * @throws If the key is not a valid collection member key
156
+ */
157
+ function splitCollectionMemberKey(key, collectionKey) {
158
+ if (collectionKey && !isCollectionMemberKey(collectionKey, key)) {
159
+ throw new Error(`Invalid '${collectionKey}' collection key provided, it isn't compatible with '${key}' key.`);
160
+ }
161
+ if (!collectionKey) {
162
+ const resolvedKey = getCollectionKey(key);
163
+ if (!resolvedKey) {
164
+ throw new Error(`Invalid '${key}' key provided, only collection keys are allowed.`);
165
+ }
166
+ // eslint-disable-next-line no-param-reassign
167
+ collectionKey = resolvedKey;
168
+ }
169
+ return [collectionKey, key.slice(collectionKey.length)];
170
+ }
171
+ /**
172
+ * Initializes the RAM-only key set. Called once during Onyx.init().
173
+ */
174
+ function setRamOnlyKeys(keys) {
175
+ ramOnlyKeySet = keys;
176
+ }
177
+ /**
178
+ * Checks if a given key is a RAM-only key, RAM-only collection key, or a RAM-only collection member.
179
+ *
180
+ * For example, given ramOnlyKeys: ["ramOnlyKey", "ramOnlyCollection_"]:
181
+ * - isRamOnlyKey("ramOnlyKey") → true
182
+ * - isRamOnlyKey("ramOnlyCollection_") → true
183
+ * - isRamOnlyKey("ramOnlyCollection_1") → true
184
+ * - isRamOnlyKey("someOtherKey") → false
185
+ */
186
+ function isRamOnlyKey(key) {
187
+ var _a;
188
+ return ramOnlyKeySet.has(key) || ramOnlyKeySet.has((_a = getCollectionKey(key)) !== null && _a !== void 0 ? _a : '');
189
+ }
190
+ exports.default = {
191
+ setCollectionKeys,
192
+ getCollectionKeys,
193
+ isCollectionKey,
194
+ isCollectionMemberKey,
195
+ isCollectionMember,
196
+ isKeyMatch,
197
+ getCollectionKey,
198
+ registerMemberKey,
199
+ deregisterMemberKey,
200
+ getMembersOfCollection,
201
+ splitCollectionMemberKey,
202
+ setRamOnlyKeys,
203
+ isRamOnlyKey,
204
+ };