react-native-onyx 1.0.55 → 1.0.57
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 +218 -168
- 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 +48 -13
- package/lib/withOnyx.js +35 -7
- 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,47 @@ 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));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
|
|
266
|
+
* If the requested key is a collection, it will return an object with all the collection members.
|
|
267
|
+
*
|
|
268
|
+
* @param {String} key
|
|
269
|
+
* @param {Object} mapping
|
|
270
|
+
* @returns {Mixed}
|
|
271
|
+
*/
|
|
272
|
+
function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
273
|
+
let val = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
|
|
274
|
+
|
|
275
|
+
if (isCollectionKey(key)) {
|
|
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);
|
|
280
|
+
if (cachedValue) {
|
|
281
|
+
// This is permissible because we're in the process of constructing the final object in a reduce function.
|
|
282
|
+
// eslint-disable-next-line no-param-reassign
|
|
283
|
+
finalObject[matchedKey] = cachedValue;
|
|
284
|
+
}
|
|
285
|
+
return finalObject;
|
|
286
|
+
}, {});
|
|
287
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isEmpty(values)) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
val = values;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (mapping.selector) {
|
|
294
|
+
const state = mapping.withOnyxInstance ? mapping.withOnyxInstance.state : undefined;
|
|
295
|
+
if (isCollectionKey(key)) {
|
|
296
|
+
return reduceCollectionWithSelector(val, mapping.selector, state);
|
|
297
|
+
}
|
|
298
|
+
return getSubsetOfData(val, mapping.selector, state);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return val;
|
|
269
302
|
}
|
|
270
303
|
|
|
271
304
|
/**
|
|
@@ -275,7 +308,7 @@ function isSafeEvictionKey(testKey) {
|
|
|
275
308
|
* @param {String} key
|
|
276
309
|
*/
|
|
277
310
|
function removeLastAccessedKey(key) {
|
|
278
|
-
recentlyAccessedKeys =
|
|
311
|
+
recentlyAccessedKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().without(recentlyAccessedKeys, key);
|
|
279
312
|
}
|
|
280
313
|
|
|
281
314
|
/**
|
|
@@ -305,7 +338,7 @@ function addLastAccessedKey(key) {
|
|
|
305
338
|
* @param {Number} connectionID
|
|
306
339
|
*/
|
|
307
340
|
function removeFromEvictionBlockList(key, connectionID) {
|
|
308
|
-
evictionBlocklist[key] =
|
|
341
|
+
evictionBlocklist[key] = underscore__WEBPACK_IMPORTED_MODULE_1___default().without(evictionBlocklist[key] || [], connectionID);
|
|
309
342
|
|
|
310
343
|
// Remove the key if there are no more subscribers
|
|
311
344
|
if (evictionBlocklist[key].length === 0) {
|
|
@@ -342,8 +375,8 @@ function addToEvictionBlockList(key, connectionID) {
|
|
|
342
375
|
function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
343
376
|
return getAllKeys().
|
|
344
377
|
then((keys) => {
|
|
345
|
-
|
|
346
|
-
|
|
378
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(evictionAllowList, (safeEvictionKey) => {
|
|
379
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => {
|
|
347
380
|
if (!isKeyMatch(safeEvictionKey, key)) {
|
|
348
381
|
return;
|
|
349
382
|
}
|
|
@@ -359,12 +392,12 @@ function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
|
359
392
|
* @returns {Object}
|
|
360
393
|
*/
|
|
361
394
|
function getCachedCollection(collectionKey) {
|
|
362
|
-
const collectionMemberKeys =
|
|
395
|
+
const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getAllKeys(),
|
|
363
396
|
(storedKey) => isCollectionMemberKey(collectionKey, storedKey));
|
|
364
397
|
|
|
365
398
|
|
|
366
|
-
return
|
|
367
|
-
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);
|
|
368
401
|
if (!cachedValue) {
|
|
369
402
|
return prev;
|
|
370
403
|
}
|
|
@@ -386,7 +419,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
386
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
|
|
387
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
|
|
388
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().
|
|
389
|
-
const stateMappingKeys =
|
|
422
|
+
const stateMappingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(callbackToStateMapping);
|
|
390
423
|
for (let i = 0; i < stateMappingKeys.length; i++) {
|
|
391
424
|
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
|
|
392
425
|
if (!subscriber) {
|
|
@@ -394,7 +427,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
394
427
|
}
|
|
395
428
|
|
|
396
429
|
// Skip iteration if we do not have a collection key or a collection member key on this subscriber
|
|
397
|
-
if (!
|
|
430
|
+
if (!_Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(subscriber.key, collectionKey)) {
|
|
398
431
|
continue;
|
|
399
432
|
}
|
|
400
433
|
|
|
@@ -413,7 +446,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
413
446
|
const cachedCollection = getCachedCollection(collectionKey);
|
|
414
447
|
|
|
415
448
|
// Regular Onyx.connect() subscriber found.
|
|
416
|
-
if (
|
|
449
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(subscriber.callback)) {
|
|
417
450
|
// If they are subscribed to the collection key and using waitForCollectionCallback then we'll
|
|
418
451
|
// send the whole cached collection.
|
|
419
452
|
if (isSubscribedToCollectionKey) {
|
|
@@ -424,7 +457,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
424
457
|
|
|
425
458
|
// If they are not using waitForCollectionCallback then we notify the subscriber with
|
|
426
459
|
// the new merged data but only for any keys in the partial collection.
|
|
427
|
-
const dataKeys =
|
|
460
|
+
const dataKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(partialCollection);
|
|
428
461
|
for (let j = 0; j < dataKeys.length; j++) {
|
|
429
462
|
const dataKey = dataKeys[j];
|
|
430
463
|
subscriber.callback(cachedCollection[dataKey], dataKey);
|
|
@@ -465,14 +498,14 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
465
498
|
}
|
|
466
499
|
|
|
467
500
|
subscriber.withOnyxInstance.setState((prevState) => {
|
|
468
|
-
const finalCollection =
|
|
469
|
-
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);
|
|
470
503
|
for (let j = 0; j < dataKeys.length; j++) {
|
|
471
504
|
const dataKey = dataKeys[j];
|
|
472
505
|
finalCollection[dataKey] = cachedCollection[dataKey];
|
|
473
506
|
}
|
|
474
507
|
|
|
475
|
-
|
|
508
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevState[subscriber.statePropertyName], finalCollection, 'keysChanged', collectionKey);
|
|
476
509
|
return {
|
|
477
510
|
[subscriber.statePropertyName]: finalCollection
|
|
478
511
|
};
|
|
@@ -485,7 +518,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
485
518
|
// However, we only want to update this subscriber if the partial data contains a change.
|
|
486
519
|
// Otherwise, we would update them with a value they already have and trigger an unnecessary re-render.
|
|
487
520
|
const dataFromCollection = partialCollection[subscriber.key];
|
|
488
|
-
if (
|
|
521
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(dataFromCollection)) {
|
|
489
522
|
continue;
|
|
490
523
|
}
|
|
491
524
|
|
|
@@ -497,7 +530,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
497
530
|
const prevData = prevState[subscriber.statePropertyName];
|
|
498
531
|
const newData = getSubsetOfData(cachedCollection[subscriber.key], subscriber.selector, subscriber.withOnyxInstance.state);
|
|
499
532
|
if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, newData)) {
|
|
500
|
-
|
|
533
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keysChanged', collectionKey);
|
|
501
534
|
return {
|
|
502
535
|
[subscriber.statePropertyName]: newData
|
|
503
536
|
};
|
|
@@ -515,7 +548,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
515
548
|
return null;
|
|
516
549
|
}
|
|
517
550
|
|
|
518
|
-
|
|
551
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keysChanged', collectionKey);
|
|
519
552
|
return {
|
|
520
553
|
[subscriber.statePropertyName]: data
|
|
521
554
|
};
|
|
@@ -538,7 +571,7 @@ function keysChanged(collectionKey, partialCollection) {
|
|
|
538
571
|
*/
|
|
539
572
|
function keyChanged(key, data, canUpdateSubscriber) {
|
|
540
573
|
// Add or remove this key from the recentlyAccessedKeys lists
|
|
541
|
-
if (!
|
|
574
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(data)) {
|
|
542
575
|
addLastAccessedKey(key);
|
|
543
576
|
} else {
|
|
544
577
|
removeLastAccessedKey(key);
|
|
@@ -547,15 +580,15 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
547
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
|
|
548
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
|
|
549
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.
|
|
550
|
-
const stateMappingKeys =
|
|
583
|
+
const stateMappingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(callbackToStateMapping);
|
|
551
584
|
for (let i = 0; i < stateMappingKeys.length; i++) {
|
|
552
585
|
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
|
|
553
|
-
if (!subscriber || !isKeyMatch(subscriber.key, key) ||
|
|
586
|
+
if (!subscriber || !isKeyMatch(subscriber.key, key) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(canUpdateSubscriber) && !canUpdateSubscriber(subscriber)) {
|
|
554
587
|
continue;
|
|
555
588
|
}
|
|
556
589
|
|
|
557
590
|
// Subscriber is a regular call to connect() and provided a callback
|
|
558
|
-
if (
|
|
591
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(subscriber.callback)) {
|
|
559
592
|
if (isCollectionKey(subscriber.key) && subscriber.waitForCollectionCallback) {
|
|
560
593
|
const cachedCollection = getCachedCollection(subscriber.key);
|
|
561
594
|
cachedCollection[key] = data;
|
|
@@ -584,7 +617,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
584
617
|
...newData
|
|
585
618
|
};
|
|
586
619
|
if (!(0,fast_equals__WEBPACK_IMPORTED_MODULE_0__.deepEqual)(prevData, prevDataWithNewData)) {
|
|
587
|
-
|
|
620
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, prevData, newData, 'keyChanged', key);
|
|
588
621
|
return {
|
|
589
622
|
[subscriber.statePropertyName]: prevDataWithNewData
|
|
590
623
|
};
|
|
@@ -600,7 +633,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
600
633
|
...collection,
|
|
601
634
|
[key]: data
|
|
602
635
|
};
|
|
603
|
-
|
|
636
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, collection, newCollection, 'keyChanged', key);
|
|
604
637
|
return {
|
|
605
638
|
[subscriber.statePropertyName]: newCollection
|
|
606
639
|
};
|
|
@@ -631,7 +664,7 @@ function keyChanged(key, data, canUpdateSubscriber) {
|
|
|
631
664
|
return null;
|
|
632
665
|
}
|
|
633
666
|
|
|
634
|
-
|
|
667
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(subscriber, previousData, data, 'keyChanged', key);
|
|
635
668
|
return {
|
|
636
669
|
[subscriber.statePropertyName]: data
|
|
637
670
|
};
|
|
@@ -677,12 +710,12 @@ function sendDataToConnection(mapping, val, matchedKey) {
|
|
|
677
710
|
}
|
|
678
711
|
}
|
|
679
712
|
|
|
680
|
-
|
|
713
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.logSetStateCall(mapping, null, newData, 'sendDataToConnection');
|
|
681
714
|
mapping.withOnyxInstance.setWithOnyxState(mapping.statePropertyName, newData);
|
|
682
715
|
return;
|
|
683
716
|
}
|
|
684
717
|
|
|
685
|
-
if (
|
|
718
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(mapping.callback)) {
|
|
686
719
|
mapping.callback(val, matchedKey);
|
|
687
720
|
}
|
|
688
721
|
}
|
|
@@ -700,11 +733,11 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
700
733
|
}
|
|
701
734
|
|
|
702
735
|
// Try to free some cache whenever we connect to a safe eviction key
|
|
703
|
-
|
|
736
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].removeLeastRecentlyUsedKeys();
|
|
704
737
|
|
|
705
738
|
if (mapping.withOnyxInstance && !isCollectionKey(mapping.key)) {
|
|
706
739
|
// All React components subscribing to a key flagged as a safe eviction key must implement the canEvict property.
|
|
707
|
-
if (
|
|
740
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(mapping.canEvict)) {
|
|
708
741
|
throw new Error(
|
|
709
742
|
`Cannot subscribe to safe eviction key '${mapping.key}' without providing a canEvict value.`);
|
|
710
743
|
|
|
@@ -722,8 +755,8 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
722
755
|
* @param {Object} mapping
|
|
723
756
|
*/
|
|
724
757
|
function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
725
|
-
Promise.all(
|
|
726
|
-
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) => {
|
|
727
760
|
// eslint-disable-next-line no-param-reassign
|
|
728
761
|
finalObject[matchingKeys[i]] = value;
|
|
729
762
|
return finalObject;
|
|
@@ -750,11 +783,10 @@ function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
|
750
783
|
* @param {Boolean} [mapping.initWithStoredValues] If set to false, then no data will be prefilled into the
|
|
751
784
|
* component
|
|
752
785
|
* @param {Boolean} [mapping.waitForCollectionCallback] If set to true, it will return the entire collection to the callback as a single object
|
|
753
|
-
* @param {
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
* 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).
|
|
758
790
|
* @returns {Number} an ID to use when calling disconnect
|
|
759
791
|
*/
|
|
760
792
|
function connect(mapping) {
|
|
@@ -774,7 +806,7 @@ function connect(mapping) {
|
|
|
774
806
|
// We search all the keys in storage to see if any are a "match" for the subscriber we are connecting so that we
|
|
775
807
|
// can send data back to the subscriber. Note that multiple keys can match as a subscriber could either be
|
|
776
808
|
// subscribed to a "collection key" or a single key.
|
|
777
|
-
const matchingKeys =
|
|
809
|
+
const matchingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(keys, (key) => isKeyMatch(mapping.key, key));
|
|
778
810
|
|
|
779
811
|
// If the key being connected to does not exist we initialize the value with null. For subscribers that connected
|
|
780
812
|
// directly via connect() they will simply get a null value sent to them without any information about which key matched
|
|
@@ -788,7 +820,7 @@ function connect(mapping) {
|
|
|
788
820
|
// When using a callback subscriber we will either trigger the provided callback for each key we find or combine all values
|
|
789
821
|
// into an object and just make a single call. The latter behavior is enabled by providing a waitForCollectionCallback key
|
|
790
822
|
// combined with a subscription to a collection key.
|
|
791
|
-
if (
|
|
823
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(mapping.callback)) {
|
|
792
824
|
if (isCollectionKey(mapping.key)) {
|
|
793
825
|
if (mapping.waitForCollectionCallback) {
|
|
794
826
|
getCollectionDataAndSendAsObject(matchingKeys, mapping);
|
|
@@ -889,9 +921,9 @@ function notifyCollectionSubscribersOnNextTick(key, value) {
|
|
|
889
921
|
* @return {Promise}
|
|
890
922
|
*/
|
|
891
923
|
function remove(key) {
|
|
892
|
-
|
|
924
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key);
|
|
893
925
|
notifySubscribersOnNextTick(key, null);
|
|
894
|
-
return
|
|
926
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItem(key);
|
|
895
927
|
}
|
|
896
928
|
|
|
897
929
|
/**
|
|
@@ -906,23 +938,23 @@ function remove(key) {
|
|
|
906
938
|
* @return {Promise}
|
|
907
939
|
*/
|
|
908
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];}
|
|
909
|
-
|
|
941
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Handled error: ${error}`);
|
|
910
942
|
|
|
911
|
-
if (error &&
|
|
912
|
-
|
|
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.');
|
|
913
945
|
throw error;
|
|
914
946
|
}
|
|
915
947
|
|
|
916
948
|
// Find the first key that we can remove that has no subscribers in our blocklist
|
|
917
|
-
const keyForRemoval =
|
|
949
|
+
const keyForRemoval = underscore__WEBPACK_IMPORTED_MODULE_1___default().find(recentlyAccessedKeys, (key) => !evictionBlocklist[key]);
|
|
918
950
|
|
|
919
951
|
if (!keyForRemoval) {
|
|
920
|
-
|
|
952
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Out of storage. But found no acceptable keys to remove.');
|
|
921
953
|
throw error;
|
|
922
954
|
}
|
|
923
955
|
|
|
924
956
|
// Remove the least recently viewed key that is not currently being accessed and retry.
|
|
925
|
-
|
|
957
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
|
|
926
958
|
return remove(keyForRemoval).
|
|
927
959
|
then(() => onyxMethod(...args));
|
|
928
960
|
}
|
|
@@ -937,14 +969,14 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
|
|
|
937
969
|
*/
|
|
938
970
|
function broadcastUpdate(key, value, hasChanged, method) {
|
|
939
971
|
// Logging properties only since values could be sensitive things we don't want to log
|
|
940
|
-
|
|
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(',')}` : ''}`);
|
|
941
973
|
|
|
942
974
|
// Update subscribers if the cached value has changed, or when the subscriber specifically requires
|
|
943
975
|
// all updates regardless of value changes (indicated by initWithStoredValues set to false).
|
|
944
976
|
if (hasChanged) {
|
|
945
|
-
|
|
977
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
|
|
946
978
|
} else {
|
|
947
|
-
|
|
979
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].addToAccessedKeys(key);
|
|
948
980
|
}
|
|
949
981
|
|
|
950
982
|
notifySubscribersOnNextTick(key, value, (subscriber) => hasChanged || subscriber.initWithStoredValues === false);
|
|
@@ -968,15 +1000,15 @@ function hasPendingMergeForKey(key) {
|
|
|
968
1000
|
* @returns {Promise}
|
|
969
1001
|
*/
|
|
970
1002
|
function set(key, value) {
|
|
971
|
-
if (
|
|
1003
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(value)) {
|
|
972
1004
|
return remove(key);
|
|
973
1005
|
}
|
|
974
1006
|
|
|
975
1007
|
if (hasPendingMergeForKey(key)) {
|
|
976
|
-
|
|
1008
|
+
_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.`);
|
|
977
1009
|
}
|
|
978
1010
|
|
|
979
|
-
const hasChanged =
|
|
1011
|
+
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, value);
|
|
980
1012
|
|
|
981
1013
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
982
1014
|
broadcastUpdate(key, value, hasChanged, 'set');
|
|
@@ -986,7 +1018,7 @@ function set(key, value) {
|
|
|
986
1018
|
return Promise.resolve();
|
|
987
1019
|
}
|
|
988
1020
|
|
|
989
|
-
return
|
|
1021
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].setItem(key, value).
|
|
990
1022
|
catch((error) => evictStorageAndRetry(error, set, key, value));
|
|
991
1023
|
}
|
|
992
1024
|
|
|
@@ -999,7 +1031,7 @@ function set(key, value) {
|
|
|
999
1031
|
* @return {Array} an array of key - value pairs <[key, value]>
|
|
1000
1032
|
*/
|
|
1001
1033
|
function prepareKeyValuePairsForStorage(data) {
|
|
1002
|
-
return
|
|
1034
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().map(data, (value, key) => [key, value]);
|
|
1003
1035
|
}
|
|
1004
1036
|
|
|
1005
1037
|
/**
|
|
@@ -1013,13 +1045,13 @@ function prepareKeyValuePairsForStorage(data) {
|
|
|
1013
1045
|
function multiSet(data) {
|
|
1014
1046
|
const keyValuePairs = prepareKeyValuePairsForStorage(data);
|
|
1015
1047
|
|
|
1016
|
-
|
|
1048
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (val, key) => {
|
|
1017
1049
|
// Update cache and optimistically inform subscribers on the next tick
|
|
1018
|
-
|
|
1050
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, val);
|
|
1019
1051
|
notifySubscribersOnNextTick(key, val);
|
|
1020
1052
|
});
|
|
1021
1053
|
|
|
1022
|
-
return
|
|
1054
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairs).
|
|
1023
1055
|
catch((error) => evictStorageAndRetry(error, multiSet, data));
|
|
1024
1056
|
}
|
|
1025
1057
|
|
|
@@ -1032,17 +1064,17 @@ function multiSet(data) {
|
|
|
1032
1064
|
* @returns {*}
|
|
1033
1065
|
*/
|
|
1034
1066
|
function applyMerge(existingValue, changes) {
|
|
1035
|
-
const lastChange =
|
|
1067
|
+
const lastChange = underscore__WEBPACK_IMPORTED_MODULE_1___default().last(changes);
|
|
1036
1068
|
|
|
1037
|
-
if (
|
|
1069
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(existingValue) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(lastChange)) {
|
|
1038
1070
|
return lastChange;
|
|
1039
1071
|
}
|
|
1040
1072
|
|
|
1041
|
-
if (
|
|
1073
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(existingValue) || underscore__WEBPACK_IMPORTED_MODULE_1___default().every(changes, (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject))) {
|
|
1042
1074
|
// Object values are merged one after the other
|
|
1043
1075
|
// lodash adds a small overhead so we don't use it here
|
|
1044
1076
|
// eslint-disable-next-line prefer-object-spread, rulesdir/prefer-underscore-method
|
|
1045
|
-
return
|
|
1077
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => (0,_fastMerge__WEBPACK_IMPORTED_MODULE_8__["default"])(modifiedData, change),
|
|
1046
1078
|
existingValue || {});
|
|
1047
1079
|
}
|
|
1048
1080
|
|
|
@@ -1095,11 +1127,11 @@ function merge(key, changes) {
|
|
|
1095
1127
|
|
|
1096
1128
|
// For objects, the key for null values needs to be removed from the object to ensure the value will get removed from storage completely.
|
|
1097
1129
|
// On native, SQLite will remove top-level keys that are null. To be consistent, we remove them on web too.
|
|
1098
|
-
if (!
|
|
1099
|
-
modifiedData =
|
|
1130
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(modifiedData) && underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(modifiedData)) {
|
|
1131
|
+
modifiedData = underscore__WEBPACK_IMPORTED_MODULE_1___default().omit(modifiedData, (value) => underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(value));
|
|
1100
1132
|
}
|
|
1101
1133
|
|
|
1102
|
-
const hasChanged =
|
|
1134
|
+
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].hasValueChanged(key, modifiedData);
|
|
1103
1135
|
|
|
1104
1136
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
1105
1137
|
broadcastUpdate(key, modifiedData, hasChanged, 'merge');
|
|
@@ -1109,9 +1141,9 @@ function merge(key, changes) {
|
|
|
1109
1141
|
return Promise.resolve();
|
|
1110
1142
|
}
|
|
1111
1143
|
|
|
1112
|
-
return
|
|
1144
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].mergeItem(key, batchedChanges, modifiedData);
|
|
1113
1145
|
} catch (error) {
|
|
1114
|
-
|
|
1146
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`An error occurred while applying merge for key: ${key}, Error: ${error}`);
|
|
1115
1147
|
}
|
|
1116
1148
|
|
|
1117
1149
|
return Promise.resolve();
|
|
@@ -1124,13 +1156,13 @@ function merge(key, changes) {
|
|
|
1124
1156
|
* @returns {Promise}
|
|
1125
1157
|
*/
|
|
1126
1158
|
function initializeWithDefaultKeyStates() {
|
|
1127
|
-
return
|
|
1159
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).
|
|
1128
1160
|
then((pairs) => {
|
|
1129
|
-
const asObject =
|
|
1161
|
+
const asObject = underscore__WEBPACK_IMPORTED_MODULE_1___default().object(pairs);
|
|
1130
1162
|
|
|
1131
|
-
const merged = (0,
|
|
1132
|
-
|
|
1133
|
-
|
|
1163
|
+
const merged = (0,_fastMerge__WEBPACK_IMPORTED_MODULE_8__["default"])(asObject, defaultKeyStates);
|
|
1164
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(merged);
|
|
1165
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(merged, (val, key) => keyChanged(key, val));
|
|
1134
1166
|
});
|
|
1135
1167
|
}
|
|
1136
1168
|
|
|
@@ -1168,19 +1200,19 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1168
1200
|
// status, or activeClients need to remain in Onyx even when signed out)
|
|
1169
1201
|
// 2. Any keys with a default state (because they need to remain in Onyx as their default, and setting them
|
|
1170
1202
|
// to null would cause unknown behavior)
|
|
1171
|
-
|
|
1172
|
-
const isKeyToPreserve =
|
|
1173
|
-
const isDefaultKey =
|
|
1203
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => {
|
|
1204
|
+
const isKeyToPreserve = underscore__WEBPACK_IMPORTED_MODULE_1___default().contains(keysToPreserve, key);
|
|
1205
|
+
const isDefaultKey = underscore__WEBPACK_IMPORTED_MODULE_1___default().has(defaultKeyStates, key);
|
|
1174
1206
|
|
|
1175
1207
|
// If the key is being removed or reset to default:
|
|
1176
1208
|
// 1. Update it in the cache
|
|
1177
1209
|
// 2. Figure out whether it is a collection key or not,
|
|
1178
1210
|
// since collection key subscribers need to be updated differently
|
|
1179
1211
|
if (!isKeyToPreserve) {
|
|
1180
|
-
const oldValue =
|
|
1181
|
-
const newValue =
|
|
1212
|
+
const oldValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].getValue(key);
|
|
1213
|
+
const newValue = underscore__WEBPACK_IMPORTED_MODULE_1___default().get(defaultKeyStates, key, null);
|
|
1182
1214
|
if (newValue !== oldValue) {
|
|
1183
|
-
|
|
1215
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, newValue);
|
|
1184
1216
|
const collectionKey = key.substring(0, key.indexOf('_') + 1);
|
|
1185
1217
|
if (collectionKey) {
|
|
1186
1218
|
if (!keyValuesToResetAsCollection[collectionKey]) {
|
|
@@ -1202,18 +1234,18 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1202
1234
|
});
|
|
1203
1235
|
|
|
1204
1236
|
// Notify the subscribers for each key/value group so they can receive the new values
|
|
1205
|
-
|
|
1237
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keyValuesToResetIndividually, (value, key) => {
|
|
1206
1238
|
notifySubscribersOnNextTick(key, value);
|
|
1207
1239
|
});
|
|
1208
|
-
|
|
1240
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keyValuesToResetAsCollection, (value, key) => {
|
|
1209
1241
|
notifyCollectionSubscribersOnNextTick(key, value);
|
|
1210
1242
|
});
|
|
1211
1243
|
|
|
1212
|
-
const defaultKeyValuePairs =
|
|
1244
|
+
const defaultKeyValuePairs = underscore__WEBPACK_IMPORTED_MODULE_1___default().pairs(underscore__WEBPACK_IMPORTED_MODULE_1___default().omit(defaultKeyStates, keysToPreserve));
|
|
1213
1245
|
|
|
1214
1246
|
// Remove only the items that we want cleared from storage, and reset others to default
|
|
1215
|
-
|
|
1216
|
-
return
|
|
1247
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keysToBeClearedFromStorage, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].drop(key));
|
|
1248
|
+
return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItems(keysToBeClearedFromStorage).then(() => _storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(defaultKeyValuePairs));
|
|
1217
1249
|
});
|
|
1218
1250
|
}
|
|
1219
1251
|
|
|
@@ -1232,14 +1264,14 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1232
1264
|
* @returns {Promise}
|
|
1233
1265
|
*/
|
|
1234
1266
|
function mergeCollection(collectionKey, collection) {
|
|
1235
|
-
if (!
|
|
1236
|
-
|
|
1267
|
+
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)) {
|
|
1268
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo('mergeCollection() called with invalid or empty value. Skipping this update.');
|
|
1237
1269
|
return Promise.resolve();
|
|
1238
1270
|
}
|
|
1239
1271
|
|
|
1240
1272
|
// Confirm all the collection keys belong to the same parent
|
|
1241
1273
|
let hasCollectionKeyCheckFailed = false;
|
|
1242
|
-
|
|
1274
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(collection, (_data, dataKey) => {
|
|
1243
1275
|
if (isKeyMatch(collectionKey, dataKey)) {
|
|
1244
1276
|
return;
|
|
1245
1277
|
}
|
|
@@ -1249,7 +1281,7 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1249
1281
|
}
|
|
1250
1282
|
|
|
1251
1283
|
hasCollectionKeyCheckFailed = true;
|
|
1252
|
-
|
|
1284
|
+
_Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Provided collection doesn't have all its data belonging to the same parent. CollectionKey: ${collectionKey}, DataKey: ${dataKey}`);
|
|
1253
1285
|
});
|
|
1254
1286
|
|
|
1255
1287
|
// Gracefully handle bad mergeCollection updates so it doesn't block the merge queue
|
|
@@ -1260,13 +1292,13 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1260
1292
|
return getAllKeys().
|
|
1261
1293
|
then((persistedKeys) => {
|
|
1262
1294
|
// Split to keys that exist in storage and keys that don't
|
|
1263
|
-
const [existingKeys, newKeys] =
|
|
1295
|
+
const [existingKeys, newKeys] = underscore__WEBPACK_IMPORTED_MODULE_1___default().chain(collection).
|
|
1264
1296
|
keys().
|
|
1265
1297
|
partition((key) => persistedKeys.includes(key)).
|
|
1266
1298
|
value();
|
|
1267
1299
|
|
|
1268
|
-
const existingKeyCollection =
|
|
1269
|
-
const newCollection =
|
|
1300
|
+
const existingKeyCollection = underscore__WEBPACK_IMPORTED_MODULE_1___default().pick(collection, existingKeys);
|
|
1301
|
+
const newCollection = underscore__WEBPACK_IMPORTED_MODULE_1___default().pick(collection, newKeys);
|
|
1270
1302
|
const keyValuePairsForExistingCollection = prepareKeyValuePairsForStorage(existingKeyCollection);
|
|
1271
1303
|
const keyValuePairsForNewCollection = prepareKeyValuePairsForStorage(newCollection);
|
|
1272
1304
|
|
|
@@ -1275,17 +1307,17 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1275
1307
|
// New keys will be added via multiSet while existing keys will be updated using multiMerge
|
|
1276
1308
|
// This is because setting a key that doesn't exist yet with multiMerge will throw errors
|
|
1277
1309
|
if (keyValuePairsForExistingCollection.length > 0) {
|
|
1278
|
-
promises.push(
|
|
1310
|
+
promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiMerge(keyValuePairsForExistingCollection));
|
|
1279
1311
|
}
|
|
1280
1312
|
|
|
1281
1313
|
if (keyValuePairsForNewCollection.length > 0) {
|
|
1282
|
-
promises.push(
|
|
1314
|
+
promises.push(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].multiSet(keyValuePairsForNewCollection));
|
|
1283
1315
|
}
|
|
1284
1316
|
|
|
1285
1317
|
// Prefill cache if necessary by calling get() on any existing keys and then merge original data to cache
|
|
1286
1318
|
// and update all subscribers
|
|
1287
|
-
Promise.all(
|
|
1288
|
-
|
|
1319
|
+
Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(existingKeys, get)).then(() => {
|
|
1320
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].merge(collection);
|
|
1289
1321
|
keysChanged(collectionKey, collection);
|
|
1290
1322
|
});
|
|
1291
1323
|
|
|
@@ -1302,11 +1334,11 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1302
1334
|
*/
|
|
1303
1335
|
function update(data) {
|
|
1304
1336
|
// First, validate the Onyx object is in the format we expect
|
|
1305
|
-
|
|
1306
|
-
if (!
|
|
1337
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref) => {let { onyxMethod, key } = _ref;
|
|
1338
|
+
if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().contains([METHOD.CLEAR, METHOD.SET, METHOD.MERGE, METHOD.MERGE_COLLECTION], onyxMethod)) {
|
|
1307
1339
|
throw new Error(`Invalid onyxMethod ${onyxMethod} in Onyx update.`);
|
|
1308
1340
|
}
|
|
1309
|
-
if (onyxMethod !== METHOD.CLEAR && !
|
|
1341
|
+
if (onyxMethod !== METHOD.CLEAR && !underscore__WEBPACK_IMPORTED_MODULE_1___default().isString(key)) {
|
|
1310
1342
|
throw new Error(`Invalid ${typeof key} key provided in Onyx update. Onyx key must be of type string.`);
|
|
1311
1343
|
}
|
|
1312
1344
|
});
|
|
@@ -1314,7 +1346,7 @@ function update(data) {
|
|
|
1314
1346
|
const promises = [];
|
|
1315
1347
|
let clearPromise = Promise.resolve();
|
|
1316
1348
|
|
|
1317
|
-
|
|
1349
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref2) => {let { onyxMethod, key, value } = _ref2;
|
|
1318
1350
|
switch (onyxMethod) {
|
|
1319
1351
|
case METHOD.SET:
|
|
1320
1352
|
promises.push(() => set(key, value));
|
|
@@ -1333,7 +1365,7 @@ function update(data) {
|
|
|
1333
1365
|
|
|
1334
1366
|
});
|
|
1335
1367
|
|
|
1336
|
-
return clearPromise.then(() => Promise.all(
|
|
1368
|
+
return clearPromise.then(() => Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(promises, (p) => p())));
|
|
1337
1369
|
}
|
|
1338
1370
|
|
|
1339
1371
|
/**
|
|
@@ -1341,10 +1373,10 @@ function update(data) {
|
|
|
1341
1373
|
* @param {string[]} keyList
|
|
1342
1374
|
*/
|
|
1343
1375
|
function setMemoryOnlyKeys(keyList) {
|
|
1344
|
-
|
|
1376
|
+
_storage__WEBPACK_IMPORTED_MODULE_4__["default"].setMemoryOnlyKeys(keyList);
|
|
1345
1377
|
|
|
1346
1378
|
// 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.
|
|
1347
|
-
|
|
1379
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(Infinity);
|
|
1348
1380
|
}
|
|
1349
1381
|
|
|
1350
1382
|
/**
|
|
@@ -1388,11 +1420,11 @@ function init()
|
|
|
1388
1420
|
}
|
|
1389
1421
|
|
|
1390
1422
|
if (debugSetState) {
|
|
1391
|
-
|
|
1423
|
+
_metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_7__.setShouldDebugSetState(true);
|
|
1392
1424
|
}
|
|
1393
1425
|
|
|
1394
1426
|
if (maxCachedKeysCount > 0) {
|
|
1395
|
-
|
|
1427
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].setRecentKeysLimit(maxCachedKeysCount);
|
|
1396
1428
|
}
|
|
1397
1429
|
|
|
1398
1430
|
// Let Onyx know about all of our keys
|
|
@@ -1411,9 +1443,9 @@ function init()
|
|
|
1411
1443
|
|
|
1412
1444
|
then(deferredInitTask.resolve);
|
|
1413
1445
|
|
|
1414
|
-
if (shouldSyncMultipleInstances &&
|
|
1415
|
-
|
|
1416
|
-
|
|
1446
|
+
if (shouldSyncMultipleInstances && underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(_storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync)) {
|
|
1447
|
+
_storage__WEBPACK_IMPORTED_MODULE_4__["default"].keepInstancesSync((key, value) => {
|
|
1448
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_3__["default"].set(key, value);
|
|
1417
1449
|
keyChanged(key, value);
|
|
1418
1450
|
});
|
|
1419
1451
|
}
|
|
@@ -1431,12 +1463,13 @@ const Onyx = {
|
|
|
1431
1463
|
clear,
|
|
1432
1464
|
getAllKeys,
|
|
1433
1465
|
init,
|
|
1434
|
-
registerLogger:
|
|
1466
|
+
registerLogger: _Logger__WEBPACK_IMPORTED_MODULE_5__.registerLogger,
|
|
1435
1467
|
addToEvictionBlockList,
|
|
1436
1468
|
removeFromEvictionBlockList,
|
|
1437
1469
|
isSafeEvictionKey,
|
|
1438
1470
|
METHOD,
|
|
1439
|
-
setMemoryOnlyKeys
|
|
1471
|
+
setMemoryOnlyKeys,
|
|
1472
|
+
tryGetCachedValue
|
|
1440
1473
|
};
|
|
1441
1474
|
|
|
1442
1475
|
/**
|
|
@@ -2402,13 +2435,25 @@ function getDisplayName(component) {
|
|
|
2402
2435
|
// disconnected. It is a key value store with the format {[mapping.key]: connectionID}.
|
|
2403
2436
|
this.activeConnectionIDs = {};
|
|
2404
2437
|
|
|
2438
|
+
const cachedState = underscore__WEBPACK_IMPORTED_MODULE_2___default().reduce(mapOnyxToState, (resultObj, mapping, propertyName) => {
|
|
2439
|
+
const key = _Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, props);
|
|
2440
|
+
const value = _Onyx__WEBPACK_IMPORTED_MODULE_4__["default"].tryGetCachedValue(key, mapping);
|
|
2441
|
+
|
|
2442
|
+
if (value !== undefined) {
|
|
2443
|
+
// eslint-disable-next-line no-param-reassign
|
|
2444
|
+
resultObj[propertyName] = value;
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
return resultObj;
|
|
2448
|
+
}, {});
|
|
2449
|
+
|
|
2450
|
+
// If we have all the data we need, then we can render the component immediately
|
|
2451
|
+
cachedState.loading = underscore__WEBPACK_IMPORTED_MODULE_2___default().size(cachedState) < requiredKeysForInit.length;
|
|
2452
|
+
|
|
2405
2453
|
// Object holding the temporary initial state for the component while we load the various Onyx keys
|
|
2406
|
-
this.tempState =
|
|
2454
|
+
this.tempState = cachedState;
|
|
2407
2455
|
|
|
2408
|
-
this.state =
|
|
2409
|
-
// If there are no required keys for init then we can render the wrapped component immediately
|
|
2410
|
-
loading: requiredKeysForInit.length > 0
|
|
2411
|
-
};
|
|
2456
|
+
this.state = cachedState;
|
|
2412
2457
|
}
|
|
2413
2458
|
|
|
2414
2459
|
componentDidMount() {
|
|
@@ -2425,7 +2470,6 @@ function getDisplayName(component) {
|
|
|
2425
2470
|
underscore__WEBPACK_IMPORTED_MODULE_2___default().each(mapOnyxToState, (mapping, propertyName) => {
|
|
2426
2471
|
const previousKey = _Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, prevProps);
|
|
2427
2472
|
const newKey = _Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, this.props);
|
|
2428
|
-
|
|
2429
2473
|
if (previousKey !== newKey) {
|
|
2430
2474
|
_Onyx__WEBPACK_IMPORTED_MODULE_4__["default"].disconnect(this.activeConnectionIDs[previousKey], previousKey);
|
|
2431
2475
|
delete this.activeConnectionIDs[previousKey];
|
|
@@ -2453,6 +2497,16 @@ function getDisplayName(component) {
|
|
|
2453
2497
|
* @param {*} val
|
|
2454
2498
|
*/
|
|
2455
2499
|
setWithOnyxState(statePropertyName, val) {
|
|
2500
|
+
// We might have loaded the values for the onyx keys/mappings already from the cache.
|
|
2501
|
+
// In case we were able to load all the values upfront, the loading state will be false.
|
|
2502
|
+
// However, Onyx.js will always call setWithOnyxState, as it doesn't know that this implementation
|
|
2503
|
+
// already loaded the values from cache. Thus we have to check whether the value has changed
|
|
2504
|
+
// before we set the state to prevent unnecessary renders.
|
|
2505
|
+
const prevValue = this.state[statePropertyName];
|
|
2506
|
+
if (!this.state.loading && prevValue === val) {
|
|
2507
|
+
return;
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2456
2510
|
if (!this.state.loading) {
|
|
2457
2511
|
this.setState({ [statePropertyName]: val });
|
|
2458
2512
|
return;
|
|
@@ -2465,7 +2519,14 @@ function getDisplayName(component) {
|
|
|
2465
2519
|
return;
|
|
2466
2520
|
}
|
|
2467
2521
|
|
|
2468
|
-
|
|
2522
|
+
const stateUpdate = { ...this.tempState, loading: false };
|
|
2523
|
+
|
|
2524
|
+
// The state is set here manually, instead of using setState because setState is an async operation, meaning it might execute on the next tick,
|
|
2525
|
+
// or at a later point in the microtask queue. That can lead to a race condition where
|
|
2526
|
+
// setWithOnyxState is called before the state is actually set. This results in unreliable behavior when checking the loading state and has been mainly observed on fabric.
|
|
2527
|
+
this.state = stateUpdate;
|
|
2528
|
+
|
|
2529
|
+
this.setState(stateUpdate); // Trigger a render
|
|
2469
2530
|
delete this.tempState;
|
|
2470
2531
|
}
|
|
2471
2532
|
|
|
@@ -3672,17 +3733,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_localforage_removeitems__;
|
|
|
3672
3733
|
|
|
3673
3734
|
/***/ }),
|
|
3674
3735
|
|
|
3675
|
-
/***/ "lodash/get":
|
|
3676
|
-
/*!*****************************!*\
|
|
3677
|
-
!*** external "lodash/get" ***!
|
|
3678
|
-
\*****************************/
|
|
3679
|
-
/***/ ((module) => {
|
|
3680
|
-
|
|
3681
|
-
"use strict";
|
|
3682
|
-
module.exports = __WEBPACK_EXTERNAL_MODULE_lodash_get__;
|
|
3683
|
-
|
|
3684
|
-
/***/ }),
|
|
3685
|
-
|
|
3686
3736
|
/***/ "lodash/transform":
|
|
3687
3737
|
/*!***********************************!*\
|
|
3688
3738
|
!*** external "lodash/transform" ***!
|