react-native-onyx 2.0.3 → 2.0.5
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/Onyx.js +31 -25
- package/dist/OnyxCache.d.ts +34 -80
- package/dist/OnyxCache.js +27 -83
- package/dist/storage/NativeStorage.d.ts +1 -1
- package/dist/storage/WebStorage.d.ts +2 -18
- package/dist/storage/WebStorage.js +4 -6
- package/dist/storage/__mocks__/index.d.ts +21 -21
- package/dist/storage/__mocks__/index.js +7 -8
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.native.d.ts +1 -1
- package/dist/storage/providers/IDBKeyVal.d.ts +2 -25
- package/dist/storage/providers/IDBKeyVal.js +14 -69
- package/dist/storage/providers/SQLiteStorage.d.ts +2 -51
- package/dist/storage/providers/SQLiteStorage.js +19 -81
- package/dist/storage/providers/types.d.ts +68 -0
- package/dist/storage/providers/types.js +2 -0
- package/dist/utils.d.ts +16 -9
- package/dist/utils.js +31 -42
- package/dist/withOnyx.js +1 -1
- package/package.json +3 -1
package/dist/utils.js
CHANGED
|
@@ -1,66 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
function
|
|
8
|
-
return typeof
|
|
3
|
+
/** Checks whether the given object is an object and not null/undefined. */
|
|
4
|
+
function isEmptyObject(obj) {
|
|
5
|
+
return typeof obj === 'object' && Object.keys(obj || {}).length === 0;
|
|
9
6
|
}
|
|
10
7
|
// Mostly copied from https://medium.com/@lubaka.a/how-to-remove-lodash-performance-improvement-b306669ad0e1
|
|
11
8
|
/**
|
|
12
|
-
*
|
|
13
|
-
* @returns {boolean}
|
|
9
|
+
* Checks whether the given value can be merged. It has to be an object, but not an array, RegExp or Date.
|
|
14
10
|
*/
|
|
15
|
-
function isMergeableObject(
|
|
16
|
-
const nonNullObject =
|
|
17
|
-
return
|
|
18
|
-
Object.prototype.toString.call(val) !== '[object RegExp]' &&
|
|
19
|
-
Object.prototype.toString.call(val) !== '[object Date]' &&
|
|
20
|
-
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
21
|
-
!Array.isArray(val));
|
|
11
|
+
function isMergeableObject(value) {
|
|
12
|
+
const nonNullObject = value != null ? typeof value === 'object' : false;
|
|
13
|
+
return nonNullObject && Object.prototype.toString.call(value) !== '[object RegExp]' && Object.prototype.toString.call(value) !== '[object Date]' && !Array.isArray(value);
|
|
22
14
|
}
|
|
23
15
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @
|
|
16
|
+
* Merges the source object into the target object.
|
|
17
|
+
* @param target - The target object.
|
|
18
|
+
* @param source - The source object.
|
|
19
|
+
* @param shouldRemoveNullObjectValues - If true, null object values will be removed.
|
|
20
|
+
* @returns - The merged object.
|
|
28
21
|
*/
|
|
29
22
|
function mergeObject(target, source, shouldRemoveNullObjectValues = true) {
|
|
30
23
|
const destination = {};
|
|
31
24
|
if (isMergeableObject(target)) {
|
|
32
25
|
// lodash adds a small overhead so we don't use it here
|
|
33
|
-
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
34
26
|
const targetKeys = Object.keys(target);
|
|
35
27
|
for (let i = 0; i < targetKeys.length; ++i) {
|
|
36
28
|
const key = targetKeys[i];
|
|
29
|
+
const sourceValue = source === null || source === void 0 ? void 0 : source[key];
|
|
30
|
+
const targetValue = target === null || target === void 0 ? void 0 : target[key];
|
|
37
31
|
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
38
|
-
const isSourceOrTargetNull =
|
|
32
|
+
const isSourceOrTargetNull = targetValue === null || sourceValue === null;
|
|
39
33
|
const shouldOmitSourceKey = shouldRemoveNullObjectValues && isSourceOrTargetNull;
|
|
40
34
|
if (!shouldOmitSourceKey) {
|
|
41
|
-
destination[key] =
|
|
35
|
+
destination[key] = targetValue;
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
38
|
}
|
|
45
|
-
// lodash adds a small overhead so we don't use it here
|
|
46
|
-
// eslint-disable-next-line rulesdir/prefer-underscore-method
|
|
47
39
|
const sourceKeys = Object.keys(source);
|
|
48
40
|
for (let i = 0; i < sourceKeys.length; ++i) {
|
|
49
41
|
const key = sourceKeys[i];
|
|
42
|
+
const sourceValue = source === null || source === void 0 ? void 0 : source[key];
|
|
43
|
+
const targetValue = target === null || target === void 0 ? void 0 : target[key];
|
|
50
44
|
// If shouldRemoveNullObjectValues is true, we want to remove null values from the merged object
|
|
51
|
-
const shouldOmitSourceKey = shouldRemoveNullObjectValues &&
|
|
45
|
+
const shouldOmitSourceKey = shouldRemoveNullObjectValues && sourceValue === null;
|
|
52
46
|
// If we pass undefined as the updated value for a key, we want to generally ignore it
|
|
53
|
-
const isSourceKeyUndefined =
|
|
47
|
+
const isSourceKeyUndefined = sourceValue === undefined;
|
|
54
48
|
if (!isSourceKeyUndefined && !shouldOmitSourceKey) {
|
|
55
|
-
const isSourceKeyMergable = isMergeableObject(
|
|
56
|
-
if (isSourceKeyMergable &&
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
destination[key] = fastMerge(target[key], source[key], shouldRemoveNullObjectValues);
|
|
60
|
-
}
|
|
49
|
+
const isSourceKeyMergable = isMergeableObject(sourceValue);
|
|
50
|
+
if (isSourceKeyMergable && targetValue) {
|
|
51
|
+
// eslint-disable-next-line no-use-before-define
|
|
52
|
+
destination[key] = fastMerge(targetValue, sourceValue, shouldRemoveNullObjectValues);
|
|
61
53
|
}
|
|
62
|
-
else if (!shouldRemoveNullObjectValues ||
|
|
63
|
-
destination[key] =
|
|
54
|
+
else if (!shouldRemoveNullObjectValues || sourceValue !== null) {
|
|
55
|
+
destination[key] = sourceValue;
|
|
64
56
|
}
|
|
65
57
|
}
|
|
66
58
|
}
|
|
@@ -72,28 +64,25 @@ function mergeObject(target, source, shouldRemoveNullObjectValues = true) {
|
|
|
72
64
|
* We generally want to remove null values from objects written to disk and cache, because it decreases the amount of data stored in memory and on disk.
|
|
73
65
|
* On native, when merging an existing value with new changes, SQLite will use JSON_PATCH, which removes top-level nullish values.
|
|
74
66
|
* To be consistent with the behaviour for merge, we'll also want to remove null values for "set" operations.
|
|
75
|
-
*
|
|
76
|
-
* @param {Object|Array} target
|
|
77
|
-
* @param {Object|Array} source
|
|
78
|
-
* @param {Boolean} shouldRemoveNullObjectValues
|
|
79
|
-
* @returns {Object|Array}
|
|
80
67
|
*/
|
|
81
68
|
function fastMerge(target, source, shouldRemoveNullObjectValues = true) {
|
|
82
69
|
// We have to ignore arrays and nullish values here,
|
|
83
70
|
// otherwise "mergeObject" will throw an error,
|
|
84
71
|
// because it expects an object as "source"
|
|
85
|
-
if (
|
|
72
|
+
if (Array.isArray(source) || source === null || source === undefined) {
|
|
86
73
|
return source;
|
|
87
74
|
}
|
|
88
75
|
return mergeObject(target, source, shouldRemoveNullObjectValues);
|
|
89
76
|
}
|
|
77
|
+
/** Deep removes the nested null values from the given value. */
|
|
90
78
|
function removeNestedNullValues(value) {
|
|
91
|
-
if (typeof value === 'object' && !
|
|
79
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
92
80
|
return fastMerge(value, value);
|
|
93
81
|
}
|
|
94
82
|
return value;
|
|
95
83
|
}
|
|
84
|
+
/** Formats the action name by uppercasing and adding the key if provided. */
|
|
96
85
|
function formatActionName(method, key) {
|
|
97
86
|
return key ? `${method.toUpperCase()}/${key}` : method.toUpperCase();
|
|
98
87
|
}
|
|
99
|
-
exports.default = {
|
|
88
|
+
exports.default = { isEmptyObject, fastMerge, formatActionName, removeNestedNullValues };
|
package/dist/withOnyx.js
CHANGED
|
@@ -189,7 +189,7 @@ function default_1(mapOnyxToState, shouldDelayUpdates = false) {
|
|
|
189
189
|
// This simply bypasses the loading check if the tempState is gone and the update can be safely queued with a normal setStateProxy.
|
|
190
190
|
if (!this.state.loading || !this.tempState) {
|
|
191
191
|
// Performance optimization, do not trigger update with same values
|
|
192
|
-
if (prevValue === val || utils_1.default.
|
|
192
|
+
if (prevValue === val || (utils_1.default.isEmptyObject(prevValue) && utils_1.default.isEmptyObject(val))) {
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
195
|
this.setStateProxy({ [statePropertyName]: val });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-onyx",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"author": "Expensify, Inc.",
|
|
5
5
|
"homepage": "https://expensify.com",
|
|
6
6
|
"description": "State management for React Native",
|
|
@@ -49,10 +49,12 @@
|
|
|
49
49
|
"@testing-library/jest-native": "^3.4.2",
|
|
50
50
|
"@testing-library/react-native": "^7.0.2",
|
|
51
51
|
"@types/jest": "^28.1.8",
|
|
52
|
+
"@types/lodash": "^4.14.202",
|
|
52
53
|
"@types/node": "^20.11.5",
|
|
53
54
|
"@types/react": "^18.2.14",
|
|
54
55
|
"@types/react-dom": "^18.2.18",
|
|
55
56
|
"@types/react-native": "^0.70.0",
|
|
57
|
+
"@types/underscore": "^1.11.15",
|
|
56
58
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
57
59
|
"@typescript-eslint/parser": "^6.19.0",
|
|
58
60
|
"eslint": "^8.56.0",
|