@arrai-innovations/reactive-helpers 2.8.0 → 3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrai-innovations/reactive-helpers",
3
- "version": "2.8.0",
3
+ "version": "3.0.0",
4
4
  "description": "VueJS 3 utility composition functions to help manipulate objects and lists.",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -601,7 +601,7 @@ describe("use/objectSubscription.js", function () {
601
601
  },
602
602
  });
603
603
  objectSubscription.objectInstance.state.crud.retrieve = customCrudRetrieve;
604
- objectSubscription.state.crud.subscribe = customCrudSubscribe;
604
+ objectSubscription.objectInstance.state.crud.subscribe = customCrudSubscribe;
605
605
 
606
606
  const subscribePromise = objectSubscription.subscribe();
607
607
  crudRetrieveResolve(crudRetrieveResolved);
@@ -1,7 +1,7 @@
1
1
  import inspect from "browser-util-inspect";
2
2
  import { cloneDeep } from "lodash";
3
3
  import { computed, effectScope, reactive } from "vue";
4
- import { assignReactiveObject } from "../utils/assignReactiveObject";
4
+ import { addOrUpdateReactiveObject, assignReactiveObject } from "../utils/assignReactiveObject";
5
5
  import { getFakeId } from "../utils/getFakeId";
6
6
 
7
7
  export class ListError extends Error {
@@ -80,7 +80,7 @@ export function useListInstance({ crudArgs, listArgs = {}, retrieveArgs = {} })
80
80
  // prevent linking of all instances to the same default .args object
81
81
  Object.assign(state.crud, cloneDeep(defaultCrud));
82
82
  if (crudArgs) {
83
- assignReactiveObject(state.crud.args, crudArgs);
83
+ addOrUpdateReactiveObject(state.crud.args, crudArgs);
84
84
  }
85
85
 
86
86
  const defaultPageCallback = (newObjects) => {
@@ -1,10 +1,9 @@
1
- import { computed, effectScope, reactive, toRef } from "vue";
2
- import { useListInstance } from "./listInstance";
3
- import { cloneDeep, isEmpty, isObject } from "lodash";
4
- import { assignReactiveObject } from "../utils/assignReactiveObject";
5
1
  import inspect from "browser-util-inspect";
2
+ import { cloneDeep, isEmpty, isObject } from "lodash";
3
+ import { computed, effectScope, reactive, toRef } from "vue";
6
4
  import { useCancellableIntent } from "../utils/cancellableIntent";
7
5
  import { loadingCombine } from "../utils/loadingCombine";
6
+ import { useListInstance } from "./listInstance";
8
7
 
9
8
  export class ListSubscriptionError extends Error {
10
9
  constructor(message) {
@@ -14,13 +13,11 @@ export class ListSubscriptionError extends Error {
14
13
  }
15
14
 
16
15
  const defaultCrud = {
17
- args: {},
18
16
  subscribe: undefined,
19
17
  };
20
18
 
21
- export function setListSubscriptionCrud({ subscribe, args = {} }) {
19
+ export function setListSubscriptionCrud({ subscribe }) {
22
20
  defaultCrud.subscribe = subscribe;
23
- Object.assign(defaultCrud.args, args);
24
21
  }
25
22
 
26
23
  export function useListSubscriptions(args, listInstances = {}) {
@@ -35,23 +32,18 @@ export function useListSubscription({ listInstance, crudArgs, listArgs, retrieve
35
32
  if (!listInstance) {
36
33
  listInstance = useListInstance({ crudArgs, listArgs, retrieveArgs });
37
34
  }
35
+ if (!listInstance.state.crud.subscribe) {
36
+ listInstance.state.crud.subscribe = defaultCrud.subscribe;
37
+ }
38
+
38
39
  let subscribeIntent, listIntent;
39
40
  const state = reactive({
40
- crud: {
41
- args: {},
42
- subscribe: undefined,
43
- },
44
41
  subscriptionLoading: undefined,
45
42
  subscriptionErrored: false,
46
43
  subscriptionError: null,
47
44
  intendToList: false,
48
45
  intendToSubscribe: false,
49
46
  });
50
- // prevent linking of all instances to the same default .args object
51
- Object.assign(state.crud, cloneDeep(defaultCrud));
52
- if (crudArgs) {
53
- assignReactiveObject(state.crud.args, crudArgs);
54
- }
55
47
 
56
48
  function publicSubscribe({ list = true } = {}) {
57
49
  let didSubscribe = false;
@@ -160,8 +152,8 @@ export function useListSubscription({ listInstance, crudArgs, listArgs, retrieve
160
152
  subscribeIntent = useCancellableIntent({
161
153
  awaitableWithCancel: () => {
162
154
  // this function cannot be async, or the resulting promise will lose its .cancel() method
163
- const subscribePromise = state.crud.subscribe({
164
- crudArgs: cloneDeep(state.crud.args),
155
+ const subscribePromise = listInstance.state.crud.subscribe({
156
+ crudArgs: cloneDeep(listInstance.state.crud.args),
165
157
  listArgs: cloneDeep(listInstance.state.listArgs),
166
158
  retrieveArgs: cloneDeep(listInstance.state.retrieveArgs),
167
159
  subscriptionEventCallback,
@@ -175,7 +167,11 @@ export function useListSubscription({ listInstance, crudArgs, listArgs, retrieve
175
167
  catchPromise.cancel = subscribePromise.cancel;
176
168
  return catchPromise;
177
169
  },
178
- watchArguments: [toRef(state, "intendToSubscribe"), toRef(state, "listArgs"), toRef(state, "retrieveArgs")],
170
+ watchArguments: [
171
+ toRef(state, "intendToSubscribe"),
172
+ toRef(listInstance.state, "listArgs"),
173
+ toRef(state, "retrieveArgs"),
174
+ ],
179
175
  clearActiveOnResolved: false,
180
176
  });
181
177
 
@@ -186,7 +182,12 @@ export function useListSubscription({ listInstance, crudArgs, listArgs, retrieve
186
182
  listInstance.clearList();
187
183
  return listInstance.list();
188
184
  },
189
- watchArguments: [toRef(state, "intendToList"), toRef(state, "listArgs"), toRef(state, "retrieveArgs")],
185
+ watchArguments: [
186
+ toRef(state, "intendToList"),
187
+ toRef(listInstance.state, "listArgs"),
188
+ toRef(state, "retrieveArgs"),
189
+ ],
190
+ nameOnLog: "listIntent",
190
191
  });
191
192
  });
192
193
 
@@ -67,12 +67,19 @@ export function useObjectCalculated({
67
67
  state.deleted = toRef(parentState, "deleted");
68
68
 
69
69
  watch(
70
- [() => Object.keys(state.calculatedObjectRules)],
70
+ [() => state.calculatedObjectRules && Object.keys(state.calculatedObjectRules)],
71
71
  () => {
72
- const { addedKeys, removedKeys, sameKeys } = keyDiff(
73
- Object.keys(state.calculatedObjectRules),
74
- Object.keys(calculatedObjectOriginalFunctions)
75
- );
72
+ let addedKeys = [],
73
+ removedKeys = [],
74
+ sameKeys = [];
75
+ if (!state.calculatedObjectRules) {
76
+ removedKeys = Object.keys(calculatedObjectOriginalFunctions);
77
+ } else {
78
+ ({ addedKeys, removedKeys, sameKeys } = keyDiff(
79
+ Object.keys(state.calculatedObjectRules),
80
+ Object.keys(calculatedObjectOriginalFunctions)
81
+ ));
82
+ }
76
83
  for (const sameKey of sameKeys) {
77
84
  if (calculatedObjectOriginalFunctions[sameKey] !== state.calculatedObjectRules[sameKey]) {
78
85
  removedKeys.push(sameKey);
@@ -1,6 +1,6 @@
1
1
  import { cloneDeep } from "lodash";
2
- import { effectScope, reactive, unref } from "vue";
3
- import { assignReactiveObject } from "../utils/assignReactiveObject";
2
+ import { effectScope, reactive } from "vue";
3
+ import { addOrUpdateReactiveObject, assignReactiveObject } from "../utils/assignReactiveObject";
4
4
 
5
5
  export class ObjectError extends Error {
6
6
  constructor(message) {
@@ -56,9 +56,7 @@ export function useObjectInstance({ crudArgs, id, retrieveArgs }) {
56
56
  // prevent linking of all instances to the same default .args object
57
57
  Object.assign(state.crud, cloneDeep(defaultCrud));
58
58
  if (crudArgs) {
59
- // generally you won't have a ref to an object, but indirectly, you could have a ref to a reactive.
60
- // either way, we want a reactive or plain object. computed isn't going to work for this.
61
- assignReactiveObject(state.crud.args, unref(crudArgs));
59
+ addOrUpdateReactiveObject(state.crud.args, crudArgs);
62
60
  }
63
61
 
64
62
  // due to retrieve being called by `useCancelleableIntent`, if called manually then by the watch,
@@ -67,12 +67,19 @@ export function useObjectRelated({
67
67
  state.deleted = toRef(parentState, "deleted");
68
68
 
69
69
  watch(
70
- [() => Object.keys(state.relatedObjectRules)],
70
+ [() => state.relatedObjectRules && Object.keys(state.relatedObjectRules)],
71
71
  () => {
72
- const { addedKeys: addedRuleKeys, removedKeys: removedRuleKeys } = keyDiff(
73
- Object.keys(state.relatedObjectRules),
74
- Object.keys(state.relatedObjectObjects)
75
- );
72
+ let addedRuleKeys = [],
73
+ removedRuleKeys = [];
74
+ if (!state.relatedObjectRules) {
75
+ removedRuleKeys = Object.keys(state.relatedObjectObjects);
76
+ } else {
77
+ ({ addedKeys: addedRuleKeys, removedKeys: removedRuleKeys } = keyDiff(
78
+ Object.keys(state.relatedObjectRules),
79
+ Object.keys(state.relatedObjectObjects)
80
+ ));
81
+ }
82
+
76
83
  for (const removedRuleKey of removedRuleKeys) {
77
84
  delete state.relatedObjectObjects[removedRuleKey];
78
85
  if (relatedObjectEffectScopes[removedRuleKey]) {
@@ -1,4 +1,3 @@
1
- import { cloneDeep } from "lodash";
2
1
  import { computed, effectScope, reactive, toRef } from "vue";
3
2
  import { assignReactiveObject } from "../utils/assignReactiveObject";
4
3
  import { useCancellableIntent } from "../utils/cancellableIntent";
@@ -13,13 +12,11 @@ export class ObjectSubscriptionError extends Error {
13
12
  }
14
13
 
15
14
  const defaultCrud = {
16
- args: {},
17
15
  subscribe: undefined,
18
16
  };
19
17
 
20
- export function setObjectSubscriptionCrud({ subscribe, args = {} }) {
18
+ export function setObjectSubscriptionCrud({ subscribe }) {
21
19
  defaultCrud.subscribe = subscribe;
22
- Object.assign(defaultCrud.args, args);
23
20
  }
24
21
 
25
22
  export function useObjectSubscriptions(subscriptionArgs) {
@@ -39,11 +36,10 @@ export function useObjectSubscription({ objectInstance, crudArgs, id, retrieveAr
39
36
  if (!objectInstance) {
40
37
  objectInstance = useObjectInstance({ crudArgs, id, retrieveArgs });
41
38
  }
39
+ if (!objectInstance.state.crud.subscribe) {
40
+ objectInstance.state.crud.subscribe = defaultCrud.subscribe;
41
+ }
42
42
  const state = reactive({
43
- crud: {
44
- args: {},
45
- subscribe: undefined,
46
- },
47
43
  subscriptionLoading: undefined,
48
44
  subscriptionErrored: false,
49
45
  subscriptionError: null,
@@ -51,11 +47,6 @@ export function useObjectSubscription({ objectInstance, crudArgs, id, retrieveAr
51
47
  intendToSubscribe: false,
52
48
  intendToRetrieve: false,
53
49
  });
54
- // prevent linking of all instances to the same default .args object
55
- Object.assign(state.crud, cloneDeep(defaultCrud));
56
- if (crudArgs) {
57
- assignReactiveObject(state.crud.args, crudArgs);
58
- }
59
50
 
60
51
  let subscribeIntent, retrieveIntent;
61
52
 
@@ -92,8 +83,8 @@ export function useObjectSubscription({ objectInstance, crudArgs, id, retrieveAr
92
83
  state.subscriptionErrored = false;
93
84
  state.subscriptionError = null;
94
85
  let subscribePromise;
95
- subscribePromise = state.crud.subscribe({
96
- crudArgs: state.crud.args,
86
+ subscribePromise = objectInstance.state.crud.subscribe({
87
+ crudArgs: objectInstance.state.crud.args,
97
88
  id: objectInstance.state.id,
98
89
  retrieveArgs: state.retrieveArgs,
99
90
  callback: (data, action) => {
@@ -1,8 +1,8 @@
1
+ import inspect from "browser-util-inspect";
2
+ import { isArray, isObject } from "lodash";
3
+ import { isReactive, isRef, toRef, unref } from "vue";
1
4
  import { keyDiff } from "./keyDiff.js";
2
5
  import { union } from "./set.js";
3
- import { isReactive, toRef } from "vue";
4
- import { isArray, isObject } from "lodash";
5
- import inspect from "browser-util-inspect";
6
6
 
7
7
  export class AssignReactiveObjectError extends Error {
8
8
  constructor(message) {
@@ -20,6 +20,16 @@ function isArrayOrObject(key, value) {
20
20
  export function addOrUpdateReactiveObject(target, source, exclude = [], addedKeys = null, sameKeys = null) {
21
21
  isArrayOrObject("target", target);
22
22
  isArrayOrObject("source", source);
23
+ if (isRef(target)) {
24
+ const unrefedTarget = unref(target);
25
+ isArrayOrObject("unrefedTarget", unrefedTarget);
26
+ target = unrefedTarget;
27
+ }
28
+ if (isRef(source)) {
29
+ const unrefedSource = unref(source);
30
+ isArrayOrObject("unrefedSource", unrefedSource);
31
+ source = unrefedSource;
32
+ }
23
33
  if (!addedKeys && !sameKeys) {
24
34
  ({ addedKeys, sameKeys } = keyDiff(Object.keys(source) || [], Object.keys(target) || []));
25
35
  }
@@ -42,6 +52,16 @@ export function assignReactiveObject(target, source, exclude = []) {
42
52
  }
43
53
  isArrayOrObject("target", target);
44
54
  isArrayOrObject("source", source);
55
+ if (isRef(target)) {
56
+ const unrefedTarget = unref(target);
57
+ isArrayOrObject("unrefedTarget", unrefedTarget);
58
+ target = unrefedTarget;
59
+ }
60
+ if (isRef(source)) {
61
+ const unrefedSource = unref(source);
62
+ isArrayOrObject("unrefedSource", unrefedSource);
63
+ source = unrefedSource;
64
+ }
45
65
  const targetIsArray = isArray(target);
46
66
  const { addedKeys, sameKeys, removedKeys } = keyDiff(Object.keys(source) || [], Object.keys(target) || []);
47
67
  if (targetIsArray) {