@arrai-innovations/reactive-helpers 20.1.2 → 21.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/README.md +22 -893
- package/config/listCrud.js +30 -27
- package/config/objectCrud.js +20 -13
- package/index.js +5 -3
- package/package.json +5 -3
- package/types/config/commonCrud.d.ts +0 -1
- package/types/config/listCrud.d.ts +28 -41
- package/types/config/objectCrud.d.ts +14 -29
- package/types/index.d.ts +5 -4
- package/types/tests/unit/config/listCrud.spec.d.ts +0 -1
- package/types/tests/unit/config/objectCrud.spec.d.ts +0 -1
- package/types/tests/unit/crudPromise.d.ts +42 -15
- package/types/tests/unit/mockOnUnmounted.d.ts +0 -1
- package/types/tests/unit/poll.d.ts +0 -1
- package/types/tests/unit/scopedIt.d.ts +15 -0
- package/types/tests/unit/setup.d.ts +2 -0
- package/types/tests/unit/use/cancellableIntent.spec.d.ts +0 -1
- package/types/tests/unit/use/combineClasses.spec.d.ts +1 -0
- package/types/tests/unit/use/list.spec.d.ts +1 -0
- package/types/tests/unit/use/listCalculated.spec.d.ts +0 -1
- package/types/tests/unit/use/listFilter.spec.d.ts +0 -1
- package/types/tests/unit/use/listInstance.spec.d.ts +0 -1
- package/types/tests/unit/use/listRelated.spec.d.ts +0 -1
- package/types/tests/unit/use/listSearch.spec.d.ts +0 -1
- package/types/tests/unit/use/listSort.spec.d.ts +0 -1
- package/types/tests/unit/use/listSubscription.spec.d.ts +0 -1
- package/types/tests/unit/use/loadingError.spec.d.ts +0 -1
- package/types/tests/unit/use/object.spec.d.ts +1 -0
- package/types/tests/unit/use/objectCalculated.spec.d.ts +1 -0
- package/types/tests/unit/use/objectInstance.spec.d.ts +0 -1
- package/types/tests/unit/use/objectRelated.spec.d.ts +1 -0
- package/types/tests/unit/use/objectSubscription.spec.d.ts +0 -1
- package/types/tests/unit/use/proxyLoadingError.spec.d.ts +0 -1
- package/types/tests/unit/use/search.error.spec.d.ts +1 -0
- package/types/tests/unit/use/search.spec.d.ts +0 -1
- package/types/tests/unit/utils/assignReactiveObject.extra.spec.d.ts +1 -0
- package/types/tests/unit/utils/assignReactiveObject.refs.spec.d.ts +1 -0
- package/types/tests/unit/utils/assignReactiveObject.spec.d.ts +0 -1
- package/types/tests/unit/utils/cancellableFetch.spec.d.ts +1 -0
- package/types/tests/unit/utils/classes.spec.d.ts +0 -1
- package/types/tests/unit/utils/compact.spec.d.ts +1 -0
- package/types/tests/unit/utils/deepUnref.spec.d.ts +1 -0
- package/types/tests/unit/utils/deleteKey.spec.d.ts +0 -1
- package/types/tests/unit/utils/flattenPaths.spec.d.ts +0 -1
- package/types/tests/unit/utils/flattenPathsWithValues.spec.d.ts +1 -0
- package/types/tests/unit/utils/getFakePk.spec.d.ts +1 -0
- package/types/tests/unit/utils/keepAliveTry.spec.d.ts +1 -0
- package/types/tests/unit/utils/keyDiff.spec.d.ts +0 -1
- package/types/tests/unit/utils/set.spec.d.ts +0 -1
- package/types/tests/unit/utils/transformWalk.spec.d.ts +1 -0
- package/types/tests/unit/utils/unwrapNested.spec.d.ts +1 -0
- package/types/tests/unit/utils/watches.spec.d.ts +0 -1
- package/types/use/cancellableIntent.d.ts +121 -48
- package/types/use/combineClasses.d.ts +0 -1
- package/types/use/error.d.ts +48 -0
- package/types/use/list.d.ts +9 -32
- package/types/use/listCalculated.d.ts +107 -49
- package/types/use/listFilter.d.ts +13 -31
- package/types/use/listInstance.d.ts +137 -71
- package/types/use/listRelated.d.ts +106 -43
- package/types/use/listSearch.d.ts +24 -12
- package/types/use/listSort.d.ts +3 -34
- package/types/use/listSubscription.d.ts +40 -57
- package/types/use/loading.d.ts +37 -0
- package/types/use/loadingError.d.ts +5 -100
- package/types/use/object.d.ts +3 -12
- package/types/use/objectCalculated.d.ts +3 -9
- package/types/use/objectInstance.d.ts +59 -47
- package/types/use/objectRelated.d.ts +3 -9
- package/types/use/objectSubscription.d.ts +33 -51
- package/types/use/proxyError.d.ts +27 -0
- package/types/use/proxyLoading.d.ts +15 -0
- package/types/use/proxyLoadingError.d.ts +8 -16
- package/types/use/search.d.ts +2 -3
- package/types/utils/assignReactiveObject.d.ts +0 -1
- package/types/utils/cancellableFetch.d.ts +0 -1
- package/types/utils/cancellablePromise.d.ts +0 -1
- package/types/utils/classes.d.ts +2 -8
- package/types/utils/compact.d.ts +0 -1
- package/types/utils/deepUnref.d.ts +2 -23
- package/types/utils/deleteKey.d.ts +6 -6
- package/types/utils/flattenPaths.d.ts +0 -1
- package/types/utils/flattenPathsWithValues.d.ts +29 -0
- package/types/utils/getFakePk.d.ts +0 -1
- package/types/utils/keepAliveTry.d.ts +0 -1
- package/types/utils/keyDiff.d.ts +9 -10
- package/types/utils/loadingCombine.d.ts +0 -1
- package/types/utils/proxyRunning.d.ts +2 -3
- package/types/utils/refIfReactive.d.ts +0 -1
- package/types/utils/relatedCalculatedHelpers.d.ts +0 -1
- package/types/utils/set.d.ts +0 -1
- package/types/utils/transformWalk.d.ts +0 -1
- package/types/utils/unwrapNested.d.ts +0 -1
- package/types/utils/watches.d.ts +0 -1
- package/use/cancellableIntent.js +185 -100
- package/use/error.js +44 -0
- package/use/list.js +51 -111
- package/use/listCalculated.js +75 -98
- package/use/listFilter.js +91 -186
- package/use/listInstance.js +357 -282
- package/use/listRelated.js +52 -72
- package/use/listSearch.js +49 -86
- package/use/listSort.js +121 -237
- package/use/listSubscription.js +181 -274
- package/use/loading.js +35 -0
- package/use/loadingError.js +7 -81
- package/use/object.js +47 -67
- package/use/objectCalculated.js +103 -65
- package/use/objectInstance.js +253 -241
- package/use/objectRelated.js +48 -30
- package/use/objectSubscription.js +110 -175
- package/use/proxyError.js +48 -0
- package/use/proxyLoading.js +22 -0
- package/use/proxyLoadingError.js +9 -35
- package/use/search.js +4 -2
- package/utils/assignReactiveObject.js +8 -8
- package/utils/classes.js +7 -28
- package/utils/deepUnref.js +15 -2
- package/utils/deleteKey.js +13 -5
- package/utils/flattenPathsWithValues.js +65 -0
- package/utils/keyDiff.js +5 -5
- package/utils/proxyRunning.js +16 -10
- package/types/config/commonCrud.d.ts.map +0 -1
- package/types/config/listCrud.d.ts.map +0 -1
- package/types/config/objectCrud.d.ts.map +0 -1
- package/types/index.d.ts.map +0 -1
- package/types/tests/unit/config/listCrud.spec.d.ts.map +0 -1
- package/types/tests/unit/config/objectCrud.spec.d.ts.map +0 -1
- package/types/tests/unit/crudPromise.d.ts.map +0 -1
- package/types/tests/unit/expectHelpers.d.ts +0 -2
- package/types/tests/unit/expectHelpers.d.ts.map +0 -1
- package/types/tests/unit/mockOnUnmounted.d.ts.map +0 -1
- package/types/tests/unit/poll.d.ts.map +0 -1
- package/types/tests/unit/use/cancellableIntent.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listCalculated.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listFilter.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listInstance.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listRelated.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listSearch.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listSort.spec.d.ts.map +0 -1
- package/types/tests/unit/use/listSubscription.spec.d.ts.map +0 -1
- package/types/tests/unit/use/loadingError.spec.d.ts.map +0 -1
- package/types/tests/unit/use/objectInstance.spec.d.ts.map +0 -1
- package/types/tests/unit/use/objectSubscription.spec.d.ts.map +0 -1
- package/types/tests/unit/use/proxyLoadingError.spec.d.ts.map +0 -1
- package/types/tests/unit/use/search.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/assignReactiveObject.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/classes.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/deleteKey.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/flattenPaths.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/keyDiff.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/set.spec.d.ts.map +0 -1
- package/types/tests/unit/utils/watches.spec.d.ts.map +0 -1
- package/types/use/cancellableIntent.d.ts.map +0 -1
- package/types/use/combineClasses.d.ts.map +0 -1
- package/types/use/list.d.ts.map +0 -1
- package/types/use/listCalculated.d.ts.map +0 -1
- package/types/use/listFilter.d.ts.map +0 -1
- package/types/use/listInstance.d.ts.map +0 -1
- package/types/use/listKeys.d.ts +0 -15
- package/types/use/listKeys.d.ts.map +0 -1
- package/types/use/listRelated.d.ts.map +0 -1
- package/types/use/listSearch.d.ts.map +0 -1
- package/types/use/listSort.d.ts.map +0 -1
- package/types/use/listSubscription.d.ts.map +0 -1
- package/types/use/loadingError.d.ts.map +0 -1
- package/types/use/object.d.ts.map +0 -1
- package/types/use/objectCalculated.d.ts.map +0 -1
- package/types/use/objectInstance.d.ts.map +0 -1
- package/types/use/objectRelated.d.ts.map +0 -1
- package/types/use/objectSubscription.d.ts.map +0 -1
- package/types/use/paginatedListInstance.d.ts +0 -60
- package/types/use/paginatedListInstance.d.ts.map +0 -1
- package/types/use/proxyLoadingError.d.ts.map +0 -1
- package/types/use/search.d.ts.map +0 -1
- package/types/use/watchesRunning.d.ts +0 -63
- package/types/use/watchesRunning.d.ts.map +0 -1
- package/types/utils/assignReactiveObject.d.ts.map +0 -1
- package/types/utils/cancellableFetch.d.ts.map +0 -1
- package/types/utils/cancellablePromise.d.ts.map +0 -1
- package/types/utils/classes.d.ts.map +0 -1
- package/types/utils/compact.d.ts.map +0 -1
- package/types/utils/deepUnref.d.ts.map +0 -1
- package/types/utils/deleteKey.d.ts.map +0 -1
- package/types/utils/flattenPaths.d.ts.map +0 -1
- package/types/utils/getFakePk.d.ts.map +0 -1
- package/types/utils/keepAliveTry.d.ts.map +0 -1
- package/types/utils/keyDiff.d.ts.map +0 -1
- package/types/utils/loadingCombine.d.ts.map +0 -1
- package/types/utils/proxyRunning.d.ts.map +0 -1
- package/types/utils/refIfReactive.d.ts.map +0 -1
- package/types/utils/relatedCalculatedHelpers.d.ts.map +0 -1
- package/types/utils/set.d.ts.map +0 -1
- package/types/utils/transformWalk.d.ts.map +0 -1
- package/types/utils/unwrapNested.d.ts.map +0 -1
- package/types/utils/watches.d.ts.map +0 -1
- package/use/listKeys.js +0 -105
- package/use/paginatedListInstance.js +0 -126
- package/use/watchesRunning.js +0 -69
package/use/list.js
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import { useListCalculated } from "./listCalculated.js";
|
|
2
2
|
import { useListFilter } from "./listFilter.js";
|
|
3
3
|
import { useListInstance } from "./listInstance.js";
|
|
4
|
-
import {
|
|
5
|
-
listSortFunctions,
|
|
6
|
-
listFilterFunctions,
|
|
7
|
-
listRelatedFunctions,
|
|
8
|
-
listCalculatedFunctions,
|
|
9
|
-
listSubscriptionFunctions,
|
|
10
|
-
listInstanceFunctions,
|
|
11
|
-
listSearchFunctions,
|
|
12
|
-
} from "./listKeys.js";
|
|
13
4
|
import { useListRelated } from "./listRelated.js";
|
|
14
5
|
import { useListSearch } from "./listSearch.js";
|
|
15
6
|
import { useListSort } from "./listSort.js";
|
|
16
7
|
import { useListSubscription } from "./listSubscription.js";
|
|
17
|
-
import {
|
|
18
|
-
import { effectScope, reactive, shallowReactive, shallowReadonly, toRef } from "vue";
|
|
8
|
+
import { effectScope, shallowReactive, shallowReadonly, toRef } from "vue";
|
|
19
9
|
|
|
20
10
|
/**
|
|
21
11
|
* Provides a comprehensive Vue 3 composable function for managing a list of objects. This module orchestrates several
|
|
@@ -66,45 +56,17 @@ export class ListError extends Error {
|
|
|
66
56
|
/**
|
|
67
57
|
* @typedef {object} ListOptions
|
|
68
58
|
* @property {ListRawProps} props - The properties for configuring the list.
|
|
69
|
-
* @property {import('../config/listCrud.js').ListCrudHandlers} handlers - Additional handlers to be included in the list manager.
|
|
70
|
-
* @property {
|
|
71
|
-
* @property {
|
|
72
|
-
* @property {boolean}
|
|
73
|
-
* @property {number} searchThrottle - The throttle time for text search.
|
|
74
|
-
* @property {number} sortThrottleWait - The throttle time for sorting.
|
|
75
|
-
* @property {boolean} searchShowAllWhenEmpty - Indicates whether all items should be shown when the search query is empty.
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Represents the combined state definitions for all list-related components.
|
|
80
|
-
* This interface aggregates the raw state from multiple list management functionalities.
|
|
81
|
-
*
|
|
82
|
-
* @typedef {(
|
|
83
|
-
* (
|
|
84
|
-
* import('./listInstance.js').ListInstanceRawState |
|
|
85
|
-
* import('./paginatedListInstance.js').PagedListInstanceRawState
|
|
86
|
-
* ) &
|
|
87
|
-
* import('./listSubscription.js').ListSubscriptionRawState &
|
|
88
|
-
* import('./listRelated.js').ListRelatedRawState &
|
|
89
|
-
* import('./listCalculated.js').ListCalculatedRawState &
|
|
90
|
-
* import('./listFilter.js').ListFilterRawState &
|
|
91
|
-
* import('./listSearch.js').ListSearchRawState &
|
|
92
|
-
* import('./listSort.js').ListSortRawState
|
|
93
|
-
* )} ListRawState
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Represents the reactive state derived from aggregating states of various list-related components.
|
|
98
|
-
* This state is typically used within Vue components for reactivity and access to updated list properties.
|
|
99
|
-
*
|
|
100
|
-
* @typedef {import('vue').UnwrapNestedRefs<ListRawState>} ListState
|
|
59
|
+
* @property {import('../config/listCrud.js').ListCrudHandlers} [handlers] - Additional handlers to be included in the list manager.
|
|
60
|
+
* @property {number} [searchThrottle] - The throttle time for text search.
|
|
61
|
+
* @property {number} [sortThrottleWait] - The throttle time for sorting.
|
|
62
|
+
* @property {boolean} [searchShowAllWhenEmpty] - Indicates whether all items should be shown when the search query is empty.
|
|
101
63
|
*/
|
|
102
64
|
|
|
103
65
|
/**
|
|
104
66
|
* Holds references to instances of all list-related composables, facilitating direct access and management.
|
|
105
67
|
*
|
|
106
68
|
* @typedef {{
|
|
107
|
-
* listInstance: import('./listInstance.js').ListInstance
|
|
69
|
+
* listInstance: import('./listInstance.js').ListInstance,
|
|
108
70
|
* listSubscription: import('./listSubscription.js').ListSubscription,
|
|
109
71
|
* listRelated: import('./listRelated.js').ListRelated,
|
|
110
72
|
* listCalculated: import('./listCalculated.js').ListCalculated,
|
|
@@ -123,20 +85,14 @@ export class ListError extends Error {
|
|
|
123
85
|
* )} ListFunctions
|
|
124
86
|
*/
|
|
125
87
|
|
|
126
|
-
// & import('./listRelated.js').ListRelatedFunctions
|
|
127
|
-
// & import('./listCalculated.js').ListCalculatedFunctions
|
|
128
|
-
// & import('./listFilter.js').ListFilterFunctions
|
|
129
|
-
// & import('./listSearch.js').ListSearchFunctions
|
|
130
|
-
// & import('./listSort.js').ListSortFunctions
|
|
131
|
-
|
|
132
88
|
/**
|
|
133
89
|
* Encapsulates properties relevant to the overall management of list-related hooks, including state, direct access to hooks,
|
|
134
90
|
* and scoped effects.
|
|
135
91
|
*
|
|
136
92
|
* @typedef {object} ListManagerProperties
|
|
137
93
|
* @property {ListManaged} managed - A readonly reference to the managed list hooks.
|
|
138
|
-
* @property {
|
|
139
|
-
* @property {
|
|
94
|
+
* @property {import('./listSort.js').ListSortState} state - Represents the final reactive state in the list processing chain.
|
|
95
|
+
* @property {() => void} stop - A function to stop the effect scope and clean up resources.
|
|
140
96
|
*/
|
|
141
97
|
|
|
142
98
|
/**
|
|
@@ -146,6 +102,31 @@ export class ListError extends Error {
|
|
|
146
102
|
* @typedef {ListFunctions & ListManagerProperties} ListManager
|
|
147
103
|
*/
|
|
148
104
|
|
|
105
|
+
/* eslint-disable jsdoc/valid-types */
|
|
106
|
+
/**
|
|
107
|
+
* Extract function properties from a source object, excluding `stop`.
|
|
108
|
+
*
|
|
109
|
+
* @template {object} T
|
|
110
|
+
* @param {T} source - The source object from which to extract function properties.
|
|
111
|
+
* @returns {{
|
|
112
|
+
* [K in keyof T as K extends "stop" ? never : T[K] extends (...args: any[]) => any ? K : never]: T[K]
|
|
113
|
+
* }} - An object containing only the function properties of the source object, excluding `stop`.
|
|
114
|
+
*/
|
|
115
|
+
function mergeFns(source) {
|
|
116
|
+
const returnedFns = {};
|
|
117
|
+
for (const key of Object.keys(source)) {
|
|
118
|
+
if (key !== "stop") {
|
|
119
|
+
const val = source[key];
|
|
120
|
+
if (typeof val === "function") {
|
|
121
|
+
returnedFns[key] = val;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
return returnedFns;
|
|
127
|
+
}
|
|
128
|
+
/* eslint-enable jsdoc/valid-types */
|
|
129
|
+
|
|
149
130
|
/**
|
|
150
131
|
* Initializes multiple list management instances with provided configurations.
|
|
151
132
|
*
|
|
@@ -177,16 +158,8 @@ export const useLists = (listOptions) => {
|
|
|
177
158
|
* @returns {ListManager} - The managed stack of list-related composable functions.
|
|
178
159
|
* @throws {ListError} - If required options are not provided.
|
|
179
160
|
*/
|
|
180
|
-
export const useList = ({
|
|
181
|
-
|
|
182
|
-
handlers = {},
|
|
183
|
-
paged,
|
|
184
|
-
keepOldPages,
|
|
185
|
-
clearListOnListIntentTriggered,
|
|
186
|
-
searchThrottle = 500,
|
|
187
|
-
sortThrottleWait,
|
|
188
|
-
searchShowAllWhenEmpty,
|
|
189
|
-
}) => {
|
|
161
|
+
export const useList = ({ props, handlers = {}, searchThrottle = 500, sortThrottleWait, searchShowAllWhenEmpty }) => {
|
|
162
|
+
/** @type {ListManaged} */
|
|
190
163
|
const managed = shallowReactive({
|
|
191
164
|
listInstance: null,
|
|
192
165
|
listSubscription: null,
|
|
@@ -196,12 +169,6 @@ export const useList = ({
|
|
|
196
169
|
listSearch: null,
|
|
197
170
|
listSort: null,
|
|
198
171
|
});
|
|
199
|
-
if (paged === undefined || keepOldPages === undefined || clearListOnListIntentTriggered === undefined) {
|
|
200
|
-
throw new ListError(
|
|
201
|
-
"useList requires paged, keepOldPages, and clearListOnListIntentTriggered to be all set.",
|
|
202
|
-
"missing-arguments"
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
172
|
|
|
206
173
|
if (!("params" in props)) {
|
|
207
174
|
console.error("params not set, must be true for intendToList or intendToSubscribe to work.");
|
|
@@ -210,18 +177,15 @@ export const useList = ({
|
|
|
210
177
|
const es = effectScope();
|
|
211
178
|
|
|
212
179
|
es.run(() => {
|
|
213
|
-
managed.listInstance =
|
|
180
|
+
managed.listInstance = useListInstance({
|
|
214
181
|
props,
|
|
215
182
|
handlers,
|
|
216
|
-
keepOldPages,
|
|
217
183
|
});
|
|
218
184
|
|
|
219
185
|
managed.listSubscription = useListSubscription({
|
|
220
186
|
listInstance: managed.listInstance,
|
|
221
|
-
|
|
187
|
+
props,
|
|
222
188
|
});
|
|
223
|
-
managed.listSubscription.state.intendToList = toRef(props, "intendToList");
|
|
224
|
-
managed.listSubscription.state.intendToSubscribe = toRef(props, "intendToSubscribe");
|
|
225
189
|
|
|
226
190
|
managed.listRelated = useListRelated({
|
|
227
191
|
parentState: managed.listSubscription.state,
|
|
@@ -241,12 +205,7 @@ export const useList = ({
|
|
|
241
205
|
|
|
242
206
|
managed.listSearch = useListSearch({
|
|
243
207
|
parentState: managed.listFilter.state,
|
|
244
|
-
props
|
|
245
|
-
textSearchRules: toRef(props, "textSearchRules"),
|
|
246
|
-
textSearchValue: toRef(props, "textSearchValue"),
|
|
247
|
-
customDocumentOptions: toRef(props, "customDocumentOptions"),
|
|
248
|
-
customSearchOptions: toRef(props, "customSearchOptions"),
|
|
249
|
-
}),
|
|
208
|
+
props,
|
|
250
209
|
throttle: searchThrottle,
|
|
251
210
|
showAllWhenEmpty: searchShowAllWhenEmpty,
|
|
252
211
|
});
|
|
@@ -258,40 +217,21 @@ export const useList = ({
|
|
|
258
217
|
});
|
|
259
218
|
});
|
|
260
219
|
|
|
261
|
-
|
|
262
|
-
managed.listSubscription.clearError();
|
|
263
|
-
managed.listInstance.clearError();
|
|
264
|
-
};
|
|
265
|
-
|
|
220
|
+
// noinspection UnnecessaryLocalVariableJS
|
|
266
221
|
/** @type {ListManager} */
|
|
267
|
-
|
|
268
|
-
const returnObject = {
|
|
269
|
-
// we manage the keys on both of these, so hands off the root.
|
|
222
|
+
const manager = {
|
|
270
223
|
managed: shallowReadonly(managed),
|
|
271
224
|
state: managed.listSort.state,
|
|
272
|
-
|
|
225
|
+
stop: () => {
|
|
226
|
+
es.stop();
|
|
227
|
+
},
|
|
228
|
+
...mergeFns(managed.listInstance),
|
|
229
|
+
...mergeFns(managed.listSubscription),
|
|
230
|
+
...mergeFns(managed.listRelated),
|
|
231
|
+
...mergeFns(managed.listCalculated),
|
|
232
|
+
...mergeFns(managed.listFilter),
|
|
233
|
+
...mergeFns(managed.listSearch),
|
|
234
|
+
...mergeFns(managed.listSort),
|
|
273
235
|
};
|
|
274
|
-
|
|
275
|
-
clearError,
|
|
276
|
-
};
|
|
277
|
-
for (const [source, fnNames] of [
|
|
278
|
-
[managed.listInstance, listInstanceFunctions],
|
|
279
|
-
[managed.listSubscription, listSubscriptionFunctions],
|
|
280
|
-
[managed.listRelated, listRelatedFunctions],
|
|
281
|
-
[managed.listCalculated, listCalculatedFunctions],
|
|
282
|
-
[managed.listFilter, listFilterFunctions],
|
|
283
|
-
[managed.listSearch, listSearchFunctions],
|
|
284
|
-
[managed.listSort, listSortFunctions],
|
|
285
|
-
]) {
|
|
286
|
-
for (const fnName of fnNames) {
|
|
287
|
-
if (handledDuplicateFunctions[fnName]) {
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
returnObject[fnName] = source[fnName];
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
for (const [fnName, fn] of Object.entries(handledDuplicateFunctions)) {
|
|
294
|
-
returnObject[fnName] = fn;
|
|
295
|
-
}
|
|
296
|
-
return returnObject;
|
|
236
|
+
return manager;
|
|
297
237
|
};
|
package/use/listCalculated.js
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
import { difference } from "../utils/set.js";
|
|
2
1
|
import { keyDiff } from "../utils/keyDiff.js";
|
|
3
2
|
import { loadingCombine } from "../utils/loadingCombine.js";
|
|
4
3
|
import { proxyRunning } from "../utils/proxyRunning.js";
|
|
5
|
-
import {
|
|
6
|
-
listCalculatedStateKeys,
|
|
7
|
-
listFilterStateKeys,
|
|
8
|
-
listInstanceStateKeys,
|
|
9
|
-
listRelatedStateKeys,
|
|
10
|
-
listSearchStateKeys,
|
|
11
|
-
listSortStateKeys,
|
|
12
|
-
listSubscriptionStateKeys,
|
|
13
|
-
} from "./listKeys.js";
|
|
14
|
-
import { useWatchesRunning } from "./watchesRunning.js";
|
|
15
4
|
import isEmpty from "lodash-es/isEmpty.js";
|
|
16
|
-
import { computed, effectScope,
|
|
5
|
+
import { computed, effectScope, nextTick, reactive, ref, toRef, toRefs, unref, watch } from "vue";
|
|
17
6
|
|
|
18
7
|
/**
|
|
19
8
|
* This module provides a Vue Composition API composable function for dynamically calculating properties in lists
|
|
@@ -29,9 +18,9 @@ import { computed, effectScope, onScopeDispose, reactive, ref, toRef, unref, wat
|
|
|
29
18
|
* object from the list, optionally its related objects, and previously calculated properties to compute a new
|
|
30
19
|
* property. These functions are reactive and re-evaluate when underlying dependencies change.
|
|
31
20
|
*
|
|
32
|
-
* @typedef {
|
|
21
|
+
* @typedef {{
|
|
33
22
|
* [rule: string]: (
|
|
34
|
-
* object: import('
|
|
23
|
+
* object: import('../use/objectInstance.js').ExistingCrudObject,
|
|
35
24
|
* relatedObject: {
|
|
36
25
|
* [rule: string]: any,
|
|
37
26
|
* },
|
|
@@ -39,8 +28,7 @@ import { computed, effectScope, onScopeDispose, reactive, ref, toRef, unref, wat
|
|
|
39
28
|
* [rule: string]: import('vue').ComputedRef<any>,
|
|
40
29
|
* }
|
|
41
30
|
* ) => any,
|
|
42
|
-
* }
|
|
43
|
-
*
|
|
31
|
+
* }} ListCalculatedRules
|
|
44
32
|
*/
|
|
45
33
|
|
|
46
34
|
/**
|
|
@@ -51,8 +39,8 @@ import { computed, effectScope, onScopeDispose, reactive, ref, toRef, unref, wat
|
|
|
51
39
|
* @property {ListCalculatedRules} calculatedObjectsRules - The rules for the calculated objects.
|
|
52
40
|
* @property {boolean} calculatedObjectsParentStateObjectsWatchRunning - Whether the parent state objects watch is running.
|
|
53
41
|
* @property {boolean} calculatedObjectsWatchRunning - Whether the calculated objects watch is running.
|
|
54
|
-
* @property {boolean} calculatedRunning - Whether the calculated properties are running.
|
|
55
|
-
* @property {import('vue').
|
|
42
|
+
* @property {import('vue').ComputedRef<boolean>} calculatedRunning - Whether the calculated properties are running.
|
|
43
|
+
* @property {import('vue').ComputedRef<boolean>} running - Whether the list is running.
|
|
56
44
|
* @private
|
|
57
45
|
*/
|
|
58
46
|
|
|
@@ -86,24 +74,12 @@ import { computed, effectScope, onScopeDispose, reactive, ref, toRef, unref, wat
|
|
|
86
74
|
* )>} ListCalculatedParentState
|
|
87
75
|
*/
|
|
88
76
|
|
|
89
|
-
const parentStateKeys = difference(
|
|
90
|
-
new Set([
|
|
91
|
-
...listInstanceStateKeys,
|
|
92
|
-
...listSubscriptionStateKeys,
|
|
93
|
-
...listRelatedStateKeys,
|
|
94
|
-
...listFilterStateKeys,
|
|
95
|
-
...listSortStateKeys,
|
|
96
|
-
...listSearchStateKeys,
|
|
97
|
-
]),
|
|
98
|
-
new Set(listCalculatedStateKeys)
|
|
99
|
-
);
|
|
100
|
-
|
|
101
77
|
/**
|
|
102
78
|
* The options to create a list calculated composition function.
|
|
103
79
|
*
|
|
104
80
|
* @typedef {object} ListCalculatedOptions - Options to configure the behavior of the list calculated properties.
|
|
105
81
|
* @property {ListCalculatedParentState} parentState - The parent state that interacts with the calculated objects.
|
|
106
|
-
* @property {ListCalculatedRules} calculatedObjectsRules - A reactive reference to rules used for dynamic calculations
|
|
82
|
+
* @property {import('vue').Ref<ListCalculatedRules>} calculatedObjectsRules - A reactive reference to rules used for dynamic calculations
|
|
107
83
|
* within list objects. Proper setup of this reference ensures that updates are managed reactively, including deep
|
|
108
84
|
* property changes.
|
|
109
85
|
*/
|
|
@@ -114,8 +90,7 @@ const parentStateKeys = difference(
|
|
|
114
90
|
* @typedef {object} ListCalculatedProperties
|
|
115
91
|
* @property {ListCalculatedState} state - The state for the list calculated property.
|
|
116
92
|
* @property {ListCalculatedParentState} parentState - The parent state object.
|
|
117
|
-
* @property {
|
|
118
|
-
* @property {import('vue').EffectScope} effectScope - The effect scope for the list calculated property.
|
|
93
|
+
* @property {() => void} stop - Stops composition's effects and cleans up resources.
|
|
119
94
|
*/
|
|
120
95
|
|
|
121
96
|
// if we provided functions, we would add a typedef and mix them into ListCalculated
|
|
@@ -199,13 +174,22 @@ export function useListCalculateds(listCalculatedArgs) {
|
|
|
199
174
|
* list, facilitating real-time updates and complex dependency management across multiple components.
|
|
200
175
|
*/
|
|
201
176
|
export function useListCalculated({ parentState, calculatedObjectsRules }) {
|
|
177
|
+
const es = effectScope();
|
|
178
|
+
const parentRefs = toRefs(parentState);
|
|
179
|
+
/** @type {import('vue').Ref<boolean|undefined>} */
|
|
180
|
+
const parentRunning = ref(undefined);
|
|
181
|
+
proxyRunning(parentState, "running", parentRunning);
|
|
202
182
|
/** @type {ListCalculatedState} */
|
|
203
|
-
// @ts-ignore - The rest of the properties are added in the effect scope.
|
|
204
183
|
const state = reactive({
|
|
184
|
+
...parentRefs,
|
|
205
185
|
calculatedObjectsRules,
|
|
206
186
|
calculatedObjects: {},
|
|
207
|
-
calculatedObjectsParentStateObjectsWatchRunning:
|
|
208
|
-
calculatedObjectsWatchRunning:
|
|
187
|
+
calculatedObjectsParentStateObjectsWatchRunning: true,
|
|
188
|
+
calculatedObjectsWatchRunning: true,
|
|
189
|
+
calculatedRunning: computed(() =>
|
|
190
|
+
loadingCombine(state.calculatedObjectsParentStateObjectsWatchRunning, state.calculatedObjectsWatchRunning)
|
|
191
|
+
),
|
|
192
|
+
running: computed(() => loadingCombine(state.calculatedRunning, parentRunning.value)),
|
|
209
193
|
});
|
|
210
194
|
const calculatedObjectsEffectScopes = {};
|
|
211
195
|
|
|
@@ -217,14 +201,16 @@ export function useListCalculated({ parentState, calculatedObjectsRules }) {
|
|
|
217
201
|
for (const removedKey of removedKeys) {
|
|
218
202
|
delete state.calculatedObjects[removedKey];
|
|
219
203
|
if (calculatedObjectsEffectScopes[removedKey]) {
|
|
220
|
-
calculatedObjectsEffectScopes[removedKey].stop();
|
|
204
|
+
calculatedObjectsEffectScopes[removedKey].objectScope.stop();
|
|
221
205
|
delete calculatedObjectsEffectScopes[removedKey];
|
|
222
206
|
}
|
|
223
207
|
}
|
|
224
208
|
for (const addedKey of addedKeys) {
|
|
225
209
|
state.calculatedObjects[addedKey] = {};
|
|
226
210
|
}
|
|
227
|
-
|
|
211
|
+
nextTick(() => {
|
|
212
|
+
state.calculatedObjectsParentStateObjectsWatchRunning = false;
|
|
213
|
+
});
|
|
228
214
|
}
|
|
229
215
|
|
|
230
216
|
function calculatedObjectsWatch() {
|
|
@@ -248,84 +234,75 @@ export function useListCalculated({ parentState, calculatedObjectsRules }) {
|
|
|
248
234
|
addedRuleKeys = [];
|
|
249
235
|
}
|
|
250
236
|
for (const removedRuleKey of removedRuleKeys) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
237
|
+
if (calculatedObjectsEffectScopes[objectKey]?.ruleScopes?.[removedRuleKey]) {
|
|
238
|
+
calculatedObjectsEffectScopes[objectKey].ruleScopes[removedRuleKey].stop();
|
|
239
|
+
delete calculatedObjectsEffectScopes[objectKey].ruleScopes[removedRuleKey];
|
|
240
|
+
}
|
|
254
241
|
}
|
|
255
242
|
if (!calculatedObjectsEffectScopes[objectKey]) {
|
|
256
|
-
calculatedObjectsEffectScopes[objectKey] =
|
|
243
|
+
calculatedObjectsEffectScopes[objectKey] = {
|
|
244
|
+
objectScope: es.run(() => effectScope()),
|
|
245
|
+
ruleScopes: {},
|
|
246
|
+
};
|
|
257
247
|
}
|
|
258
248
|
const originalObjectRef = toRef(parentState.objects, objectKey);
|
|
259
249
|
const relatedObjectRef = parentState.relatedObjects
|
|
260
250
|
? toRef(parentState.relatedObjects, objectKey)
|
|
261
251
|
: ref(undefined);
|
|
262
|
-
calculatedObjectsEffectScopes[objectKey].run(() => {
|
|
252
|
+
calculatedObjectsEffectScopes[objectKey].objectScope.run(() => {
|
|
263
253
|
for (const addedRuleKey of addedRuleKeys) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
254
|
+
const addedRuleScope = effectScope();
|
|
255
|
+
calculatedObjectsObject[addedRuleKey] = addedRuleScope.run(() =>
|
|
256
|
+
computed(() =>
|
|
257
|
+
state.calculatedObjectsRules?.[addedRuleKey]?.(
|
|
258
|
+
unref(originalObjectRef),
|
|
259
|
+
unref(relatedObjectRef),
|
|
260
|
+
calculatedObjectsObject
|
|
261
|
+
)
|
|
269
262
|
)
|
|
270
263
|
);
|
|
264
|
+
calculatedObjectsEffectScopes[objectKey].ruleScopes[addedRuleKey] = addedRuleScope;
|
|
271
265
|
}
|
|
272
266
|
});
|
|
273
267
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
let watchesRunning = null;
|
|
278
|
-
|
|
279
|
-
const es = effectScope();
|
|
280
|
-
|
|
281
|
-
es.run(() => {
|
|
282
|
-
for (const key of parentStateKeys) {
|
|
283
|
-
state[key] = toRef(parentState, key);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
watch(() => Object.keys(parentState.objects), parentStateObjectsWatch, { immediate: true });
|
|
287
|
-
watch(
|
|
288
|
-
[
|
|
289
|
-
() => Object.keys(state.calculatedObjects),
|
|
290
|
-
() =>
|
|
291
|
-
state.calculatedObjectsRules
|
|
292
|
-
? Object.keys(state.calculatedObjectsRules)
|
|
293
|
-
: state.calculatedObjectsRules,
|
|
294
|
-
],
|
|
295
|
-
calculatedObjectsWatch,
|
|
296
|
-
{ immediate: true }
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
watchesRunning = useWatchesRunning({
|
|
300
|
-
triggerRefs: [
|
|
301
|
-
computed(() =>
|
|
302
|
-
state.calculatedObjectsRules && !isEmpty(state.calculatedObjectsRules) ? parentState.loading : false
|
|
303
|
-
),
|
|
304
|
-
],
|
|
305
|
-
watchSentinelRefs: [
|
|
306
|
-
toRef(state, "calculatedObjectsParentStateObjectsWatchRunning"),
|
|
307
|
-
toRef(state, "calculatedObjectsWatchRunning"),
|
|
308
|
-
],
|
|
268
|
+
nextTick(() => {
|
|
269
|
+
state.calculatedObjectsWatchRunning = false;
|
|
309
270
|
});
|
|
271
|
+
}
|
|
310
272
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
273
|
+
watch(
|
|
274
|
+
() => Object.keys(parentState.objects),
|
|
275
|
+
() => {
|
|
276
|
+
state.calculatedObjectsParentStateObjectsWatchRunning = true;
|
|
277
|
+
},
|
|
278
|
+
{ flush: "sync" }
|
|
279
|
+
);
|
|
280
|
+
watch(() => Object.keys(parentState.objects), parentStateObjectsWatch, { immediate: true });
|
|
281
|
+
watch(
|
|
282
|
+
() => Object.keys(state.calculatedObjects),
|
|
283
|
+
() => {
|
|
284
|
+
state.calculatedObjectsWatchRunning = true;
|
|
285
|
+
},
|
|
286
|
+
{ flush: "sync" }
|
|
287
|
+
);
|
|
288
|
+
watch(
|
|
289
|
+
[
|
|
290
|
+
() => Object.keys(state.calculatedObjects),
|
|
291
|
+
() =>
|
|
292
|
+
state.calculatedObjectsRules ? Object.keys(state.calculatedObjectsRules) : state.calculatedObjectsRules,
|
|
293
|
+
],
|
|
294
|
+
calculatedObjectsWatch,
|
|
295
|
+
{ immediate: true }
|
|
296
|
+
);
|
|
324
297
|
|
|
325
298
|
return {
|
|
326
299
|
state,
|
|
327
300
|
parentState,
|
|
328
|
-
|
|
329
|
-
|
|
301
|
+
stop: () => {
|
|
302
|
+
es.stop();
|
|
303
|
+
for (const key of Object.keys(calculatedObjectsEffectScopes)) {
|
|
304
|
+
delete calculatedObjectsEffectScopes[key];
|
|
305
|
+
}
|
|
306
|
+
},
|
|
330
307
|
};
|
|
331
308
|
}
|