react-native-onyx 1.0.94 → 1.0.95
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 +52 -39
- 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.d.ts +5 -9
- package/lib/Onyx.js +18 -9
- package/lib/storage/providers/IDBKeyVal.js +1 -1
- package/lib/types.d.ts +38 -19
- package/lib/utils.js +32 -28
- package/package.json +1 -1
package/dist/web.development.js
CHANGED
|
@@ -1124,7 +1124,13 @@ function set(key, value) {
|
|
|
1124
1124
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logAlert(`Onyx.set() called after Onyx.merge() for key: ${key}. It is recommended to use set() or merge() not both.`);
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
-
|
|
1127
|
+
// We can remove all null values in an object by merging it with itself
|
|
1128
|
+
// utils.fastMerge recursively goes through the object and removes all null values
|
|
1129
|
+
// Passing two identical objects as source and target to fastMerge will not change it, but only remove the null values
|
|
1130
|
+
let valueWithNullRemoved = value;
|
|
1131
|
+
if (typeof value === 'object' && !underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(value)) {
|
|
1132
|
+
valueWithNullRemoved = _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(value, value);
|
|
1133
|
+
}
|
|
1128
1134
|
|
|
1129
1135
|
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, valueWithNullRemoved);
|
|
1130
1136
|
|
|
@@ -1181,9 +1187,10 @@ function multiSet(data) {
|
|
|
1181
1187
|
* @private
|
|
1182
1188
|
* @param {*} existingValue
|
|
1183
1189
|
* @param {Array<*>} changes Array of changes that should be applied to the existing value
|
|
1190
|
+
* @param {Boolean} shouldRemoveNullObjectValues
|
|
1184
1191
|
* @returns {*}
|
|
1185
1192
|
*/
|
|
1186
|
-
function applyMerge(existingValue, changes) {
|
|
1193
|
+
function applyMerge(existingValue, changes, shouldRemoveNullObjectValues) {
|
|
1187
1194
|
const lastChange = underscore__WEBPACK_IMPORTED_MODULE_1___default().last(changes);
|
|
1188
1195
|
|
|
1189
1196
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(lastChange)) {
|
|
@@ -1192,7 +1199,7 @@ function applyMerge(existingValue, changes) {
|
|
|
1192
1199
|
|
|
1193
1200
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().some(changes, (underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject))) {
|
|
1194
1201
|
// Object values are then merged one after the other
|
|
1195
|
-
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(modifiedData, change),
|
|
1202
|
+
return underscore__WEBPACK_IMPORTED_MODULE_1___default().reduce(changes, (modifiedData, change) => _utils__WEBPACK_IMPORTED_MODULE_9__["default"].fastMerge(modifiedData, change, shouldRemoveNullObjectValues),
|
|
1196
1203
|
existingValue || {});
|
|
1197
1204
|
}
|
|
1198
1205
|
|
|
@@ -1240,7 +1247,8 @@ function merge(key, changes) {
|
|
|
1240
1247
|
then((existingValue) => {
|
|
1241
1248
|
try {
|
|
1242
1249
|
// 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)
|
|
1243
|
-
|
|
1250
|
+
// We don't want to remove null values from the "batchedChanges", because SQLite uses them to remove keys from storage natively.
|
|
1251
|
+
let batchedChanges = applyMerge(undefined, mergeQueue[key], false);
|
|
1244
1252
|
|
|
1245
1253
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(batchedChanges)) {
|
|
1246
1254
|
return remove(key);
|
|
@@ -1255,15 +1263,16 @@ function merge(key, changes) {
|
|
|
1255
1263
|
delete mergeQueuePromise[key];
|
|
1256
1264
|
|
|
1257
1265
|
// After that we merge the batched changes with the existing value
|
|
1258
|
-
|
|
1259
|
-
|
|
1266
|
+
// We can remove null values from the "modifiedData", because "null" implicates that the user wants to remove a value from storage.
|
|
1267
|
+
// The "modifiedData" will be directly "set" in storage instead of being merged
|
|
1268
|
+
const modifiedData = shouldOverwriteExistingValue ? batchedChanges : applyMerge(existingValue, [batchedChanges], true);
|
|
1260
1269
|
|
|
1261
1270
|
// On native platforms we use SQLite which utilises JSON_PATCH to merge changes.
|
|
1262
1271
|
// JSON_PATCH generally removes top-level nullish values from the stored object.
|
|
1263
|
-
// When there is no existing value though, SQLite will just insert the changes as a new value and thus the
|
|
1264
|
-
// Therefore we need to remove
|
|
1272
|
+
// When there is no existing value though, SQLite will just insert the changes as a new value and thus the null values won't be removed.
|
|
1273
|
+
// Therefore we need to remove null values from the `batchedChanges` which are sent to the SQLite, if no existing value is present.
|
|
1265
1274
|
if (!existingValue) {
|
|
1266
|
-
batchedChanges =
|
|
1275
|
+
batchedChanges = applyMerge(undefined, mergeQueue[key], true);
|
|
1267
1276
|
}
|
|
1268
1277
|
|
|
1269
1278
|
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, modifiedData);
|
|
@@ -2291,7 +2300,7 @@ const provider = {
|
|
|
2291
2300
|
const upsertMany = underscore__WEBPACK_IMPORTED_MODULE_1___default().map(pairs, (_ref2, index) => {let [key, value] = _ref2;
|
|
2292
2301
|
const prev = values[index];
|
|
2293
2302
|
const newValue = underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(prev) ? _utils__WEBPACK_IMPORTED_MODULE_2__["default"].fastMerge(prev, value) : value;
|
|
2294
|
-
return (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.promisifyRequest)(store.put(
|
|
2303
|
+
return (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.promisifyRequest)(store.put(newValue, key));
|
|
2295
2304
|
});
|
|
2296
2305
|
return Promise.all(upsertMany);
|
|
2297
2306
|
});
|
|
@@ -2396,8 +2405,8 @@ function areObjectsEmpty(a, b) {
|
|
|
2396
2405
|
return (
|
|
2397
2406
|
typeof a === 'object' &&
|
|
2398
2407
|
typeof b === 'object' &&
|
|
2399
|
-
|
|
2400
|
-
|
|
2408
|
+
underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(a) &&
|
|
2409
|
+
underscore__WEBPACK_IMPORTED_MODULE_0___default().isEmpty(b));
|
|
2401
2410
|
|
|
2402
2411
|
}
|
|
2403
2412
|
|
|
@@ -2417,9 +2426,12 @@ function isMergeableObject(val) {
|
|
|
2417
2426
|
/**
|
|
2418
2427
|
* @param {Object} target
|
|
2419
2428
|
* @param {Object} source
|
|
2429
|
+
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2420
2430
|
* @returns {Object}
|
|
2421
2431
|
*/
|
|
2422
|
-
function mergeObject(target, source) {
|
|
2432
|
+
function mergeObject(target, source) {let shouldRemoveNullObjectValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
2433
|
+
const targetAndSourceIdentical = target === source;
|
|
2434
|
+
|
|
2423
2435
|
const destination = {};
|
|
2424
2436
|
if (isMergeableObject(target)) {
|
|
2425
2437
|
// lodash adds a small overhead so we don't use it here
|
|
@@ -2427,6 +2439,13 @@ function mergeObject(target, source) {
|
|
|
2427
2439
|
const targetKeys = Object.keys(target);
|
|
2428
2440
|
for (let i = 0; i < targetKeys.length; ++i) {
|
|
2429
2441
|
const key = targetKeys[i];
|
|
2442
|
+
|
|
2443
|
+
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
2444
|
+
if (shouldRemoveNullObjectValues && (target[key] === null || source[key] === null)) {
|
|
2445
|
+
// eslint-disable-next-line no-continue
|
|
2446
|
+
continue;
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2430
2449
|
destination[key] = target[key];
|
|
2431
2450
|
}
|
|
2432
2451
|
}
|
|
@@ -2436,15 +2455,22 @@ function mergeObject(target, source) {
|
|
|
2436
2455
|
const sourceKeys = Object.keys(source);
|
|
2437
2456
|
for (let i = 0; i < sourceKeys.length; ++i) {
|
|
2438
2457
|
const key = sourceKeys[i];
|
|
2439
|
-
|
|
2458
|
+
|
|
2459
|
+
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
2460
|
+
if (shouldRemoveNullObjectValues && source[key] === null) {
|
|
2440
2461
|
// eslint-disable-next-line no-continue
|
|
2441
2462
|
continue;
|
|
2442
2463
|
}
|
|
2464
|
+
|
|
2443
2465
|
if (!isMergeableObject(source[key]) || !target[key]) {
|
|
2466
|
+
if (targetAndSourceIdentical) {
|
|
2467
|
+
// eslint-disable-next-line no-continue
|
|
2468
|
+
continue;
|
|
2469
|
+
}
|
|
2444
2470
|
destination[key] = source[key];
|
|
2445
2471
|
} else {
|
|
2446
2472
|
// eslint-disable-next-line no-use-before-define
|
|
2447
|
-
destination[key] = fastMerge(target[key], source[key]);
|
|
2473
|
+
destination[key] = fastMerge(target[key], source[key], shouldRemoveNullObjectValues);
|
|
2448
2474
|
}
|
|
2449
2475
|
}
|
|
2450
2476
|
|
|
@@ -2452,41 +2478,28 @@ function mergeObject(target, source) {
|
|
|
2452
2478
|
}
|
|
2453
2479
|
|
|
2454
2480
|
/**
|
|
2481
|
+
* Merges two objects and removes null values if "shouldRemoveNullObjectValues" is set to true
|
|
2482
|
+
*
|
|
2483
|
+
* We generally want to remove null values from objects written to disk and cache, because it decreases the amount of data stored in memory and on disk.
|
|
2484
|
+
* On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
|
|
2485
|
+
* To be consistent with the behaviour for merge, we'll also want to remove null values for "set" operations.
|
|
2486
|
+
*
|
|
2455
2487
|
* @param {Object|Array} target
|
|
2456
2488
|
* @param {Object|Array} source
|
|
2489
|
+
* @param {Boolean} shouldRemoveNullObjectValues
|
|
2457
2490
|
* @returns {Object|Array}
|
|
2458
2491
|
*/
|
|
2459
|
-
function fastMerge(target, source) {
|
|
2492
|
+
function fastMerge(target, source) {let shouldRemoveNullObjectValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
2460
2493
|
// We have to ignore arrays and nullish values here,
|
|
2461
2494
|
// otherwise "mergeObject" will throw an error,
|
|
2462
2495
|
// because it expects an object as "source"
|
|
2463
|
-
if (
|
|
2496
|
+
if (underscore__WEBPACK_IMPORTED_MODULE_0___default().isArray(source) || source === null || source === undefined) {
|
|
2464
2497
|
return source;
|
|
2465
2498
|
}
|
|
2466
|
-
return mergeObject(target, source);
|
|
2467
|
-
}
|
|
2468
|
-
|
|
2469
|
-
/**
|
|
2470
|
-
* We generally want to remove top-level nullish values from objects written to disk and cache, because it decreases the amount of data stored in memory and on disk.
|
|
2471
|
-
* On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
|
|
2472
|
-
* To be consistent with the behaviour for merge, we'll also want to remove nullish values for "set" operations.
|
|
2473
|
-
* On web, IndexedDB will keep the top-level keys along with a null value and this uses up storage and memory.
|
|
2474
|
-
* This method will ensure that keys for null values are removed before an object is written to disk and cache so that all platforms are storing the data in the same efficient way.
|
|
2475
|
-
* @private
|
|
2476
|
-
* @param {*} value
|
|
2477
|
-
* @returns {*}
|
|
2478
|
-
*/
|
|
2479
|
-
function removeNullObjectValues(value) {
|
|
2480
|
-
if (underscore__WEBPACK_IMPORTED_MODULE_0__.isArray(value) || !underscore__WEBPACK_IMPORTED_MODULE_0__.isObject(value)) {
|
|
2481
|
-
return value;
|
|
2482
|
-
}
|
|
2483
|
-
|
|
2484
|
-
const objectWithoutNullObjectValues = underscore__WEBPACK_IMPORTED_MODULE_0__.omit(value, (objectValue) => underscore__WEBPACK_IMPORTED_MODULE_0__.isNull(objectValue));
|
|
2485
|
-
|
|
2486
|
-
return objectWithoutNullObjectValues;
|
|
2499
|
+
return mergeObject(target, source, shouldRemoveNullObjectValues);
|
|
2487
2500
|
}
|
|
2488
2501
|
|
|
2489
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
|
|
2502
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ areObjectsEmpty, fastMerge });
|
|
2490
2503
|
|
|
2491
2504
|
/***/ }),
|
|
2492
2505
|
|