@arrai-innovations/reactive-helpers 11.0.1 → 11.0.2
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/package.json
CHANGED
|
@@ -191,5 +191,69 @@ describe("use/listRelated", () => {
|
|
|
191
191
|
},
|
|
192
192
|
},
|
|
193
193
|
});
|
|
194
|
+
intermediateListInstance.state.objects[2].name = "intermediate1a";
|
|
195
|
+
intermediateListInstance.state.objects[2].related_id = "6";
|
|
196
|
+
intermediateListInstance.state.objects[2].related_ids = ["7", "8"];
|
|
197
|
+
intermediateListInstance.state.objects[3].name = "intermediate2a";
|
|
198
|
+
intermediateListInstance.state.objects[3].related_id = "4";
|
|
199
|
+
intermediateListInstance.state.objects[3].related_ids = ["5", "9"];
|
|
200
|
+
relatedListInstance.state.objects[4].name = "related1a";
|
|
201
|
+
relatedListInstance.state.objects[5].name = "related2a";
|
|
202
|
+
relatedListInstance.state.objects[6].name = "related3a";
|
|
203
|
+
relatedListInstance.state.objects[7].name = "related4a";
|
|
204
|
+
relatedListInstance.addListObject({
|
|
205
|
+
id: "8",
|
|
206
|
+
name: "related5",
|
|
207
|
+
});
|
|
208
|
+
relatedListInstance.addListObject({
|
|
209
|
+
id: "9",
|
|
210
|
+
name: "related6",
|
|
211
|
+
});
|
|
212
|
+
expect(deepUnref(listRelated.state.relatedObjects)).toEqual({
|
|
213
|
+
1: {
|
|
214
|
+
intermediateItems: [
|
|
215
|
+
{
|
|
216
|
+
id: "2",
|
|
217
|
+
name: "intermediate1a",
|
|
218
|
+
related_ids: ["7", "8"],
|
|
219
|
+
related_id: "6",
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: "3",
|
|
223
|
+
name: "intermediate2a",
|
|
224
|
+
related_ids: ["5", "9"],
|
|
225
|
+
related_id: "4",
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
intermediateItem: {
|
|
229
|
+
id: "2",
|
|
230
|
+
name: "intermediate1a",
|
|
231
|
+
related_ids: ["7", "8"],
|
|
232
|
+
related_id: "6",
|
|
233
|
+
},
|
|
234
|
+
relatedItems: [
|
|
235
|
+
{
|
|
236
|
+
id: "7",
|
|
237
|
+
name: "related4a",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: "8",
|
|
241
|
+
name: "related5",
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
id: "5",
|
|
245
|
+
name: "related2a",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: "9",
|
|
249
|
+
name: "related6",
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
relatedItem: {
|
|
253
|
+
id: "6",
|
|
254
|
+
name: "related3a",
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
});
|
|
194
258
|
});
|
|
195
259
|
});
|
package/use/listCalculated.js
CHANGED
|
@@ -66,9 +66,6 @@ export function useListCalculated({ parentState, calculatedObjectsRules }) {
|
|
|
66
66
|
function calculatedObjectsWatch() {
|
|
67
67
|
const calculatedObjectsRulesIsEmpty = !state.calculatedObjectsRules || isEmpty(state.calculatedObjectsRules);
|
|
68
68
|
for (const objectKey of Object.keys(state.calculatedObjects)) {
|
|
69
|
-
if (!calculatedObjectsEffectScopes[objectKey]) {
|
|
70
|
-
calculatedObjectsEffectScopes[objectKey] = effectScope();
|
|
71
|
-
}
|
|
72
69
|
const originalObject = toRef(parentState.objects, objectKey);
|
|
73
70
|
const relatedObject = parentState.relatedObjects
|
|
74
71
|
? toRef(parentState.relatedObjects, objectKey)
|
|
@@ -91,8 +88,13 @@ export function useListCalculated({ parentState, calculatedObjectsRules }) {
|
|
|
91
88
|
addedRuleKeys = [];
|
|
92
89
|
}
|
|
93
90
|
for (const removedRuleKey of removedRuleKeys) {
|
|
91
|
+
// this is an unofficial api
|
|
92
|
+
calculatedObjectsObject[removedRuleKey].effect.stop();
|
|
94
93
|
delete calculatedObjectsObject[removedRuleKey];
|
|
95
94
|
}
|
|
95
|
+
if (!calculatedObjectsEffectScopes[objectKey]) {
|
|
96
|
+
calculatedObjectsEffectScopes[objectKey] = effectScope();
|
|
97
|
+
}
|
|
96
98
|
calculatedObjectsEffectScopes[objectKey].run(() => {
|
|
97
99
|
for (const addedRuleKey of addedRuleKeys) {
|
|
98
100
|
calculatedObjectsObject[addedRuleKey] = computed(() =>
|
package/use/listKeys.js
CHANGED
package/use/listRelated.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { difference } from "../utils/index.js";
|
|
2
1
|
import { keyDiff } from "../utils/keyDiff.js";
|
|
3
2
|
import { loadingCombine } from "../utils/loadingCombine.js";
|
|
3
|
+
import { getObjectRelatedByKey } from "../utils/relatedCalculatedHelpers.js";
|
|
4
|
+
import { difference } from "../utils/set.js";
|
|
4
5
|
import {
|
|
5
6
|
listSubscriptionStateKeys,
|
|
6
7
|
listInstanceStateKeys,
|
|
@@ -15,7 +16,6 @@ import get from "lodash-es/get.js";
|
|
|
15
16
|
import identity from "lodash-es/identity.js";
|
|
16
17
|
import isArray from "lodash-es/isArray.js";
|
|
17
18
|
import isEmpty from "lodash-es/isEmpty.js";
|
|
18
|
-
import isEqual from "lodash-es/isEqual.js";
|
|
19
19
|
import isUndefined from "lodash-es/isUndefined.js";
|
|
20
20
|
import { computed, effectScope, onScopeDispose, reactive, toRef, unref, watch } from "vue";
|
|
21
21
|
|
|
@@ -43,23 +43,47 @@ export function useListRelateds(instances, args) {
|
|
|
43
43
|
export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
44
44
|
const state = reactive({
|
|
45
45
|
relatedObjectsRules: relatedObjectsRules,
|
|
46
|
-
relatedObjects: {
|
|
46
|
+
relatedObjects: {
|
|
47
|
+
// id: {
|
|
48
|
+
// rule: list of objects or single object,
|
|
49
|
+
// },
|
|
50
|
+
},
|
|
51
|
+
objAndKeyForIdAndRule: {
|
|
52
|
+
// id: {
|
|
53
|
+
// rule: {
|
|
54
|
+
// obj: object,
|
|
55
|
+
// key: string,
|
|
56
|
+
// },
|
|
57
|
+
// },
|
|
58
|
+
},
|
|
59
|
+
fkForIdAndRule: {
|
|
60
|
+
// id: {
|
|
61
|
+
// rule: list of ids or single id,
|
|
62
|
+
// },
|
|
63
|
+
},
|
|
47
64
|
relatedObjectsParentStateObjectsWatchRunning: false,
|
|
48
65
|
relatedObjectsWatchRunning: false,
|
|
49
66
|
});
|
|
50
67
|
const relatedObjectsEffectScopes = {};
|
|
51
68
|
|
|
52
69
|
function parentStateObjectsWatch() {
|
|
53
|
-
const { addedKeys, removedKeys } = keyDiff(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
const { addedKeys: addedIds, removedKeys: removedIds } = keyDiff(
|
|
71
|
+
Object.keys(parentState.objects),
|
|
72
|
+
Object.keys(state.relatedObjects)
|
|
73
|
+
);
|
|
74
|
+
for (const removedId of removedIds) {
|
|
75
|
+
delete state.relatedObjects[removedId];
|
|
76
|
+
delete state.objAndKeyForIdAndRule[removedId];
|
|
77
|
+
delete state.fkForIdAndRule[removedId];
|
|
78
|
+
if (relatedObjectsEffectScopes[removedId]) {
|
|
79
|
+
relatedObjectsEffectScopes[removedId].stop();
|
|
80
|
+
delete relatedObjectsEffectScopes[removedId];
|
|
59
81
|
}
|
|
60
82
|
}
|
|
61
|
-
for (const
|
|
62
|
-
state.relatedObjects[
|
|
83
|
+
for (const addedId of addedIds) {
|
|
84
|
+
state.relatedObjects[addedId] = {};
|
|
85
|
+
state.objAndKeyForIdAndRule[addedId] = {};
|
|
86
|
+
state.fkForIdAndRule[addedId] = {};
|
|
63
87
|
}
|
|
64
88
|
state.relatedObjectsParentStateObjectsWatchRunning = false;
|
|
65
89
|
}
|
|
@@ -67,66 +91,58 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
67
91
|
function relatedObjectsWatch() {
|
|
68
92
|
const relatedObjectsRulesIsEmpty = !state.relatedObjectsRules || isEmpty(state.relatedObjectsRules);
|
|
69
93
|
for (const objectKey of Object.keys(state.relatedObjects)) {
|
|
70
|
-
const relatedObjectsObject = state.relatedObjects[objectKey];
|
|
71
94
|
const originalObjectRef = toRef(parentState.objects, objectKey);
|
|
72
95
|
const relatedObjectRef = toRef(state.relatedObjects, objectKey);
|
|
73
96
|
let removedRuleKeys, addedRuleKeys;
|
|
74
97
|
if (!relatedObjectsRulesIsEmpty) {
|
|
75
98
|
({ removedKeys: removedRuleKeys, addedKeys: addedRuleKeys } = keyDiff(
|
|
76
99
|
Object.keys(state.relatedObjectsRules),
|
|
77
|
-
Object.keys(
|
|
100
|
+
Object.keys(state.relatedObjects[objectKey])
|
|
78
101
|
));
|
|
79
102
|
} else {
|
|
80
|
-
if (isEmpty(
|
|
103
|
+
if (isEmpty(state.relatedObjects[objectKey])) {
|
|
81
104
|
return;
|
|
82
105
|
}
|
|
83
|
-
removedRuleKeys = Object.keys(
|
|
84
|
-
addedRuleKeys =
|
|
106
|
+
removedRuleKeys = new Set(Object.keys(state.relatedObjects[objectKey]));
|
|
107
|
+
addedRuleKeys = new Set();
|
|
85
108
|
}
|
|
86
109
|
for (const removedRuleKey of removedRuleKeys) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
state.relatedObjects[objectKey][removedRuleKey]?.effect?.stop();
|
|
111
|
+
delete state.relatedObjects[objectKey][removedRuleKey];
|
|
112
|
+
state.objAndKeyForIdAndRule[objectKey][removedRuleKey]?.effect?.stop();
|
|
113
|
+
delete state.objAndKeyForIdAndRule[objectKey][removedRuleKey];
|
|
114
|
+
state.fkForIdAndRule[objectKey][removedRuleKey]?.effect?.stop();
|
|
115
|
+
delete state.fkForIdAndRule[objectKey][removedRuleKey];
|
|
91
116
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
if (addedRuleKeys.size) {
|
|
118
|
+
if (!relatedObjectsEffectScopes[objectKey]) {
|
|
119
|
+
relatedObjectsEffectScopes[objectKey] = effectScope();
|
|
120
|
+
}
|
|
121
|
+
relatedObjectsEffectScopes[objectKey].run(() => {
|
|
122
|
+
for (const addedRuleKey of addedRuleKeys) {
|
|
123
|
+
const rules = toRef(state.relatedObjectsRules, addedRuleKey);
|
|
124
|
+
state.objAndKeyForIdAndRule[objectKey][addedRuleKey] = computed(() => {
|
|
125
|
+
const rulePkKey = unref(rules).pkKey || addedRuleKey;
|
|
126
|
+
const object = unref(originalObjectRef);
|
|
127
|
+
const relatedObject = unref(relatedObjectRef);
|
|
128
|
+
return getObjectRelatedByKey(object, relatedObject, rulePkKey);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
state.fkForIdAndRule[objectKey][addedRuleKey] = computed(() => {
|
|
132
|
+
const ruleOrder = unref(rules).order;
|
|
133
|
+
const relatedObject = unref(relatedObjectRef);
|
|
134
|
+
const [objectForGet, key] = unref(state.objAndKeyForIdAndRule[objectKey][addedRuleKey]);
|
|
135
|
+
let value = get(objectForGet, key);
|
|
136
|
+
if (objectForGet === relatedObject && isUndefined(value)) {
|
|
110
137
|
// is the first level an array?
|
|
111
|
-
const firstLevelKey =
|
|
112
|
-
const firstLevelItem = get(
|
|
138
|
+
const firstLevelKey = key.split(".")[0];
|
|
139
|
+
const firstLevelItem = get(relatedObject, firstLevelKey);
|
|
113
140
|
if (isArray(firstLevelItem)) {
|
|
114
|
-
const restOfKey =
|
|
141
|
+
const restOfKey = key.slice(firstLevelKey.length + 1);
|
|
115
142
|
value = firstLevelItem.map((e) => get(e, restOfKey)).flat();
|
|
116
143
|
}
|
|
117
144
|
}
|
|
118
|
-
|
|
119
|
-
value = get(unref(originalObjectRef), rulePkKey);
|
|
120
|
-
}
|
|
121
|
-
if (isUndefined(value)) {
|
|
122
|
-
if (!isUndefined(relatedObjectsObject[addedRuleKey])) {
|
|
123
|
-
relatedObjectsObject[addedRuleKey] = undefined;
|
|
124
|
-
}
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (isArray(value)) {
|
|
128
|
-
// the related list could be sorted differently than the original list.
|
|
129
|
-
if (ruleOrder?.length) {
|
|
145
|
+
if (isArray(value) && ruleOrder?.length) {
|
|
130
146
|
value = value.filter(identity);
|
|
131
147
|
const indexById = Object.fromEntries(ruleOrder.map((e, i) => [e, i]));
|
|
132
148
|
value.sort((a, b) => {
|
|
@@ -135,24 +151,20 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
135
151
|
return aIndex - bIndex;
|
|
136
152
|
});
|
|
137
153
|
}
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
154
|
+
return value;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
state.relatedObjects[objectKey][addedRuleKey] = computed(() => {
|
|
158
|
+
const value = unref(state.fkForIdAndRule[objectKey][addedRuleKey]);
|
|
159
|
+
const objects = unref(rules).objects;
|
|
160
|
+
if (isArray(value)) {
|
|
161
|
+
return value.map((e) => objects[e]).filter(identity);
|
|
162
|
+
}
|
|
163
|
+
return objects[value];
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
156
168
|
}
|
|
157
169
|
state.relatedObjectsWatchRunning = false;
|
|
158
170
|
}
|
|
@@ -168,10 +180,7 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
168
180
|
|
|
169
181
|
watch(() => Object.keys(parentState.objects), parentStateObjectsWatch, { immediate: true });
|
|
170
182
|
watch(
|
|
171
|
-
[
|
|
172
|
-
() => Object.keys(state.relatedObjects),
|
|
173
|
-
() => (state.relatedObjectsRules ? Object.keys(state.relatedObjectsRules) : state.relatedObjectsRules),
|
|
174
|
-
],
|
|
183
|
+
[() => Object.keys(state.relatedObjects), () => Object.keys(state.relatedObjectsRules || {})],
|
|
175
184
|
relatedObjectsWatch,
|
|
176
185
|
{ immediate: true }
|
|
177
186
|
);
|
|
@@ -15,3 +15,12 @@ export const getObjectRelatedCalculatedByKey = (obj, relatedObj, calculatedObj,
|
|
|
15
15
|
}
|
|
16
16
|
return [getObj, getKey];
|
|
17
17
|
};
|
|
18
|
+
|
|
19
|
+
export const getObjectRelatedByKey = (obj, relatedObj, key) => {
|
|
20
|
+
let getObj = obj,
|
|
21
|
+
getKey = key.replace(relatedItemRegex, () => {
|
|
22
|
+
getObj = relatedObj;
|
|
23
|
+
return "";
|
|
24
|
+
});
|
|
25
|
+
return [getObj, getKey];
|
|
26
|
+
};
|