react-native-onyx 1.0.56 → 1.0.58
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/web.development.js +176 -174
- package/dist/web.development.js.map +1 -1
- package/dist/web.min.js +1 -1
- package/dist/web.min.js.map +1 -1
- package/lib/Onyx.js +40 -25
- package/package.json +1 -2
package/dist/web.development.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
2
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
-
module.exports = factory(require("fast-equals"), require("
|
|
3
|
+
module.exports = factory(require("fast-equals"), require("underscore"), require("localforage"), require("localforage-removeitems"), require("lodash/transform"), require("react"));
|
|
4
4
|
else if(typeof define === 'function' && define.amd)
|
|
5
|
-
define(["fast-equals", "
|
|
5
|
+
define(["fast-equals", "underscore", "localforage", "localforage-removeitems", "lodash/transform", "react"], factory);
|
|
6
6
|
else if(typeof exports === 'object')
|
|
7
|
-
exports["react-native-onyx/web"] = factory(require("fast-equals"), require("
|
|
7
|
+
exports["react-native-onyx/web"] = factory(require("fast-equals"), require("underscore"), require("localforage"), require("localforage-removeitems"), require("lodash/transform"), require("react"));
|
|
8
8
|
else
|
|
9
|
-
root["react-native-onyx/web"] = factory(root["fast-equals"], root["
|
|
10
|
-
})(self, (__WEBPACK_EXTERNAL_MODULE_fast_equals__,
|
|
9
|
+
root["react-native-onyx/web"] = factory(root["fast-equals"], root["underscore"], root["localforage"], root["localforage-removeitems"], root["lodash/transform"], root["react"]);
|
|
10
|
+
})(self, (__WEBPACK_EXTERNAL_MODULE_fast_equals__, __WEBPACK_EXTERNAL_MODULE_underscore__, __WEBPACK_EXTERNAL_MODULE_localforage__, __WEBPACK_EXTERNAL_MODULE_localforage_removeitems__, __WEBPACK_EXTERNAL_MODULE_lodash_transform__, __WEBPACK_EXTERNAL_MODULE_react__) => {
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
12
|
/******/ var __webpack_modules__ = ({
|
|
13
13
|
|
|
@@ -71,17 +71,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
71
71
|
/* harmony export */ });
|
|
72
72
|
/* harmony import */ var fast_equals__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fast-equals */ "fast-equals");
|
|
73
73
|
/* harmony import */ var fast_equals__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fast_equals__WEBPACK_IMPORTED_MODULE_0__);
|
|
74
|
-
/* harmony import */ var
|
|
75
|
-
/* harmony import */ var
|
|
76
|
-
/* harmony import */ var
|
|
77
|
-
/* harmony import */ var
|
|
78
|
-
/* harmony import */ var
|
|
79
|
-
/* harmony import */ var
|
|
80
|
-
/* harmony import */ var
|
|
81
|
-
/* harmony import */ var
|
|
82
|
-
/* harmony import */ var
|
|
83
|
-
/* harmony import */ var _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./metrics/PerformanceUtils */ "./lib/metrics/PerformanceUtils.js");
|
|
84
|
-
/* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./storage */ "./lib/storage/index.web.js");
|
|
74
|
+
/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! underscore */ "underscore");
|
|
75
|
+
/* harmony import */ var underscore__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(underscore__WEBPACK_IMPORTED_MODULE_1__);
|
|
76
|
+
/* harmony import */ var _Logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Logger */ "./lib/Logger.js");
|
|
77
|
+
/* harmony import */ var _OnyxCache__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./OnyxCache */ "./lib/OnyxCache.js");
|
|
78
|
+
/* harmony import */ var _Str__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Str */ "./lib/Str.js");
|
|
79
|
+
/* harmony import */ var _createDeferredTask__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./createDeferredTask */ "./lib/createDeferredTask.js");
|
|
80
|
+
/* harmony import */ var _fastMerge__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./fastMerge */ "./lib/fastMerge.js");
|
|
81
|
+
/* harmony import */ var _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./metrics/PerformanceUtils */ "./lib/metrics/PerformanceUtils.js");
|
|
82
|
+
/* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./storage */ "./lib/storage/index.web.js");
|
|
85
83
|
/* eslint-disable no-continue */
|
|
86
84
|
|
|
87
85
|
|
|
@@ -93,7 +91,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
93
91
|
|
|
94
92
|
|
|
95
93
|
|
|
96
|
-
|
|
97
94
|
// Method constants
|
|
98
95
|
const METHOD = {
|
|
99
96
|
SET: 'set',
|
|
@@ -129,20 +126,16 @@ const evictionBlocklist = {};
|
|
|
129
126
|
let defaultKeyStates = {};
|
|
130
127
|
|
|
131
128
|
// Connections can be made before `Onyx.init`. They would wait for this task before resolving
|
|
132
|
-
const deferredInitTask = (0,
|
|
129
|
+
const deferredInitTask = (0,_createDeferredTask__WEBPACK_IMPORTED_MODULE_2__["default"])();
|
|
133
130
|
|
|
134
131
|
/**
|
|
135
|
-
* Uses a selector
|
|
132
|
+
* Uses a selector function to return a simplified version of sourceData
|
|
136
133
|
* @param {Mixed} sourceData
|
|
137
|
-
* @param {
|
|
134
|
+
* @param {Function} selector Function that takes sourceData and returns a simplified version of it
|
|
138
135
|
* @param {Object} [withOnyxInstanceState]
|
|
139
|
-
* If it's a string, the selector is passed to lodashGet on the sourceData
|
|
140
|
-
* If it's a function, it is passed the sourceData and it should return the simplified data
|
|
141
136
|
* @returns {Mixed}
|
|
142
137
|
*/
|
|
143
|
-
const getSubsetOfData = (sourceData, selector, withOnyxInstanceState) =>
|
|
144
|
-
selector(sourceData, withOnyxInstanceState) :
|
|
145
|
-
lodash_get__WEBPACK_IMPORTED_MODULE_1___default()(sourceData, selector);
|
|
138
|
+
const getSubsetOfData = (sourceData, selector, withOnyxInstanceState) => selector(sourceData, withOnyxInstanceState);
|
|
146
139
|
|
|
147
140
|
/**
|
|
148
141
|
* Takes a collection of items (eg. {testKey_1:{a:'a'}, testKey_2:{b:'b'}})
|
|
@@ -153,7 +146,7 @@ lodash_get__WEBPACK_IMPORTED_MODULE_1___default()(sourceData, selector);
|
|
|
153
146
|
* @param {Object} [withOnyxInstanceState]
|
|
154
147
|
* @returns {Object}
|
|
155
148
|
*/
|
|
156
|
-
const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceState) =>
|
|
149
|
+
const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceState) => underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(collection, (finalCollection, item, key) => {
|
|
157
150
|
// eslint-disable-next-line no-param-reassign
|
|
158
151
|
finalCollection[key] = getSubsetOfData(item, selector, withOnyxInstanceState);
|
|
159
152
|
|
|
@@ -169,26 +162,26 @@ const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceStat
|
|
|
169
162
|
*/
|
|
170
163
|
function get(key) {
|
|
171
164
|
// When we already have the value in cache - resolve right away
|
|
172
|
-
if (
|
|
173
|
-
return Promise.resolve(
|
|
165
|
+
if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasCacheForKey(key)) {
|
|
166
|
+
return Promise.resolve(_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key));
|
|
174
167
|
}
|
|
175
168
|
|
|
176
169
|
const taskName = `get:${key}`;
|
|
177
170
|
|
|
178
171
|
// When a value retrieving task for this key is still running hook to it
|
|
179
|
-
if (
|
|
180
|
-
return
|
|
172
|
+
if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasPendingTask(taskName)) {
|
|
173
|
+
return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getTaskPromise(taskName);
|
|
181
174
|
}
|
|
182
175
|
|
|
183
176
|
// Otherwise retrieve the value from storage and capture a promise to aid concurrent usages
|
|
184
|
-
const promise =
|
|
177
|
+
const promise = _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getItem(key).
|
|
185
178
|
then((val) => {
|
|
186
|
-
|
|
179
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, val);
|
|
187
180
|
return val;
|
|
188
181
|
}).
|
|
189
|
-
catch((err) =>
|
|
182
|
+
catch((err) => _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Unable to get item from persistent storage. Key: ${key} Error: ${err}`));
|
|
190
183
|
|
|
191
|
-
return
|
|
184
|
+
return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].captureTask(taskName, promise);
|
|
192
185
|
}
|
|
193
186
|
|
|
194
187
|
/**
|
|
@@ -198,7 +191,7 @@ function get(key) {
|
|
|
198
191
|
*/
|
|
199
192
|
function getAllKeys() {
|
|
200
193
|
// When we've already read stored keys, resolve right away
|
|
201
|
-
const storedKeys =
|
|
194
|
+
const storedKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys();
|
|
202
195
|
if (storedKeys.length > 0) {
|
|
203
196
|
return Promise.resolve(storedKeys);
|
|
204
197
|
}
|
|
@@ -206,18 +199,18 @@ function getAllKeys() {
|
|
|
206
199
|
const taskName = 'getAllKeys';
|
|
207
200
|
|
|
208
201
|
// When a value retrieving task for all keys is still running hook to it
|
|
209
|
-
if (
|
|
210
|
-
return
|
|
202
|
+
if (_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasPendingTask(taskName)) {
|
|
203
|
+
return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getTaskPromise(taskName);
|
|
211
204
|
}
|
|
212
205
|
|
|
213
206
|
// Otherwise retrieve the keys from storage and capture a promise to aid concurrent usages
|
|
214
|
-
const promise =
|
|
207
|
+
const promise = _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys().
|
|
215
208
|
then((keys) => {
|
|
216
|
-
|
|
209
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].addKey(key));
|
|
217
210
|
return keys;
|
|
218
211
|
});
|
|
219
212
|
|
|
220
|
-
return
|
|
213
|
+
return _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].captureTask(taskName, promise);
|
|
221
214
|
}
|
|
222
215
|
|
|
223
216
|
/**
|
|
@@ -229,7 +222,7 @@ function getAllKeys() {
|
|
|
229
222
|
* @returns {Boolean}
|
|
230
223
|
*/
|
|
231
224
|
function isCollectionKey(key) {
|
|
232
|
-
return
|
|
225
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().contains(underscore__WEBPACK_IMPORTED_MODULE_1___default().values(onyxKeys.COLLECTION), key);
|
|
233
226
|
}
|
|
234
227
|
|
|
235
228
|
/**
|
|
@@ -238,7 +231,7 @@ function isCollectionKey(key) {
|
|
|
238
231
|
* @returns {Boolean}
|
|
239
232
|
*/
|
|
240
233
|
function isCollectionMemberKey(collectionKey, key) {
|
|
241
|
-
return
|
|
234
|
+
return _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(key, collectionKey) && key.length > collectionKey.length;
|
|
242
235
|
}
|
|
243
236
|
|
|
244
237
|
/**
|
|
@@ -252,7 +245,7 @@ function isCollectionMemberKey(collectionKey, key) {
|
|
|
252
245
|
*/
|
|
253
246
|
function isKeyMatch(configKey, key) {
|
|
254
247
|
return isCollectionKey(configKey) ?
|
|
255
|
-
|
|
248
|
+
_Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(key, configKey) :
|
|
256
249
|
configKey === key;
|
|
257
250
|
}
|
|
258
251
|
|
|
@@ -265,7 +258,7 @@ function isKeyMatch(configKey, key) {
|
|
|
265
258
|
* @returns {Boolean}
|
|
266
259
|
*/
|
|
267
260
|
function isSafeEvictionKey(testKey) {
|
|
268
|
-
return
|
|
261
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().some(evictionAllowList, (key) => isKeyMatch(key, testKey));
|
|
269
262
|
}
|
|
270
263
|
|
|
271
264
|
/**
|
|
@@ -277,13 +270,13 @@ function isSafeEvictionKey(testKey) {
|
|
|
277
270
|
* @returns {Mixed}
|
|
278
271
|
*/
|
|
279
272
|
function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
280
|
-
let val =
|
|
273
|
+
let val = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
|
|
281
274
|
|
|
282
275
|
if (isCollectionKey(key)) {
|
|
283
|
-
const allKeys =
|
|
284
|
-
const matchingKeys =
|
|
285
|
-
const values =
|
|
286
|
-
const cachedValue =
|
|
276
|
+
const allKeys = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys();
|
|
277
|
+
const matchingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(allKeys, (k) => k.startsWith(key));
|
|
278
|
+
const values = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(matchingKeys, (finalObject, matchedKey) => {
|
|
279
|
+
const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(matchedKey);
|
|
287
280
|
if (cachedValue) {
|
|
288
281
|
// This is permissible because we're in the process of constructing the final object in a reduce function.
|
|
289
282
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -291,7 +284,7 @@ function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments
|
|
|
291
284
|
}
|
|
292
285
|
return finalObject;
|
|
293
286
|
}, {});
|
|
294
|
-
if (
|
|
287
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isEmpty(values)) {
|
|
295
288
|
return;
|
|
296
289
|
}
|
|
297
290
|
val = values;
|
|
@@ -315,7 +308,7 @@ function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments
|
|
|
315
308
|
* @param {String} key
|
|
316
309
|
*/
|
|
317
310
|
function removeLastAccessedKey(key) {
|
|
318
|
-
recentlyAccessedKeys =
|
|
311
|
+
recentlyAccessedKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().without(recentlyAccessedKeys, key);
|
|
319
312
|
}
|
|
320
313
|
|
|
321
314
|
/**
|
|
@@ -345,7 +338,7 @@ function addLastAccessedKey(key) {
|
|
|
345
338
|
* @param {Number} connectionID
|
|
346
339
|
*/
|
|
347
340
|
function removeFromEvictionBlockList(key, connectionID) {
|
|
348
|
-
evictionBlocklist[key] =
|
|
341
|
+
evictionBlocklist[key] = underscore__WEBPACK_IMPORTED_MODULE_1___default().without(evictionBlocklist[key] || [], connectionID);
|
|
349
342
|
|
|
350
343
|
// Remove the key if there are no more subscribers
|
|
351
344
|
if (evictionBlocklist[key].length === 0) {
|
|
@@ -382,8 +375,8 @@ function addToEvictionBlockList(key, connectionID) {
|
|
|
382
375
|
function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
383
376
|
return getAllKeys().
|
|
384
377
|
then((keys) => {
|
|
385
|
-
|
|
386
|
-
|
|
378
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(evictionAllowList, (safeEvictionKey) => {
|
|
379
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => {
|
|
387
380
|
if (!isKeyMatch(safeEvictionKey, key)) {
|
|
388
381
|
return;
|
|
389
382
|
}
|
|
@@ -399,12 +392,12 @@ function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
|
399
392
|
* @returns {Object}
|
|
400
393
|
*/
|
|
401
394
|
function getCachedCollection(collectionKey) {
|
|
402
|
-
const collectionMemberKeys =
|
|
395
|
+
const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys(),
|
|
403
396
|
(storedKey) => isCollectionMemberKey(collectionKey, storedKey));
|
|
404
397
|
|
|
405
398
|
|
|
406
|
-
return
|
|
407
|
-
const cachedValue =
|
|
399
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(collectionMemberKeys, (prev, curr) => {
|
|
400
|
+
const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(curr);
|
|
408
401
|
if (!cachedValue) {
|
|
409
402
|
return prev;
|
|
410
403
|
}
|
|
@@ -426,7 +419,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
426
419
|
// We are iterating over all subscribers similar to keyChanged(). However, we are looking for subscribers who are subscribing to either a collection key or
|
|
427
420
|
// 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
|
|
428
421
|
// 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().
|
|
429
|
-
const stateMappingKeys =
|
|
422
|
+
const stateMappingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(callbackToStateMapping);
|
|
430
423
|
for (let i = 0; i < stateMappingKeys.length; i++) {
|
|
431
424
|
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
|
|
432
425
|
if (!subscriber) {
|
|
@@ -434,7 +427,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
434
427
|
}
|
|
435
428
|
|
|
436
429
|
// Skip iteration if we do not have a collection key or a collection member key on this subscriber
|
|
437
|
-
if (!
|
|
430
|
+
if (!_Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(subscriber.key, collectionKey)) {
|
|
438
431
|
continue;
|
|
439
432
|
}
|
|
440
433
|
|
|
@@ -453,7 +446,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
453
446
|
const cachedCollection = getCachedCollection(collectionKey);
|
|
454
447
|
|
|
455
448
|
// Regular Onyx.connect() subscriber found.
|
|
456
|
-
if (
|
|
449
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(subscriber.callback)) {
|
|
457
450
|
// If they are subscribed to the collection key and using waitForCollectionCallback then we'll
|
|
458
451
|
// send the whole cached collection.
|
|
459
452
|
if (isSubscribedToCollectionKey) {
|
|
@@ -464,7 +457,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
464
457
|
|
|
465
458
|
// If they are not using waitForCollectionCallback then we notify the subscriber with
|
|
466
459
|
// the new merged data but only for any keys in the partial collection.
|
|
467
|
-
const dataKeys =
|
|
460
|
+
const dataKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(partialCollection);
|
|
468
461
|
for (let j = 0; j < dataKeys.length; j++) {
|
|
469
462
|
const dataKey = dataKeys[j];
|
|
470
463
|
subscriber.callback(cachedCollection[dataKey], dataKey);
|
|
@@ -505,14 +498,14 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
505
498
|
}
|
|
506
499
|
|
|
507
500
|
subscriber.withOnyxInstance.setState((prevState) => {
|
|
508
|
-
const finalCollection =
|
|
509
|
-
const dataKeys =
|
|
501
|
+
const finalCollection = underscore__WEBPACK_IMPORTED_MODULE_1___default().clone(prevState[subscriber.statePropertyName] || {});
|
|
502
|
+
const dataKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(partialCollection);
|
|
510
503
|
for (let j = 0; j < dataKeys.length; j++) {
|
|
511
504
|
const dataKey = dataKeys[j];
|
|
512
505
|
finalCollection[dataKey] = cachedCollection[dataKey];
|
|
513
506
|
}
|
|
514
507
|
|
|
515
|
-
|
|
508
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevState[subscriber.statePropertyName], finalCollection, 'keysChanged', collectionKey);
|
|
516
509
|
return {
|
|
517
510
|
[subscriber.statePropertyName]: finalCollection
|
|
518
511
|
};
|
|
@@ -525,7 +518,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
525
518
|
// However, we only want to update this subscriber if the partial data contains a change.
|
|
526
519
|
// Otherwise, we would update them with a value they already have and trigger an unnecessary re-render.
|
|
527
520
|
const dataFromCollection = partialCollection[subscriber.key];
|
|
528
|
-
if (
|
|
521
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(dataFromCollection)) {
|
|
529
522
|
continue;
|
|
530
523
|
}
|
|
531
524
|
|
|
@@ -537,7 +530,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
537
530
|
const prevData = prevState[subscriber.statePropertyName];
|
|
538
531
|
const newData = getSubsetOfData(cachedCollection[subscriber.key], subscriber.selector, subscriber.withOnyxInstance.state);
|
|
539
532
|
if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, newData)) {
|
|
540
|
-
|
|
533
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
|
|
541
534
|
return {
|
|
542
535
|
[subscriber.statePropertyName]: newData
|
|
543
536
|
};
|
|
@@ -555,7 +548,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
555
548
|
return null;
|
|
556
549
|
}
|
|
557
550
|
|
|
558
|
-
|
|
551
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keysChanged', collectionKey);
|
|
559
552
|
return {
|
|
560
553
|
[subscriber.statePropertyName]: data
|
|
561
554
|
};
|
|
@@ -578,7 +571,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
578
571
|
*/
|
|
579
572
|
function keyChanged(key, data, canUpdateSubscriber) {
|
|
580
573
|
// Add or remove this key from the recentlyAccessedKeys lists
|
|
581
|
-
if (!
|
|
574
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(data)) {
|
|
582
575
|
addLastAccessedKey(key);
|
|
583
576
|
} else {
|
|
584
577
|
removeLastAccessedKey(key);
|
|
@@ -587,15 +580,15 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
587
580
|
// We are iterating over all subscribers to see if they are interested in the key that has just changed. If the subscriber's key is a collection key then we will
|
|
588
581
|
// notify them if the key that changed is a collection member. Or if it is a regular key notify them when there is an exact match. Depending on whether the subscriber
|
|
589
582
|
// was connected via withOnyx we will call setState() directly on the withOnyx instance. If it is a regular connection we will pass the data to the provided callback.
|
|
590
|
-
const stateMappingKeys =
|
|
583
|
+
const stateMappingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(callbackToStateMapping);
|
|
591
584
|
for (let i = 0; i < stateMappingKeys.length; i++) {
|
|
592
585
|
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
|
|
593
|
-
if (!subscriber || !isKeyMatch(subscriber.key, key) ||
|
|
586
|
+
if (!subscriber || !isKeyMatch(subscriber.key, key) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(canUpdateSubscriber) && !canUpdateSubscriber(subscriber)) {
|
|
594
587
|
continue;
|
|
595
588
|
}
|
|
596
589
|
|
|
597
590
|
// Subscriber is a regular call to connect() and provided a callback
|
|
598
|
-
if (
|
|
591
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(subscriber.callback)) {
|
|
599
592
|
if (isCollectionKey(subscriber.key) && subscriber.waitForCollectionCallback) {
|
|
600
593
|
const cachedCollection = getCachedCollection(subscriber.key);
|
|
601
594
|
cachedCollection[key] = data;
|
|
@@ -624,7 +617,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
624
617
|
...newData
|
|
625
618
|
};
|
|
626
619
|
if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, prevDataWithNewData)) {
|
|
627
|
-
|
|
620
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keyChanged', key);
|
|
628
621
|
return {
|
|
629
622
|
[subscriber.statePropertyName]: prevDataWithNewData
|
|
630
623
|
};
|
|
@@ -640,7 +633,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
640
633
|
...collection,
|
|
641
634
|
[key]: data
|
|
642
635
|
};
|
|
643
|
-
|
|
636
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, collection, newCollection, 'keyChanged', key);
|
|
644
637
|
return {
|
|
645
638
|
[subscriber.statePropertyName]: newCollection
|
|
646
639
|
};
|
|
@@ -671,7 +664,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
671
664
|
return null;
|
|
672
665
|
}
|
|
673
666
|
|
|
674
|
-
|
|
667
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keyChanged', key);
|
|
675
668
|
return {
|
|
676
669
|
[subscriber.statePropertyName]: data
|
|
677
670
|
};
|
|
@@ -717,12 +710,12 @@ function sendDataToConnection(mapping, val, matchedKey) {
|
|
|
717
710
|
}
|
|
718
711
|
}
|
|
719
712
|
|
|
720
|
-
|
|
713
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
|
|
721
714
|
mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
|
|
722
715
|
return;
|
|
723
716
|
}
|
|
724
717
|
|
|
725
|
-
if (
|
|
718
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(mapping.callback)) {
|
|
726
719
|
mapping.callback(val, matchedKey);
|
|
727
720
|
}
|
|
728
721
|
}
|
|
@@ -740,11 +733,11 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
740
733
|
}
|
|
741
734
|
|
|
742
735
|
// Try to free some cache whenever we connect to a safe eviction key
|
|
743
|
-
|
|
736
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].removeLeastRecentlyUsedKeys();
|
|
744
737
|
|
|
745
738
|
if (mapping.withOnyxInstance && !isCollectionKey(mapping.key)) {
|
|
746
739
|
// All React components subscribing to a key flagged as a safe eviction key must implement the canEvict property.
|
|
747
|
-
if (
|
|
740
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(mapping.canEvict)) {
|
|
748
741
|
throw new Error(
|
|
749
742
|
`Cannot subscribe to safe eviction key '${mapping.key}' without providing a canEvict value.`);
|
|
750
743
|
|
|
@@ -762,8 +755,8 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
762
755
|
* @param {Object} mapping
|
|
763
756
|
*/
|
|
764
757
|
function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
765
|
-
Promise.all(
|
|
766
|
-
then((values) =>
|
|
758
|
+
Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(matchingKeys, (key) => get(key))).
|
|
759
|
+
then((values) => underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(values, (finalObject, value, i) => {
|
|
767
760
|
// eslint-disable-next-line no-param-reassign
|
|
768
761
|
finalObject[matchingKeys[i]] = value;
|
|
769
762
|
return finalObject;
|
|
@@ -790,11 +783,10 @@ function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
|
790
783
|
* @param {Boolean} [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
|
|
791
784
|
* component
|
|
792
785
|
* @param {Boolean} [mapping.waitForCollectionCallback] If set to true, it will return the entire collection to the callback as a single object
|
|
793
|
-
* @param {
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
*
|
|
797
|
-
* be expensive from a performance standpoint).
|
|
786
|
+
* @param {Function} [mapping.selector] THIS PARAM IS ONLY USED WITH withOnyx(). If included, this will be used to subscribe to a subset of an Onyx key's data.
|
|
787
|
+
* The sourceData and withOnyx state are passed to the selector and should return the simplified data. Using this setting on `withOnyx` can have very positive
|
|
788
|
+
* performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally
|
|
789
|
+
* cause the component to re-render (and that can be expensive from a performance standpoint).
|
|
798
790
|
* @returns {Number} an ID to use when calling disconnect
|
|
799
791
|
*/
|
|
800
792
|
function connect(mapping) {
|
|
@@ -814,7 +806,7 @@ function connect(mapping) {
|
|
|
814
806
|
// We search all the keys in storage to see if any are a "match" for the subscriber we are connecting so that we
|
|
815
807
|
// can send data back to the subscriber. Note that multiple keys can match as a subscriber could either be
|
|
816
808
|
// subscribed to a "collection key" or a single key.
|
|
817
|
-
const matchingKeys =
|
|
809
|
+
const matchingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(keys, (key) => isKeyMatch(mapping.key, key));
|
|
818
810
|
|
|
819
811
|
// If the key being connected to does not exist we initialize the value with null. For subscribers that connected
|
|
820
812
|
// directly via connect() they will simply get a null value sent to them without any information about which key matched
|
|
@@ -828,7 +820,7 @@ function connect(mapping) {
|
|
|
828
820
|
// When using a callback subscriber we will either trigger the provided callback for each key we find or combine all values
|
|
829
821
|
// into an object and just make a single call. The latter behavior is enabled by providing a waitForCollectionCallback key
|
|
830
822
|
// combined with a subscription to a collection key.
|
|
831
|
-
if (
|
|
823
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(mapping.callback)) {
|
|
832
824
|
if (isCollectionKey(mapping.key)) {
|
|
833
825
|
if (mapping.waitForCollectionCallback) {
|
|
834
826
|
getCollectionDataAndSendAsObject(matchingKeys, mapping);
|
|
@@ -929,9 +921,9 @@ function notifyCollectionSubscribersOnNextTick(key, value) {
|
|
|
929
921
|
* @return {Promise}
|
|
930
922
|
*/
|
|
931
923
|
function remove(key) {
|
|
932
|
-
|
|
924
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key);
|
|
933
925
|
notifySubscribersOnNextTick(key, null);
|
|
934
|
-
return
|
|
926
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItem(key);
|
|
935
927
|
}
|
|
936
928
|
|
|
937
929
|
/**
|
|
@@ -946,23 +938,23 @@ function remove(key) {
|
|
|
946
938
|
* @return {Promise}
|
|
947
939
|
*/
|
|
948
940
|
function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {args[_key - 2] = arguments[_key];}
|
|
949
|
-
|
|
941
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Handled error: ${error}`);
|
|
950
942
|
|
|
951
|
-
if (error &&
|
|
952
|
-
|
|
943
|
+
if (error && _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(error.message, 'Failed to execute \'put\' on \'IDBObjectStore\'')) {
|
|
944
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Attempted to set invalid data set in Onyx. Please ensure all data is serializable.');
|
|
953
945
|
throw error;
|
|
954
946
|
}
|
|
955
947
|
|
|
956
948
|
// Find the first key that we can remove that has no subscribers in our blocklist
|
|
957
|
-
const keyForRemoval =
|
|
949
|
+
const keyForRemoval = underscore__WEBPACK_IMPORTED_MODULE_1___default().find(recentlyAccessedKeys, (key) => !evictionBlocklist[key]);
|
|
958
950
|
|
|
959
951
|
if (!keyForRemoval) {
|
|
960
|
-
|
|
952
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Out of storage. But found no acceptable keys to remove.');
|
|
961
953
|
throw error;
|
|
962
954
|
}
|
|
963
955
|
|
|
964
956
|
// Remove the least recently viewed key that is not currently being accessed and retry.
|
|
965
|
-
|
|
957
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
|
|
966
958
|
return remove(keyForRemoval).
|
|
967
959
|
then(() => onyxMethod(...args));
|
|
968
960
|
}
|
|
@@ -977,14 +969,14 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
|
|
|
977
969
|
*/
|
|
978
970
|
function broadcastUpdate(key, value, hasChanged, method) {
|
|
979
971
|
// Logging properties only since values could be sensitive things we don't want to log
|
|
980
|
-
|
|
972
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`${method}() called for key: ${key}${underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) ? ` properties: ${underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(value).join(',')}` : ''}`);
|
|
981
973
|
|
|
982
974
|
// Update subscribers if the cached value has changed, or when the subscriber specifically requires
|
|
983
975
|
// all updates regardless of value changes (indicated by initWithStoredValues set to false).
|
|
984
976
|
if (hasChanged) {
|
|
985
|
-
|
|
977
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
|
|
986
978
|
} else {
|
|
987
|
-
|
|
979
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].addToAccessedKeys(key);
|
|
988
980
|
}
|
|
989
981
|
|
|
990
982
|
notifySubscribersOnNextTick(key, value, (subscriber) => hasChanged || subscriber.initWithStoredValues === false);
|
|
@@ -999,6 +991,24 @@ function hasPendingMergeForKey(key) {
|
|
|
999
991
|
return Boolean(mergeQueue[key]);
|
|
1000
992
|
}
|
|
1001
993
|
|
|
994
|
+
/**
|
|
995
|
+
* We generally want to remove top-level nullish values from objects written to disk and cache, because it decreases the amount of data stored in memory and on disk.
|
|
996
|
+
* On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
|
|
997
|
+
* To be consistent with the behaviour for merge, we'll also want to remove nullish values for "set" operations.
|
|
998
|
+
* On web, IndexedDB will keep the top-level keys along with a null value and this uses up storage and memory.
|
|
999
|
+
* This method will ensure that keys for null values are removed before an object is written to disk and cache so that all platforms are storing the data in the same efficient way.
|
|
1000
|
+
* @private
|
|
1001
|
+
* @param {*} value
|
|
1002
|
+
* @returns {*}
|
|
1003
|
+
*/
|
|
1004
|
+
function removeNullObjectValues(value) {
|
|
1005
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(value) || !underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value)) {
|
|
1006
|
+
return value;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().omit(value, (objectValue) => underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(objectValue));
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1002
1012
|
/**
|
|
1003
1013
|
* Write a value to our store with the given key
|
|
1004
1014
|
*
|
|
@@ -1008,26 +1018,28 @@ function hasPendingMergeForKey(key) {
|
|
|
1008
1018
|
* @returns {Promise}
|
|
1009
1019
|
*/
|
|
1010
1020
|
function set(key, value) {
|
|
1011
|
-
if (
|
|
1021
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(value)) {
|
|
1012
1022
|
return remove(key);
|
|
1013
1023
|
}
|
|
1014
1024
|
|
|
1015
1025
|
if (hasPendingMergeForKey(key)) {
|
|
1016
|
-
|
|
1026
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Onyx.set() called after Onyx.merge() for key: ${key}. It is recommended to use set() or merge() not both.`);
|
|
1017
1027
|
}
|
|
1018
1028
|
|
|
1019
|
-
const
|
|
1029
|
+
const valueWithNullRemoved = removeNullObjectValues(value);
|
|
1030
|
+
|
|
1031
|
+
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, valueWithNullRemoved);
|
|
1020
1032
|
|
|
1021
1033
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
1022
|
-
broadcastUpdate(key,
|
|
1034
|
+
broadcastUpdate(key, valueWithNullRemoved, hasChanged, 'set');
|
|
1023
1035
|
|
|
1024
1036
|
// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
|
|
1025
1037
|
if (!hasChanged) {
|
|
1026
1038
|
return Promise.resolve();
|
|
1027
1039
|
}
|
|
1028
1040
|
|
|
1029
|
-
return
|
|
1030
|
-
catch((error) => evictStorageAndRetry(error, set, key,
|
|
1041
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].setItem(key, valueWithNullRemoved).
|
|
1042
|
+
catch((error) => evictStorageAndRetry(error, set, key, valueWithNullRemoved));
|
|
1031
1043
|
}
|
|
1032
1044
|
|
|
1033
1045
|
/**
|
|
@@ -1039,7 +1051,7 @@ function set(key, value) {
|
|
|
1039
1051
|
* @return {Array} an array of key - value pairs <[key, value]>
|
|
1040
1052
|
*/
|
|
1041
1053
|
function prepareKeyValuePairsForStorage(data) {
|
|
1042
|
-
return
|
|
1054
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().map(data, (value, key) => [key, value]);
|
|
1043
1055
|
}
|
|
1044
1056
|
|
|
1045
1057
|
/**
|
|
@@ -1053,13 +1065,13 @@ function prepareKeyValuePairsForStorage(data) {
|
|
|
1053
1065
|
function multiSet(data) {
|
|
1054
1066
|
const keyValuePairs = prepareKeyValuePairsForStorage(data);
|
|
1055
1067
|
|
|
1056
|
-
|
|
1068
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (val, key) => {
|
|
1057
1069
|
// Update cache and optimistically inform subscribers on the next tick
|
|
1058
|
-
|
|
1070
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, val);
|
|
1059
1071
|
notifySubscribersOnNextTick(key, val);
|
|
1060
1072
|
});
|
|
1061
1073
|
|
|
1062
|
-
return
|
|
1074
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairs).
|
|
1063
1075
|
catch((error) => evictStorageAndRetry(error, multiSet, data));
|
|
1064
1076
|
}
|
|
1065
1077
|
|
|
@@ -1072,17 +1084,17 @@ function multiSet(data) {
|
|
|
1072
1084
|
* @returns {*}
|
|
1073
1085
|
*/
|
|
1074
1086
|
function applyMerge(existingValue, changes) {
|
|
1075
|
-
const lastChange =
|
|
1087
|
+
const lastChange = underscore__WEBPACK_IMPORTED_MODULE_1___default().last(changes);
|
|
1076
1088
|
|
|
1077
|
-
if (
|
|
1089
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(existingValue) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(lastChange)) {
|
|
1078
1090
|
return lastChange;
|
|
1079
1091
|
}
|
|
1080
1092
|
|
|
1081
|
-
if (
|
|
1093
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(existingValue) || underscore__WEBPACK_IMPORTED_MODULE_1___default().every(changes, (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject))) {
|
|
1082
1094
|
// Object values are merged one after the other
|
|
1083
1095
|
// lodash adds a small overhead so we don't use it here
|
|
1084
1096
|
// eslint-disable-next-line prefer-object-spread, rulesdir/prefer-underscore-method
|
|
1085
|
-
return
|
|
1097
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => (0,_fastMerge__WEBPACK_IMPORTED_MODULE_8__["default"])(modifiedData, change),
|
|
1086
1098
|
existingValue || {});
|
|
1087
1099
|
}
|
|
1088
1100
|
|
|
@@ -1124,22 +1136,24 @@ function merge(key, changes) {
|
|
|
1124
1136
|
then((existingValue) => {
|
|
1125
1137
|
try {
|
|
1126
1138
|
// We first only merge the changes, so we can provide these to the native implementation (SQLite uses only delta changes in "JSON_PATCH" to merge)
|
|
1127
|
-
|
|
1139
|
+
let batchedChanges = applyMerge(undefined, mergeQueue[key]);
|
|
1128
1140
|
|
|
1129
1141
|
// Clean up the write queue so we
|
|
1130
1142
|
// don't apply these changes again
|
|
1131
1143
|
delete mergeQueue[key];
|
|
1132
1144
|
|
|
1133
1145
|
// After that we merge the batched changes with the existing value
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
//
|
|
1137
|
-
//
|
|
1138
|
-
|
|
1139
|
-
|
|
1146
|
+
const modifiedData = removeNullObjectValues(applyMerge(existingValue, [batchedChanges]));
|
|
1147
|
+
|
|
1148
|
+
// On native platforms we use SQLite which utilises JSON_PATCH to merge changes.
|
|
1149
|
+
// JSON_PATCH generally removes top-level nullish values from the stored object.
|
|
1150
|
+
// When there is no existing value though, SQLite will just insert the changes as a new value and thus the top-level nullish values won't be removed.
|
|
1151
|
+
// Therefore we need to remove nullish values from the `batchedChanges` which are sent to the SQLite, if no existing value is present.
|
|
1152
|
+
if (!existingValue) {
|
|
1153
|
+
batchedChanges = removeNullObjectValues(batchedChanges);
|
|
1140
1154
|
}
|
|
1141
1155
|
|
|
1142
|
-
const hasChanged =
|
|
1156
|
+
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, modifiedData);
|
|
1143
1157
|
|
|
1144
1158
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
1145
1159
|
broadcastUpdate(key, modifiedData, hasChanged, 'merge');
|
|
@@ -1149,9 +1163,9 @@ function merge(key, changes) {
|
|
|
1149
1163
|
return Promise.resolve();
|
|
1150
1164
|
}
|
|
1151
1165
|
|
|
1152
|
-
return
|
|
1166
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].mergeItem(key, batchedChanges, modifiedData);
|
|
1153
1167
|
} catch (error) {
|
|
1154
|
-
|
|
1168
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`An error occurred while applying merge for key: ${key}, Error: ${error}`);
|
|
1155
1169
|
}
|
|
1156
1170
|
|
|
1157
1171
|
return Promise.resolve();
|
|
@@ -1164,13 +1178,13 @@ function merge(key, changes) {
|
|
|
1164
1178
|
* @returns {Promise}
|
|
1165
1179
|
*/
|
|
1166
1180
|
function initializeWithDefaultKeyStates() {
|
|
1167
|
-
return
|
|
1181
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).
|
|
1168
1182
|
then((pairs) => {
|
|
1169
|
-
const asObject =
|
|
1183
|
+
const asObject = underscore__WEBPACK_IMPORTED_MODULE_1___default().object(pairs);
|
|
1170
1184
|
|
|
1171
|
-
const merged = (0,
|
|
1172
|
-
|
|
1173
|
-
|
|
1185
|
+
const merged = (0,_fastMerge__WEBPACK_IMPORTED_MODULE_8__["default"])(asObject, defaultKeyStates);
|
|
1186
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(merged);
|
|
1187
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(merged, (val, key) => keyChanged(key, val));
|
|
1174
1188
|
});
|
|
1175
1189
|
}
|
|
1176
1190
|
|
|
@@ -1208,19 +1222,19 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1208
1222
|
// status, or activeClients need to remain in Onyx even when signed out)
|
|
1209
1223
|
// 2. Any keys with a default state (because they need to remain in Onyx as their default, and setting them
|
|
1210
1224
|
// to null would cause unknown behavior)
|
|
1211
|
-
|
|
1212
|
-
const isKeyToPreserve =
|
|
1213
|
-
const isDefaultKey =
|
|
1225
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => {
|
|
1226
|
+
const isKeyToPreserve = underscore__WEBPACK_IMPORTED_MODULE_1___default().contains(keysToPreserve, key);
|
|
1227
|
+
const isDefaultKey = underscore__WEBPACK_IMPORTED_MODULE_1___default().has(defaultKeyStates, key);
|
|
1214
1228
|
|
|
1215
1229
|
// If the key is being removed or reset to default:
|
|
1216
1230
|
// 1. Update it in the cache
|
|
1217
1231
|
// 2. Figure out whether it is a collection key or not,
|
|
1218
1232
|
// since collection key subscribers need to be updated differently
|
|
1219
1233
|
if (!isKeyToPreserve) {
|
|
1220
|
-
const oldValue =
|
|
1221
|
-
const newValue =
|
|
1234
|
+
const oldValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
|
|
1235
|
+
const newValue = underscore__WEBPACK_IMPORTED_MODULE_1___default().get(defaultKeyStates, key, null);
|
|
1222
1236
|
if (newValue !== oldValue) {
|
|
1223
|
-
|
|
1237
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, newValue);
|
|
1224
1238
|
const collectionKey = key.substring(0, key.indexOf('_') + 1);
|
|
1225
1239
|
if (collectionKey) {
|
|
1226
1240
|
if (!keyValuesToResetAsCollection[collectionKey]) {
|
|
@@ -1242,18 +1256,18 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1242
1256
|
});
|
|
1243
1257
|
|
|
1244
1258
|
// Notify the subscribers for each key/value group so they can receive the new values
|
|
1245
|
-
|
|
1259
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keyValuesToResetIndividually, (value, key) => {
|
|
1246
1260
|
notifySubscribersOnNextTick(key, value);
|
|
1247
1261
|
});
|
|
1248
|
-
|
|
1262
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keyValuesToResetAsCollection, (value, key) => {
|
|
1249
1263
|
notifyCollectionSubscribersOnNextTick(key, value);
|
|
1250
1264
|
});
|
|
1251
1265
|
|
|
1252
|
-
const defaultKeyValuePairs =
|
|
1266
|
+
const defaultKeyValuePairs = underscore__WEBPACK_IMPORTED_MODULE_1___default().pairs(underscore__WEBPACK_IMPORTED_MODULE_1___default().omit(defaultKeyStates, keysToPreserve));
|
|
1253
1267
|
|
|
1254
1268
|
// Remove only the items that we want cleared from storage, and reset others to default
|
|
1255
|
-
|
|
1256
|
-
return
|
|
1269
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keysToBeClearedFromStorage, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key));
|
|
1270
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItems(keysToBeClearedFromStorage).then(() => _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(defaultKeyValuePairs));
|
|
1257
1271
|
});
|
|
1258
1272
|
}
|
|
1259
1273
|
|
|
@@ -1272,14 +1286,14 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1272
1286
|
* @returns {Promise}
|
|
1273
1287
|
*/
|
|
1274
1288
|
function mergeCollection(collectionKey, collection) {
|
|
1275
|
-
if (!
|
|
1276
|
-
|
|
1289
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(collection) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(collection) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isEmpty(collection)) {
|
|
1290
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo('mergeCollection() called with invalid or empty value. Skipping this update.');
|
|
1277
1291
|
return Promise.resolve();
|
|
1278
1292
|
}
|
|
1279
1293
|
|
|
1280
1294
|
// Confirm all the collection keys belong to the same parent
|
|
1281
1295
|
let hasCollectionKeyCheckFailed = false;
|
|
1282
|
-
|
|
1296
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(collection, (_data, dataKey) => {
|
|
1283
1297
|
if (isKeyMatch(collectionKey, dataKey)) {
|
|
1284
1298
|
return;
|
|
1285
1299
|
}
|
|
@@ -1289,7 +1303,7 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1289
1303
|
}
|
|
1290
1304
|
|
|
1291
1305
|
hasCollectionKeyCheckFailed = true;
|
|
1292
|
-
|
|
1306
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
1293
1307
|
});
|
|
1294
1308
|
|
|
1295
1309
|
// Gracefully handle bad mergeCollection updates so it doesn't block the merge queue
|
|
@@ -1300,13 +1314,13 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1300
1314
|
return getAllKeys().
|
|
1301
1315
|
then((persistedKeys) => {
|
|
1302
1316
|
// Split to keys that exist in storage and keys that don't
|
|
1303
|
-
const [existingKeys, newKeys] =
|
|
1317
|
+
const [existingKeys, newKeys] = underscore__WEBPACK_IMPORTED_MODULE_1___default().chain(collection).
|
|
1304
1318
|
keys().
|
|
1305
1319
|
partition((key) => persistedKeys.includes(key)).
|
|
1306
1320
|
value();
|
|
1307
1321
|
|
|
1308
|
-
const existingKeyCollection =
|
|
1309
|
-
const newCollection =
|
|
1322
|
+
const existingKeyCollection = underscore__WEBPACK_IMPORTED_MODULE_1___default().pick(collection, existingKeys);
|
|
1323
|
+
const newCollection = underscore__WEBPACK_IMPORTED_MODULE_1___default().pick(collection, newKeys);
|
|
1310
1324
|
const keyValuePairsForExistingCollection = prepareKeyValuePairsForStorage(existingKeyCollection);
|
|
1311
1325
|
const keyValuePairsForNewCollection = prepareKeyValuePairsForStorage(newCollection);
|
|
1312
1326
|
|
|
@@ -1315,17 +1329,17 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1315
1329
|
// New keys will be added via multiSet while existing keys will be updated using multiMerge
|
|
1316
1330
|
// This is because setting a key that doesn't exist yet with multiMerge will throw errors
|
|
1317
1331
|
if (keyValuePairsForExistingCollection.length > 0) {
|
|
1318
|
-
promises.push(
|
|
1332
|
+
promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiMerge(keyValuePairsForExistingCollection));
|
|
1319
1333
|
}
|
|
1320
1334
|
|
|
1321
1335
|
if (keyValuePairsForNewCollection.length > 0) {
|
|
1322
|
-
promises.push(
|
|
1336
|
+
promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairsForNewCollection));
|
|
1323
1337
|
}
|
|
1324
1338
|
|
|
1325
1339
|
// Prefill cache if necessary by calling get() on any existing keys and then merge original data to cache
|
|
1326
1340
|
// and update all subscribers
|
|
1327
|
-
Promise.all(
|
|
1328
|
-
|
|
1341
|
+
Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(existingKeys, get)).then(() => {
|
|
1342
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(collection);
|
|
1329
1343
|
keysChanged(collectionKey, collection);
|
|
1330
1344
|
});
|
|
1331
1345
|
|
|
@@ -1342,11 +1356,11 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1342
1356
|
*/
|
|
1343
1357
|
function update(data) {
|
|
1344
1358
|
// First, validate the Onyx object is in the format we expect
|
|
1345
|
-
|
|
1346
|
-
if (!
|
|
1359
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref) => {let { onyxMethod, key } = _ref;
|
|
1360
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().contains([METHOD.CLEAR, METHOD.SET, METHOD.MERGE, METHOD.MERGE_COLLECTION], onyxMethod)) {
|
|
1347
1361
|
throw new Error(`Invalid onyxMethod ${onyxMethod} in Onyx update.`);
|
|
1348
1362
|
}
|
|
1349
|
-
if (onyxMethod !== METHOD.CLEAR && !
|
|
1363
|
+
if (onyxMethod !== METHOD.CLEAR && !underscore__WEBPACK_IMPORTED_MODULE_1___default().isString(key)) {
|
|
1350
1364
|
throw new Error(`Invalid ${typeof key} key provided in Onyx update. Onyx key must be of type string.`);
|
|
1351
1365
|
}
|
|
1352
1366
|
});
|
|
@@ -1354,7 +1368,7 @@ function update(data) {
|
|
|
1354
1368
|
const promises = [];
|
|
1355
1369
|
let clearPromise = Promise.resolve();
|
|
1356
1370
|
|
|
1357
|
-
|
|
1371
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref2) => {let { onyxMethod, key, value } = _ref2;
|
|
1358
1372
|
switch (onyxMethod) {
|
|
1359
1373
|
case METHOD.SET:
|
|
1360
1374
|
promises.push(() => set(key, value));
|
|
@@ -1373,7 +1387,7 @@ function update(data) {
|
|
|
1373
1387
|
|
|
1374
1388
|
});
|
|
1375
1389
|
|
|
1376
|
-
return clearPromise.then(() => Promise.all(
|
|
1390
|
+
return clearPromise.then(() => Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(promises, (p) => p())));
|
|
1377
1391
|
}
|
|
1378
1392
|
|
|
1379
1393
|
/**
|
|
@@ -1381,10 +1395,10 @@ function update(data) {
|
|
|
1381
1395
|
* @param {string[]} keyList
|
|
1382
1396
|
*/
|
|
1383
1397
|
function setMemoryOnlyKeys(keyList) {
|
|
1384
|
-
|
|
1398
|
+
_storage__WEBPACK_IMPORTED_MODULE_4__["default"].setMemoryOnlyKeys(keyList);
|
|
1385
1399
|
|
|
1386
1400
|
// When in memory only mode for certain keys we do not want to ever drop items from the cache as the user will have no way to recover them again via storage.
|
|
1387
|
-
|
|
1401
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(Infinity);
|
|
1388
1402
|
}
|
|
1389
1403
|
|
|
1390
1404
|
/**
|
|
@@ -1428,11 +1442,11 @@ function init()
|
|
|
1428
1442
|
}
|
|
1429
1443
|
|
|
1430
1444
|
if (debugSetState) {
|
|
1431
|
-
|
|
1445
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.setShouldDebugSetState(true);
|
|
1432
1446
|
}
|
|
1433
1447
|
|
|
1434
1448
|
if (maxCachedKeysCount > 0) {
|
|
1435
|
-
|
|
1449
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(maxCachedKeysCount);
|
|
1436
1450
|
}
|
|
1437
1451
|
|
|
1438
1452
|
// Let Onyx know about all of our keys
|
|
@@ -1451,9 +1465,9 @@ function init()
|
|
|
1451
1465
|
|
|
1452
1466
|
then(deferredInitTask.resolve);
|
|
1453
1467
|
|
|
1454
|
-
if (shouldSyncMultipleInstances &&
|
|
1455
|
-
|
|
1456
|
-
|
|
1468
|
+
if (shouldSyncMultipleInstances && underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync)) {
|
|
1469
|
+
_storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync((key, value) => {
|
|
1470
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
|
|
1457
1471
|
keyChanged(key, value);
|
|
1458
1472
|
});
|
|
1459
1473
|
}
|
|
@@ -1466,12 +1480,11 @@ const Onyx = {
|
|
|
1466
1480
|
multiSet,
|
|
1467
1481
|
merge,
|
|
1468
1482
|
mergeCollection,
|
|
1469
|
-
hasPendingMergeForKey,
|
|
1470
1483
|
update,
|
|
1471
1484
|
clear,
|
|
1472
1485
|
getAllKeys,
|
|
1473
1486
|
init,
|
|
1474
|
-
registerLogger:
|
|
1487
|
+
registerLogger: _Logger__WEBPACK_IMPORTED_MODULE_5__.registerLogger,
|
|
1475
1488
|
addToEvictionBlockList,
|
|
1476
1489
|
removeFromEvictionBlockList,
|
|
1477
1490
|
isSafeEvictionKey,
|
|
@@ -3741,17 +3754,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_localforage_removeitems__;
|
|
|
3741
3754
|
|
|
3742
3755
|
/***/ }),
|
|
3743
3756
|
|
|
3744
|
-
/***/ "lodash/get":
|
|
3745
|
-
/*!*****************************!*\
|
|
3746
|
-
!*** external "lodash/get" ***!
|
|
3747
|
-
\*****************************/
|
|
3748
|
-
/***/ ((module) => {
|
|
3749
|
-
|
|
3750
|
-
"use strict";
|
|
3751
|
-
module.exports = __WEBPACK_EXTERNAL_MODULE_lodash_get__;
|
|
3752
|
-
|
|
3753
|
-
/***/ }),
|
|
3754
|
-
|
|
3755
3757
|
/***/ "lodash/transform":
|
|
3756
3758
|
/*!***********************************!*\
|
|
3757
3759
|
!*** external "lodash/transform" ***!
|