react-native-onyx 1.0.32 → 1.0.34

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/lib/Onyx.js CHANGED
@@ -799,8 +799,7 @@ function notifyCollectionSubscribersOnNextTick(key, value) {
799
799
  * @return {Promise}
800
800
  */
801
801
  function remove(key) {
802
- // Cache the fact that the value was removed
803
- cache.set(key, null);
802
+ cache.drop(key);
804
803
  notifySubscribersOnNextTick(key, null);
805
804
  return Storage.removeItem(key);
806
805
  }
@@ -847,8 +846,9 @@ function evictStorageAndRetry(error, onyxMethod, ...args) {
847
846
  * @returns {Promise}
848
847
  */
849
848
  function set(key, value) {
850
- // Logging properties only since values could be sensitive things we don't want to log
851
- Logger.logInfo(`set() called for key: ${key}${_.isObject(value) ? ` properties: ${_.keys(value).join(',')}` : ''}`);
849
+ if (_.isNull(value)) {
850
+ return remove(key);
851
+ }
852
852
 
853
853
  // eslint-disable-next-line no-use-before-define
854
854
  if (hasPendingMergeForKey(key)) {
@@ -1050,6 +1050,10 @@ function clear(keysToPreserve = []) {
1050
1050
  const keyValuesToReset = [];
1051
1051
  const defaultKeys = _.keys(defaultKeyStates);
1052
1052
 
1053
+ // Get all the values for the keys that need to be preserved. These key/value pairs will be set
1054
+ // in Onyx after the database is cleared().
1055
+ const keyValuesToPreserve = _.map(keysToPreserve, key => [key, cache.getValue(key)]);
1056
+
1053
1057
  // The only keys that should not be cleared are:
1054
1058
  // 1. Anything specifically passed in keysToPreserve (because some keys like language preferences, offline
1055
1059
  // status, or activeClients need to remain in Onyx even when signed out)
@@ -1102,7 +1106,11 @@ function clear(keysToPreserve = []) {
1102
1106
  notifyCollectionSubscribersOnNextTick(key, value);
1103
1107
  });
1104
1108
 
1105
- return Storage.multiSet(keyValuesToReset);
1109
+ // Call clear() and make sure that the default key/values and the key/values from the parameter
1110
+ // are preserved in storage. This makes sure to always leave storage in a state that contains
1111
+ // all the default values and any additional values that we want to remain after the database is cleared.
1112
+ return Storage.clear()
1113
+ .then(() => Storage.multiSet([...defaultKeyValuePairs, ...keyValuesToPreserve]));
1106
1114
  });
1107
1115
  }
1108
1116
 
@@ -1294,6 +1302,7 @@ const Onyx = {
1294
1302
  mergeCollection,
1295
1303
  update,
1296
1304
  clear,
1305
+ getAllKeys,
1297
1306
  init,
1298
1307
  registerLogger: Logger.registerLogger,
1299
1308
  addToEvictionBlockList,
package/lib/OnyxCache.js CHANGED
@@ -104,6 +104,8 @@ class OnyxCache {
104
104
  */
105
105
  drop(key) {
106
106
  delete this.storageMap[key];
107
+ this.storageKeys.delete(key);
108
+ this.recentKeys.delete(key);
107
109
  }
108
110
 
109
111
  /**
package/lib/SyncQueue.js CHANGED
@@ -21,6 +21,14 @@ export default class SyncQueue {
21
21
  this.run = run;
22
22
  }
23
23
 
24
+ /**
25
+ * Stop the queue from being processed and clear out any existing tasks
26
+ */
27
+ abort() {
28
+ this.queue = [];
29
+ this.isProcessing = false;
30
+ }
31
+
24
32
  process() {
25
33
  if (this.isProcessing || this.queue.length === 0) {
26
34
  return;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * This file is here to wrap LocalForage with a layer that provides data-changed events like the ones that exist
3
+ * when using LocalStorage APIs in the browser. These events are great because multiple tabs can listen for when
4
+ * data changes and then stay up-to-date with everything happening in Onyx.
5
+ */
1
6
  import _ from 'underscore';
2
7
  import Storage from './providers/LocalForage';
3
8
 
@@ -27,10 +32,23 @@ const webStorage = {
27
32
  .then(() => raiseStorageSyncEvent(key));
28
33
 
29
34
  // If we just call Storage.clear other tabs will have no idea which keys were available previously
30
- // so that they can call keysChanged for them. That's why we iterate and remove keys one by one
31
- this.clear = () => Storage.getAllKeys()
32
- .then(keys => _.map(keys, key => this.removeItem(key)))
33
- .then(tasks => Promise.all(tasks));
35
+ // so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
36
+ // event for each one
37
+ this.clear = () => {
38
+ let allKeys;
39
+
40
+ // They keys must be retreived before storage is cleared or else the list of keys would be empty
41
+ return Storage.getAllKeys()
42
+ .then((keys) => {
43
+ allKeys = keys;
44
+ })
45
+ .then(() => Storage.clear())
46
+ .then(() => {
47
+ // Now that storage is cleared, the storage sync event can happen which is a more atomic action
48
+ // for other browser tabs
49
+ _.each(allKeys, raiseStorageSyncEvent);
50
+ });
51
+ };
34
52
 
35
53
  // This listener will only be triggered by events coming from other tabs
36
54
  global.addEventListener('storage', (event) => {
@@ -74,7 +74,7 @@ const provider = {
74
74
  removeItem: AsyncStorage.removeItem,
75
75
 
76
76
  /**
77
- * Clear absolutely everything from storage
77
+ * Clear everything from storage
78
78
  * @returns {Promise<void>}
79
79
  */
80
80
  clear: AsyncStorage.clear,
@@ -75,10 +75,13 @@ const provider = {
75
75
  },
76
76
 
77
77
  /**
78
- * Clear absolutely everything from storage
78
+ * Clear everything from storage and also stops the SyncQueue from adding anything more to storage
79
79
  * @returns {Promise<void>}
80
80
  */
81
- clear: localforage.clear,
81
+ clear() {
82
+ this.setItemQueue.abort();
83
+ return localforage.clear();
84
+ },
82
85
 
83
86
  /**
84
87
  * Returns all keys available in storage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-onyx",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "author": "Expensify, Inc.",
5
5
  "homepage": "https://expensify.com",
6
6
  "description": "State management for React Native",