@arrai-innovations/reactive-helpers 11.4.2 → 13.0.0
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/.husky/pre-commit +0 -1
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.prettierignore +1 -0
- package/README.md +11 -10
- package/config/listCrud.js +32 -1
- package/config/objectCrud.js +47 -1
- package/docs/README.md +43 -0
- package/docs/config/listCrud.md +97 -0
- package/docs/config/objectCrud.md +123 -0
- package/docs/use/cancellableIntent.md +163 -0
- package/docs/use/combineClasses.md +52 -0
- package/docs/use/list.md +285 -0
- package/docs/use/listCalculated.md +773 -0
- package/docs/use/listFilter.md +877 -0
- package/docs/use/listInstance.md +483 -0
- package/docs/use/listKeys.md +91 -0
- package/docs/use/listRelated.md +685 -0
- package/docs/use/listSearch.md +889 -0
- package/docs/use/listSort.md +1144 -0
- package/docs/use/listSubscription.md +379 -0
- package/docs/use/loadingError.md +21 -0
- package/docs/use/object.md +437 -0
- package/docs/use/objectCalculated.md +606 -0
- package/docs/use/objectInstance.md +486 -0
- package/docs/use/objectRelated.md +588 -0
- package/docs/use/objectSubscription.md +459 -0
- package/docs/use/paginatedListInstance.md +147 -0
- package/docs/use/search.md +311 -0
- package/docs/use/watchesRunning.md +80 -0
- package/docs/utils/assignReactiveObject.md +351 -0
- package/docs/utils/classes.md +100 -0
- package/docs/utils/compact.md +57 -0
- package/docs/utils/deleteKey.md +53 -0
- package/docs/utils/flattenPaths.md +45 -0
- package/docs/utils/getFakeId.md +34 -0
- package/docs/utils/keyDiff.md +101 -0
- package/docs/utils/loadingCombine.md +28 -0
- package/docs/utils/proxyRunning.md +33 -0
- package/docs/utils/relatedCalculatedHelpers.md +75 -0
- package/docs/utils/set.md +139 -0
- package/docs/utils/transformWalk.md +33 -0
- package/docs/utils/watches.md +441 -0
- package/eslint.config.js +125 -0
- package/index.js +34 -3
- package/lint-staged.config.js +5 -1
- package/makeTypeDoc.sh +25 -0
- package/package.json +27 -19
- package/tests/unit/config/listCrud.spec.js +5 -0
- package/tests/unit/config/objectCrud.spec.js +5 -0
- package/tests/unit/crudPromise.js +22 -3
- package/tests/unit/mockOnUnmounted.js +1 -1
- package/tests/unit/use/cancellableIntent.spec.js +2 -0
- package/tests/unit/use/listCalculated.spec.js +4 -3
- package/tests/unit/use/listFilter.spec.js +11 -7
- package/tests/unit/use/listInstance.spec.js +32 -14
- package/tests/unit/use/listRelated.spec.js +3 -2
- package/tests/unit/use/listSearch.spec.js +9 -7
- package/tests/unit/use/listSort.spec.js +29 -22
- package/tests/unit/use/listSubscription.spec.js +11 -5
- package/tests/unit/use/objectInstance.spec.js +15 -2
- package/tests/unit/use/objectSubscription.spec.js +31 -16
- package/tests/unit/use/search.spec.js +2 -2
- package/tests/unit/utils/assignReactiveObject.spec.js +21 -13
- package/tests/unit/utils/classes.spec.js +7 -6
- package/tests/unit/utils/watches.spec.js +4 -4
- package/tsconfig.json +19 -0
- package/typedoc-local-plugins/customize-output.js +13 -0
- package/typedoc.json +12 -0
- package/use/cancellableIntent.js +73 -2
- package/use/combineClasses.js +41 -31
- package/use/list.js +139 -5
- package/use/listCalculated.js +175 -10
- package/use/listFilter.js +175 -21
- package/use/listInstance.js +215 -94
- package/use/listRelated.js +260 -72
- package/use/listSearch.js +178 -57
- package/use/listSort.js +188 -21
- package/use/listSubscription.js +211 -63
- package/use/loadingError.js +43 -0
- package/use/object.js +187 -23
- package/use/objectCalculated.js +168 -16
- package/use/objectInstance.js +183 -102
- package/use/objectRelated.js +276 -84
- package/use/objectSubscription.js +169 -17
- package/use/paginatedListInstance.js +30 -1
- package/use/search.js +39 -23
- package/use/watchesRunning.js +41 -6
- package/utils/assignReactiveObject.js +139 -88
- package/utils/classes.js +57 -48
- package/utils/compact.js +28 -2
- package/utils/deleteKey.js +14 -1
- package/utils/flattenPaths.js +19 -9
- package/utils/getFakeId.js +11 -1
- package/utils/keyDiff.js +26 -35
- package/utils/loadingCombine.js +7 -4
- package/utils/proxyRunning.js +16 -8
- package/utils/relatedCalculatedHelpers.js +17 -0
- package/utils/set.js +66 -0
- package/utils/transformWalk.js +7 -6
- package/utils/watches.js +205 -71
- package/.eslintignore +0 -2
- package/.eslintrc.cjs +0 -25
- package/.jsdoc2md.json +0 -4
- package/config/index.js +0 -2
- package/docs.md +0 -1002
- package/jsdoc-to-markdown.sh +0 -16
- package/tests/unit/.eslintrc.cjs +0 -11
- package/tests/unit/config/index.spec.js +0 -18
- package/tests/unit/use/index.spec.js +0 -18
- package/tests/unit/utils/index.spec.js +0 -18
- package/use/index.js +0 -19
- package/utils/debugMessage.js +0 -209
- package/utils/debugWatch.js +0 -29
- package/utils/index.js +0 -16
- package/utils/lifecycleDebug.js +0 -126
package/utils/classes.js
CHANGED
|
@@ -7,51 +7,27 @@ import isString from "lodash-es/isString.js";
|
|
|
7
7
|
import { isRef, unref } from "vue";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
/* eslint-enable jsdoc/check-types */
|
|
25
|
-
/**
|
|
26
|
-
* @typedef {Array<CSSClassNames, CSSString[], CSSString, CSSObject>} CSSClasses A mixed array containing multiple ways of specifying CSS classes.
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* A mixed array containing multiple ways of specifying CSS classes.
|
|
30
|
-
* @typedef {Array<
|
|
31
|
-
* CSSClassNames,
|
|
32
|
-
* CSSString[],
|
|
33
|
-
* CSSString,
|
|
34
|
-
* CSSObject,
|
|
35
|
-
* Ref<CSSClassNames>,
|
|
36
|
-
* Ref<CSSString[]>,
|
|
37
|
-
* Ref<CSSString>,
|
|
38
|
-
* Ref<CSSClassNames>
|
|
39
|
-
* >} CSSClassesWithRefs
|
|
40
|
-
*/
|
|
41
|
-
/**
|
|
42
|
-
* @typedef {CSSString|CSSObject} CSSStringOrObject A CSS object or a space-separated list of CSS classes.
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @param {...CSSClasses} classes A mixed array containing multiple ways of specifying CSS classes.
|
|
47
|
-
* @returns {CSSStringOrObject} A CSS object or a space-separated list of CSS classes.
|
|
10
|
+
* Normalize various ways of specifying CSS classes into an object for use in Vue.js.
|
|
11
|
+
*
|
|
12
|
+
* @param {...(
|
|
13
|
+
* string |
|
|
14
|
+
* string[] |
|
|
15
|
+
* string[][] |
|
|
16
|
+
* {[key: string]: boolean | import("vue").Ref<boolean> } |
|
|
17
|
+
* import("vue").Ref<string | string[] | string[][]>
|
|
18
|
+
* )} classes - A mixed array containing multiple ways of specifying CSS classes.
|
|
19
|
+
* @returns {(
|
|
20
|
+
* {[key: string]: boolean | import("vue").Ref<boolean> }|
|
|
21
|
+
* {[key: string]: boolean | import("vue").Ref<boolean> }[]
|
|
22
|
+
* )} An object or array of objects containing CSS classes. Arrays are used if refs are present, to preserve order
|
|
23
|
+
* of operations in reactive contexts.
|
|
48
24
|
*/
|
|
49
25
|
export const objectifyClasses = (...classes) => {
|
|
50
26
|
const flatClasses = classes.flat(Infinity).filter(identity);
|
|
51
27
|
const objects = flatClasses.map((c) => {
|
|
52
28
|
if (isString(c)) {
|
|
53
|
-
|
|
54
|
-
c =
|
|
29
|
+
const cSplit = c.split(/\s+/);
|
|
30
|
+
c = cSplit.reduce((acc, c) => {
|
|
55
31
|
acc[c] = true;
|
|
56
32
|
return acc;
|
|
57
33
|
}, {});
|
|
@@ -91,8 +67,14 @@ export const objectifyClasses = (...classes) => {
|
|
|
91
67
|
return Object.assign({}, ...objects);
|
|
92
68
|
};
|
|
93
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @private
|
|
72
|
+
* @param {(import("vue").Ref<any>|any)[]} val - The value to unref.
|
|
73
|
+
* @returns {any[]} - The value with refs unref'd.
|
|
74
|
+
*/
|
|
94
75
|
const deepUnrefArrays = (val) => {
|
|
95
76
|
// object values as refs is fine, but array elements as refs should be unref'd
|
|
77
|
+
/** @type {any} */
|
|
96
78
|
let checkedVal = isRef(val) ? unref(val) : val;
|
|
97
79
|
|
|
98
80
|
if (!isObject(checkedVal)) {
|
|
@@ -112,12 +94,35 @@ const deepUnrefArrays = (val) => {
|
|
|
112
94
|
};
|
|
113
95
|
|
|
114
96
|
/**
|
|
115
|
-
* @
|
|
116
|
-
*
|
|
117
|
-
*
|
|
97
|
+
* @typedef {(
|
|
98
|
+
* string |
|
|
99
|
+
* { [classnames: string]: boolean | import("vue").Ref<boolean> } |
|
|
100
|
+
* { [classnames: string]: boolean | import("vue").Ref<boolean> }[]
|
|
101
|
+
* )} CombinedClasses - The normalized form of the CSS classes, either as a string of space-separated class names or an
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @typedef {(
|
|
106
|
+
* (string | string[] | string[][]) |
|
|
107
|
+
* { [classnames: string]: boolean | import("vue").Ref<boolean> } |
|
|
108
|
+
* import("vue").Ref<string | string[] | string[][]> |
|
|
109
|
+
* import("vue").Ref<{ [classnames: string]: (boolean | import("vue").Ref<boolean>) }> |
|
|
110
|
+
* import("vue").UnwrapNestedRefs<{ [classnames: string]: (boolean | import("vue").Ref<boolean>) }>
|
|
111
|
+
* )} CombinedClassesArgument
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Combines and normalizes different formats of CSS class specifications into a single format suitable for Vue.js
|
|
116
|
+
* components. If objects are in the mix, objects are returned. Otherwise, a string is returned.
|
|
117
|
+
*
|
|
118
|
+
* We unref your refs, so probably want a computed around this.
|
|
119
|
+
*
|
|
120
|
+
* @param {...(CombinedClassesArgument|CombinedClassesArgument[])} classes - A variable list of class specifications in
|
|
121
|
+
* different formats.
|
|
122
|
+
* @returns {CombinedClasses} - The normalized form of the CSS classes, either as a string of space-separated class
|
|
123
|
+
* names or an object map of class names to boolean values indicating their presence.
|
|
118
124
|
*/
|
|
119
125
|
export const combineClasses = (...classes) => {
|
|
120
|
-
// we unref your refs, so probably want a computed around this
|
|
121
126
|
// ultimately, strings and objects are classes, arrays are organization and containers
|
|
122
127
|
const rawClasses = deepUnrefArrays(classes);
|
|
123
128
|
const flattenedClasses = rawClasses.flat(Infinity);
|
|
@@ -134,8 +139,10 @@ export const combineClasses = (...classes) => {
|
|
|
134
139
|
};
|
|
135
140
|
|
|
136
141
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
142
|
+
* Normalizes various ways of specifying CSS classes into a space-separated list of CSS classes.
|
|
143
|
+
*
|
|
144
|
+
* @param {string | string[] | {[classnames: string]: boolean}} cls - Handles the multiple ways of specifying CSS class related values.
|
|
145
|
+
* @returns {string} A space-separated list of CSS classes.
|
|
139
146
|
*/
|
|
140
147
|
export const stringifyClass = (cls) => {
|
|
141
148
|
if (isArray(cls)) {
|
|
@@ -150,8 +157,10 @@ export const stringifyClass = (cls) => {
|
|
|
150
157
|
};
|
|
151
158
|
|
|
152
159
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
160
|
+
* Normalizes various ways of specifying CSS classes into a space-separated list of CSS classes.
|
|
161
|
+
*
|
|
162
|
+
* @param {...(string | string[] | {[classnames: string]: boolean})} classes - Handles the multiple ways of specifying CSS class related values.
|
|
163
|
+
* @returns {string} - A space-separated list of CSS classes.
|
|
155
164
|
*/
|
|
156
165
|
export const stringifyClasses = (...classes) =>
|
|
157
166
|
classes
|
package/utils/compact.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import isEmpty from "lodash-es/isEmpty.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Remove empty objects from a mixed object array tree. Mutates
|
|
5
|
+
* the object.
|
|
6
|
+
*
|
|
7
|
+
* @private
|
|
8
|
+
* @param {object} obj - The object to remove empty objects from.
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
3
11
|
const removeEmptyObjectsRecursive = (obj) => {
|
|
4
12
|
if (typeof obj !== "object" || obj === null) {
|
|
5
13
|
return;
|
|
@@ -18,18 +26,26 @@ const removeEmptyObjectsRecursive = (obj) => {
|
|
|
18
26
|
for (const item of obj) {
|
|
19
27
|
removeEmptyObjectsRecursive(item);
|
|
20
28
|
}
|
|
21
|
-
return;
|
|
22
29
|
}
|
|
23
30
|
};
|
|
24
31
|
|
|
25
32
|
/**
|
|
26
33
|
* Remove empty objects from a mixed object array tree. Mutates the object.
|
|
27
|
-
*
|
|
34
|
+
*
|
|
35
|
+
* @param {object|Array} obj - The object or array to remove empty objects from.
|
|
36
|
+
* @returns {void}
|
|
28
37
|
*/
|
|
29
38
|
export const removeEmptyObjects = (obj) => {
|
|
30
39
|
removeEmptyObjectsRecursive(obj);
|
|
31
40
|
};
|
|
32
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Remove empty objects from a mixed object array tree. Mutates the object.
|
|
44
|
+
*
|
|
45
|
+
* @private
|
|
46
|
+
* @param {object} obj - The object to remove empty objects from.
|
|
47
|
+
* @returns {void}
|
|
48
|
+
*/
|
|
33
49
|
const compactSparseArraysRecursive = (obj) => {
|
|
34
50
|
if (typeof obj !== "object" || obj === null) {
|
|
35
51
|
return;
|
|
@@ -52,12 +68,20 @@ const compactSparseArraysRecursive = (obj) => {
|
|
|
52
68
|
|
|
53
69
|
/**
|
|
54
70
|
* Remove undefined values from arrays in a mixed object array tree. Mutates the object.
|
|
71
|
+
*
|
|
55
72
|
* @param {object | Array} obj - The object or array to compact sparse arrays in.
|
|
56
73
|
*/
|
|
57
74
|
export const compactSparseArrays = (obj) => {
|
|
58
75
|
compactSparseArraysRecursive(obj);
|
|
59
76
|
};
|
|
60
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Remove empty objects and undefined values from arrays in a mixed object array tree. Mutates the object.
|
|
80
|
+
*
|
|
81
|
+
* @private
|
|
82
|
+
* @param {object} obj - The object to remove empty objects from and compact sparse arrays in.
|
|
83
|
+
* @returns {void}
|
|
84
|
+
*/
|
|
61
85
|
const removeEmptyObjectsAndCompactSparseArraysRecursive = (obj) => {
|
|
62
86
|
if (typeof obj !== "object" || obj === null) {
|
|
63
87
|
return;
|
|
@@ -85,7 +109,9 @@ const removeEmptyObjectsAndCompactSparseArraysRecursive = (obj) => {
|
|
|
85
109
|
|
|
86
110
|
/**
|
|
87
111
|
* Remove empty objects and undefined values from arrays in a mixed object array tree. Mutates the object.
|
|
112
|
+
*
|
|
88
113
|
* @param {object | Array} obj - The object or array to remove empty objects from and compact sparse arrays in.
|
|
114
|
+
* @returns {void}
|
|
89
115
|
*/
|
|
90
116
|
export const removeEmptyObjectsAndCompactSparseArrays = (obj) => {
|
|
91
117
|
removeEmptyObjectsAndCompactSparseArraysRecursive(obj);
|
package/utils/deleteKey.js
CHANGED
|
@@ -14,6 +14,13 @@ function toKey(value) {
|
|
|
14
14
|
return result == "0" && 1 / value == -(1 / 0) ? "-0" : result;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Split a string into an array of keys.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} string - The string to split.
|
|
21
|
+
* @param {object} object - The object to split keys for.
|
|
22
|
+
* @returns {string[]} Returns the new array of split keys.
|
|
23
|
+
*/
|
|
17
24
|
export function lodashLikePathSplit(string, object) {
|
|
18
25
|
if (isArray(string)) {
|
|
19
26
|
return string;
|
|
@@ -25,14 +32,20 @@ export function lodashLikePathSplit(string, object) {
|
|
|
25
32
|
if (string.charCodeAt(0) === 46 /* . */) {
|
|
26
33
|
result.push("");
|
|
27
34
|
}
|
|
35
|
+
// @ts-ignore - based on lodash-es/_stringToPath
|
|
28
36
|
string.replace(rePropName, function (match, number, quote, subString) {
|
|
29
37
|
result.push(quote ? subString.replace(reEscapeChar, "$1") : number || match);
|
|
30
38
|
});
|
|
31
39
|
return result;
|
|
32
40
|
}
|
|
33
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Delete a key from an object. Lodash-like delete function, as companion for get/set.
|
|
44
|
+
*
|
|
45
|
+
* @param {object} obj - The object to modify.
|
|
46
|
+
* @param {string} path - The key to delete.
|
|
47
|
+
*/
|
|
34
48
|
export function del(obj, path) {
|
|
35
|
-
// lodash-like delete function, as companion for get/set
|
|
36
49
|
if (!obj) {
|
|
37
50
|
return;
|
|
38
51
|
}
|
package/utils/flattenPaths.js
CHANGED
|
@@ -3,22 +3,32 @@ import isObject from "lodash-es/isObject.js";
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Get all paths from an array or object.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* @module utils/flattenPaths.js
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Turn an array or object into an array of path strings. Recurses for any found arrays or objects.
|
|
11
12
|
*
|
|
12
13
|
* Array indexes are wrapped in square brackets and object keys are prefixed with a period.
|
|
13
|
-
*
|
|
14
|
-
* @param {Array | object} arrayOrObject
|
|
15
|
-
* @param {object} options
|
|
16
|
-
* @param {string} options.currentPath
|
|
17
|
-
* @param {number} options.depth
|
|
18
|
-
* @param {number} options.limit
|
|
19
|
-
* @returns {string[]}
|
|
14
|
+
*
|
|
15
|
+
* @param {Array | object} arrayOrObject - Array or object to flatten.
|
|
16
|
+
* @param {object} [options] - Options.
|
|
17
|
+
* @param {string} [options.currentPath=""] - Current path, for recursion or as a starting point.
|
|
18
|
+
* @param {number} [options.depth=0] - Current depth, for recursion.
|
|
19
|
+
* @param {number} [options.limit=0] - Limit the depth of recursion.
|
|
20
|
+
* @returns {string[]} Paths.
|
|
20
21
|
*/
|
|
21
|
-
export function flattenPaths(arrayOrObject, { currentPath
|
|
22
|
+
export function flattenPaths(arrayOrObject, { currentPath, depth, limit } = {}) {
|
|
23
|
+
if (typeof currentPath === "undefined") {
|
|
24
|
+
currentPath = "";
|
|
25
|
+
}
|
|
26
|
+
if (typeof depth === "undefined") {
|
|
27
|
+
depth = 0;
|
|
28
|
+
}
|
|
29
|
+
if (typeof limit === "undefined") {
|
|
30
|
+
limit = 0;
|
|
31
|
+
}
|
|
22
32
|
// arrayOrObject keys or indexes values can be objects or arrays.
|
|
23
33
|
// find all paths you could use lodash to "get()" to.
|
|
24
34
|
// indexes use `[${index}]`, keys use `.${key}`
|
package/utils/getFakeId.js
CHANGED
|
@@ -2,6 +2,16 @@ import isArray from "lodash-es/isArray.js";
|
|
|
2
2
|
import isMap from "lodash-es/isMap.js";
|
|
3
3
|
import isSet from "lodash-es/isSet.js";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Get a fake id that is not in the array, set, map, or object.
|
|
7
|
+
*
|
|
8
|
+
* @param {Array|Set|Map|object} arraySetMapOrObject - The array, set, map, or object to check for the fake id.
|
|
9
|
+
* An array is assumed to be an array of objects.
|
|
10
|
+
* A set is assumed to be a set of ids.
|
|
11
|
+
* A map or object is assumed to be an object with keys that are ids.
|
|
12
|
+
* @param {string} key - The key to check for in the array or object.
|
|
13
|
+
* @returns {string} - The fake id.
|
|
14
|
+
*/
|
|
5
15
|
export function getFakeId(arraySetMapOrObject, key = "id") {
|
|
6
16
|
// sets are assumed to be of ids
|
|
7
17
|
// arrays are assumed to be objects with an property matching the passed key
|
|
@@ -18,5 +28,5 @@ export function getFakeId(arraySetMapOrObject, key = "id") {
|
|
|
18
28
|
do {
|
|
19
29
|
fakeId = Math.floor(Math.random() * Number.MIN_SAFE_INTEGER);
|
|
20
30
|
} while (test());
|
|
21
|
-
return fakeId;
|
|
31
|
+
return fakeId.toString();
|
|
22
32
|
}
|
package/utils/keyDiff.js
CHANGED
|
@@ -4,43 +4,34 @@ import { difference, intersection } from "./set.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Calculate the difference between objects in terms of what keys
|
|
6
6
|
* are the same, what keys are removed, and what keys are added.
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* @module utils/keyDiff.js
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @property {boolean} [sameKeys=true] - if true, return keys that are the same
|
|
14
|
-
* @property {boolean} [removedKeys=true] - if true, return keys that are removed
|
|
15
|
-
* @property {boolean} [addedKeys=true] - if true, return keys that are added
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Result object of keyDiff and keyDiffDeep
|
|
12
|
+
* Result object of keyDiff and keyDiffDeep.
|
|
13
|
+
*
|
|
20
14
|
* @typedef {object} KeyDiffResult
|
|
21
|
-
* @property {Set} [sameKeys] -
|
|
22
|
-
* @property {Set} [removedKeys] -
|
|
23
|
-
* @property {Set} [addedKeys] -
|
|
15
|
+
* @property {Set} [sameKeys] - If sameKeys option is true, return keys that are the same.
|
|
16
|
+
* @property {Set} [removedKeys] - If removedKeys option is true, return keys that are removed.
|
|
17
|
+
* @property {Set} [addedKeys] - If addedKeys option is true, return keys that are added.
|
|
24
18
|
*/
|
|
25
19
|
|
|
26
20
|
/**
|
|
27
21
|
* Calculate the difference between two arrays of keys, in terms of what keys
|
|
28
22
|
* are the same, what keys are removed, and what keys are added.
|
|
29
|
-
*
|
|
30
|
-
* @param {string[]|Set} newKeys -
|
|
31
|
-
* @param {string[]|Set} oldKeys -
|
|
32
|
-
* @param {
|
|
33
|
-
* @
|
|
23
|
+
*
|
|
24
|
+
* @param {string[]|Set} newKeys - Keys to consider as new.
|
|
25
|
+
* @param {string[]|Set} oldKeys - Keys to consider as old.
|
|
26
|
+
* @param {object} [options] - Which differences are returned.
|
|
27
|
+
* @param {boolean} [options.sameKeys=true] - If true, return keys that are the same.
|
|
28
|
+
* @param {boolean} [options.removedKeys=true] - If true, return keys that are removed.
|
|
29
|
+
* @param {boolean} [options.addedKeys=true] - If true, return keys that are added.
|
|
30
|
+
* @returns {KeyDiffResult} - The differences.
|
|
34
31
|
*/
|
|
35
32
|
export function keyDiff(newKeys, oldKeys, { sameKeys = true, removedKeys = true, addedKeys = true } = {}) {
|
|
36
|
-
let newKeysSet = newKeys;
|
|
37
|
-
let oldKeysSet = oldKeys;
|
|
38
|
-
if (!(newKeys instanceof Set)) {
|
|
39
|
-
newKeysSet = new Set(newKeys);
|
|
40
|
-
}
|
|
41
|
-
if (!(oldKeys instanceof Set)) {
|
|
42
|
-
oldKeysSet = new Set(oldKeys);
|
|
43
|
-
}
|
|
33
|
+
let newKeysSet = newKeys instanceof Set ? newKeys : new Set(newKeys);
|
|
34
|
+
let oldKeysSet = oldKeys instanceof Set ? oldKeys : new Set(oldKeys);
|
|
44
35
|
const returnValue = {};
|
|
45
36
|
if (sameKeys) {
|
|
46
37
|
returnValue.sameKeys = intersection(newKeysSet, oldKeysSet);
|
|
@@ -57,15 +48,15 @@ export function keyDiff(newKeys, oldKeys, { sameKeys = true, removedKeys = true,
|
|
|
57
48
|
/**
|
|
58
49
|
* Calculate the difference between two objects, in terms of what keys are the same,
|
|
59
50
|
* what keys are removed, and what keys are added. Keys are sourced deeply in the objects.
|
|
60
|
-
*
|
|
61
|
-
* @param {object} newObj -
|
|
62
|
-
* @param {object} oldObj -
|
|
63
|
-
* @param {
|
|
64
|
-
* @
|
|
65
|
-
* @
|
|
66
|
-
* @
|
|
67
|
-
* @
|
|
68
|
-
* @returns {KeyDiffResult} -
|
|
51
|
+
*
|
|
52
|
+
* @param {object} newObj - The new version of the object.
|
|
53
|
+
* @param {object} oldObj - The old version of the object.
|
|
54
|
+
* @param {object} [options] - Which differences are returned.
|
|
55
|
+
* @property {boolean} [sameKeys=true] - If true, return keys that are the same.
|
|
56
|
+
* @property {boolean} [removedKeys=true] - If true, return keys that are removed.
|
|
57
|
+
* @property {boolean} [addedKeys=true] - If true, return keys that are added.
|
|
58
|
+
* @property {number} [limit] - Limit the depth of recursion.
|
|
59
|
+
* @returns {KeyDiffResult} - The differences.
|
|
69
60
|
*/
|
|
70
61
|
export function keyDiffDeep(newObj, oldObj, options = {}) {
|
|
71
62
|
const additionalFlattenArgs = [];
|
package/utils/loadingCombine.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combine multiple loading states into a single loading state. If any are loading, the combined state is loading.
|
|
3
|
+
* If all are undefined, the combined state is undefined. Otherwise, the combined state is not loading.
|
|
4
|
+
*
|
|
5
|
+
* @param {...(boolean | undefined)} loadingStates - The loading states to combine.
|
|
6
|
+
* @returns {boolean | undefined} The combined loading state.
|
|
7
|
+
*/
|
|
1
8
|
export function loadingCombine(...loadingStates) {
|
|
2
|
-
// loadingStates is an array of booleans or undefined
|
|
3
|
-
// if any true, return true
|
|
4
|
-
// if all undefined, return undefined
|
|
5
|
-
// otherwise return false (all false)
|
|
6
9
|
if (loadingStates.some((loadingState) => loadingState === true)) {
|
|
7
10
|
return true;
|
|
8
11
|
}
|
package/utils/proxyRunning.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { nextTick, toRef, watch } from "vue";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Proxy a parent's running state to a child's running state.
|
|
5
|
+
*
|
|
6
|
+
* @param {import("vue").UnwrapNestedRefs<object>} parentState - The parent state.
|
|
7
|
+
* @param {string} parentStateProp - The parent state property.
|
|
8
|
+
* @param {import("vue").Ref<boolean>} ref - The ref to proxy to.
|
|
9
|
+
*/
|
|
10
|
+
export function proxyRunning(parentState, parentStateProp, ref) {
|
|
11
|
+
// we want you to have been running false for two ticks before we stop you, but we want you to start running
|
|
12
|
+
// true immediately the point of this is to reduce running flicker where the stack has running states awaiting
|
|
13
|
+
// other running states
|
|
6
14
|
let falseTickCount = 0;
|
|
7
15
|
const checkStillFalse = () => {
|
|
8
16
|
if (falseTickCount > 1) {
|
|
9
|
-
|
|
17
|
+
ref.value = false;
|
|
10
18
|
falseTickCount = 0;
|
|
11
19
|
} else if (parentState[parentStateProp] === false) {
|
|
12
20
|
falseTickCount++;
|
|
@@ -16,11 +24,11 @@ export function proxyRunning(parentState, parentStateProp, state, prop) {
|
|
|
16
24
|
}
|
|
17
25
|
};
|
|
18
26
|
watch(toRef(parentState, parentStateProp), (running) => {
|
|
19
|
-
if (running &&
|
|
20
|
-
|
|
21
|
-
} else if (!running &&
|
|
27
|
+
if (running && ref.value !== running) {
|
|
28
|
+
ref.value = running;
|
|
29
|
+
} else if (!running && ref.value !== running) {
|
|
22
30
|
nextTick(checkStillFalse);
|
|
23
31
|
}
|
|
24
32
|
});
|
|
25
|
-
|
|
33
|
+
ref.value = parentState[parentStateProp];
|
|
26
34
|
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export const relatedItemRegex = /^relatedItem\./;
|
|
2
2
|
export const calculatedItemRegex = /^calculatedItem\./;
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Get the object and key of a calculated item.
|
|
6
|
+
*
|
|
7
|
+
* @param {object} obj - The object to get the calculated item from.
|
|
8
|
+
* @param {object} relatedObj - The object to get the related item from.
|
|
9
|
+
* @param {object} calculatedObj - The object to get the calculated item from.
|
|
10
|
+
* @param {string} key - The key to get the calculated item from.
|
|
11
|
+
* @returns {[object, string]} The object and key of the calculated item.
|
|
12
|
+
*/
|
|
4
13
|
export const getObjectRelatedCalculatedByKey = (obj, relatedObj, calculatedObj, key) => {
|
|
5
14
|
let getObj = obj,
|
|
6
15
|
getKey = key.replace(relatedItemRegex, () => {
|
|
@@ -16,6 +25,14 @@ export const getObjectRelatedCalculatedByKey = (obj, relatedObj, calculatedObj,
|
|
|
16
25
|
return [getObj, getKey];
|
|
17
26
|
};
|
|
18
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Get the object and key of a related item.
|
|
30
|
+
*
|
|
31
|
+
* @param {object} obj - The object to get the related item from.
|
|
32
|
+
* @param {object} relatedObj - The object to get the related item from.
|
|
33
|
+
* @param {string} key - The key to get the related item from.
|
|
34
|
+
* @returns {[object, string]} The object and key of the related item.
|
|
35
|
+
*/
|
|
19
36
|
export const getObjectRelatedByKey = (obj, relatedObj, key) => {
|
|
20
37
|
let getObj = obj,
|
|
21
38
|
getKey = key.replace(relatedItemRegex, () => {
|
package/utils/set.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#implementing_basic_set_operations
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Checks if one set is a superset of another set, meaning all elements of the subset are contained within the set.
|
|
5
|
+
*
|
|
6
|
+
* @param {Set} set - The candidate superset.
|
|
7
|
+
* @param {Set} subset - The candidate subset.
|
|
8
|
+
* @returns {boolean} Returns true if the set contains all elements of the subset, otherwise false.
|
|
9
|
+
* @example
|
|
10
|
+
* const a = new Set([1, 2, 3]);
|
|
11
|
+
* const b = new Set([2, 3]);
|
|
12
|
+
* console.log(isSuperset(a, b)); // true
|
|
13
|
+
*/
|
|
3
14
|
export const isSuperset = (set, subset) => {
|
|
4
15
|
for (const elem of subset) {
|
|
5
16
|
if (!set.has(elem)) {
|
|
@@ -9,6 +20,17 @@ export const isSuperset = (set, subset) => {
|
|
|
9
20
|
return true;
|
|
10
21
|
};
|
|
11
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Returns the union of two sets, containing all unique elements from both sets.
|
|
25
|
+
*
|
|
26
|
+
* @param {Set} setA - The first set.
|
|
27
|
+
* @param {Set} setB - The second set.
|
|
28
|
+
* @returns {Set} A new Set containing all elements from both input sets.
|
|
29
|
+
* @example
|
|
30
|
+
* const a = new Set([1, 2, 3]);
|
|
31
|
+
* const b = new Set([3, 4, 5]);
|
|
32
|
+
* console.log(union(a, b)); // Set(1, 2, 3, 4, 5)
|
|
33
|
+
*/
|
|
12
34
|
export const union = (setA, setB) => {
|
|
13
35
|
const _union = new Set(setA);
|
|
14
36
|
for (let elem of setB) {
|
|
@@ -17,6 +39,17 @@ export const union = (setA, setB) => {
|
|
|
17
39
|
return _union;
|
|
18
40
|
};
|
|
19
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Returns the intersection of two sets, containing only elements that are present in both sets.
|
|
44
|
+
*
|
|
45
|
+
* @param {Set} setA - The first set.
|
|
46
|
+
* @param {Set} setB - The second set.
|
|
47
|
+
* @returns {Set} A new Set containing common elements from both input sets.
|
|
48
|
+
* @example
|
|
49
|
+
* const a = new Set([1, 2, 3]);
|
|
50
|
+
* const b = new Set([2, 3, 4]);
|
|
51
|
+
* console.log(intersection(a, b)); // Set(2, 3)
|
|
52
|
+
*/
|
|
20
53
|
export const intersection = (setA, setB) => {
|
|
21
54
|
const _intersection = new Set();
|
|
22
55
|
for (const elem of setB) {
|
|
@@ -27,6 +60,17 @@ export const intersection = (setA, setB) => {
|
|
|
27
60
|
return _intersection;
|
|
28
61
|
};
|
|
29
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Returns the symmetric difference of two sets, containing elements present in only one of the sets.
|
|
65
|
+
*
|
|
66
|
+
* @param {Set} setA - The first set.
|
|
67
|
+
* @param {Set} setB - The second set.
|
|
68
|
+
* @returns {Set} A new Set containing elements that are only in one of the input sets.
|
|
69
|
+
* @example
|
|
70
|
+
* const a = new Set([1, 2, 3]);
|
|
71
|
+
* const b = new Set([3, 4, 5]);
|
|
72
|
+
* console.log(symmetricDifference(a, b)); // Set(1, 2, 4, 5)
|
|
73
|
+
*/
|
|
30
74
|
export const symmetricDifference = (setA, setB) => {
|
|
31
75
|
const _difference = new Set(setA);
|
|
32
76
|
for (const elem of setB) {
|
|
@@ -39,6 +83,17 @@ export const symmetricDifference = (setA, setB) => {
|
|
|
39
83
|
return _difference;
|
|
40
84
|
};
|
|
41
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Returns the difference of two sets, containing elements present only in the first set but not in the second.
|
|
88
|
+
*
|
|
89
|
+
* @param {Set} setA - The first set.
|
|
90
|
+
* @param {Set} setB - The second set.
|
|
91
|
+
* @returns {Set} A new Set containing elements from the first set that are not in the second set.
|
|
92
|
+
* @example
|
|
93
|
+
* const a = new Set([1, 2, 3]);
|
|
94
|
+
* const b = new Set([3, 4]);
|
|
95
|
+
* console.log(difference(a, b)); // Set(1, 2)
|
|
96
|
+
*/
|
|
42
97
|
export const difference = (setA, setB) => {
|
|
43
98
|
const _difference = new Set(setA);
|
|
44
99
|
for (const elem of setB) {
|
|
@@ -47,6 +102,17 @@ export const difference = (setA, setB) => {
|
|
|
47
102
|
return _difference;
|
|
48
103
|
};
|
|
49
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Tests if two sets are equal, meaning they contain exactly the same elements.
|
|
107
|
+
*
|
|
108
|
+
* @param {Set} setA - The first set.
|
|
109
|
+
* @param {Set} setB - The second set.
|
|
110
|
+
* @returns {boolean} Returns true if both sets are equal in size and content, otherwise false.
|
|
111
|
+
* @example
|
|
112
|
+
* const a = new Set([1, 2, 3]);
|
|
113
|
+
* const b = new Set([1, 2, 3]);
|
|
114
|
+
* console.log(equals(a, b)); // true
|
|
115
|
+
*/
|
|
50
116
|
export const equals = (setA, setB) => {
|
|
51
117
|
return setA.size === setB.size && isSuperset(setA, setB);
|
|
52
118
|
};
|
package/utils/transformWalk.js
CHANGED
|
@@ -2,12 +2,18 @@ import isSet from "lodash-es/isSet.js";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Object walking utility.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* @module utils/transformWalk.js
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Recursively walks through an object's values and applies a transformation function to each value.
|
|
10
11
|
* The value recursed into is the transformed value, not the original value.
|
|
12
|
+
*
|
|
13
|
+
* @param {object} obj - The object to start walking from.
|
|
14
|
+
* @param {Function} transformFn - The function to transform each value.
|
|
15
|
+
* @param {string} path - The path to the current value.
|
|
16
|
+
* @returns {object} The transformed object.
|
|
11
17
|
* @example
|
|
12
18
|
*
|
|
13
19
|
* const obj = {
|
|
@@ -31,11 +37,6 @@ import isSet from "lodash-es/isSet.js";
|
|
|
31
37
|
* // d: [3, 4, { e: 10 }]
|
|
32
38
|
* // }
|
|
33
39
|
* // }
|
|
34
|
-
* @function transformWalk
|
|
35
|
-
* @param {*} obj The object to start walking from.
|
|
36
|
-
* @param {Function} transformFn The function to transform each value.
|
|
37
|
-
* @param {string} path The path to the current value.
|
|
38
|
-
* @returns {*} The transformed initial value.
|
|
39
40
|
*/
|
|
40
41
|
export const transformWalk = (obj, transformFn, path = "") => {
|
|
41
42
|
if (typeof obj !== "object" || obj === null || isSet(obj)) {
|