react-native-onyx 1.0.121 → 1.0.123
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 +1 -0
- package/dist/web.development.js +38 -42
- 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 +38 -42
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -410,5 +410,6 @@ To continuously work on Onyx we have to set up a task that copies content to par
|
|
|
410
410
|
|
|
411
411
|
There are Playwright e2e tests implemented for the web. To run them:
|
|
412
412
|
|
|
413
|
+
- in the tests/e2e/app directory, run `npm install`
|
|
413
414
|
- `npm run e2e` to run the e2e tests
|
|
414
415
|
- or `npm run e2e-ui` to run the e2e tests in UI mode
|
package/dist/web.development.js
CHANGED
|
@@ -1219,17 +1219,18 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
|
|
|
1219
1219
|
*
|
|
1220
1220
|
* @param {String} key
|
|
1221
1221
|
* @param {*} value
|
|
1222
|
-
* @param {Boolean} hasChanged
|
|
1223
1222
|
* @param {String} method
|
|
1223
|
+
* @param {Boolean} hasChanged
|
|
1224
|
+
* @param {Boolean} wasRemoved
|
|
1224
1225
|
* @returns {Promise}
|
|
1225
1226
|
*/
|
|
1226
|
-
function broadcastUpdate(key, value,
|
|
1227
|
+
function broadcastUpdate(key, value, method, hasChanged) {let wasRemoved = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
1227
1228
|
// Logging properties only since values could be sensitive things we don't want to log
|
|
1228
1229
|
_Logger__WEBPACK_IMPORTED_MODULE_6__.logInfo(`${method}() called for key: ${key}${underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) ? ` properties: ${underscore__WEBPACK_IMPORTED_MODULE_1___default().keys(value).join(',')}` : ''}`);
|
|
1229
1230
|
|
|
1230
1231
|
// Update subscribers if the cached value has changed, or when the subscriber specifically requires
|
|
1231
1232
|
// all updates regardless of value changes (indicated by initWithStoredValues set to false).
|
|
1232
|
-
if (hasChanged) {
|
|
1233
|
+
if (hasChanged && !wasRemoved) {
|
|
1233
1234
|
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, value);
|
|
1234
1235
|
} else {
|
|
1235
1236
|
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].addToAccessedKeys(key);
|
|
@@ -1251,18 +1252,18 @@ function hasPendingMergeForKey(key) {
|
|
|
1251
1252
|
* Otherwise removes all nested null values in objects and returns the object
|
|
1252
1253
|
* @param {String} key
|
|
1253
1254
|
* @param {Mixed} value
|
|
1254
|
-
* @returns {Mixed}
|
|
1255
|
+
* @returns {Mixed} The value without null values and a boolean "wasRemoved", which indicates if the key got removed completely
|
|
1255
1256
|
*/
|
|
1256
1257
|
function removeNullValues(key, value) {
|
|
1257
1258
|
if (underscore__WEBPACK_IMPORTED_MODULE_1___default().isNull(value)) {
|
|
1258
1259
|
remove(key);
|
|
1259
|
-
return
|
|
1260
|
+
return { value, wasRemoved: true };
|
|
1260
1261
|
}
|
|
1261
1262
|
|
|
1262
1263
|
// We can remove all null values in an object by merging it with itself
|
|
1263
1264
|
// utils.fastMerge recursively goes through the object and removes all null values
|
|
1264
1265
|
// Passing two identical objects as source and target to fastMerge will not change it, but only remove the null values
|
|
1265
|
-
return _utils__WEBPACK_IMPORTED_MODULE_9__["default"].removeNestedNullValues(value);
|
|
1266
|
+
return { value: _utils__WEBPACK_IMPORTED_MODULE_9__["default"].removeNestedNullValues(value), wasRemoved: false };
|
|
1266
1267
|
}
|
|
1267
1268
|
|
|
1268
1269
|
/**
|
|
@@ -1283,41 +1284,48 @@ function set(key, value) {
|
|
|
1283
1284
|
return Promise.resolve();
|
|
1284
1285
|
}
|
|
1285
1286
|
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
if (valueWithoutNull === null) {
|
|
1289
|
-
return Promise.resolve();
|
|
1290
|
-
}
|
|
1287
|
+
// If the value is null, we remove the key from storage
|
|
1288
|
+
const { value: valueAfterRemoving, wasRemoved } = removeNullValues(key, value);
|
|
1291
1289
|
|
|
1292
1290
|
if (hasPendingMergeForKey(key)) {
|
|
1293
|
-
|
|
1291
|
+
delete mergeQueue[key];
|
|
1294
1292
|
}
|
|
1295
1293
|
|
|
1296
|
-
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key,
|
|
1294
|
+
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, valueAfterRemoving);
|
|
1297
1295
|
|
|
1298
1296
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
1299
|
-
const updatePromise = broadcastUpdate(key,
|
|
1297
|
+
const updatePromise = broadcastUpdate(key, valueAfterRemoving, 'set', hasChanged, wasRemoved);
|
|
1300
1298
|
|
|
1301
|
-
// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
|
|
1302
|
-
if (!hasChanged) {
|
|
1299
|
+
// If the value has not changed or the key got removed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
|
|
1300
|
+
if (!hasChanged || wasRemoved) {
|
|
1303
1301
|
return updatePromise;
|
|
1304
1302
|
}
|
|
1305
1303
|
|
|
1306
|
-
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].setItem(key,
|
|
1307
|
-
catch((error) => evictStorageAndRetry(error, set, key,
|
|
1304
|
+
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].setItem(key, valueAfterRemoving).
|
|
1305
|
+
catch((error) => evictStorageAndRetry(error, set, key, valueAfterRemoving)).
|
|
1308
1306
|
then(() => updatePromise);
|
|
1309
1307
|
}
|
|
1310
1308
|
|
|
1311
1309
|
/**
|
|
1312
1310
|
* Storage expects array like: [["@MyApp_user", value_1], ["@MyApp_key", value_2]]
|
|
1313
1311
|
* This method transforms an object like {'@MyApp_user': myUserValue, '@MyApp_key': myKeyValue}
|
|
1314
|
-
* to an array of key-value pairs in the above format
|
|
1312
|
+
* to an array of key-value pairs in the above format and removes key-value pairs that are being set to null
|
|
1315
1313
|
* @private
|
|
1316
1314
|
* @param {Record} data
|
|
1317
1315
|
* @return {Array} an array of key - value pairs <[key, value]>
|
|
1318
1316
|
*/
|
|
1319
1317
|
function prepareKeyValuePairsForStorage(data) {
|
|
1320
|
-
|
|
1318
|
+
const keyValuePairs = [];
|
|
1319
|
+
|
|
1320
|
+
underscore__WEBPACK_IMPORTED_MODULE_1___default().forEach(data, (value, key) => {
|
|
1321
|
+
const { value: valueAfterRemoving, wasRemoved } = removeNullValues(key, value);
|
|
1322
|
+
|
|
1323
|
+
if (wasRemoved) return;
|
|
1324
|
+
|
|
1325
|
+
keyValuePairs.push([key, valueAfterRemoving]);
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1328
|
+
return keyValuePairs;
|
|
1321
1329
|
}
|
|
1322
1330
|
|
|
1323
1331
|
/**
|
|
@@ -1340,25 +1348,13 @@ function multiSet(data) {
|
|
|
1340
1348
|
|
|
1341
1349
|
const keyValuePairs = prepareKeyValuePairsForStorage(data);
|
|
1342
1350
|
|
|
1343
|
-
const updatePromises = underscore__WEBPACK_IMPORTED_MODULE_1___default().map(
|
|
1351
|
+
const updatePromises = underscore__WEBPACK_IMPORTED_MODULE_1___default().map(keyValuePairs, (_ref2) => {let [key, value] = _ref2;
|
|
1344
1352
|
// Update cache and optimistically inform subscribers on the next tick
|
|
1345
|
-
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key,
|
|
1346
|
-
return scheduleSubscriberUpdate(key,
|
|
1353
|
+
_OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].set(key, value);
|
|
1354
|
+
return scheduleSubscriberUpdate(key, value);
|
|
1347
1355
|
});
|
|
1348
1356
|
|
|
1349
|
-
|
|
1350
|
-
underscore__WEBPACK_IMPORTED_MODULE_1___default().map(keyValuePairs, (_ref2) => {let [key, value] = _ref2;
|
|
1351
|
-
const valueWithoutNull = removeNullValues(key, value);
|
|
1352
|
-
|
|
1353
|
-
if (valueWithoutNull === null) {
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
return [key, valueWithoutNull];
|
|
1357
|
-
}),
|
|
1358
|
-
Boolean);
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(keyValuePairsWithoutNull).
|
|
1357
|
+
return _storage__WEBPACK_IMPORTED_MODULE_5__["default"].multiSet(keyValuePairs).
|
|
1362
1358
|
catch((error) => evictStorageAndRetry(error, multiSet, data)).
|
|
1363
1359
|
then(() => Promise.all(updatePromises));
|
|
1364
1360
|
}
|
|
@@ -1434,6 +1430,9 @@ function merge(key, changes) {
|
|
|
1434
1430
|
mergeQueue[key] = [changes];
|
|
1435
1431
|
|
|
1436
1432
|
mergeQueuePromise[key] = get(key).then((existingValue) => {
|
|
1433
|
+
// Calls to Onyx.set after a merge will terminate the current merge process and clear the merge queue
|
|
1434
|
+
if (mergeQueue[key] == null) return;
|
|
1435
|
+
|
|
1437
1436
|
try {
|
|
1438
1437
|
// 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)
|
|
1439
1438
|
// We don't want to remove null values from the "batchedChanges", because SQLite uses them to remove keys from storage natively.
|
|
@@ -1448,10 +1447,7 @@ function merge(key, changes) {
|
|
|
1448
1447
|
delete mergeQueuePromise[key];
|
|
1449
1448
|
|
|
1450
1449
|
// If the batched changes equal null, we want to remove the key from storage, to reduce storage size
|
|
1451
|
-
|
|
1452
|
-
remove(key);
|
|
1453
|
-
return;
|
|
1454
|
-
}
|
|
1450
|
+
const { wasRemoved } = removeNullValues(key, batchedChanges);
|
|
1455
1451
|
|
|
1456
1452
|
// After that we merge the batched changes with the existing value
|
|
1457
1453
|
// We can remove null values from the "modifiedData", because "null" implicates that the user wants to remove a value from storage.
|
|
@@ -1469,10 +1465,10 @@ function merge(key, changes) {
|
|
|
1469
1465
|
const hasChanged = _OnyxCache__WEBPACK_IMPORTED_MODULE_4__["default"].hasValueChanged(key, modifiedData);
|
|
1470
1466
|
|
|
1471
1467
|
// This approach prioritizes fast UI changes without waiting for data to be stored in device storage.
|
|
1472
|
-
const updatePromise = broadcastUpdate(key, modifiedData, hasChanged,
|
|
1468
|
+
const updatePromise = broadcastUpdate(key, modifiedData, 'merge', hasChanged, wasRemoved);
|
|
1473
1469
|
|
|
1474
1470
|
// If the value has not changed, calling Storage.setItem() would be redundant and a waste of performance, so return early instead.
|
|
1475
|
-
if (!hasChanged || isClearing) {
|
|
1471
|
+
if (!hasChanged || isClearing || wasRemoved) {
|
|
1476
1472
|
return updatePromise;
|
|
1477
1473
|
}
|
|
1478
1474
|
|