@arrai-innovations/reactive-helpers 2.1.2 → 2.2.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/package.json +1 -1
- package/use/index.js +1 -0
- package/use/listCalculated.js +128 -0
package/package.json
CHANGED
package/use/index.js
CHANGED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { isEmpty } from "lodash";
|
|
2
|
+
import { computed, effectScope, onScopeDispose, reactive, toRef, toRefs, watch } from "vue";
|
|
3
|
+
import { keyDiff } from "../utils";
|
|
4
|
+
|
|
5
|
+
// the simpler sibling of useListRelated
|
|
6
|
+
// rules are just keys to functions that will be called with the object
|
|
7
|
+
// and the result will be added as a computed property
|
|
8
|
+
export function useListCalculated({
|
|
9
|
+
parentState,
|
|
10
|
+
calculatedObjectsRules,
|
|
11
|
+
calculatedObjectsPropertyName = "calculatedObjects", // NOT REACTIVE
|
|
12
|
+
}) {
|
|
13
|
+
const state = reactive({
|
|
14
|
+
calculatedObjectsRules,
|
|
15
|
+
calculatedObjectsObjects: {},
|
|
16
|
+
objects: {},
|
|
17
|
+
});
|
|
18
|
+
const calculatedObjectsEffectScopes = {};
|
|
19
|
+
const combinedEffectScopes = {};
|
|
20
|
+
|
|
21
|
+
// don't change calculatedObjectsPropertyName on us or it will break
|
|
22
|
+
const copn = calculatedObjectsPropertyName + "";
|
|
23
|
+
|
|
24
|
+
function parentStateObjectsWatch() {
|
|
25
|
+
const { addedKeys, removedKeys } = keyDiff(
|
|
26
|
+
Object.keys(parentState.objects),
|
|
27
|
+
Object.keys(state.calculatedObjectsObjects)
|
|
28
|
+
);
|
|
29
|
+
for (const removedKey of removedKeys) {
|
|
30
|
+
delete state.calculatedObjectsObjects[removedKey];
|
|
31
|
+
delete state.objects[removedKey];
|
|
32
|
+
if (calculatedObjectsEffectScopes[removedKey]) {
|
|
33
|
+
calculatedObjectsEffectScopes[removedKey].stop();
|
|
34
|
+
delete calculatedObjectsEffectScopes[removedKey];
|
|
35
|
+
}
|
|
36
|
+
if (combinedEffectScopes[removedKey]) {
|
|
37
|
+
combinedEffectScopes[removedKey].stop();
|
|
38
|
+
delete combinedEffectScopes[removedKey];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const addedKey of addedKeys) {
|
|
42
|
+
state.calculatedObjectsObjects[addedKey] = {};
|
|
43
|
+
combinedEffectScopes[addedKey] = effectScope();
|
|
44
|
+
combinedEffectScopes[addedKey].run(() => {
|
|
45
|
+
state.objects[addedKey] = computed(() =>
|
|
46
|
+
reactive({
|
|
47
|
+
...toRefs(state.calculatedObjectsObjects[addedKey]),
|
|
48
|
+
...toRefs(parentState.objects[addedKey]),
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function calculatedObjectsWatch() {
|
|
56
|
+
if (state.calculatedObjectsRules === false) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const calculatedObjectsRulesIsEmpty = isEmpty(state.calculatedObjectsRules);
|
|
60
|
+
for (const objectKey of Object.keys(state.calculatedObjectsObjects)) {
|
|
61
|
+
const calculatedObjectsEffectScope = effectScope();
|
|
62
|
+
calculatedObjectsEffectScope.run(() => {
|
|
63
|
+
const calculatedObjectsObject = state.calculatedObjectsObjects[objectKey];
|
|
64
|
+
const originalObject = parentState.objects[objectKey];
|
|
65
|
+
if (!calculatedObjectsObject[copn]) {
|
|
66
|
+
calculatedObjectsObject[copn] = {};
|
|
67
|
+
}
|
|
68
|
+
let removedRuleKeys, addedRuleKeys;
|
|
69
|
+
if (!calculatedObjectsRulesIsEmpty) {
|
|
70
|
+
({ removedKeys: removedRuleKeys, addedKeys: addedRuleKeys } = keyDiff(
|
|
71
|
+
Object.keys(state.calculatedObjectsRules),
|
|
72
|
+
Object.keys(calculatedObjectsObject[copn])
|
|
73
|
+
));
|
|
74
|
+
} else {
|
|
75
|
+
if (isEmpty(calculatedObjectsObject[copn])) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
removedRuleKeys = Object.keys(calculatedObjectsObject[copn]);
|
|
79
|
+
addedRuleKeys = [];
|
|
80
|
+
}
|
|
81
|
+
for (const removedRuleKey of removedRuleKeys) {
|
|
82
|
+
delete calculatedObjectsObject[copn][removedRuleKey];
|
|
83
|
+
}
|
|
84
|
+
for (const addedRuleKey of addedRuleKeys) {
|
|
85
|
+
calculatedObjectsObject[copn][addedRuleKey] = computed(() => {
|
|
86
|
+
return state.calculatedObjectsRules?.[addedRuleKey]?.(originalObject);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
calculatedObjectsEffectScopes[objectKey] = calculatedObjectsEffectScope;
|
|
91
|
+
}
|
|
92
|
+
parentStateObjectsWatch();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const es = effectScope();
|
|
96
|
+
|
|
97
|
+
es.run(() => {
|
|
98
|
+
state.order = toRef(parentState, "order");
|
|
99
|
+
state.objectsInOrder = computed(() => state.order.map((id) => state.objects[id]));
|
|
100
|
+
|
|
101
|
+
watch(() => Object.keys(parentState.objects), parentStateObjectsWatch, { immediate: true });
|
|
102
|
+
watch(
|
|
103
|
+
[
|
|
104
|
+
() => Object.keys(state.calculatedObjectsObjects),
|
|
105
|
+
() =>
|
|
106
|
+
state.calculatedObjectsRules
|
|
107
|
+
? Object.keys(state.calculatedObjectsRules)
|
|
108
|
+
: state.calculatedObjectsRules,
|
|
109
|
+
],
|
|
110
|
+
calculatedObjectsWatch,
|
|
111
|
+
{ immediate: true }
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
onScopeDispose(() => {
|
|
115
|
+
for (const objectKey of Object.keys(calculatedObjectsEffectScopes)) {
|
|
116
|
+
calculatedObjectsEffectScopes[objectKey].stop();
|
|
117
|
+
}
|
|
118
|
+
for (const objectKey of Object.keys(combinedEffectScopes)) {
|
|
119
|
+
combinedEffectScopes[objectKey].stop();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
state,
|
|
126
|
+
effectScope: es,
|
|
127
|
+
};
|
|
128
|
+
}
|