react-native-onyx 2.0.21 → 2.0.23
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/API.md +49 -64
- package/dist/DevTools.js +0 -1
- package/dist/Onyx.d.ts +49 -258
- package/dist/Onyx.js +192 -1165
- package/dist/OnyxCache.d.ts +14 -15
- package/dist/OnyxUtils.d.ts +320 -0
- package/dist/OnyxUtils.js +1061 -0
- package/dist/PerformanceUtils.d.ts +3 -5
- package/dist/index.d.ts +3 -2
- package/dist/storage/InstanceSync/index.d.ts +14 -0
- package/dist/storage/InstanceSync/index.js +20 -0
- package/dist/storage/InstanceSync/index.web.d.ts +27 -0
- package/dist/storage/InstanceSync/index.web.js +59 -0
- package/dist/storage/__mocks__/index.d.ts +15 -13
- package/dist/storage/__mocks__/index.js +43 -81
- package/dist/storage/index.d.ts +6 -2
- package/dist/storage/index.js +170 -2
- package/dist/storage/platforms/index.d.ts +2 -0
- package/dist/storage/{NativeStorage.js → platforms/index.js} +2 -2
- package/dist/storage/platforms/index.native.d.ts +2 -0
- package/dist/storage/{index.native.js → platforms/index.native.js} +2 -2
- package/dist/storage/providers/{IDBKeyVal.js → IDBKeyValProvider.js} +23 -19
- package/dist/storage/providers/MemoryOnlyProvider.d.ts +9 -0
- package/dist/storage/providers/MemoryOnlyProvider.js +124 -0
- package/dist/storage/providers/NoopProvider.js +85 -0
- package/dist/storage/providers/SQLiteProvider.d.ts +3 -0
- package/dist/storage/providers/{SQLiteStorage.js → SQLiteProvider.js} +17 -11
- package/dist/storage/providers/types.d.ts +17 -14
- package/dist/types.d.ts +128 -55
- package/dist/types.js +2 -0
- package/dist/useOnyx.js +11 -10
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +29 -16
- package/dist/withOnyx.js +6 -5
- package/package.json +1 -1
- package/dist/storage/NativeStorage.d.ts +0 -2
- package/dist/storage/WebStorage.d.ts +0 -3
- package/dist/storage/WebStorage.js +0 -62
- package/dist/storage/index.native.d.ts +0 -2
- /package/dist/storage/providers/{IDBKeyVal.d.ts → IDBKeyValProvider.d.ts} +0 -0
- /package/dist/storage/providers/{SQLiteStorage.d.ts → NoopProvider.d.ts} +0 -0
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/prefer-for-of */
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
/** Checks whether the given object is an object and not null/undefined. */
|
|
4
5
|
function isEmptyObject(obj) {
|
|
@@ -9,8 +10,8 @@ function isEmptyObject(obj) {
|
|
|
9
10
|
* Checks whether the given value can be merged. It has to be an object, but not an array, RegExp or Date.
|
|
10
11
|
*/
|
|
11
12
|
function isMergeableObject(value) {
|
|
12
|
-
const
|
|
13
|
-
return
|
|
13
|
+
const isNonNullObject = value != null ? typeof value === 'object' : false;
|
|
14
|
+
return isNonNullObject && Object.prototype.toString.call(value) !== '[object RegExp]' && Object.prototype.toString.call(value) !== '[object Date]' && !Array.isArray(value);
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Merges the source object into the target object.
|
|
@@ -21,37 +22,49 @@ function isMergeableObject(value) {
|
|
|
21
22
|
*/
|
|
22
23
|
function mergeObject(target, source, shouldRemoveNullObjectValues = true) {
|
|
23
24
|
const destination = {};
|
|
25
|
+
// First we want to copy over all keys from the target into the destination object,
|
|
26
|
+
// in case "target" is a mergable object.
|
|
27
|
+
// If "shouldRemoveNullObjectValues" is true, we want to remove null values from the merged object
|
|
28
|
+
// and therefore we need to omit keys where either the source or target value is null.
|
|
24
29
|
if (isMergeableObject(target)) {
|
|
25
|
-
// lodash adds a small overhead so we don't use it here
|
|
26
30
|
const targetKeys = Object.keys(target);
|
|
27
31
|
for (let i = 0; i < targetKeys.length; ++i) {
|
|
28
32
|
const key = targetKeys[i];
|
|
29
33
|
const sourceValue = source === null || source === void 0 ? void 0 : source[key];
|
|
30
34
|
const targetValue = target === null || target === void 0 ? void 0 : target[key];
|
|
31
|
-
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
35
|
+
// If "shouldRemoveNullObjectValues" is true, we want to remove null values from the merged object.
|
|
36
|
+
// Therefore, if either target or source value is null, we want to prevent the key from being set.
|
|
32
37
|
const isSourceOrTargetNull = targetValue === null || sourceValue === null;
|
|
33
|
-
const
|
|
34
|
-
if (!
|
|
38
|
+
const shouldOmitTargetKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
|
|
39
|
+
if (!shouldOmitTargetKey) {
|
|
35
40
|
destination[key] = targetValue;
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
}
|
|
44
|
+
// After copying over all keys from the target object, we want to merge the source object into the destination object.
|
|
39
45
|
const sourceKeys = Object.keys(source);
|
|
40
46
|
for (let i = 0; i < sourceKeys.length; ++i) {
|
|
41
47
|
const key = sourceKeys[i];
|
|
42
48
|
const sourceValue = source === null || source === void 0 ? void 0 : source[key];
|
|
43
49
|
const targetValue = target === null || target === void 0 ? void 0 : target[key];
|
|
44
|
-
// If
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
// If undefined is passed as the source value for a key, we want to generally ignore it.
|
|
51
|
+
// If "shouldRemoveNullObjectValues" is set to true and the source value is null,
|
|
52
|
+
// we don't want to set/merge the source value into the merged object.
|
|
53
|
+
const shouldIgnoreNullSourceValue = shouldRemoveNullObjectValues && sourceValue === null;
|
|
54
|
+
const shouldOmitSourceKey = sourceValue === undefined || shouldIgnoreNullSourceValue;
|
|
55
|
+
if (!shouldOmitSourceKey) {
|
|
56
|
+
// If the source value is a mergable object, we want to merge it into the target value.
|
|
57
|
+
// If "shouldRemoveNullObjectValues" is true, "fastMerge" will recursively
|
|
58
|
+
// remove nested null values from the merged object.
|
|
59
|
+
// If source value is any other value we need to set the source value it directly.
|
|
60
|
+
if (isMergeableObject(sourceValue)) {
|
|
61
|
+
// If the target value is null or undefined, we need to fallback to an empty object,
|
|
62
|
+
// so that we can still use "fastMerge" to merge the source value,
|
|
63
|
+
// to ensure that nested null values are removed from the merged object.
|
|
64
|
+
const targetValueWithFallback = (targetValue !== null && targetValue !== void 0 ? targetValue : {});
|
|
65
|
+
destination[key] = fastMerge(targetValueWithFallback, sourceValue, shouldRemoveNullObjectValues);
|
|
53
66
|
}
|
|
54
|
-
else
|
|
67
|
+
else {
|
|
55
68
|
destination[key] = sourceValue;
|
|
56
69
|
}
|
|
57
70
|
}
|
package/dist/withOnyx.js
CHANGED
|
@@ -37,6 +37,7 @@ const underscore_1 = __importDefault(require("underscore"));
|
|
|
37
37
|
const Onyx_1 = __importDefault(require("./Onyx"));
|
|
38
38
|
const Str = __importStar(require("./Str"));
|
|
39
39
|
const utils_1 = __importDefault(require("./utils"));
|
|
40
|
+
const OnyxUtils_1 = __importDefault(require("./OnyxUtils"));
|
|
40
41
|
// This is a list of keys that can exist on a `mapping`, but are not directly related to loading data from Onyx. When the keys of a mapping are looped over to check
|
|
41
42
|
// if a key has changed, it's a good idea to skip looking at these properties since they would have unexpected results.
|
|
42
43
|
const mappingPropertiesToIgnoreChangesTo = ['initialValue', 'allowStaleData'];
|
|
@@ -77,7 +78,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
77
78
|
this.activeConnectionIDs = {};
|
|
78
79
|
const cachedState = underscore_1.default.reduce(mapOnyxToState, (resultObj, mapping, propertyName) => {
|
|
79
80
|
const key = Str.result(mapping.key, props);
|
|
80
|
-
let value =
|
|
81
|
+
let value = OnyxUtils_1.default.tryGetCachedValue(key, mapping);
|
|
81
82
|
if (!value && mapping.initialValue) {
|
|
82
83
|
value = mapping.initialValue;
|
|
83
84
|
}
|
|
@@ -92,7 +93,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
92
93
|
* In reality, Onyx.merge() will only update the subscriber after all merges have been batched and the previous value is retrieved via a get() (returns a promise).
|
|
93
94
|
* So, we won't use the cache optimization here as it will lead us to arbitrarily defer various actions in the application code.
|
|
94
95
|
*/
|
|
95
|
-
if ((value !== undefined && !
|
|
96
|
+
if ((value !== undefined && !OnyxUtils_1.default.hasPendingMergeForKey(key)) || mapping.allowStaleData) {
|
|
96
97
|
// eslint-disable-next-line no-param-reassign
|
|
97
98
|
resultObj[propertyName] = value;
|
|
98
99
|
}
|
|
@@ -246,14 +247,14 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
246
247
|
}
|
|
247
248
|
const canEvict = Str.result(mapping.canEvict, this.props);
|
|
248
249
|
const key = Str.result(mapping.key, this.props);
|
|
249
|
-
if (!
|
|
250
|
+
if (!OnyxUtils_1.default.isSafeEvictionKey(key)) {
|
|
250
251
|
throw new Error(`canEvict can't be used on key '${key}'. This key must explicitly be flagged as safe for removal by adding it to Onyx.init({safeEvictionKeys: []}).`);
|
|
251
252
|
}
|
|
252
253
|
if (canEvict) {
|
|
253
|
-
|
|
254
|
+
OnyxUtils_1.default.removeFromEvictionBlockList(key, mapping.connectionID);
|
|
254
255
|
}
|
|
255
256
|
else {
|
|
256
|
-
|
|
257
|
+
OnyxUtils_1.default.addToEvictionBlockList(key, mapping.connectionID);
|
|
257
258
|
}
|
|
258
259
|
});
|
|
259
260
|
}
|
package/package.json
CHANGED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
/**
|
|
7
|
-
* This file is here to wrap IDBKeyVal with a layer that provides data-changed events like the ones that exist
|
|
8
|
-
* when using LocalStorage APIs in the browser. These events are great because multiple tabs can listen for when
|
|
9
|
-
* data changes and then stay up-to-date with everything happening in Onyx.
|
|
10
|
-
*/
|
|
11
|
-
const IDBKeyVal_1 = __importDefault(require("./providers/IDBKeyVal"));
|
|
12
|
-
const SYNC_ONYX = 'SYNC_ONYX';
|
|
13
|
-
/**
|
|
14
|
-
* Raise an event thorough `localStorage` to let other tabs know a value changed
|
|
15
|
-
*/
|
|
16
|
-
function raiseStorageSyncEvent(onyxKey) {
|
|
17
|
-
global.localStorage.setItem(SYNC_ONYX, onyxKey);
|
|
18
|
-
global.localStorage.removeItem(SYNC_ONYX);
|
|
19
|
-
}
|
|
20
|
-
function raiseStorageSyncManyKeysEvent(onyxKeys) {
|
|
21
|
-
onyxKeys.forEach((onyxKey) => {
|
|
22
|
-
raiseStorageSyncEvent(onyxKey);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
const webStorage = Object.assign(Object.assign({}, IDBKeyVal_1.default), {
|
|
26
|
-
/**
|
|
27
|
-
* @param onStorageKeyChanged Storage synchronization mechanism keeping all opened tabs in sync
|
|
28
|
-
*/
|
|
29
|
-
keepInstancesSync(onStorageKeyChanged) {
|
|
30
|
-
// Override set, remove and clear to raise storage events that we intercept in other tabs
|
|
31
|
-
this.setItem = (key, value) => IDBKeyVal_1.default.setItem(key, value).then(() => raiseStorageSyncEvent(key));
|
|
32
|
-
this.removeItem = (key) => IDBKeyVal_1.default.removeItem(key).then(() => raiseStorageSyncEvent(key));
|
|
33
|
-
this.removeItems = (keys) => IDBKeyVal_1.default.removeItems(keys).then(() => raiseStorageSyncManyKeysEvent(keys));
|
|
34
|
-
this.mergeItem = (key, batchedChanges, modifiedData) => IDBKeyVal_1.default.mergeItem(key, batchedChanges, modifiedData).then(() => raiseStorageSyncEvent(key));
|
|
35
|
-
// If we just call Storage.clear other tabs will have no idea which keys were available previously
|
|
36
|
-
// so that they can call keysChanged for them. That's why we iterate over every key and raise a storage sync
|
|
37
|
-
// event for each one
|
|
38
|
-
this.clear = () => {
|
|
39
|
-
let allKeys;
|
|
40
|
-
// The keys must be retrieved before storage is cleared or else the list of keys would be empty
|
|
41
|
-
return IDBKeyVal_1.default.getAllKeys()
|
|
42
|
-
.then((keys) => {
|
|
43
|
-
allKeys = keys;
|
|
44
|
-
})
|
|
45
|
-
.then(() => IDBKeyVal_1.default.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
|
-
allKeys.forEach(raiseStorageSyncEvent);
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
|
-
// This listener will only be triggered by events coming from other tabs
|
|
53
|
-
global.addEventListener('storage', (event) => {
|
|
54
|
-
// Ignore events that don't originate from the SYNC_ONYX logic
|
|
55
|
-
if (event.key !== SYNC_ONYX || !event.newValue) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const onyxKey = event.newValue;
|
|
59
|
-
IDBKeyVal_1.default.getItem(onyxKey).then((value) => onStorageKeyChanged(onyxKey, value));
|
|
60
|
-
});
|
|
61
|
-
} });
|
|
62
|
-
exports.default = webStorage;
|
|
File without changes
|
|
File without changes
|