react-native-onyx 1.0.63 → 1.0.65

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.
@@ -96,6 +96,7 @@ const METHOD = {
96
96
  SET: 'set',
97
97
  MERGE: 'merge',
98
98
  MERGE_COLLECTION: 'mergecollection',
99
+ MULTI_SET: 'multiset',
99
100
  CLEAR: 'clear'
100
101
  };
101
102
 
@@ -926,6 +927,20 @@ function remove(key) {
926
927
  return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].removeItem(key);
927
928
  }
928
929
 
930
+ /**
931
+ * @private
932
+ * @returns {Promise<void>}
933
+ */
934
+ function reportStorageQuota() {
935
+ return _storage__WEBPACK_IMPORTED_MODULE_4__["default"].getDatabaseSize().
936
+ then((_ref) => {let { bytesUsed, bytesRemaining } = _ref;
937
+ _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Storage Quota Check -- bytesUsed: ${bytesUsed} bytesRemaining: ${bytesRemaining}`);
938
+ }).
939
+ catch((dbSizeError) => {
940
+ _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert(`Unable to get database size. Error: ${dbSizeError}`);
941
+ });
942
+ }
943
+
929
944
  /**
930
945
  * If we fail to set or merge we must handle this by
931
946
  * evicting some data from Onyx and then retrying to do
@@ -938,7 +953,7 @@ function remove(key) {
938
953
  * @return {Promise}
939
954
  */
940
955
  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];}
941
- _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Handled error: ${error}`);
956
+ _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Failed to save to storage. Error: ${error}. onyxMethod: ${onyxMethod.name}`);
942
957
 
943
958
  if (error && _Str__WEBPACK_IMPORTED_MODULE_6__.startsWith(error.message, 'Failed to execute \'put\' on \'IDBObjectStore\'')) {
944
959
  _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Attempted to set invalid data set in Onyx. Please ensure all data is serializable.');
@@ -947,14 +962,17 @@ function evictStorageAndRetry(error, onyxMethod) {for (var _len = arguments.leng
947
962
 
948
963
  // Find the first key that we can remove that has no subscribers in our blocklist
949
964
  const keyForRemoval = underscore__WEBPACK_IMPORTED_MODULE_1___default().find(recentlyAccessedKeys, (key) => !evictionBlocklist[key]);
950
-
951
965
  if (!keyForRemoval) {
966
+ // If we have no acceptable keys to remove then we are possibly trying to save mission critical data. If this is the case,
967
+ // then we should stop retrying as there is not much the user can do to fix this. Instead of getting them stuck in an infinite loop we
968
+ // will allow this write to be skipped.
952
969
  _Logger__WEBPACK_IMPORTED_MODULE_5__.logAlert('Out of storage. But found no acceptable keys to remove.');
953
- throw error;
970
+ return reportStorageQuota();
954
971
  }
955
972
 
956
973
  // Remove the least recently viewed key that is not currently being accessed and retry.
957
974
  _Logger__WEBPACK_IMPORTED_MODULE_5__.logInfo(`Out of storage. Evicting least recently accessed key (${keyForRemoval}) and retrying.`);
975
+ reportStorageQuota();
958
976
  return remove(keyForRemoval).
959
977
  then(() => onyxMethod(...args));
960
978
  }
@@ -1350,16 +1368,21 @@ function mergeCollection(collectionKey, collection) {
1350
1368
  /**
1351
1369
  * Insert API responses and lifecycle data into Onyx
1352
1370
  *
1353
- * @param {Array} data An array of objects with shape {onyxMethod: oneOf('set', 'merge', 'mergeCollection'), key: string, value: *}
1371
+ * @param {Array} data An array of objects with shape {onyxMethod: oneOf('set', 'merge', 'mergeCollection', 'multiSet', 'clear'), key: string, value: *}
1354
1372
  * @returns {Promise} resolves when all operations are complete
1355
1373
  */
1356
1374
  function update(data) {
1357
1375
  // First, validate the Onyx object is in the format we expect
1358
- underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref) => {let { onyxMethod, key } = _ref;
1359
- if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().contains([METHOD.CLEAR, METHOD.SET, METHOD.MERGE, METHOD.MERGE_COLLECTION], onyxMethod)) {
1376
+ underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref2) => {let { onyxMethod, key, value } = _ref2;
1377
+ if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().contains([METHOD.CLEAR, METHOD.SET, METHOD.MERGE, METHOD.MERGE_COLLECTION, METHOD.MULTI_SET], onyxMethod)) {
1360
1378
  throw new Error(`Invalid onyxMethod ${onyxMethod} in Onyx update.`);
1361
1379
  }
1362
- if (onyxMethod !== METHOD.CLEAR && !underscore__WEBPACK_IMPORTED_MODULE_1___default().isString(key)) {
1380
+ if (onyxMethod === METHOD.MULTI_SET) {
1381
+ // For multiset, we just expect the value to be an object
1382
+ if (!underscore__WEBPACK_IMPORTED_MODULE_1___default().isObject(value) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isArray(value) || underscore__WEBPACK_IMPORTED_MODULE_1___default().isFunction(value)) {
1383
+ throw new Error('Invalid value provided in Onyx multiSet. Onyx multiSet value must be of type object.');
1384
+ }
1385
+ } else if (onyxMethod !== METHOD.CLEAR && !underscore__WEBPACK_IMPORTED_MODULE_1___default().isString(key)) {
1363
1386
  throw new Error(`Invalid ${typeof key} key provided in Onyx update. Onyx key must be of type string.`);
1364
1387
  }
1365
1388
  });
@@ -1367,7 +1390,7 @@ function update(data) {
1367
1390
  const promises = [];
1368
1391
  let clearPromise = Promise.resolve();
1369
1392
 
1370
- underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref2) => {let { onyxMethod, key, value } = _ref2;
1393
+ underscore__WEBPACK_IMPORTED_MODULE_1___default().each(data, (_ref3) => {let { onyxMethod, key, value } = _ref3;
1371
1394
  switch (onyxMethod) {
1372
1395
  case METHOD.SET:
1373
1396
  promises.push(() => set(key, value));
@@ -1378,6 +1401,9 @@ function update(data) {
1378
1401
  case METHOD.MERGE_COLLECTION:
1379
1402
  promises.push(() => mergeCollection(key, value));
1380
1403
  break;
1404
+ case METHOD.MULTI_SET:
1405
+ promises.push(() => multiSet(value));
1406
+ break;
1381
1407
  case METHOD.CLEAR:
1382
1408
  clearPromise = clear();
1383
1409
  break;
@@ -2263,7 +2289,26 @@ const provider = {
2263
2289
  * @param {Array} keysParam
2264
2290
  * @returns {Promise}
2265
2291
  */
2266
- removeItems: (keysParam) => (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.delMany)(keysParam, getCustomStore())
2292
+ removeItems: (keysParam) => (0,idb_keyval__WEBPACK_IMPORTED_MODULE_0__.delMany)(keysParam, getCustomStore()),
2293
+
2294
+ /**
2295
+ * Gets the total bytes of the database file
2296
+ * @returns {Promise<number>}
2297
+ */
2298
+ getDatabaseSize() {
2299
+ if (!window.navigator || !window.navigator.storage) {
2300
+ throw new Error('StorageManager browser API unavailable');
2301
+ }
2302
+
2303
+ return window.navigator.storage.estimate().
2304
+ then((value) => ({
2305
+ bytesUsed: value.usage,
2306
+ bytesRemaining: value.quota - value.usage
2307
+ })).
2308
+ catch((error) => {
2309
+ throw new Error(`Unable to estimate web storage quota. Original error: ${error}`);
2310
+ });
2311
+ }
2267
2312
  };
2268
2313
 
2269
2314
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (provider);