@arrai-innovations/reactive-helpers 2.3.3 → 2.3.4

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrai-innovations/reactive-helpers",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "VueJS 3 utility composition functions to help manipulate objects and lists.",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -45,6 +45,12 @@ describe("use/listRelated", () => {
45
45
  relatedObjectsPropertyName: "myRelatedObjects",
46
46
  });
47
47
  await nextTick();
48
+ // listRelated.state.objects is doing proxy shenanigans
49
+ // in uses handler.has
50
+ expect("myRelatedObjects" in listRelated.state.objects[1]).toBe(true);
51
+ expect("relatedItems" in listRelated.state.objects[1].myRelatedObjects).toBe(true);
52
+ expect("relatedItem" in listRelated.state.objects[1].myRelatedObjects).toBe(true);
53
+ // expect uses enumeration, which uses handler.ownKeys and handler.getOwnPropertyDescriptor
48
54
  expect(unrefAndToRawDeep(listRelated.state.objects)).toEqual({
49
55
  1: {
50
56
  id: "1",
@@ -1,5 +1,5 @@
1
1
  import { isEmpty } from "lodash";
2
- import { computed, effectScope, onScopeDispose, reactive, toRef, toRefs, watch } from "vue";
2
+ import { computed, effectScope, onScopeDispose, reactive, toRef, watch } from "vue";
3
3
  import { keyDiff } from "../utils";
4
4
 
5
5
  export function useListCalculateds(instances, args) {
@@ -10,6 +10,7 @@ export function useListCalculateds(instances, args) {
10
10
  });
11
11
  }
12
12
  }
13
+
13
14
  // the simpler sibling of useListRelated
14
15
  // rules are just keys to functions that will be called with the object
15
16
  // and the result will be added as a computed property
@@ -24,7 +25,6 @@ export function useListCalculated({
24
25
  objects: {},
25
26
  });
26
27
  const calculatedObjectsEffectScopes = {};
27
- const combinedEffectScopes = {};
28
28
 
29
29
  // don't change calculatedObjectsPropertyName on us or it will break
30
30
  const copn = calculatedObjectsPropertyName + "";
@@ -41,21 +41,19 @@ export function useListCalculated({
41
41
  calculatedObjectsEffectScopes[removedKey].stop();
42
42
  delete calculatedObjectsEffectScopes[removedKey];
43
43
  }
44
- if (combinedEffectScopes[removedKey]) {
45
- combinedEffectScopes[removedKey].stop();
46
- delete combinedEffectScopes[removedKey];
47
- }
48
44
  }
49
45
  for (const addedKey of addedKeys) {
50
46
  state.calculatedObjectsObjects[addedKey] = {};
51
- combinedEffectScopes[addedKey] = effectScope();
52
- combinedEffectScopes[addedKey].run(() => {
53
- state.objects[addedKey] = computed(() =>
54
- reactive({
55
- ...toRefs(state.calculatedObjectsObjects[addedKey]),
56
- ...toRefs(parentState.objects[addedKey]),
57
- })
58
- );
47
+ state.objects[addedKey] = new Proxy(parentState.objects[addedKey], {
48
+ get(target, prop, receiver) {
49
+ if (prop === copn) {
50
+ return state.calculatedObjectsObjects[addedKey];
51
+ }
52
+ return Reflect.get(target, prop, receiver);
53
+ },
54
+ ownKeys(target) {
55
+ return Reflect.ownKeys(target).concat(copn);
56
+ },
59
57
  });
60
58
  }
61
59
  }
@@ -123,9 +121,6 @@ export function useListCalculated({
123
121
  for (const objectKey of Object.keys(calculatedObjectsEffectScopes)) {
124
122
  calculatedObjectsEffectScopes[objectKey].stop();
125
123
  }
126
- for (const objectKey of Object.keys(combinedEffectScopes)) {
127
- combinedEffectScopes[objectKey].stop();
128
- }
129
124
  });
130
125
  });
131
126
 
@@ -1,5 +1,5 @@
1
- import { computed, effectScope, onScopeDispose, reactive, toRef, toRefs, unref, watch } from "vue";
2
1
  import { get, isArray, isEmpty, isUndefined } from "lodash";
2
+ import { computed, effectScope, onScopeDispose, reactive, toRef, unref, watch } from "vue";
3
3
  import { keyDiff } from "../utils/keyDiff";
4
4
 
5
5
  export function useListRelateds(instances, args) {
@@ -22,7 +22,6 @@ export function useListRelated({
22
22
  objects: {},
23
23
  });
24
24
  const relatedObjectsEffectScopes = {};
25
- const combinedEffectScopes = {};
26
25
 
27
26
  // don't change relatedObjectsPropertyName on us or it will break
28
27
  const ropn = relatedObjectsPropertyName + "";
@@ -39,21 +38,39 @@ export function useListRelated({
39
38
  relatedObjectsEffectScopes[removedKey].stop();
40
39
  delete relatedObjectsEffectScopes[removedKey];
41
40
  }
42
- if (combinedEffectScopes[removedKey]) {
43
- combinedEffectScopes[removedKey].stop();
44
- delete combinedEffectScopes[removedKey];
45
- }
46
41
  }
47
42
  for (const addedKey of addedKeys) {
48
43
  state.relatedObjectsObjects[addedKey] = {};
49
- combinedEffectScopes[addedKey] = effectScope();
50
- combinedEffectScopes[addedKey].run(() => {
51
- state.objects[addedKey] = computed(() =>
52
- reactive({
53
- ...toRefs(state.relatedObjectsObjects[addedKey]),
54
- ...toRefs(parentState.objects[addedKey]),
55
- })
56
- );
44
+ state.objects[addedKey] = new Proxy(parentState.objects[addedKey], {
45
+ get(target, prop, receiver) {
46
+ if (prop === ropn) {
47
+ return state.relatedObjectsObjects[addedKey];
48
+ }
49
+ return Reflect.get(target, prop, receiver);
50
+ },
51
+ ownKeys(target) {
52
+ return Reflect.ownKeys(target).concat(ropn);
53
+ },
54
+ has(target, prop) {
55
+ if (prop === ropn) {
56
+ return true;
57
+ }
58
+ return Reflect.has(target, prop);
59
+ },
60
+ getOwnPropertyDescriptor(target, p) {
61
+ if (p === ropn) {
62
+ return {
63
+ configurable: true,
64
+ enumerable: true,
65
+ value: state.relatedObjectsObjects[addedKey],
66
+ writable: true,
67
+ };
68
+ }
69
+ return Reflect.getOwnPropertyDescriptor(target, p);
70
+ },
71
+ defineProperty() {
72
+ return false;
73
+ },
57
74
  });
58
75
  }
59
76
  }
@@ -64,31 +81,31 @@ export function useListRelated({
64
81
  }
65
82
  const relatedObjectsRulesIsEmpty = isEmpty(state.relatedObjectsRules);
66
83
  for (const objectKey of Object.keys(state.relatedObjectsObjects)) {
84
+ if (relatedObjectsEffectScopes[objectKey]) {
85
+ relatedObjectsEffectScopes[objectKey].stop();
86
+ }
67
87
  const relatedObjectsEffectScope = effectScope();
68
88
  relatedObjectsEffectScope.run(() => {
69
89
  const relatedObjectsObject = state.relatedObjectsObjects[objectKey];
70
90
  const originalObject = parentState.objects[objectKey];
71
- if (!relatedObjectsObject[ropn]) {
72
- relatedObjectsObject[ropn] = {};
73
- }
74
91
  let removedRuleKeys, addedRuleKeys;
75
92
  if (!relatedObjectsRulesIsEmpty) {
76
93
  ({ removedKeys: removedRuleKeys, addedKeys: addedRuleKeys } = keyDiff(
77
94
  Object.keys(state.relatedObjectsRules),
78
- Object.keys(relatedObjectsObject[ropn])
95
+ Object.keys(relatedObjectsObject)
79
96
  ));
80
97
  } else {
81
- if (isEmpty(relatedObjectsObject[ropn])) {
98
+ if (isEmpty(relatedObjectsObject)) {
82
99
  return;
83
100
  }
84
- removedRuleKeys = Object.keys(relatedObjectsObject[ropn]);
101
+ removedRuleKeys = Object.keys(relatedObjectsObject);
85
102
  addedRuleKeys = [];
86
103
  }
87
104
  for (const removedRuleKey of removedRuleKeys) {
88
- delete relatedObjectsObject[ropn][removedRuleKey];
105
+ delete relatedObjectsObject[removedRuleKey];
89
106
  }
90
107
  for (const addedRuleKey of addedRuleKeys) {
91
- relatedObjectsObject[ropn][addedRuleKey] = computed(() => {
108
+ relatedObjectsObject[addedRuleKey] = computed(() => {
92
109
  // deal with computed objects being passed.
93
110
  const ruleObjects = unref(state.relatedObjectsRules?.[addedRuleKey]?.objects);
94
111
  const rulePkKey = state.relatedObjectsRules?.[addedRuleKey]?.pkKey || addedRuleKey;
@@ -131,9 +148,6 @@ export function useListRelated({
131
148
  for (const objectKey of Object.keys(relatedObjectsEffectScopes)) {
132
149
  relatedObjectsEffectScopes[objectKey].stop();
133
150
  }
134
- for (const objectKey of Object.keys(combinedEffectScopes)) {
135
- combinedEffectScopes[objectKey].stop();
136
- }
137
151
  });
138
152
  });
139
153
  return {
@@ -1,4 +1,4 @@
1
- import { computed, effectScope, onScopeDispose, reactive, toRef, toRefs, watch } from "vue";
1
+ import { computed, effectScope, onScopeDispose, reactive, watch } from "vue";
2
2
  import { keyDiff } from "../utils";
3
3
 
4
4
  export function useObjectCalculateds(instances, args) {
@@ -9,6 +9,7 @@ export function useObjectCalculateds(instances, args) {
9
9
  });
10
10
  }
11
11
  }
12
+
12
13
  // the single object version of useListCalculated
13
14
  export function useObjectCalculated({
14
15
  parentState,
@@ -29,12 +30,37 @@ export function useObjectCalculated({
29
30
  const es = effectScope();
30
31
 
31
32
  es.run(() => {
32
- state.object = computed(() =>
33
- reactive({
34
- [copn]: toRef(state, "calculatedObjectObject"),
35
- ...toRefs(parentState.object),
36
- })
37
- );
33
+ state.object = new Proxy(parentState.object, {
34
+ get(target, key, receiver) {
35
+ if (key === copn) {
36
+ return state.calculatedObjectObject;
37
+ }
38
+ return Reflect.get(target, key, receiver);
39
+ },
40
+ ownKeys(target) {
41
+ return Reflect.ownKeys(target).concat(copn);
42
+ },
43
+ has(target, key) {
44
+ if (key === copn) {
45
+ return true;
46
+ }
47
+ return Reflect.has(target, key);
48
+ },
49
+ getOwnPropertyDescriptor(target, key) {
50
+ if (key === copn) {
51
+ return {
52
+ configurable: true,
53
+ enumerable: true,
54
+ value: state.calculatedObjectObject,
55
+ writable: true,
56
+ };
57
+ }
58
+ return Reflect.getOwnPropertyDescriptor(target, key);
59
+ },
60
+ defineProperty() {
61
+ return false;
62
+ },
63
+ });
38
64
 
39
65
  watch(
40
66
  [() => Object.keys(state.calculatedObjectRules)],