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.
- package/dist/DevTools/RealDevTools.js +2 -2
- package/dist/Onyx.js +11 -10
- package/dist/OnyxCache.d.ts +0 -26
- package/dist/OnyxCache.js +15 -85
- package/dist/OnyxConnectionManager.js +2 -1
- package/dist/OnyxKeys.d.ts +93 -0
- package/dist/OnyxKeys.js +204 -0
- package/dist/OnyxMerge/index.js +2 -1
- package/dist/OnyxMerge/index.native.js +2 -1
- package/dist/OnyxSnapshotCache.js +2 -2
- package/dist/OnyxUtils.d.ts +1 -69
- package/dist/OnyxUtils.js +38 -155
- package/dist/useOnyx.js +2 -1
- package/package.json +1 -1
|
@@ -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
|
|
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) =>
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
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(
|
|
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] =
|
|
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) =>
|
|
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 =
|
|
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) =>
|
|
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
|
|
463
|
-
const collectionItemKeys = Object.keys(updateQueue).filter((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.
|
package/dist/OnyxCache.d.ts
CHANGED
|
@@ -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
|
|
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', '
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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) =>
|
|
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 (!
|
|
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
|
-
|
|
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
|
-
(
|
|
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;
|
package/dist/OnyxKeys.js
ADDED
|
@@ -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
|
+
};
|