react-native-onyx 1.0.38 → 1.0.39
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 +78 -53
- 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 +34 -44
- package/lib/storage/WebStorage.js +9 -0
- package/lib/storage/providers/AsyncStorage.js +7 -0
- package/lib/storage/providers/LocalForage.js +13 -0
- package/lib/storage/providers/SQLiteStorage.js +12 -0
- package/package.json +5 -1
package/lib/Onyx.js
CHANGED
|
@@ -1047,55 +1047,46 @@ function initializeWithDefaultKeyStates() {
|
|
|
1047
1047
|
function clear(keysToPreserve = []) {
|
|
1048
1048
|
return getAllKeys()
|
|
1049
1049
|
.then((keys) => {
|
|
1050
|
-
const
|
|
1051
|
-
const
|
|
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)]);
|
|
1050
|
+
const keysToBeClearedFromStorage = [];
|
|
1051
|
+
const keyValuesToResetAsCollection = {};
|
|
1052
|
+
const keyValuesToResetIndividually = {};
|
|
1056
1053
|
|
|
1057
1054
|
// The only keys that should not be cleared are:
|
|
1058
1055
|
// 1. Anything specifically passed in keysToPreserve (because some keys like language preferences, offline
|
|
1059
1056
|
// status, or activeClients need to remain in Onyx even when signed out)
|
|
1060
1057
|
// 2. Any keys with a default state (because they need to remain in Onyx as their default, and setting them
|
|
1061
1058
|
// to null would cause unknown behavior)
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
_.each(keyValuesToReset, (keyValue) => {
|
|
1085
|
-
const key = keyValue[0];
|
|
1086
|
-
const value = keyValue[1];
|
|
1087
|
-
cache.set(key, value);
|
|
1088
|
-
|
|
1089
|
-
const collectionKey = key.substring(0, key.indexOf('_') + 1);
|
|
1090
|
-
if (collectionKey) {
|
|
1091
|
-
if (!keyValuesToResetAsCollection[collectionKey]) {
|
|
1092
|
-
keyValuesToResetAsCollection[collectionKey] = {};
|
|
1059
|
+
_.each(keys, (key) => {
|
|
1060
|
+
const isKeyToPreserve = _.contains(keysToPreserve, key);
|
|
1061
|
+
const isDefaultKey = _.has(defaultKeyStates, key);
|
|
1062
|
+
|
|
1063
|
+
// If the key is being removed or reset to default:
|
|
1064
|
+
// 1. Update it in the cache
|
|
1065
|
+
// 2. Figure out whether it is a collection key or not,
|
|
1066
|
+
// since collection key subscribers need to be updated differently
|
|
1067
|
+
if (!isKeyToPreserve) {
|
|
1068
|
+
const oldValue = cache.getValue(key);
|
|
1069
|
+
const newValue = _.get(defaultKeyStates, key, null);
|
|
1070
|
+
if (newValue !== oldValue) {
|
|
1071
|
+
cache.set(key, newValue);
|
|
1072
|
+
const collectionKey = key.substring(0, key.indexOf('_') + 1);
|
|
1073
|
+
if (collectionKey) {
|
|
1074
|
+
if (!keyValuesToResetAsCollection[collectionKey]) {
|
|
1075
|
+
keyValuesToResetAsCollection[collectionKey] = {};
|
|
1076
|
+
}
|
|
1077
|
+
keyValuesToResetAsCollection[collectionKey][key] = newValue;
|
|
1078
|
+
} else {
|
|
1079
|
+
keyValuesToResetIndividually[key] = newValue;
|
|
1080
|
+
}
|
|
1093
1081
|
}
|
|
1094
|
-
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
if (isKeyToPreserve || isDefaultKey) {
|
|
1095
1085
|
return;
|
|
1096
1086
|
}
|
|
1097
1087
|
|
|
1098
|
-
|
|
1088
|
+
// If it isn't preserved and doesn't have a default, we'll remove it
|
|
1089
|
+
keysToBeClearedFromStorage.push(key);
|
|
1099
1090
|
});
|
|
1100
1091
|
|
|
1101
1092
|
// Notify the subscribers for each key/value group so they can receive the new values
|
|
@@ -1106,11 +1097,10 @@ function clear(keysToPreserve = []) {
|
|
|
1106
1097
|
notifyCollectionSubscribersOnNextTick(key, value);
|
|
1107
1098
|
});
|
|
1108
1099
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
//
|
|
1112
|
-
return Storage.
|
|
1113
|
-
.then(() => Storage.multiSet([...defaultKeyValuePairs, ...keyValuesToPreserve]));
|
|
1100
|
+
const defaultKeyValuePairs = _.pairs(_.omit(defaultKeyStates, keysToPreserve));
|
|
1101
|
+
|
|
1102
|
+
// Remove only the items that we want cleared from storage, and reset others to default
|
|
1103
|
+
return Storage.removeItems(keysToBeClearedFromStorage).then(() => Storage.multiSet(defaultKeyValuePairs));
|
|
1114
1104
|
});
|
|
1115
1105
|
}
|
|
1116
1106
|
|
|
@@ -17,6 +17,12 @@ function raiseStorageSyncEvent(onyxKey) {
|
|
|
17
17
|
global.localStorage.removeItem(SYNC_ONYX, onyxKey);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function raiseStorageSyncManyKeysEvent(onyxKeys) {
|
|
21
|
+
_.each(onyxKeys, (onyxKey) => {
|
|
22
|
+
raiseStorageSyncEvent(onyxKey);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
const webStorage = {
|
|
21
27
|
...Storage,
|
|
22
28
|
|
|
@@ -31,6 +37,9 @@ const webStorage = {
|
|
|
31
37
|
this.removeItem = key => Storage.removeItem(key)
|
|
32
38
|
.then(() => raiseStorageSyncEvent(key));
|
|
33
39
|
|
|
40
|
+
this.removeItems = keys => Storage.removeItems(keys)
|
|
41
|
+
.then(() => raiseStorageSyncManyKeysEvent(keys));
|
|
42
|
+
|
|
34
43
|
// If we just call Storage.clear other tabs will have no idea which keys were available previously
|
|
35
44
|
// so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
|
|
36
45
|
// event for each one
|
|
@@ -73,6 +73,13 @@ const provider = {
|
|
|
73
73
|
*/
|
|
74
74
|
removeItem: AsyncStorage.removeItem,
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Remove given keys and their values from storage
|
|
78
|
+
* @param {Array} keys
|
|
79
|
+
* @returns {Promise}
|
|
80
|
+
*/
|
|
81
|
+
removeItems: keys => Promise.all(_.map(keys, key => AsyncStorage.removeItem(key))),
|
|
82
|
+
|
|
76
83
|
/**
|
|
77
84
|
* Clear everything from storage
|
|
78
85
|
* @returns {Promise<void>}
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
import localforage from 'localforage';
|
|
8
8
|
import _ from 'underscore';
|
|
9
|
+
import {extendPrototype} from 'localforage-removeitems';
|
|
9
10
|
import SyncQueue from '../../SyncQueue';
|
|
10
11
|
import fastMerge from '../../fastMerge';
|
|
11
12
|
|
|
13
|
+
extendPrototype(localforage);
|
|
14
|
+
|
|
12
15
|
localforage.config({
|
|
13
16
|
name: 'OnyxDB',
|
|
14
17
|
});
|
|
@@ -103,6 +106,16 @@ const provider = {
|
|
|
103
106
|
*/
|
|
104
107
|
removeItem: localforage.removeItem,
|
|
105
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Remove given keys and their values from storage
|
|
111
|
+
*
|
|
112
|
+
* @param {Array} keys
|
|
113
|
+
* @returns {Promise}
|
|
114
|
+
*/
|
|
115
|
+
removeItems(keys) {
|
|
116
|
+
return localforage.removeItems(keys);
|
|
117
|
+
},
|
|
118
|
+
|
|
106
119
|
/**
|
|
107
120
|
* Sets the value for a given key. The only requirement is that the value should be serializable to JSON string
|
|
108
121
|
* @param {String} key
|
|
@@ -111,6 +111,18 @@ const provider = {
|
|
|
111
111
|
*/
|
|
112
112
|
removeItem: key => db.executeAsync('DELETE FROM keyvaluepairs WHERE record_key = ?;', [key]),
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Removes given keys and their values from storage
|
|
116
|
+
*
|
|
117
|
+
* @param {Array<String>} keys
|
|
118
|
+
* @returns {Promise<void>}
|
|
119
|
+
*/
|
|
120
|
+
removeItems: (keys) => {
|
|
121
|
+
const placeholders = _.map(keys, () => '?').join(',');
|
|
122
|
+
const query = `DELETE FROM keyvaluepairs WHERE record_key IN (${placeholders});`;
|
|
123
|
+
return db.executeAsync(query, keys);
|
|
124
|
+
},
|
|
125
|
+
|
|
114
126
|
/**
|
|
115
127
|
* Clears absolutely everything from storage
|
|
116
128
|
* @returns {Promise<void>}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-onyx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39",
|
|
4
4
|
"author": "Expensify, Inc.",
|
|
5
5
|
"homepage": "https://expensify.com",
|
|
6
6
|
"description": "State management for React Native",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
|
80
80
|
"expensify-common": ">=1",
|
|
81
81
|
"localforage": "^1.10.0",
|
|
82
|
+
"localforage-removeitems": "^1.4.0",
|
|
82
83
|
"react": ">=18.1.0",
|
|
83
84
|
"react-native-performance": "^4.0.0",
|
|
84
85
|
"react-native-quick-sqlite": "^8.0.0-beta.2"
|
|
@@ -95,6 +96,9 @@
|
|
|
95
96
|
},
|
|
96
97
|
"localforage": {
|
|
97
98
|
"optional": true
|
|
99
|
+
},
|
|
100
|
+
"localforage-removeitems": {
|
|
101
|
+
"optional": true
|
|
98
102
|
}
|
|
99
103
|
},
|
|
100
104
|
"engines": {
|