react-native-onyx 3.0.53 → 3.0.55

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.
package/README.md CHANGED
@@ -351,59 +351,6 @@ const ReportActionsView = ({reportID, isActiveReport}) => {
351
351
  export default ReportActionsView;
352
352
  ```
353
353
 
354
- # Benchmarks
355
-
356
- Provide the `captureMetrics` boolean flag to `Onyx.init` to capture call statistics
357
-
358
- ```js
359
- Onyx.init({
360
- keys: ONYXKEYS,
361
- evictableKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
362
- captureMetrics: Config.BENCHMARK_ONYX,
363
- });
364
- ```
365
-
366
- At any point you can get the collected statistics using `Onyx.getMetrics()`.
367
- This will return an object containing `totalTime`, `averageTime` and `summaries`.
368
- `summaries` is a collection of statistics for each method it contains data about:
369
- - method name
370
- - total, max, min, average times for this method calls
371
- - calls - a list of individual calls with each having: start time; end time; call duration; call arguments
372
- - start/end times are relative to application launch time - 0.00 being exactly at launch
373
-
374
- If you wish to reset the metrics and start over use `Onyx.resetMetrics()`
375
-
376
- Finally, there's a `Onyx.printMetrics()` method which prints human statistics information on the dev console. You can use this method during debugging. For example add an `Onyx.printMetrics()` line somewhere in code or call it through the dev console. It supports 3 popular formats *MD* - human friendly markdown, *CSV* and *JSON*. The default is MD if you want to print another format call `Onyx.printMetrics({ format: 'csv' })` or
377
- `Onyx.printMetrics({ format: 'json' })`.
378
-
379
- Sample output of `Onyx.printMetrics()`
380
-
381
- ```
382
- ### Onyx Benchmark
383
- - Total: 1.5min
384
- - Last call finished at: 12.55sec
385
-
386
- | method | total time spent | max | min | avg | time last call completed | calls made |
387
- |-----------------|-----------------:|----------:|---------:|----------:|-------------------------:|-----------:|
388
- | Onyx:getAllKeys | 1.2min | 2.16sec | 0.159ms | 782.230ms | 12.55sec | 90 |
389
- | Onyx:merge | 4.73sec | 2.00sec | 74.412ms | 591.642ms | 10.24sec | 8 |
390
- | Onyx:set | 3.90sec | 846.760ms | 43.663ms | 433.056ms | 7.47sec | 9 |
391
- | Onyx:get | 8.87sec | 2.00sec | 0.063ms | 61.998ms | 10.24sec | 143 |
392
-
393
-
394
- | Onyx:set |
395
- |---------------------------------------------------------------|
396
- | start time | end time | duration | args |
397
- |-----------:|----------:|----------:|--------------------------|
398
- | 291.042ms | 553.079ms | 262.037ms | session, [object Object] |
399
- | 293.719ms | 553.316ms | 259.597ms | account, [object Object] |
400
- | 294.541ms | 553.651ms | 259.109ms | network, [object Object] |
401
- | 365.378ms | 554.246ms | 188.867ms | iou, [object Object] |
402
- | 1.08sec | 2.20sec | 1.12sec | network, [object Object] |
403
- | 1.08sec | 2.20sec | 1.12sec | iou, [object Object] |
404
- | 1.17sec | 2.20sec | 1.03sec | currentURL, / |
405
- ```
406
-
407
354
  # Debug mode
408
355
 
409
356
  It can be useful to log why Onyx is calling `setState()` on a particular React component so that we can understand which key changed, what changed about the value, and the connected component that ultimately rendered as a result. When used correctly this can help isolate problem areas and unnecessary renders in the code. To enable this feature, pass `debugSetState: true` to the config and grep JS console logs for `[Onyx-Debug]`.
@@ -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.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as Logger from './Logger';
2
2
  import type { CollectionKeyBase, ConnectOptions, InitOptions, OnyxKey, OnyxMergeCollectionInput, OnyxSetCollectionInput, OnyxMergeInput, OnyxMultiSetInput, OnyxSetInput, OnyxUpdate, SetOptions } from './types';
3
3
  import type { Connection } from './OnyxConnectionManager';
4
4
  /** Initialize the store with actions and listening for storage events */
5
- declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances, enablePerformanceMetrics, enableDevTools, skippableCollectionMemberIDs, ramOnlyKeys, snapshotMergeKeys, }: InitOptions): void;
5
+ declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances, enableDevTools, skippableCollectionMemberIDs, ramOnlyKeys, snapshotMergeKeys, }: InitOptions): void;
6
6
  /**
7
7
  * Connects to an Onyx key given the options passed and listens to its changes.
8
8
  * This method will be deprecated soon. Please use `Onyx.connectWithoutView()` instead.
package/dist/Onyx.js CHANGED
@@ -42,35 +42,30 @@ 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
- const GlobalSettings = __importStar(require("./GlobalSettings"));
48
- const metrics_1 = __importDefault(require("./metrics"));
49
48
  const OnyxMerge_1 = __importDefault(require("./OnyxMerge"));
50
49
  /** Initialize the store with actions and listening for storage events */
51
- function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, enablePerformanceMetrics = false, enableDevTools = true, skippableCollectionMemberIDs = [], ramOnlyKeys = [], snapshotMergeKeys = [], }) {
50
+ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, enableDevTools = true, skippableCollectionMemberIDs = [], ramOnlyKeys = [], snapshotMergeKeys = [], }) {
52
51
  var _a;
53
- if (enablePerformanceMetrics) {
54
- GlobalSettings.setPerformanceMetricsEnabled(true);
55
- applyDecorators();
56
- }
57
52
  (0, DevTools_1.initDevTools)(enableDevTools);
58
53
  storage_1.default.init();
59
54
  OnyxUtils_1.default.setSkippableCollectionMemberIDs(new Set(skippableCollectionMemberIDs));
60
55
  OnyxUtils_1.default.setSnapshotMergeKeys(new Set(snapshotMergeKeys));
61
- OnyxCache_1.default.setRamOnlyKeys(new Set(ramOnlyKeys));
56
+ OnyxKeys_1.default.setRamOnlyKeys(new Set(ramOnlyKeys));
62
57
  if (shouldSyncMultipleInstances) {
63
58
  (_a = storage_1.default.keepInstancesSync) === null || _a === void 0 ? void 0 : _a.call(storage_1.default, (key, value) => {
64
59
  // RAM-only keys should never sync from storage as they may have stale persisted data
65
60
  // from before the key was migrated to RAM-only.
66
- if (OnyxUtils_1.default.isRamOnlyKey(key)) {
61
+ if (OnyxKeys_1.default.isRamOnlyKey(key)) {
67
62
  return;
68
63
  }
69
64
  OnyxCache_1.default.set(key, value);
70
65
  // Check if this is a collection member key to prevent duplicate callbacks
71
66
  // When a collection is updated, individual members sync separately to other tabs
72
67
  // Setting isProcessingCollectionUpdate=true prevents triggering collection callbacks for each individual update
73
- const isKeyCollectionMember = OnyxUtils_1.default.isCollectionMember(key);
68
+ const isKeyCollectionMember = OnyxKeys_1.default.isCollectionMember(key);
74
69
  OnyxUtils_1.default.keyChanged(key, value, undefined, isKeyCollectionMember);
75
70
  });
76
71
  }
@@ -83,7 +78,7 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
83
78
  // eager cache loading populates the key index (cache.setAllKeys) inside initializeWithDefaultKeyStates,
84
79
  // and the evictable keys list depends on that index being populated.
85
80
  OnyxUtils_1.default.initializeWithDefaultKeyStates()
86
- .then(() => OnyxCache_1.default.addEvictableKeysToRecentlyAccessedList(OnyxUtils_1.default.isCollectionKey, OnyxUtils_1.default.getAllKeys))
81
+ .then(() => OnyxCache_1.default.addEvictableKeysToRecentlyAccessedList(OnyxKeys_1.default.isCollectionKey, OnyxUtils_1.default.getAllKeys))
87
82
  .then(OnyxUtils_1.default.getDeferredInitTask().resolve);
88
83
  }
89
84
  /**
@@ -194,7 +189,7 @@ function merge(key, changes) {
194
189
  const skippableCollectionMemberIDs = OnyxUtils_1.default.getSkippableCollectionMemberIDs();
195
190
  if (skippableCollectionMemberIDs.size) {
196
191
  try {
197
- const [, collectionMemberID] = OnyxUtils_1.default.splitCollectionMemberKey(key);
192
+ const [, collectionMemberID] = OnyxKeys_1.default.splitCollectionMemberKey(key);
198
193
  if (skippableCollectionMemberIDs.has(collectionMemberID)) {
199
194
  // The key is a skippable one, so we set the new changes to undefined.
200
195
  // eslint-disable-next-line no-param-reassign
@@ -322,7 +317,7 @@ function clear(keysToPreserve = []) {
322
317
  // to null would cause unknown behavior)
323
318
  // 2.1 However, if a default key was explicitly set to null, we need to reset it to the default value
324
319
  for (const key of allKeys) {
325
- const isKeyToPreserve = keysToPreserve.some((preserveKey) => OnyxUtils_1.default.isKeyMatch(preserveKey, key));
320
+ const isKeyToPreserve = keysToPreserve.some((preserveKey) => OnyxKeys_1.default.isKeyMatch(preserveKey, key));
326
321
  const isDefaultKey = key in defaultKeyStates;
327
322
  // If the key is being removed or reset to default:
328
323
  // 1. Update it in the cache
@@ -333,7 +328,7 @@ function clear(keysToPreserve = []) {
333
328
  const newValue = (_a = defaultKeyStates[key]) !== null && _a !== void 0 ? _a : null;
334
329
  if (newValue !== oldValue) {
335
330
  OnyxCache_1.default.set(key, newValue);
336
- const collectionKey = OnyxUtils_1.default.getCollectionKey(key);
331
+ const collectionKey = OnyxKeys_1.default.getCollectionKey(key);
337
332
  if (collectionKey) {
338
333
  if (!keyValuesToResetAsCollection[collectionKey]) {
339
334
  keyValuesToResetAsCollection[collectionKey] = { oldValues: {}, newValues: {} };
@@ -362,7 +357,7 @@ function clear(keysToPreserve = []) {
362
357
  }
363
358
  // Exclude RAM-only keys to prevent them from being saved to storage
364
359
  const defaultKeyValuePairs = Object.entries(Object.keys(defaultKeyStates)
365
- .filter((key) => !keysToPreserve.some((preserveKey) => OnyxUtils_1.default.isKeyMatch(preserveKey, key)) && !OnyxUtils_1.default.isRamOnlyKey(key))
360
+ .filter((key) => !keysToPreserve.some((preserveKey) => OnyxKeys_1.default.isKeyMatch(preserveKey, key)) && !OnyxKeys_1.default.isRamOnlyKey(key))
366
361
  .reduce((obj, key) => {
367
362
  // eslint-disable-next-line no-param-reassign
368
363
  obj[key] = defaultKeyStates[key];
@@ -459,8 +454,8 @@ function update(data) {
459
454
  // Group all the collection-related keys and update each collection in a single `mergeCollection` call.
460
455
  // This is needed to prevent multiple `mergeCollection` calls for the same collection and `merge` calls for the individual items of the said collection.
461
456
  // 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));
457
+ for (const collectionKey of OnyxKeys_1.default.getCollectionKeys()) {
458
+ const collectionItemKeys = Object.keys(updateQueue).filter((key) => OnyxKeys_1.default.isKeyMatch(collectionKey, key));
464
459
  if (collectionItemKeys.length <= 1) {
465
460
  // If there are no items of this collection in the updateQueue, we should skip it.
466
461
  // If there is only one item, we should update it individually, therefore retain it in the updateQueue.
@@ -548,23 +543,4 @@ const Onyx = {
548
543
  init,
549
544
  registerLogger: Logger.registerLogger,
550
545
  };
551
- function applyDecorators() {
552
- // We are reassigning the functions directly so that internal function calls are also decorated
553
- // @ts-expect-error Reassign
554
- connect = (0, metrics_1.default)(connect, 'Onyx.connect');
555
- // @ts-expect-error Reassign
556
- connectWithoutView = (0, metrics_1.default)(connectWithoutView, 'Onyx.connectWithoutView');
557
- // @ts-expect-error Reassign
558
- set = (0, metrics_1.default)(set, 'Onyx.set');
559
- // @ts-expect-error Reassign
560
- multiSet = (0, metrics_1.default)(multiSet, 'Onyx.multiSet');
561
- // @ts-expect-error Reassign
562
- merge = (0, metrics_1.default)(merge, 'Onyx.merge');
563
- // @ts-expect-error Reassign
564
- mergeCollection = (0, metrics_1.default)(mergeCollection, 'Onyx.mergeCollection');
565
- // @ts-expect-error Reassign
566
- update = (0, metrics_1.default)(update, 'Onyx.update');
567
- // @ts-expect-error Reassign
568
- clear = (0, metrics_1.default)(clear, 'Onyx.clear');
569
- }
570
546
  exports.default = Onyx;
@@ -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;