react-native-onyx 1.0.119 → 1.0.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/web.development.js +408 -113
- 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/ActiveClientManager/index.d.ts +22 -0
- package/lib/ActiveClientManager/index.native.js +23 -0
- package/lib/ActiveClientManager/index.web.js +99 -0
- package/lib/Logger.js +1 -5
- package/lib/MDTable.js +11 -14
- package/lib/Onyx.d.ts +11 -4
- package/lib/Onyx.js +344 -232
- package/lib/OnyxCache.js +12 -3
- package/lib/Str.js +17 -4
- package/lib/broadcast/index.d.ts +17 -0
- package/lib/broadcast/index.native.js +14 -0
- package/lib/broadcast/index.web.js +35 -0
- package/lib/compose.js +6 -2
- package/lib/metrics/PerformanceUtils.js +2 -7
- package/lib/metrics/index.native.js +28 -41
- package/lib/metrics/index.web.js +4 -7
- package/lib/storage/WebStorage.js +6 -11
- package/lib/storage/__mocks__/index.js +2 -2
- package/lib/storage/providers/IDBKeyVal.js +27 -37
- package/lib/storage/providers/SQLiteStorage.js +58 -62
- package/lib/types.d.ts +1 -13
- package/lib/utils.d.ts +2 -6
- package/lib/utils.js +19 -22
- package/lib/withOnyx.d.ts +8 -32
- package/lib/withOnyx.js +37 -34
- package/package.json +15 -6
package/dist/web.development.js
CHANGED
|
@@ -11,6 +11,119 @@
|
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
12
|
/******/ var __webpack_modules__ = ({
|
|
13
13
|
|
|
14
|
+
/***/ "./lib/ActiveClientManager/index.web.js":
|
|
15
|
+
/*!**********************************************!*\
|
|
16
|
+
!*** ./lib/ActiveClientManager/index.web.js ***!
|
|
17
|
+
\**********************************************/
|
|
18
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
19
|
+
|
|
20
|
+
"use strict";
|
|
21
|
+
__webpack_require__.r(__webpack_exports__);
|
|
22
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
23
|
+
/* harmony export */ "init": () => (/* binding */ init),
|
|
24
|
+
/* harmony export */ "isClientTheLeader": () => (/* binding */ isClientTheLeader),
|
|
25
|
+
/* harmony export */ "isReady": () => (/* binding */ isReady),
|
|
26
|
+
/* harmony export */ "subscribeToClientChange": () => (/* binding */ subscribeToClientChange)
|
|
27
|
+
/* harmony export */ });
|
|
28
|
+
/* harmony import */ var _Str__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Str */ "./lib/Str.js");
|
|
29
|
+
/* harmony import */ var _broadcast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../broadcast */ "./lib/broadcast/index.web.js");
|
|
30
|
+
/**
|
|
31
|
+
* When you have many tabs in one browser, the data of Onyx is shared between all of them. Since we persist write requests in Onyx, we need to ensure that
|
|
32
|
+
* only one tab is processing those saved requests or we would be duplicating data (or creating errors).
|
|
33
|
+
* This file ensures exactly that by tracking all the clientIDs connected, storing the most recent one last and it considers that last clientID the "leader".
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
const NEW_LEADER_MESSAGE = 'NEW_LEADER';
|
|
40
|
+
const REMOVED_LEADER_MESSAGE = 'REMOVE_LEADER';
|
|
41
|
+
|
|
42
|
+
const clientID = _Str__WEBPACK_IMPORTED_MODULE_0__.guid();
|
|
43
|
+
const subscribers = [];
|
|
44
|
+
let timestamp = null;
|
|
45
|
+
|
|
46
|
+
let activeClientID = null;
|
|
47
|
+
let setIsReady = () => {};
|
|
48
|
+
const isReadyPromise = new Promise((resolve) => {
|
|
49
|
+
setIsReady = resolve;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Determines when the client is ready. We need to wait both till we saved our ID in onyx AND the init method was called
|
|
54
|
+
* @returns {Promise}
|
|
55
|
+
*/
|
|
56
|
+
function isReady() {
|
|
57
|
+
return isReadyPromise;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns a boolean indicating if the current client is the leader.
|
|
62
|
+
*
|
|
63
|
+
* @returns {Boolean}
|
|
64
|
+
*/
|
|
65
|
+
function isClientTheLeader() {
|
|
66
|
+
return activeClientID === clientID;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Subscribes to when the client changes.
|
|
71
|
+
* @param {Function} callback
|
|
72
|
+
*/
|
|
73
|
+
function subscribeToClientChange(callback) {
|
|
74
|
+
subscribers.push(callback);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Subscribe to the broadcast channel to listen for messages from other tabs, so that
|
|
79
|
+
* all tabs agree on who the leader is, which should always be the last tab to open.
|
|
80
|
+
*/
|
|
81
|
+
function init() {
|
|
82
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_1__.subscribe((message) => {
|
|
83
|
+
switch (message.data.type) {
|
|
84
|
+
case NEW_LEADER_MESSAGE:{
|
|
85
|
+
// Only update the active leader if the message received was from another
|
|
86
|
+
// tab that initialized after the current one; if the timestamps are the
|
|
87
|
+
// same, it uses the client ID to tie-break
|
|
88
|
+
const isTimestampEqual = timestamp === message.data.timestamp;
|
|
89
|
+
const isTimestampNewer = timestamp > message.data.timestamp;
|
|
90
|
+
if (isClientTheLeader() && (isTimestampNewer || isTimestampEqual && clientID > message.data.clientID)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
activeClientID = message.data.clientID;
|
|
94
|
+
|
|
95
|
+
subscribers.forEach((callback) => callback());
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case REMOVED_LEADER_MESSAGE:
|
|
99
|
+
activeClientID = clientID;
|
|
100
|
+
timestamp = Date.now();
|
|
101
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_1__.sendMessage({ type: NEW_LEADER_MESSAGE, clientID, timestamp });
|
|
102
|
+
subscribers.forEach((callback) => callback());
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
break;}
|
|
106
|
+
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
activeClientID = clientID;
|
|
110
|
+
timestamp = Date.now();
|
|
111
|
+
|
|
112
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_1__.sendMessage({ type: NEW_LEADER_MESSAGE, clientID, timestamp });
|
|
113
|
+
setIsReady();
|
|
114
|
+
|
|
115
|
+
window.addEventListener('beforeunload', () => {
|
|
116
|
+
if (!isClientTheLeader()) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_1__.sendMessage({ type: REMOVED_LEADER_MESSAGE, clientID });
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
/***/ }),
|
|
126
|
+
|
|
14
127
|
/***/ "./lib/Logger.js":
|
|
15
128
|
/*!***********************!*\
|
|
16
129
|
!*** ./lib/Logger.js ***!
|
|
@@ -79,6 +192,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
79
192
|
/* harmony import */ var _createDeferredTask__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./createDeferredTask */ "./lib/createDeferredTask.js");
|
|
80
193
|
/* harmony import */ var _metrics_PerformanceUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./metrics/PerformanceUtils */ "./lib/metrics/PerformanceUtils.js");
|
|
81
194
|
/* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./storage */ "./lib/storage/index.web.js");
|
|
195
|
+
/* harmony import */ var _broadcast__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./broadcast */ "./lib/broadcast/index.web.js");
|
|
196
|
+
/* harmony import */ var _ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ActiveClientManager */ "./lib/ActiveClientManager/index.web.js");
|
|
82
197
|
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils */ "./lib/utils.js");
|
|
83
198
|
/* harmony import */ var _batch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./batch */ "./lib/batch.js");
|
|
84
199
|
/* eslint-disable no-continue */
|
|
@@ -93,6 +208,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
93
208
|
|
|
94
209
|
|
|
95
210
|
|
|
211
|
+
|
|
212
|
+
|
|
96
213
|
// Method constants
|
|
97
214
|
const METHOD = {
|
|
98
215
|
SET: 'set',
|
|
@@ -102,6 +219,8 @@ const METHOD = {
|
|
|
102
219
|
CLEAR: 'clear'
|
|
103
220
|
};
|
|
104
221
|
|
|
222
|
+
const ON_CLEAR = 'on_clear';
|
|
223
|
+
|
|
105
224
|
// Key/value store of Onyx key and arrays of values to merge
|
|
106
225
|
const mergeQueue = {};
|
|
107
226
|
const mergeQueuePromise = {};
|
|
@@ -132,6 +251,12 @@ let defaultKeyStates = {};
|
|
|
132
251
|
// Connections can be made before `Onyx.init`. They would wait for this task before resolving
|
|
133
252
|
const deferredInitTask = (0,_createDeferredTask__WEBPACK_IMPORTED_MODULE_2__["default"])();
|
|
134
253
|
|
|
254
|
+
// The promise of the clear function, saved so that no writes happen while it's executing
|
|
255
|
+
let isClearing = false;
|
|
256
|
+
|
|
257
|
+
// Callback to be executed after the clear execution ends
|
|
258
|
+
let onClearCallback = null;
|
|
259
|
+
|
|
135
260
|
let batchUpdatesPromise = null;
|
|
136
261
|
let batchUpdatesQueue = [];
|
|
137
262
|
|
|
@@ -191,12 +316,17 @@ const getSubsetOfData = (sourceData, selector, withOnyxInstanceState) => selecto
|
|
|
191
316
|
* @param {Object} [withOnyxInstanceState]
|
|
192
317
|
* @returns {Object}
|
|
193
318
|
*/
|
|
194
|
-
const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceState) =>
|
|
319
|
+
const reduceCollectionWithSelector = (collection, selector, withOnyxInstanceState) =>
|
|
320
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
321
|
+
collection,
|
|
322
|
+
(finalCollection, item, key) => {
|
|
195
323
|
// eslint-disable-next-line no-param-reassign
|
|
196
324
|
finalCollection[key] = getSubsetOfData(item, selector, withOnyxInstanceState);
|
|
197
325
|
|
|
198
326
|
return finalCollection;
|
|
199
|
-
},
|
|
327
|
+
},
|
|
328
|
+
{});
|
|
329
|
+
|
|
200
330
|
|
|
201
331
|
/**
|
|
202
332
|
* Get some data from the store
|
|
@@ -249,8 +379,7 @@ function getAllKeys() {
|
|
|
249
379
|
}
|
|
250
380
|
|
|
251
381
|
// Otherwise retrieve the keys from storage and capture a promise to aid concurrent usages
|
|
252
|
-
const promise = _storage__WEBPACK_IMPORTED_MODULE_5__["default"].getAllKeys().
|
|
253
|
-
then((keys) => {
|
|
382
|
+
const promise = _storage__WEBPACK_IMPORTED_MODULE_5__["default"].getAllKeys().then((keys) => {
|
|
254
383
|
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].addKey(key));
|
|
255
384
|
return keys;
|
|
256
385
|
});
|
|
@@ -289,9 +418,7 @@ function isCollectionMemberKey(collectionKey, key) {
|
|
|
289
418
|
* @return {Boolean}
|
|
290
419
|
*/
|
|
291
420
|
function isKeyMatch(configKey, key) {
|
|
292
|
-
return isCollectionKey(configKey) ?
|
|
293
|
-
_Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(key, configKey) :
|
|
294
|
-
configKey === key;
|
|
421
|
+
return isCollectionKey(configKey) ? _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(key, configKey) : configKey === key;
|
|
295
422
|
}
|
|
296
423
|
|
|
297
424
|
/**
|
|
@@ -326,7 +453,9 @@ function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments
|
|
|
326
453
|
return;
|
|
327
454
|
}
|
|
328
455
|
const matchingKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(allCacheKeys, (k) => k.startsWith(key));
|
|
329
|
-
const values = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
456
|
+
const values = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
457
|
+
matchingKeys,
|
|
458
|
+
(finalObject, matchedKey) => {
|
|
330
459
|
const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(matchedKey);
|
|
331
460
|
if (cachedValue) {
|
|
332
461
|
// This is permissible because we're in the process of constructing the final object in a reduce function.
|
|
@@ -334,7 +463,9 @@ function tryGetCachedValue(key) {let mapping = arguments.length > 1 && arguments
|
|
|
334
463
|
finalObject[matchedKey] = cachedValue;
|
|
335
464
|
}
|
|
336
465
|
return finalObject;
|
|
337
|
-
},
|
|
466
|
+
},
|
|
467
|
+
{});
|
|
468
|
+
|
|
338
469
|
|
|
339
470
|
val = values;
|
|
340
471
|
}
|
|
@@ -422,8 +553,7 @@ function addToEvictionBlockList(key, connectionID) {
|
|
|
422
553
|
* @returns {Promise}
|
|
423
554
|
*/
|
|
424
555
|
function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
425
|
-
return getAllKeys().
|
|
426
|
-
then((keys) => {
|
|
556
|
+
return getAllKeys().then((keys) => {
|
|
427
557
|
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(evictionAllowList, (safeEvictionKey) => {
|
|
428
558
|
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keys, (key) => {
|
|
429
559
|
if (!isKeyMatch(safeEvictionKey, key)) {
|
|
@@ -441,11 +571,11 @@ function addAllSafeEvictionKeysToRecentlyAccessedList() {
|
|
|
441
571
|
* @returns {Object}
|
|
442
572
|
*/
|
|
443
573
|
function getCachedCollection(collectionKey) {
|
|
444
|
-
const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys(),
|
|
445
|
-
(storedKey) => isCollectionMemberKey(collectionKey, storedKey));
|
|
446
|
-
|
|
574
|
+
const collectionMemberKeys = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getAllKeys(), (storedKey) => isCollectionMemberKey(collectionKey, storedKey));
|
|
447
575
|
|
|
448
|
-
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
576
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
577
|
+
collectionMemberKeys,
|
|
578
|
+
(prev, curr) => {
|
|
449
579
|
const cachedValue = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].getValue(curr);
|
|
450
580
|
if (!cachedValue) {
|
|
451
581
|
return prev;
|
|
@@ -454,7 +584,9 @@ function getCachedCollection(collectionKey) {
|
|
|
454
584
|
// eslint-disable-next-line no-param-reassign
|
|
455
585
|
prev[curr] = cachedValue;
|
|
456
586
|
return prev;
|
|
457
|
-
},
|
|
587
|
+
},
|
|
588
|
+
{});
|
|
589
|
+
|
|
458
590
|
}
|
|
459
591
|
|
|
460
592
|
/**
|
|
@@ -823,9 +955,7 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
823
955
|
if (mapping.withOnyxInstance && !isCollectionKey(mapping.key)) {
|
|
824
956
|
// All React components subscribing to a key flagged as a safe eviction key must implement the canEvict property.
|
|
825
957
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(mapping.canEvict)) {
|
|
826
|
-
throw new Error(
|
|
827
|
-
`Cannot subscribe to safe eviction key '${mapping.key}' without providing a canEvict value.`);
|
|
828
|
-
|
|
958
|
+
throw new Error(`Cannot subscribe to safe eviction key '${mapping.key}' without providing a canEvict value.`);
|
|
829
959
|
}
|
|
830
960
|
|
|
831
961
|
addLastAccessedKey(mapping.key);
|
|
@@ -841,11 +971,17 @@ function addKeyToRecentlyAccessedIfNeeded(mapping) {
|
|
|
841
971
|
*/
|
|
842
972
|
function getCollectionDataAndSendAsObject(matchingKeys, mapping) {
|
|
843
973
|
Promise.all(underscore__WEBPACK_IMPORTED_MODULE_1___default().map(matchingKeys, (key) => get(key))).
|
|
844
|
-
then((values) =>
|
|
974
|
+
then((values) =>
|
|
975
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
976
|
+
values,
|
|
977
|
+
(finalObject, value, i) => {
|
|
845
978
|
// eslint-disable-next-line no-param-reassign
|
|
846
979
|
finalObject[matchingKeys[i]] = value;
|
|
847
980
|
return finalObject;
|
|
848
|
-
},
|
|
981
|
+
},
|
|
982
|
+
{})).
|
|
983
|
+
|
|
984
|
+
|
|
849
985
|
then((val) => sendDataToConnection(mapping, val, undefined, true));
|
|
850
986
|
}
|
|
851
987
|
|
|
@@ -893,11 +1029,7 @@ function connect(mapping) {
|
|
|
893
1029
|
// Performance improvement
|
|
894
1030
|
// If the mapping is connected to an onyx key that is not a collection
|
|
895
1031
|
// we can skip the call to getAllKeys() and return an array with a single item
|
|
896
|
-
if (Boolean(mapping.key) &&
|
|
897
|
-
typeof mapping.key === 'string' &&
|
|
898
|
-
!mapping.key.endsWith('_') &&
|
|
899
|
-
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].storageKeys.has(mapping.key))
|
|
900
|
-
{
|
|
1032
|
+
if (Boolean(mapping.key) && typeof mapping.key === 'string' && !mapping.key.endsWith('_') && _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].storageKeys.has(mapping.key)) {
|
|
901
1033
|
return [mapping.key];
|
|
902
1034
|
}
|
|
903
1035
|
return getAllKeys();
|
|
@@ -1061,7 +1193,7 @@ function reportStorageQuota() {
|
|
|
1061
1193
|
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];}
|
|
1062
1194
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Failed to save to storage. Error: ${error}. onyxMethod: ${onyxMethod.name}`);
|
|
1063
1195
|
|
|
1064
|
-
if (error && _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(error.message,
|
|
1196
|
+
if (error && _Str__WEBPACK_IMPORTED_MODULE_7__.startsWith(error.message, "Failed to execute 'put' on 'IDBObjectStore'")) {
|
|
1065
1197
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert('Attempted to set invalid data set in Onyx. Please ensure all data is serializable.');
|
|
1066
1198
|
throw error;
|
|
1067
1199
|
}
|
|
@@ -1079,8 +1211,7 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
|
|
|
1079
1211
|
// Remove the least recently viewed key that is not currently being accessed and retry.
|
|
1080
1212
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
|
|
1081
1213
|
reportStorageQuota();
|
|
1082
|
-
return remove(keyForRemoval).
|
|
1083
|
-
then(() => onyxMethod(...args));
|
|
1214
|
+
return remove(keyForRemoval).then(() => onyxMethod(...args));
|
|
1084
1215
|
}
|
|
1085
1216
|
|
|
1086
1217
|
/**
|
|
@@ -1143,6 +1274,15 @@ function removeNullValues(key, value) {
|
|
|
1143
1274
|
* @returns {Promise}
|
|
1144
1275
|
*/
|
|
1145
1276
|
function set(key, value) {
|
|
1277
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1278
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.sendMessage({ type: METHOD.SET, key, value });
|
|
1279
|
+
return Promise.resolve();
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
if (isClearing) {
|
|
1283
|
+
return Promise.resolve();
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1146
1286
|
const valueWithoutNull = removeNullValues(key, value);
|
|
1147
1287
|
|
|
1148
1288
|
if (valueWithoutNull === null) {
|
|
@@ -1189,6 +1329,15 @@ function prepareKeyValuePairsForStorage(data) {
|
|
|
1189
1329
|
* @returns {Promise}
|
|
1190
1330
|
*/
|
|
1191
1331
|
function multiSet(data) {
|
|
1332
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1333
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.sendMessage({ type: METHOD.MULTI_SET, data });
|
|
1334
|
+
return Promise.resolve();
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
if (isClearing) {
|
|
1338
|
+
return Promise.resolve();
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1192
1341
|
const keyValuePairs = prepareKeyValuePairsForStorage(data);
|
|
1193
1342
|
|
|
1194
1343
|
const updatePromises = underscore__WEBPACK_IMPORTED_MODULE_1___default().map(data, (val, key) => {
|
|
@@ -1197,14 +1346,17 @@ function multiSet(data) {
|
|
|
1197
1346
|
return scheduleSubscriberUpdate(key, val);
|
|
1198
1347
|
});
|
|
1199
1348
|
|
|
1200
|
-
const keyValuePairsWithoutNull = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(
|
|
1349
|
+
const keyValuePairsWithoutNull = underscore__WEBPACK_IMPORTED_MODULE_1___default().filter(
|
|
1350
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().map(keyValuePairs, (_ref2) => {let [key, value] = _ref2;
|
|
1201
1351
|
const valueWithoutNull = removeNullValues(key, value);
|
|
1202
1352
|
|
|
1203
1353
|
if (valueWithoutNull === null) {
|
|
1204
1354
|
return;
|
|
1205
1355
|
}
|
|
1206
1356
|
return [key, valueWithoutNull];
|
|
1207
|
-
}),
|
|
1357
|
+
}),
|
|
1358
|
+
Boolean);
|
|
1359
|
+
|
|
1208
1360
|
|
|
1209
1361
|
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(keyValuePairsWithoutNull).
|
|
1210
1362
|
catch((error) => evictStorageAndRetry(error, multiSet, data)).
|
|
@@ -1229,8 +1381,7 @@ function applyMerge(existingValue, changes, shouldRemoveNullObjectValues) {
|
|
|
1229
1381
|
|
|
1230
1382
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().some(changes, (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject))) {
|
|
1231
1383
|
// Object values are then merged one after the other
|
|
1232
|
-
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(modifiedData, change, shouldRemoveNullObjectValues),
|
|
1233
|
-
existingValue || {});
|
|
1384
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(modifiedData, change, shouldRemoveNullObjectValues), existingValue || {});
|
|
1234
1385
|
}
|
|
1235
1386
|
|
|
1236
1387
|
// If we have anything else we can't merge it so we'll
|
|
@@ -1259,6 +1410,15 @@ function applyMerge(existingValue, changes, shouldRemoveNullObjectValues) {
|
|
|
1259
1410
|
* @returns {Promise}
|
|
1260
1411
|
*/
|
|
1261
1412
|
function merge(key, changes) {
|
|
1413
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1414
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.sendMessage({ type: METHOD.MERGE, key, changes });
|
|
1415
|
+
return Promise.resolve();
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
if (isClearing) {
|
|
1419
|
+
return Promise.resolve();
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1262
1422
|
// Top-level undefined values are ignored
|
|
1263
1423
|
// Therefore we need to prevent adding them to the merge queue
|
|
1264
1424
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isUndefined(changes)) {
|
|
@@ -1273,8 +1433,7 @@ function merge(key, changes) {
|
|
|
1273
1433
|
}
|
|
1274
1434
|
mergeQueue[key] = [changes];
|
|
1275
1435
|
|
|
1276
|
-
mergeQueuePromise[key] = get(key).
|
|
1277
|
-
then((existingValue) => {
|
|
1436
|
+
mergeQueuePromise[key] = get(key).then((existingValue) => {
|
|
1278
1437
|
try {
|
|
1279
1438
|
// 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)
|
|
1280
1439
|
// We don't want to remove null values from the "batchedChanges", because SQLite uses them to remove keys from storage natively.
|
|
@@ -1313,12 +1472,11 @@ function merge(key, changes) {
|
|
|
1313
1472
|
const updatePromise = broadcastUpdate(key, modifiedData, hasChanged, 'merge');
|
|
1314
1473
|
|
|
1315
1474
|
// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
|
|
1316
|
-
if (!hasChanged) {
|
|
1475
|
+
if (!hasChanged || isClearing) {
|
|
1317
1476
|
return updatePromise;
|
|
1318
1477
|
}
|
|
1319
1478
|
|
|
1320
|
-
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].mergeItem(key, batchedChanges, modifiedData).
|
|
1321
|
-
then(() => updatePromise);
|
|
1479
|
+
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].mergeItem(key, batchedChanges, modifiedData).then(() => updatePromise);
|
|
1322
1480
|
} catch (error) {
|
|
1323
1481
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`An error occurred while applying merge for key: ${key}, Error: ${error}`);
|
|
1324
1482
|
return Promise.resolve();
|
|
@@ -1334,8 +1492,7 @@ function merge(key, changes) {
|
|
|
1334
1492
|
* @returns {Promise}
|
|
1335
1493
|
*/
|
|
1336
1494
|
function initializeWithDefaultKeyStates() {
|
|
1337
|
-
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).
|
|
1338
|
-
then((pairs) => {
|
|
1495
|
+
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiGet(underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(defaultKeyStates)).then((pairs) => {
|
|
1339
1496
|
const asObject = underscore__WEBPACK_IMPORTED_MODULE_1___default().object(pairs);
|
|
1340
1497
|
|
|
1341
1498
|
const merged = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(asObject, defaultKeyStates);
|
|
@@ -1367,8 +1524,18 @@ function initializeWithDefaultKeyStates() {
|
|
|
1367
1524
|
* @returns {Promise<void>}
|
|
1368
1525
|
*/
|
|
1369
1526
|
function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
1370
|
-
|
|
1371
|
-
|
|
1527
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1528
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.sendMessage({ type: METHOD.CLEAR, keysToPreserve });
|
|
1529
|
+
return Promise.resolve();
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
if (isClearing) {
|
|
1533
|
+
return Promise.resolve();
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
isClearing = true;
|
|
1537
|
+
|
|
1538
|
+
return getAllKeys().then((keys) => {
|
|
1372
1539
|
const keysToBeClearedFromStorage = [];
|
|
1373
1540
|
const keyValuesToResetAsCollection = {};
|
|
1374
1541
|
const keyValuesToResetIndividually = {};
|
|
@@ -1425,7 +1592,13 @@ function clear() {let keysToPreserve = arguments.length > 0 && arguments[0] !==
|
|
|
1425
1592
|
|
|
1426
1593
|
// Remove only the items that we want cleared from storage, and reset others to default
|
|
1427
1594
|
underscore__WEBPACK_IMPORTED_MODULE_1___default().each(keysToBeClearedFromStorage, (key) => _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].drop(key));
|
|
1428
|
-
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].removeItems(keysToBeClearedFromStorage).
|
|
1595
|
+
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].removeItems(keysToBeClearedFromStorage).
|
|
1596
|
+
then(() => _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(defaultKeyValuePairs)).
|
|
1597
|
+
then(() => {
|
|
1598
|
+
isClearing = false;
|
|
1599
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.sendMessage({ type: METHOD.CLEAR, keysToPreserve });
|
|
1600
|
+
return Promise.all(updatePromises);
|
|
1601
|
+
});
|
|
1429
1602
|
});
|
|
1430
1603
|
}
|
|
1431
1604
|
|
|
@@ -1469,8 +1642,7 @@ function mergeCollection(collectionKey, collection) {
|
|
|
1469
1642
|
return Promise.resolve();
|
|
1470
1643
|
}
|
|
1471
1644
|
|
|
1472
|
-
return getAllKeys().
|
|
1473
|
-
then((persistedKeys) => {
|
|
1645
|
+
return getAllKeys().then((persistedKeys) => {
|
|
1474
1646
|
// Split to keys that exist in storage and keys that don't
|
|
1475
1647
|
const [existingKeys, newKeys] = underscore__WEBPACK_IMPORTED_MODULE_1___default().chain(collection).
|
|
1476
1648
|
pick((value, key) => {
|
|
@@ -1575,6 +1747,48 @@ function setMemoryOnlyKeys(keyList) {
|
|
|
1575
1747
|
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].setRecentKeysLimit(Infinity);
|
|
1576
1748
|
}
|
|
1577
1749
|
|
|
1750
|
+
/**
|
|
1751
|
+
* Sets the callback to be called when the clear finishes executing.
|
|
1752
|
+
* @param {Function} callback
|
|
1753
|
+
*/
|
|
1754
|
+
function onClear(callback) {
|
|
1755
|
+
onClearCallback = callback;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
/**
|
|
1759
|
+
* Subscribes to the Broadcast channel and executes actions based on the
|
|
1760
|
+
* types of events.
|
|
1761
|
+
*/
|
|
1762
|
+
function subscribeToEvents() {
|
|
1763
|
+
_broadcast__WEBPACK_IMPORTED_MODULE_11__.subscribe((_ref5) => {let { data } = _ref5;
|
|
1764
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
switch (data.type) {
|
|
1768
|
+
case METHOD.CLEAR:
|
|
1769
|
+
clear(data.keysToPreserve);
|
|
1770
|
+
break;
|
|
1771
|
+
case METHOD.SET:
|
|
1772
|
+
set(data.key, data.value);
|
|
1773
|
+
break;
|
|
1774
|
+
case METHOD.MULTI_SET:
|
|
1775
|
+
multiSet(data.key, data.value);
|
|
1776
|
+
break;
|
|
1777
|
+
case METHOD.MERGE:
|
|
1778
|
+
merge(data.key, data.changes);
|
|
1779
|
+
break;
|
|
1780
|
+
case ON_CLEAR:
|
|
1781
|
+
if (!onClearCallback) {
|
|
1782
|
+
break;
|
|
1783
|
+
}
|
|
1784
|
+
onClearCallback();
|
|
1785
|
+
break;
|
|
1786
|
+
default:
|
|
1787
|
+
break;}
|
|
1788
|
+
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1578
1792
|
/**
|
|
1579
1793
|
* Initialize the store with actions and listening for storage events
|
|
1580
1794
|
*
|
|
@@ -1609,6 +1823,15 @@ function init()
|
|
|
1609
1823
|
|
|
1610
1824
|
|
|
1611
1825
|
{let { keys = {}, initialKeyStates = {}, safeEvictionKeys = [], maxCachedKeysCount = 1000, captureMetrics = false, shouldSyncMultipleInstances = Boolean(__webpack_require__.g.localStorage), debugSetState = false } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1826
|
+
_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.init();
|
|
1827
|
+
|
|
1828
|
+
_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isReady().then(() => {
|
|
1829
|
+
if (!_ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader()) {
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
subscribeToEvents();
|
|
1833
|
+
});
|
|
1834
|
+
|
|
1612
1835
|
if (captureMetrics) {
|
|
1613
1836
|
// The code here is only bundled and applied when the captureMetrics is set
|
|
1614
1837
|
// eslint-disable-next-line no-use-before-define
|
|
@@ -1626,10 +1849,14 @@ function init()
|
|
|
1626
1849
|
// We need the value of the collection keys later for checking if a
|
|
1627
1850
|
// key is a collection. We store it in a map for faster lookup.
|
|
1628
1851
|
const collectionValues = underscore__WEBPACK_IMPORTED_MODULE_1___default().values(keys.COLLECTION);
|
|
1629
|
-
onyxCollectionKeyMap = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
1852
|
+
onyxCollectionKeyMap = underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(
|
|
1853
|
+
collectionValues,
|
|
1854
|
+
(acc, val) => {
|
|
1630
1855
|
acc.set(val, true);
|
|
1631
1856
|
return acc;
|
|
1632
|
-
},
|
|
1857
|
+
},
|
|
1858
|
+
new Map());
|
|
1859
|
+
|
|
1633
1860
|
|
|
1634
1861
|
// Set our default key states to use when initializing and clearing Onyx data
|
|
1635
1862
|
defaultKeyStates = initialKeyStates;
|
|
@@ -1638,11 +1865,7 @@ function init()
|
|
|
1638
1865
|
evictionAllowList = safeEvictionKeys;
|
|
1639
1866
|
|
|
1640
1867
|
// Initialize all of our keys with data provided then give green light to any pending connections
|
|
1641
|
-
Promise.all([
|
|
1642
|
-
addAllSafeEvictionKeysToRecentlyAccessedList(),
|
|
1643
|
-
initializeWithDefaultKeyStates()]).
|
|
1644
|
-
|
|
1645
|
-
then(deferredInitTask.resolve);
|
|
1868
|
+
Promise.all([addAllSafeEvictionKeysToRecentlyAccessedList(), initializeWithDefaultKeyStates()]).then(deferredInitTask.resolve);
|
|
1646
1869
|
|
|
1647
1870
|
if (shouldSyncMultipleInstances && underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(_storage__WEBPACK_IMPORTED_MODULE_5__["default"].keepInstancesSync)) {
|
|
1648
1871
|
_storage__WEBPACK_IMPORTED_MODULE_5__["default"].keepInstancesSync((key, value) => {
|
|
@@ -1670,7 +1893,11 @@ const Onyx = {
|
|
|
1670
1893
|
METHOD,
|
|
1671
1894
|
setMemoryOnlyKeys,
|
|
1672
1895
|
tryGetCachedValue,
|
|
1673
|
-
hasPendingMergeForKey
|
|
1896
|
+
hasPendingMergeForKey,
|
|
1897
|
+
onClear,
|
|
1898
|
+
isClientManagerReady: _ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isReady,
|
|
1899
|
+
isClientTheLeader: _ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.isClientTheLeader,
|
|
1900
|
+
subscribeToClientChange: _ActiveClientManager__WEBPACK_IMPORTED_MODULE_10__.subscribeToClientChange
|
|
1674
1901
|
};
|
|
1675
1902
|
|
|
1676
1903
|
/**
|
|
@@ -1776,8 +2003,17 @@ class OnyxCache {
|
|
|
1776
2003
|
// bind all public methods to prevent problems with `this`
|
|
1777
2004
|
underscore__WEBPACK_IMPORTED_MODULE_0___default().bindAll(
|
|
1778
2005
|
this,
|
|
1779
|
-
'getAllKeys',
|
|
1780
|
-
'
|
|
2006
|
+
'getAllKeys',
|
|
2007
|
+
'getValue',
|
|
2008
|
+
'hasCacheForKey',
|
|
2009
|
+
'addKey',
|
|
2010
|
+
'set',
|
|
2011
|
+
'drop',
|
|
2012
|
+
'merge',
|
|
2013
|
+
'hasPendingTask',
|
|
2014
|
+
'getTaskPromise',
|
|
2015
|
+
'captureTask',
|
|
2016
|
+
'removeLeastRecentlyUsedKeys',
|
|
1781
2017
|
'setRecentKeysLimit');
|
|
1782
2018
|
|
|
1783
2019
|
}
|
|
@@ -1967,6 +2203,7 @@ const instance = new OnyxCache();
|
|
|
1967
2203
|
"use strict";
|
|
1968
2204
|
__webpack_require__.r(__webpack_exports__);
|
|
1969
2205
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2206
|
+
/* harmony export */ "guid": () => (/* binding */ guid),
|
|
1970
2207
|
/* harmony export */ "result": () => (/* binding */ result),
|
|
1971
2208
|
/* harmony export */ "startsWith": () => (/* binding */ startsWith)
|
|
1972
2209
|
/* harmony export */ });
|
|
@@ -1982,9 +2219,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1982
2219
|
* @return {Boolean} Returns true if the haystack starts with the needle.
|
|
1983
2220
|
*/
|
|
1984
2221
|
function startsWith(haystack, needle) {
|
|
1985
|
-
return underscore__WEBPACK_IMPORTED_MODULE_0___default().isString(haystack) &&
|
|
1986
|
-
underscore__WEBPACK_IMPORTED_MODULE_0___default().isString(needle) &&
|
|
1987
|
-
haystack.startsWith(needle);
|
|
2222
|
+
return underscore__WEBPACK_IMPORTED_MODULE_0___default().isString(haystack) && underscore__WEBPACK_IMPORTED_MODULE_0___default().isString(needle) && haystack.startsWith(needle);
|
|
1988
2223
|
}
|
|
1989
2224
|
|
|
1990
2225
|
/**
|
|
@@ -2000,6 +2235,21 @@ function result(parameter) {for (var _len = arguments.length, args = new Array(_
|
|
|
2000
2235
|
return underscore__WEBPACK_IMPORTED_MODULE_0___default().isFunction(parameter) ? parameter(...args) : parameter;
|
|
2001
2236
|
}
|
|
2002
2237
|
|
|
2238
|
+
/**
|
|
2239
|
+
* A simple GUID generator taken from https://stackoverflow.com/a/32760401/9114791
|
|
2240
|
+
*
|
|
2241
|
+
* @param {String} [prefix] an optional prefix to put in front of the guid
|
|
2242
|
+
* @returns {String}
|
|
2243
|
+
*/
|
|
2244
|
+
function guid() {let prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
2245
|
+
function s4() {
|
|
2246
|
+
return Math.floor((1 + Math.random()) * 0x10000).
|
|
2247
|
+
toString(16).
|
|
2248
|
+
substring(1);
|
|
2249
|
+
}
|
|
2250
|
+
return `${prefix}${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2003
2253
|
|
|
2004
2254
|
|
|
2005
2255
|
/***/ }),
|
|
@@ -2021,6 +2271,55 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2021
2271
|
|
|
2022
2272
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (react_dom__WEBPACK_IMPORTED_MODULE_0__.unstable_batchedUpdates);
|
|
2023
2273
|
|
|
2274
|
+
/***/ }),
|
|
2275
|
+
|
|
2276
|
+
/***/ "./lib/broadcast/index.web.js":
|
|
2277
|
+
/*!************************************!*\
|
|
2278
|
+
!*** ./lib/broadcast/index.web.js ***!
|
|
2279
|
+
\************************************/
|
|
2280
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
2281
|
+
|
|
2282
|
+
"use strict";
|
|
2283
|
+
__webpack_require__.r(__webpack_exports__);
|
|
2284
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
2285
|
+
/* harmony export */ "disconnect": () => (/* binding */ disconnect),
|
|
2286
|
+
/* harmony export */ "sendMessage": () => (/* binding */ sendMessage),
|
|
2287
|
+
/* harmony export */ "subscribe": () => (/* binding */ subscribe)
|
|
2288
|
+
/* harmony export */ });
|
|
2289
|
+
const BROADCAST_ONYX = 'BROADCAST_ONYX';
|
|
2290
|
+
|
|
2291
|
+
const subscriptions = [];
|
|
2292
|
+
const channel = new BroadcastChannel(BROADCAST_ONYX);
|
|
2293
|
+
|
|
2294
|
+
/**
|
|
2295
|
+
* Sends a message to the broadcast channel.
|
|
2296
|
+
* @param {String} message
|
|
2297
|
+
*/
|
|
2298
|
+
function sendMessage(message) {
|
|
2299
|
+
channel.postMessage(message);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
/**
|
|
2303
|
+
* Subscribes to the broadcast channel. Every time a new message
|
|
2304
|
+
* is received, the callback is called.
|
|
2305
|
+
* @param {Function} callback
|
|
2306
|
+
*/
|
|
2307
|
+
function subscribe(callback) {
|
|
2308
|
+
subscriptions.push(callback);
|
|
2309
|
+
channel.onmessage = (message) => {
|
|
2310
|
+
subscriptions.forEach((c) => c(message));
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
/**
|
|
2315
|
+
* Disconnects from the broadcast channel.
|
|
2316
|
+
*/
|
|
2317
|
+
function disconnect() {
|
|
2318
|
+
channel.close();
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
|
|
2024
2323
|
/***/ }),
|
|
2025
2324
|
|
|
2026
2325
|
/***/ "./lib/createDeferredTask.js":
|
|
@@ -2097,9 +2396,7 @@ function diffObject(object, base) {
|
|
|
2097
2396
|
}
|
|
2098
2397
|
|
|
2099
2398
|
// eslint-disable-next-line no-param-reassign
|
|
2100
|
-
result[key] = underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) && underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(comparisonObject[key]) ?
|
|
2101
|
-
changes(value, comparisonObject[key]) :
|
|
2102
|
-
value;
|
|
2399
|
+
result[key] = underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) && underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(comparisonObject[key]) ? changes(value, comparisonObject[key]) : value;
|
|
2103
2400
|
});
|
|
2104
2401
|
}
|
|
2105
2402
|
return changes(object, base);
|
|
@@ -2153,7 +2450,9 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2153
2450
|
/* harmony export */ });
|
|
2154
2451
|
// For web-only implementations of Onyx, this module will just be a no-op
|
|
2155
2452
|
|
|
2156
|
-
function decorateWithMetrics(func) {
|
|
2453
|
+
function decorateWithMetrics(func) {
|
|
2454
|
+
return func;
|
|
2455
|
+
}
|
|
2157
2456
|
function getMetrics() {}
|
|
2158
2457
|
function printMetrics() {}
|
|
2159
2458
|
function resetMetrics() {}
|
|
@@ -2209,17 +2508,13 @@ const webStorage = {
|
|
|
2209
2508
|
*/
|
|
2210
2509
|
keepInstancesSync(onStorageKeyChanged) {
|
|
2211
2510
|
// Override set, remove and clear to raise storage events that we intercept in other tabs
|
|
2212
|
-
this.setItem = (key, value) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].setItem(key, value).
|
|
2213
|
-
then(() => raiseStorageSyncEvent(key));
|
|
2511
|
+
this.setItem = (key, value) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].setItem(key, value).then(() => raiseStorageSyncEvent(key));
|
|
2214
2512
|
|
|
2215
|
-
this.removeItem = (key) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].removeItem(key).
|
|
2216
|
-
then(() => raiseStorageSyncEvent(key));
|
|
2513
|
+
this.removeItem = (key) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].removeItem(key).then(() => raiseStorageSyncEvent(key));
|
|
2217
2514
|
|
|
2218
|
-
this.removeItems = (keys) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].removeItems(keys).
|
|
2219
|
-
then(() => raiseStorageSyncManyKeysEvent(keys));
|
|
2515
|
+
this.removeItems = (keys) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].removeItems(keys).then(() => raiseStorageSyncManyKeysEvent(keys));
|
|
2220
2516
|
|
|
2221
|
-
this.mergeItem = (key, batchedChanges, modifiedData) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].mergeItem(key, batchedChanges, modifiedData).
|
|
2222
|
-
then(() => raiseStorageSyncEvent(key));
|
|
2517
|
+
this.mergeItem = (key, batchedChanges, modifiedData) => _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].mergeItem(key, batchedChanges, modifiedData).then(() => raiseStorageSyncEvent(key));
|
|
2223
2518
|
|
|
2224
2519
|
// If we just call Storage.clear other tabs will have no idea which keys were available previously
|
|
2225
2520
|
// so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
|
|
@@ -2227,7 +2522,7 @@ const webStorage = {
|
|
|
2227
2522
|
this.clear = () => {
|
|
2228
2523
|
let allKeys;
|
|
2229
2524
|
|
|
2230
|
-
//
|
|
2525
|
+
// The keys must be retrieved before storage is cleared or else the list of keys would be empty
|
|
2231
2526
|
return _providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].getAllKeys().
|
|
2232
2527
|
then((keys) => {
|
|
2233
2528
|
allKeys = keys;
|
|
@@ -2248,8 +2543,7 @@ const webStorage = {
|
|
|
2248
2543
|
}
|
|
2249
2544
|
|
|
2250
2545
|
const onyxKey = event.newValue;
|
|
2251
|
-
_providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].getItem(onyxKey).
|
|
2252
|
-
then((value) => onStorageKeyChanged(onyxKey, value));
|
|
2546
|
+
_providers_IDBKeyVal__WEBPACK_IMPORTED_MODULE_1__["default"].getItem(onyxKey).then((value) => onStorageKeyChanged(onyxKey, value));
|
|
2253
2547
|
});
|
|
2254
2548
|
}
|
|
2255
2549
|
};
|
|
@@ -2321,8 +2615,7 @@ const provider = {
|
|
|
2321
2615
|
* @param {String[]} keysParam
|
|
2322
2616
|
* @return {Promise<Array<[key, value]>>}
|
|
2323
2617
|
*/
|
|
2324
|
-
multiGet: (keysParam) => (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.getMany)(keysParam, getCustomStore()).
|
|
2325
|
-
then((values) => underscore__WEBPACK_IMPORTED_MODULE_1___default().map(values, (value, index) => [keysParam[index], value])),
|
|
2618
|
+
multiGet: (keysParam) => (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.getMany)(keysParam, getCustomStore()).then((values) => underscore__WEBPACK_IMPORTED_MODULE_1___default().map(values, (value, index) => [keysParam[index], value])),
|
|
2326
2619
|
|
|
2327
2620
|
/**
|
|
2328
2621
|
* Multiple merging of existing and new values in a batch
|
|
@@ -2330,7 +2623,8 @@ const provider = {
|
|
|
2330
2623
|
* This function also removes all nested null values from an object.
|
|
2331
2624
|
* @return {Promise<void>}
|
|
2332
2625
|
*/
|
|
2333
|
-
multiMerge: (pairs) =>
|
|
2626
|
+
multiMerge: (pairs) =>
|
|
2627
|
+
getCustomStore()('readwrite', (store) => {
|
|
2334
2628
|
// Note: we are using the manual store transaction here, to fit the read and update
|
|
2335
2629
|
// of the items in one transaction to achieve best performance.
|
|
2336
2630
|
|
|
@@ -2385,8 +2679,8 @@ const provider = {
|
|
|
2385
2679
|
* @param {String} key
|
|
2386
2680
|
* @return {Promise<*>}
|
|
2387
2681
|
*/
|
|
2388
|
-
getItem: (key) =>
|
|
2389
|
-
|
|
2682
|
+
getItem: (key) =>
|
|
2683
|
+
(0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.get)(key, getCustomStore())
|
|
2390
2684
|
// idb-keyval returns undefined for missing items, but this needs to return null so that idb-keyval does the same thing as SQLiteStorage.
|
|
2391
2685
|
.then((val) => val === undefined ? null : val),
|
|
2392
2686
|
|
|
@@ -2414,7 +2708,8 @@ const provider = {
|
|
|
2414
2708
|
throw new Error('StorageManager browser API unavailable');
|
|
2415
2709
|
}
|
|
2416
2710
|
|
|
2417
|
-
return window.navigator.storage.
|
|
2711
|
+
return window.navigator.storage.
|
|
2712
|
+
estimate().
|
|
2418
2713
|
then((value) => ({
|
|
2419
2714
|
bytesUsed: value.usage,
|
|
2420
2715
|
bytesRemaining: value.quota - value.usage
|
|
@@ -2445,12 +2740,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2445
2740
|
|
|
2446
2741
|
|
|
2447
2742
|
function areObjectsEmpty(a, b) {
|
|
2448
|
-
return (
|
|
2449
|
-
typeof a === 'object' &&
|
|
2450
|
-
typeof b === 'object' &&
|
|
2451
|
-
underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(a) &&
|
|
2452
|
-
underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(b));
|
|
2453
|
-
|
|
2743
|
+
return typeof a === 'object' && typeof b === 'object' && underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(a) && underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(b);
|
|
2454
2744
|
}
|
|
2455
2745
|
|
|
2456
2746
|
// Mostly copied from https://medium.com/@lubaka.a/how-to-remove-lodash-performance-improvement-b306669ad0e1
|
|
@@ -2458,22 +2748,24 @@ function areObjectsEmpty(a, b) {
|
|
|
2458
2748
|
/**
|
|
2459
2749
|
* @param {mixed} val
|
|
2460
2750
|
* @returns {boolean}
|
|
2461
|
-
*/
|
|
2751
|
+
*/
|
|
2462
2752
|
function isMergeableObject(val) {
|
|
2463
2753
|
const nonNullObject = val != null ? typeof val === 'object' : false;
|
|
2464
|
-
return
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2754
|
+
return (
|
|
2755
|
+
nonNullObject &&
|
|
2756
|
+
Object.prototype.toString.call(val) !== '[object RegExp]' &&
|
|
2757
|
+
Object.prototype.toString.call(val) !== '[object Date]' &&
|
|
2758
|
+
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
2759
|
+
!Array.isArray(val));
|
|
2760
|
+
|
|
2469
2761
|
}
|
|
2470
2762
|
|
|
2471
2763
|
/**
|
|
2472
|
-
* @param {Object} target
|
|
2473
|
-
* @param {Object} source
|
|
2474
|
-
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2475
|
-
* @returns {Object}
|
|
2476
|
-
*/
|
|
2764
|
+
* @param {Object} target
|
|
2765
|
+
* @param {Object} source
|
|
2766
|
+
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2767
|
+
* @returns {Object}
|
|
2768
|
+
*/
|
|
2477
2769
|
function mergeObject(target, source) {let shouldRemoveNullObjectValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
2478
2770
|
const destination = {};
|
|
2479
2771
|
if (isMergeableObject(target)) {
|
|
@@ -2529,11 +2821,11 @@ function mergeObject(target, source) {let shouldRemoveNullObjectValues = argumen
|
|
|
2529
2821
|
* On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
|
|
2530
2822
|
* To be consistent with the behaviour for merge, we'll also want to remove null values for "set" operations.
|
|
2531
2823
|
*
|
|
2532
|
-
* @param {Object|Array} target
|
|
2533
|
-
* @param {Object|Array} source
|
|
2534
|
-
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2535
|
-
* @returns {Object|Array}
|
|
2536
|
-
*/
|
|
2824
|
+
* @param {Object|Array} target
|
|
2825
|
+
* @param {Object|Array} source
|
|
2826
|
+
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2827
|
+
* @returns {Object|Array}
|
|
2828
|
+
*/
|
|
2537
2829
|
function fastMerge(target, source) {let shouldRemoveNullObjectValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
2538
2830
|
// We have to ignore arrays and nullish values here,
|
|
2539
2831
|
// otherwise "mergeObject" will throw an error,
|
|
@@ -2652,11 +2944,7 @@ const getOnyxDataFromState = (state, onyxToStateMapping) => underscore__WEBPACK_
|
|
|
2652
2944
|
* In reality, Onyx.merge() will only update the subscriber after all merges have been batched and the previous value is retrieved via a get() (returns a promise).
|
|
2653
2945
|
* So, we won't use the cache optimization here as it will lead us to arbitrarily defer various actions in the application code.
|
|
2654
2946
|
*/
|
|
2655
|
-
if (
|
|
2656
|
-
value !== undefined &&
|
|
2657
|
-
!_Onyx__WEBPACK_IMPORTED_MODULE_4__["default"].hasPendingMergeForKey(key) ||
|
|
2658
|
-
mapping.allowStaleData)
|
|
2659
|
-
{
|
|
2947
|
+
if (value !== undefined && !_Onyx__WEBPACK_IMPORTED_MODULE_4__["default"].hasPendingMergeForKey(key) || mapping.allowStaleData) {
|
|
2660
2948
|
// eslint-disable-next-line no-param-reassign
|
|
2661
2949
|
resultObj[propertyName] = value;
|
|
2662
2950
|
}
|
|
@@ -2710,9 +2998,7 @@ const getOnyxDataFromState = (state, onyxToStateMapping) => underscore__WEBPACK_
|
|
|
2710
2998
|
// (eg. if a user switches chats really quickly). In this case, it's much more stable to always look at the changes to prevProp and prevState to derive the key.
|
|
2711
2999
|
// The second case cannot be used all the time because the onyx data doesn't change the first time that `componentDidUpdate()` runs after loading. In this case,
|
|
2712
3000
|
// the `mapping.previousKey` must be used for the comparison or else this logic never detects that onyx data could have changed during the loading process.
|
|
2713
|
-
const previousKey = isFirstTimeUpdatingAfterLoading ?
|
|
2714
|
-
mapping.previousKey :
|
|
2715
|
-
_Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, { ...prevProps, ...prevOnyxDataFromState });
|
|
3001
|
+
const previousKey = isFirstTimeUpdatingAfterLoading ? mapping.previousKey : _Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, { ...prevProps, ...prevOnyxDataFromState });
|
|
2716
3002
|
const newKey = _Str__WEBPACK_IMPORTED_MODULE_3__.result(mapping.key, { ...this.props, ...onyxDataFromState });
|
|
2717
3003
|
if (previousKey !== newKey) {
|
|
2718
3004
|
_Onyx__WEBPACK_IMPORTED_MODULE_4__["default"].disconnect(this.activeConnectionIDs[previousKey], previousKey);
|
|
@@ -2790,7 +3076,9 @@ const getOnyxDataFromState = (state, onyxToStateMapping) => underscore__WEBPACK_
|
|
|
2790
3076
|
|
|
2791
3077
|
// Full of hacky workarounds to prevent the race condition described above.
|
|
2792
3078
|
this.setState((prevState) => {
|
|
2793
|
-
const finalState = underscore__WEBPACK_IMPORTED_MODULE_2___default().reduce(
|
|
3079
|
+
const finalState = underscore__WEBPACK_IMPORTED_MODULE_2___default().reduce(
|
|
3080
|
+
stateUpdate,
|
|
3081
|
+
(result, value, key) => {
|
|
2794
3082
|
if (key === 'loading') {
|
|
2795
3083
|
return result;
|
|
2796
3084
|
}
|
|
@@ -2812,7 +3100,9 @@ const getOnyxDataFromState = (state, onyxToStateMapping) => underscore__WEBPACK_
|
|
|
2812
3100
|
result[key] = value;
|
|
2813
3101
|
}
|
|
2814
3102
|
return result;
|
|
2815
|
-
},
|
|
3103
|
+
},
|
|
3104
|
+
{});
|
|
3105
|
+
|
|
2816
3106
|
|
|
2817
3107
|
finalState.loading = false;
|
|
2818
3108
|
return finalState;
|
|
@@ -2928,8 +3218,13 @@ const getOnyxDataFromState = (state, onyxToStateMapping) => underscore__WEBPACK_
|
|
|
2928
3218
|
withOnyx.displayName = `withOnyx(${displayName})`;
|
|
2929
3219
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1___default().forwardRef((props, ref) => {
|
|
2930
3220
|
const Component = withOnyx;
|
|
2931
|
-
|
|
2932
|
-
|
|
3221
|
+
return /*#__PURE__*/(
|
|
3222
|
+
react__WEBPACK_IMPORTED_MODULE_1___default().createElement(Component
|
|
3223
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
3224
|
+
, _extends({}, props, {
|
|
3225
|
+
forwardedRef: ref })));
|
|
3226
|
+
|
|
3227
|
+
|
|
2933
3228
|
});
|
|
2934
3229
|
};
|
|
2935
3230
|
}
|