react-native-onyx 2.0.110 → 2.0.112
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/Onyx.d.ts +1 -1
- package/dist/Onyx.js +2 -2
- package/dist/OnyxCache.js +9 -4
- package/dist/OnyxUtils.d.ts +3 -2
- package/dist/OnyxUtils.js +22 -11
- package/dist/types.d.ts +7 -0
- package/dist/useOnyx.js +1 -3
- package/package.json +1 -1
package/dist/Onyx.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as Logger from './Logger';
|
|
|
2
2
|
import type { CollectionKeyBase, ConnectOptions, InitOptions, Mapping, OnyxKey, OnyxMergeCollectionInput, OnyxMergeInput, OnyxMultiSetInput, OnyxSetInput, OnyxUpdate } 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, debugSetState, enablePerformanceMetrics, skippableCollectionMemberIDs, }: InitOptions): void;
|
|
5
|
+
declare function init({ keys, initialKeyStates, evictableKeys, maxCachedKeysCount, shouldSyncMultipleInstances, debugSetState, enablePerformanceMetrics, skippableCollectionMemberIDs, fullyMergedSnapshotKeys, }: InitOptions): void;
|
|
6
6
|
/**
|
|
7
7
|
* Connects to an Onyx key given the options passed and listens to its changes.
|
|
8
8
|
*
|
package/dist/Onyx.js
CHANGED
|
@@ -40,7 +40,7 @@ const OnyxConnectionManager_1 = __importDefault(require("./OnyxConnectionManager
|
|
|
40
40
|
const GlobalSettings = __importStar(require("./GlobalSettings"));
|
|
41
41
|
const metrics_1 = __importDefault(require("./metrics"));
|
|
42
42
|
/** Initialize the store with actions and listening for storage events */
|
|
43
|
-
function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, debugSetState = false, enablePerformanceMetrics = false, skippableCollectionMemberIDs = [], }) {
|
|
43
|
+
function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedKeysCount = 1000, shouldSyncMultipleInstances = !!global.localStorage, debugSetState = false, enablePerformanceMetrics = false, skippableCollectionMemberIDs = [], fullyMergedSnapshotKeys = [], }) {
|
|
44
44
|
var _a;
|
|
45
45
|
if (enablePerformanceMetrics) {
|
|
46
46
|
GlobalSettings.setPerformanceMetricsEnabled(true);
|
|
@@ -61,7 +61,7 @@ function init({ keys = {}, initialKeyStates = {}, evictableKeys = [], maxCachedK
|
|
|
61
61
|
if (maxCachedKeysCount > 0) {
|
|
62
62
|
OnyxCache_1.default.setRecentKeysLimit(maxCachedKeysCount);
|
|
63
63
|
}
|
|
64
|
-
OnyxUtils_1.default.initStoreValues(keys, initialKeyStates, evictableKeys);
|
|
64
|
+
OnyxUtils_1.default.initStoreValues(keys, initialKeyStates, evictableKeys, fullyMergedSnapshotKeys);
|
|
65
65
|
// Initialize all of our keys with data provided then give green light to any pending connections
|
|
66
66
|
Promise.all([OnyxCache_1.default.addEvictableKeysToRecentlyAccessedList(OnyxUtils_1.default.isCollectionKey, OnyxUtils_1.default.getAllKeys), OnyxUtils_1.default.initializeWithDefaultKeyStates()]).then(OnyxUtils_1.default.getDeferredInitTask().resolve);
|
|
67
67
|
}
|
package/dist/OnyxCache.js
CHANGED
|
@@ -51,7 +51,7 @@ class OnyxCache {
|
|
|
51
51
|
/** Map of keys and connection arrays whose keys will never be automatically evicted */
|
|
52
52
|
this.evictionBlocklist = {};
|
|
53
53
|
/** List of keys that have been directly subscribed to or recently modified from least to most recent */
|
|
54
|
-
this.recentlyAccessedKeys =
|
|
54
|
+
this.recentlyAccessedKeys = new Set();
|
|
55
55
|
this.storageKeys = new Set();
|
|
56
56
|
this.nullishStorageKeys = new Set();
|
|
57
57
|
this.recentKeys = new Set();
|
|
@@ -252,7 +252,7 @@ class OnyxCache {
|
|
|
252
252
|
* Remove a key from the recently accessed key list.
|
|
253
253
|
*/
|
|
254
254
|
removeLastAccessedKey(key) {
|
|
255
|
-
this.recentlyAccessedKeys
|
|
255
|
+
this.recentlyAccessedKeys.delete(key);
|
|
256
256
|
}
|
|
257
257
|
/**
|
|
258
258
|
* Add a key to the list of recently accessed keys. The least
|
|
@@ -265,7 +265,7 @@ class OnyxCache {
|
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
267
267
|
this.removeLastAccessedKey(key);
|
|
268
|
-
this.recentlyAccessedKeys.
|
|
268
|
+
this.recentlyAccessedKeys.add(key);
|
|
269
269
|
}
|
|
270
270
|
/**
|
|
271
271
|
* Take all the keys that are safe to evict and add them to
|
|
@@ -291,7 +291,12 @@ class OnyxCache {
|
|
|
291
291
|
* Finds a key that can be safely evicted
|
|
292
292
|
*/
|
|
293
293
|
getKeyForEviction() {
|
|
294
|
-
|
|
294
|
+
for (const key of this.recentlyAccessedKeys) {
|
|
295
|
+
if (!this.evictionBlocklist[key]) {
|
|
296
|
+
return key;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return undefined;
|
|
295
300
|
}
|
|
296
301
|
}
|
|
297
302
|
const instance = new OnyxCache();
|
package/dist/OnyxUtils.d.ts
CHANGED
|
@@ -43,8 +43,9 @@ declare function setSkippableCollectionMemberIDs(ids: Set<string>): void;
|
|
|
43
43
|
* @param keys - `ONYXKEYS` constants object from Onyx.init()
|
|
44
44
|
* @param initialKeyStates - initial data to set when `init()` and `clear()` are called
|
|
45
45
|
* @param evictableKeys - This is an array of keys (individual or collection patterns) that when provided to Onyx are flagged as "safe" for removal.
|
|
46
|
+
* @param fullyMergedSnapshotKeys - Array of snapshot collection keys where full merge is supported and data structure can be changed after merge.
|
|
46
47
|
*/
|
|
47
|
-
declare function initStoreValues(keys: DeepRecord<string, OnyxKey>, initialKeyStates: Partial<KeyValueMapping>, evictableKeys: OnyxKey[]): void;
|
|
48
|
+
declare function initStoreValues(keys: DeepRecord<string, OnyxKey>, initialKeyStates: Partial<KeyValueMapping>, evictableKeys: OnyxKey[], fullyMergedSnapshotKeysParam?: string[]): void;
|
|
48
49
|
/**
|
|
49
50
|
* Sends an action to DevTools extension
|
|
50
51
|
*
|
|
@@ -105,7 +106,7 @@ declare function getCollectionKeys(): Set<OnyxKey>;
|
|
|
105
106
|
* is associated with a collection of keys.
|
|
106
107
|
*/
|
|
107
108
|
declare function isCollectionKey(key: OnyxKey): key is CollectionKeyBase;
|
|
108
|
-
declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string
|
|
109
|
+
declare function isCollectionMemberKey<TCollectionKey extends CollectionKeyBase>(collectionKey: TCollectionKey, key: string): key is `${TCollectionKey}${string}`;
|
|
109
110
|
/**
|
|
110
111
|
* Splits a collection member key into the collection key part and the ID part.
|
|
111
112
|
* @param key - The collection member key to split.
|
package/dist/OnyxUtils.js
CHANGED
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
/* eslint-disable no-continue */
|
|
30
30
|
const fast_equals_1 = require("fast-equals");
|
|
31
31
|
const clone_1 = __importDefault(require("lodash/clone"));
|
|
32
|
+
const pick_1 = __importDefault(require("lodash/pick"));
|
|
32
33
|
const DevTools_1 = __importDefault(require("./DevTools"));
|
|
33
34
|
const Logger = __importStar(require("./Logger"));
|
|
34
35
|
const OnyxCache_1 = __importStar(require("./OnyxCache"));
|
|
@@ -65,6 +66,7 @@ let batchUpdatesQueue = [];
|
|
|
65
66
|
// Used for comparison with a new update to avoid invoking the Onyx.connect callback with the same data.
|
|
66
67
|
const lastConnectionCallbackData = new Map();
|
|
67
68
|
let snapshotKey = null;
|
|
69
|
+
let fullyMergedSnapshotKeys;
|
|
68
70
|
// Keeps track of the last subscriptionID that was used so we can keep incrementing it
|
|
69
71
|
let lastSubscriptionID = 0;
|
|
70
72
|
// Connections can be made before `Onyx.init`. They would wait for this task before resolving
|
|
@@ -116,8 +118,9 @@ function setSkippableCollectionMemberIDs(ids) {
|
|
|
116
118
|
* @param keys - `ONYXKEYS` constants object from Onyx.init()
|
|
117
119
|
* @param initialKeyStates - initial data to set when `init()` and `clear()` are called
|
|
118
120
|
* @param evictableKeys - This is an array of keys (individual or collection patterns) that when provided to Onyx are flagged as "safe" for removal.
|
|
121
|
+
* @param fullyMergedSnapshotKeys - Array of snapshot collection keys where full merge is supported and data structure can be changed after merge.
|
|
119
122
|
*/
|
|
120
|
-
function initStoreValues(keys, initialKeyStates, evictableKeys) {
|
|
123
|
+
function initStoreValues(keys, initialKeyStates, evictableKeys, fullyMergedSnapshotKeysParam) {
|
|
121
124
|
var _a;
|
|
122
125
|
// We need the value of the collection keys later for checking if a
|
|
123
126
|
// key is a collection. We store it in a map for faster lookup.
|
|
@@ -133,6 +136,7 @@ function initStoreValues(keys, initialKeyStates, evictableKeys) {
|
|
|
133
136
|
OnyxCache_1.default.setEvictionAllowList(evictableKeys);
|
|
134
137
|
if (typeof keys.COLLECTION === 'object' && typeof keys.COLLECTION.SNAPSHOT === 'string') {
|
|
135
138
|
snapshotKey = keys.COLLECTION.SNAPSHOT;
|
|
139
|
+
fullyMergedSnapshotKeys = new Set(fullyMergedSnapshotKeysParam !== null && fullyMergedSnapshotKeysParam !== void 0 ? fullyMergedSnapshotKeysParam : []);
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
function sendActionToDevTools(method, key, value, mergedValue = undefined) {
|
|
@@ -361,8 +365,8 @@ function getCollectionKeys() {
|
|
|
361
365
|
function isCollectionKey(key) {
|
|
362
366
|
return onyxCollectionKeySet.has(key);
|
|
363
367
|
}
|
|
364
|
-
function isCollectionMemberKey(collectionKey, key
|
|
365
|
-
return key.startsWith(collectionKey) && key.length >
|
|
368
|
+
function isCollectionMemberKey(collectionKey, key) {
|
|
369
|
+
return key.startsWith(collectionKey) && key.length > collectionKey.length;
|
|
366
370
|
}
|
|
367
371
|
/**
|
|
368
372
|
* Splits a collection member key into the collection key part and the ID part.
|
|
@@ -372,7 +376,7 @@ function isCollectionMemberKey(collectionKey, key, collectionKeyLength) {
|
|
|
372
376
|
* or throws an Error if the key is not a collection one.
|
|
373
377
|
*/
|
|
374
378
|
function splitCollectionMemberKey(key, collectionKey) {
|
|
375
|
-
if (collectionKey && !isCollectionMemberKey(collectionKey, key
|
|
379
|
+
if (collectionKey && !isCollectionMemberKey(collectionKey, key)) {
|
|
376
380
|
throw new Error(`Invalid '${collectionKey}' collection key provided, it isn't compatible with '${key}' key.`);
|
|
377
381
|
}
|
|
378
382
|
if (!collectionKey) {
|
|
@@ -450,13 +454,12 @@ function tryGetCachedValue(key, mapping) {
|
|
|
450
454
|
function getCachedCollection(collectionKey, collectionMemberKeys) {
|
|
451
455
|
const allKeys = collectionMemberKeys || OnyxCache_1.default.getAllKeys();
|
|
452
456
|
const collection = {};
|
|
453
|
-
const collectionKeyLength = collectionKey.length;
|
|
454
457
|
// forEach exists on both Set and Array
|
|
455
458
|
allKeys.forEach((key) => {
|
|
456
459
|
// If we don't have collectionMemberKeys array then we have to check whether a key is a collection member key.
|
|
457
460
|
// Because in that case the keys will be coming from `cache.getAllKeys()` and we need to filter out the keys that
|
|
458
461
|
// are not part of the collection.
|
|
459
|
-
if (!collectionMemberKeys && !isCollectionMemberKey(collectionKey, key
|
|
462
|
+
if (!collectionMemberKeys && !isCollectionMemberKey(collectionKey, key)) {
|
|
460
463
|
return;
|
|
461
464
|
}
|
|
462
465
|
const cachedValue = OnyxCache_1.default.get(key);
|
|
@@ -479,7 +482,6 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
479
482
|
// individual collection key member for the collection that is being updated. It is important to note that the collection parameter cane be a PARTIAL collection
|
|
480
483
|
// and does not represent all of the combined keys and values for a collection key. It is just the "new" data that was merged in via mergeCollection().
|
|
481
484
|
const stateMappingKeys = Object.keys(callbackToStateMapping);
|
|
482
|
-
const collectionKeyLength = collectionKey.length;
|
|
483
485
|
for (const stateMappingKey of stateMappingKeys) {
|
|
484
486
|
const subscriber = callbackToStateMapping[stateMappingKey];
|
|
485
487
|
if (!subscriber) {
|
|
@@ -496,7 +498,7 @@ function keysChanged(collectionKey, partialCollection, partialPreviousCollection
|
|
|
496
498
|
/**
|
|
497
499
|
* e.g. Onyx.connect({key: `${ONYXKEYS.COLLECTION.REPORT}{reportID}`, callback: ...});
|
|
498
500
|
*/
|
|
499
|
-
const isSubscribedToCollectionMemberKey = isCollectionMemberKey(collectionKey, subscriber.key
|
|
501
|
+
const isSubscribedToCollectionMemberKey = isCollectionMemberKey(collectionKey, subscriber.key);
|
|
500
502
|
// Regular Onyx.connect() subscriber found.
|
|
501
503
|
if (typeof subscriber.callback === 'function') {
|
|
502
504
|
if (!notifyConnectSubscribers) {
|
|
@@ -1121,7 +1123,6 @@ function updateSnapshots(data, mergeFn) {
|
|
|
1121
1123
|
return [];
|
|
1122
1124
|
const promises = [];
|
|
1123
1125
|
const snapshotCollection = OnyxUtils.getCachedCollection(snapshotCollectionKey);
|
|
1124
|
-
const snapshotCollectionKeyLength = snapshotCollectionKey.length;
|
|
1125
1126
|
Object.entries(snapshotCollection).forEach(([snapshotEntryKey, snapshotEntryValue]) => {
|
|
1126
1127
|
// Snapshots may not be present in cache. We don't know how to update them so we skip.
|
|
1127
1128
|
if (!snapshotEntryValue) {
|
|
@@ -1130,7 +1131,7 @@ function updateSnapshots(data, mergeFn) {
|
|
|
1130
1131
|
let updatedData = {};
|
|
1131
1132
|
data.forEach(({ key, value }) => {
|
|
1132
1133
|
// snapshots are normal keys so we want to skip update if they are written to Onyx
|
|
1133
|
-
if (OnyxUtils.isCollectionMemberKey(snapshotCollectionKey, key
|
|
1134
|
+
if (OnyxUtils.isCollectionMemberKey(snapshotCollectionKey, key)) {
|
|
1134
1135
|
return;
|
|
1135
1136
|
}
|
|
1136
1137
|
if (typeof snapshotEntryValue !== 'object' || !('data' in snapshotEntryValue)) {
|
|
@@ -1149,7 +1150,17 @@ function updateSnapshots(data, mergeFn) {
|
|
|
1149
1150
|
return;
|
|
1150
1151
|
}
|
|
1151
1152
|
const oldValue = updatedData[key] || {};
|
|
1152
|
-
|
|
1153
|
+
let collectionKey;
|
|
1154
|
+
try {
|
|
1155
|
+
collectionKey = getCollectionKey(key);
|
|
1156
|
+
}
|
|
1157
|
+
catch (e) {
|
|
1158
|
+
// If getCollectionKey() throws an error it means the key is not a collection key.
|
|
1159
|
+
collectionKey = undefined;
|
|
1160
|
+
}
|
|
1161
|
+
const shouldFullyMerge = fullyMergedSnapshotKeys === null || fullyMergedSnapshotKeys === void 0 ? void 0 : fullyMergedSnapshotKeys.has(collectionKey || key);
|
|
1162
|
+
const newValue = shouldFullyMerge ? value : (0, pick_1.default)(value, Object.keys(snapshotData[key]));
|
|
1163
|
+
updatedData = Object.assign(Object.assign({}, updatedData), { [key]: Object.assign(oldValue, newValue) });
|
|
1153
1164
|
});
|
|
1154
1165
|
// Skip the update if there's no data to be merged
|
|
1155
1166
|
if (utils_1.default.isEmptyObject(updatedData)) {
|
package/dist/types.d.ts
CHANGED
|
@@ -403,6 +403,13 @@ type InitOptions = {
|
|
|
403
403
|
* Additionally, any subscribers from these keys to won't receive any data from Onyx.
|
|
404
404
|
*/
|
|
405
405
|
skippableCollectionMemberIDs?: string[];
|
|
406
|
+
/**
|
|
407
|
+
* Array of snapshot collection keys where full merge is supported and data structure can be changed after merge.
|
|
408
|
+
* For e.g. if oldSnapshotData is {report_1: {name 'Fitsum'}} and BE update is {report_1: {name:'Fitsum2', nickName:'Fitse'}}
|
|
409
|
+
* if it is fullyMergedSnapshotkey the `nickName` prop that didn't exist in the previous data will be merged
|
|
410
|
+
* otherwise only existing prop will be picked from the BE update and merged (in this case only name).
|
|
411
|
+
*/
|
|
412
|
+
fullyMergedSnapshotKeys?: string[];
|
|
406
413
|
};
|
|
407
414
|
type GenericFunction = (...args: any[]) => any;
|
|
408
415
|
/**
|
package/dist/useOnyx.js
CHANGED
|
@@ -74,9 +74,7 @@ function useOnyx(key, options, dependencies = []) {
|
|
|
74
74
|
try {
|
|
75
75
|
const previousCollectionKey = OnyxUtils_1.default.splitCollectionMemberKey(previousKey)[0];
|
|
76
76
|
const collectionKey = OnyxUtils_1.default.splitCollectionMemberKey(key)[0];
|
|
77
|
-
if (OnyxUtils_1.default.isCollectionMemberKey(previousCollectionKey, previousKey, previousCollectionKey
|
|
78
|
-
OnyxUtils_1.default.isCollectionMemberKey(collectionKey, key, collectionKey.length) &&
|
|
79
|
-
previousCollectionKey === collectionKey) {
|
|
77
|
+
if (OnyxUtils_1.default.isCollectionMemberKey(previousCollectionKey, previousKey) && OnyxUtils_1.default.isCollectionMemberKey(collectionKey, key) && previousCollectionKey === collectionKey) {
|
|
80
78
|
return;
|
|
81
79
|
}
|
|
82
80
|
}
|