@arrai-innovations/reactive-helpers 9.0.3 → 10.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.
@@ -1,8 +1,21 @@
1
- import { keyDiff, loadingCombine } from "../utils/index.js";
1
+ import { keyDiff } from "../utils/keyDiff.js";
2
+ import { loadingCombine } from "../utils/loadingCombine.js";
3
+ import { objectInstanceStateKeys } from "./objectInstance.js";
4
+ import { objectRelatedStateKeys } from "./objectRelated.js";
5
+ import { objectSubscriptionStateKeys } from "./objectSubscription.js";
2
6
  import { useWatchesRunning } from "./watchesRunning.js";
3
7
  import isEmpty from "lodash-es/isEmpty.js";
4
8
  import { computed, effectScope, onScopeDispose, reactive, toRef, watch } from "vue";
5
9
 
10
+ export const objectCalculatedStateKeys = [
11
+ "calculatedObject",
12
+ "calculatedObjectRules",
13
+ "calculatedObjectWatchRunning",
14
+ "parentStateObjectWatchRunning",
15
+ ];
16
+
17
+ export const objectCalculatedFunctions = [];
18
+
6
19
  export function useObjectCalculateds(instances, args) {
7
20
  for (const [key, value] of Object.entries(args)) {
8
21
  useObjectCalculated({
@@ -13,54 +26,28 @@ export function useObjectCalculateds(instances, args) {
13
26
  }
14
27
 
15
28
  // the single object version of useListCalculated
16
- export function useObjectCalculated({
17
- parentState,
18
- calculatedObjectRules,
19
- calculatedObjectPropertyName = "calculatedObject", // NOT REACTIVE
20
- passThroughPropertyNames = [
21
- // instance
22
- "crud",
23
- "deleted",
24
- "error",
25
- "errored",
26
- "id",
27
- "loading",
28
- "object",
29
- "retrieveArgs",
30
- // subscription
31
- "intendToRetrieve",
32
- "intendToSubscribe",
33
- "subscribed",
34
- "subscriptionError",
35
- "subscriptionErrored",
36
- "subscriptionLoading",
37
- // related
38
- "relatedObject",
39
- "relatedObjectObjects",
40
- "relatedObjectRules",
41
- "relatedObjectWatchRunning",
42
- "relatedRunning",
43
- ], // NOT REACTIVE
44
- }) {
29
+ export function useObjectCalculated({ parentState, calculatedObjectRules }) {
45
30
  const state = reactive({
46
31
  calculatedObjectRules,
47
- calculatedObjectObjects: {},
32
+ calculatedObject: {},
48
33
  parentStateObjectWatchRunning: false,
49
34
  calculatedObjectWatchRunning: false,
50
35
  });
51
36
  const calculatedObjectEffectScopes = {};
52
37
  const calculatedObjectOriginalFunctions = {};
53
38
 
54
- // don't change calculatedObjectPropertyName on us or it will break
55
- const copn = calculatedObjectPropertyName + "";
56
-
57
39
  let watchesRunning = null;
58
40
 
59
41
  const es = effectScope();
60
42
 
61
43
  es.run(() => {
62
- state[copn] = toRef(state, "calculatedObjectObjects");
63
- for (let key of passThroughPropertyNames) {
44
+ for (const key of objectInstanceStateKeys) {
45
+ state[key] = toRef(parentState, key);
46
+ }
47
+ for (const key of objectSubscriptionStateKeys) {
48
+ state[key] = toRef(parentState, key);
49
+ }
50
+ for (const key of objectRelatedStateKeys) {
64
51
  state[key] = toRef(parentState, key);
65
52
  }
66
53
 
@@ -84,7 +71,7 @@ export function useObjectCalculated({
84
71
  }
85
72
  for (const removedKey of removedKeys) {
86
73
  delete calculatedObjectOriginalFunctions[removedKey];
87
- delete state.calculatedObjectObjects[removedKey];
74
+ delete state.calculatedObject[removedKey];
88
75
  if (calculatedObjectEffectScopes[removedKey]) {
89
76
  calculatedObjectEffectScopes[removedKey].stop();
90
77
  delete calculatedObjectEffectScopes[removedKey];
@@ -94,7 +81,7 @@ export function useObjectCalculated({
94
81
  calculatedObjectOriginalFunctions[addedKey] = state.calculatedObjectRules[addedKey];
95
82
  calculatedObjectEffectScopes[addedKey] = effectScope();
96
83
  calculatedObjectEffectScopes[addedKey].run(() => {
97
- state.calculatedObjectObjects[addedKey] = computed(() =>
84
+ state.calculatedObject[addedKey] = computed(() =>
98
85
  calculatedObjectOriginalFunctions[addedKey](state.object)
99
86
  );
100
87
  });
@@ -110,7 +97,7 @@ export function useObjectCalculated({
110
97
  });
111
98
 
112
99
  state.calculatedRunning = toRef(watchesRunning.state, "running");
113
- state.running = computed(() => loadingCombine(watchesRunning.state.running, parentState.relatedRunning));
100
+ state.running = computed(() => loadingCombine(watchesRunning.state.running, parentState.running));
114
101
 
115
102
  onScopeDispose(() => {
116
103
  for (const key in calculatedObjectEffectScopes) {
@@ -1,6 +1,5 @@
1
- import { addOrUpdateReactiveObject, assignReactiveObject } from "../utils/index.js";
2
- import cloneDeep from "lodash-es/cloneDeep.js";
3
- import isFunction from "lodash-es/isFunction.js";
1
+ import { getObjectCrud } from "../config/objectCrud.js";
2
+ import { assignReactiveObject } from "../utils/assignReactiveObject.js";
4
3
  import { reactive, toRef } from "vue";
5
4
 
6
5
  export class ObjectError extends Error {
@@ -10,23 +9,18 @@ export class ObjectError extends Error {
10
9
  }
11
10
  }
12
11
 
13
- const defaultCrud = {
14
- args: {},
15
- retrieve: undefined,
16
- create: undefined,
17
- update: undefined,
18
- patch: undefined,
19
- delete: undefined,
20
- };
12
+ export const objectInstanceStateKeys = [
13
+ "crud",
14
+ "id",
15
+ "retrieveArgs",
16
+ "object",
17
+ "loading",
18
+ "errored",
19
+ "error",
20
+ "deleted",
21
+ ];
21
22
 
22
- export function setObjectInstanceCrud({ retrieve, create, update, patch, delete: deleteFn, args = {} }) {
23
- defaultCrud.retrieve = retrieve;
24
- defaultCrud.create = create;
25
- defaultCrud.update = update;
26
- defaultCrud.patch = patch;
27
- defaultCrud.delete = deleteFn;
28
- Object.assign(defaultCrud.args, args);
29
- }
23
+ export const objectInstanceFunctions = ["create", "retrieve", "update", "delete", "patch", "clearError", "clear"];
30
24
 
31
25
  export function useObjectInstances(instanceArgs) {
32
26
  const instances = {};
@@ -40,11 +34,11 @@ export function useObjectInstance({ props, functions = {} }) {
40
34
  const state = reactive({
41
35
  crud: {
42
36
  args: {},
43
- retrieve: undefined,
44
37
  create: undefined,
38
+ retrieve: undefined,
45
39
  update: undefined,
46
- patch: undefined,
47
40
  delete: undefined,
41
+ patch: undefined,
48
42
  },
49
43
  object: {},
50
44
  id: toRef(props, "id"),
@@ -54,18 +48,8 @@ export function useObjectInstance({ props, functions = {} }) {
54
48
  error: null,
55
49
  deleted: false,
56
50
  });
57
- // prevent linking of all instances to the same default .args object
58
- Object.assign(state.crud, cloneDeep(defaultCrud));
59
- if (props.crudArgs) {
60
- addOrUpdateReactiveObject(state.crud.args, props.crudArgs);
61
- }
62
- for (const [key, value] of Object.entries(functions)) {
63
- if (isFunction(value) && key in state.crud) {
64
- state[key] = value;
65
- } else {
66
- throw ObjectError(`Invalid function "${key}" for useObjectInstance: invalid key or not a function.`);
67
- }
68
- }
51
+
52
+ getObjectCrud(state.crud, { props, functions });
69
53
 
70
54
  // due to retrieve being called by `useCancelleableIntent`, if called manually then by the watch,
71
55
  // it will run into the loading check. Instead, return the current retrieve promise if it exists.
@@ -229,11 +213,11 @@ export function useObjectInstance({ props, functions = {} }) {
229
213
 
230
214
  return reactive({
231
215
  state,
232
- retrieve,
233
216
  create,
217
+ retrieve,
234
218
  update,
235
- patch,
236
219
  delete: deleteFn,
220
+ patch,
237
221
  clearError,
238
222
  clear,
239
223
  });
@@ -1,4 +1,7 @@
1
- import { keyDiff } from "../utils/index.js";
1
+ import { loadingCombine } from "../utils/index.js";
2
+ import { keyDiff } from "../utils/keyDiff.js";
3
+ import { objectInstanceStateKeys } from "./objectInstance.js";
4
+ import { objectSubscriptionStateKeys } from "./objectSubscription.js";
2
5
  import { useWatchesRunning } from "./watchesRunning.js";
3
6
  import get from "lodash-es/get.js";
4
7
  import isArray from "lodash-es/isArray.js";
@@ -6,6 +9,15 @@ import isEmpty from "lodash-es/isEmpty.js";
6
9
  import isUndefined from "lodash-es/isUndefined.js";
7
10
  import { computed, effectScope, onScopeDispose, reactive, toRef, unref, watch } from "vue";
8
11
 
12
+ export const objectRelatedStateKeys = [
13
+ "relatedObject",
14
+ "relatedObjectRules",
15
+ "relatedObjectWatchRunning",
16
+ "parentStateObjectWatchRunning",
17
+ ];
18
+
19
+ export const objectRelatedFunctions = [];
20
+
9
21
  export function useObjectRelateds(instances, args) {
10
22
  for (const [key, value] of Object.entries(args)) {
11
23
  useObjectRelated({
@@ -16,47 +28,24 @@ export function useObjectRelateds(instances, args) {
16
28
  }
17
29
 
18
30
  // the single object version of useListRelated
19
- export function useObjectRelated({
20
- parentState,
21
- relatedObjectRules,
22
- relatedObjectPropertyName = "relatedObject", // NOT REACTIVE
23
- passThroughPropertyNames = [
24
- // instance
25
- "crud",
26
- "deleted",
27
- "error",
28
- "errored",
29
- "id",
30
- "loading",
31
- "object",
32
- "retrieveArgs",
33
- // subscription
34
- "intendToRetrieve",
35
- "intendToSubscribe",
36
- "subscribed",
37
- "subscriptionError",
38
- "subscriptionErrored",
39
- "subscriptionLoading",
40
- ], // NOT REACTIVE
41
- }) {
31
+ export function useObjectRelated({ parentState, relatedObjectRules }) {
42
32
  const state = reactive({
43
33
  relatedObjectRules,
44
- relatedObjectObjects: {},
34
+ relatedObject: {},
45
35
  parentStateObjectWatchRunning: false,
46
36
  relatedObjectWatchRunning: false,
47
37
  });
48
38
  const relatedObjectEffectScopes = {};
49
39
 
50
- // don't change relatedObjectPropertyName on us or it will break
51
- const ropn = relatedObjectPropertyName + "";
52
-
53
40
  let watchesRunning = null;
54
41
 
55
42
  const es = effectScope();
56
43
 
57
44
  es.run(() => {
58
- state[ropn] = toRef(state, "relatedObjectObjects");
59
- for (let key of passThroughPropertyNames) {
45
+ for (const key of objectInstanceStateKeys) {
46
+ state[key] = toRef(parentState, key);
47
+ }
48
+ for (const key of objectSubscriptionStateKeys) {
60
49
  state[key] = toRef(parentState, key);
61
50
  }
62
51
 
@@ -64,16 +53,16 @@ export function useObjectRelated({
64
53
  let addedRuleKeys = [],
65
54
  removedRuleKeys = [];
66
55
  if (!state.relatedObjectRules) {
67
- removedRuleKeys = Object.keys(state.relatedObjectObjects);
56
+ removedRuleKeys = Object.keys(state.relatedObject);
68
57
  } else {
69
58
  ({ addedKeys: addedRuleKeys, removedKeys: removedRuleKeys } = keyDiff(
70
59
  Object.keys(state.relatedObjectRules),
71
- Object.keys(state.relatedObjectObjects)
60
+ Object.keys(state.relatedObject)
72
61
  ));
73
62
  }
74
63
 
75
64
  for (const removedRuleKey of removedRuleKeys) {
76
- delete state.relatedObjectObjects[removedRuleKey];
65
+ delete state.relatedObject[removedRuleKey];
77
66
  if (relatedObjectEffectScopes[removedRuleKey]) {
78
67
  relatedObjectEffectScopes[removedRuleKey].stop();
79
68
  delete relatedObjectEffectScopes[removedRuleKey];
@@ -82,7 +71,7 @@ export function useObjectRelated({
82
71
  for (const addedRuleKey of addedRuleKeys) {
83
72
  relatedObjectEffectScopes[addedRuleKey] = effectScope();
84
73
  relatedObjectEffectScopes[addedRuleKey].run(() => {
85
- state.relatedObjectObjects[addedRuleKey] = computed(() => {
74
+ state.relatedObject[addedRuleKey] = computed(() => {
86
75
  // deal with computed objects being passed.
87
76
  const ruleObjects = unref(state.relatedObjectRules?.[addedRuleKey]?.objects);
88
77
  const rulePkKey = state.relatedObjectRules?.[addedRuleKey]?.pkKey || addedRuleKey;
@@ -111,6 +100,7 @@ export function useObjectRelated({
111
100
  });
112
101
 
113
102
  state.relatedRunning = toRef(watchesRunning.state, "running");
103
+ state.running = computed(() => loadingCombine(watchesRunning.state.running, parentState.running));
114
104
 
115
105
  onScopeDispose(() => {
116
106
  for (const key in relatedObjectEffectScopes) {
@@ -1,6 +1,6 @@
1
1
  import { assignReactiveObject, loadingCombine } from "../utils/index.js";
2
2
  import { useCancellableIntent } from "./cancellableIntent.js";
3
- import { useObjectInstance } from "./objectInstance.js";
3
+ import { useObjectInstance, objectInstanceStateKeys } from "./objectInstance.js";
4
4
  import { computed, effectScope, reactive, toRef } from "vue";
5
5
 
6
6
  export class ObjectSubscriptionError extends Error {
@@ -10,13 +10,22 @@ export class ObjectSubscriptionError extends Error {
10
10
  }
11
11
  }
12
12
 
13
- const defaultCrud = {
14
- subscribe: undefined,
15
- };
16
-
17
- export function setObjectSubscriptionCrud({ subscribe }) {
18
- defaultCrud.subscribe = subscribe;
19
- }
13
+ export const objectSubscriptionStateKeys = [
14
+ "subscriptionLoading",
15
+ "subscriptionErrored",
16
+ "subscriptionError",
17
+ "subscribed",
18
+ "intendToRetrieve",
19
+ "intendToSubscribe",
20
+ ];
21
+
22
+ export const objectSubscriptionFunctions = [
23
+ "subscribe",
24
+ "unsubscribe",
25
+ "updateFromSubscription",
26
+ "deleteFromSubscription",
27
+ "clearError",
28
+ ];
20
29
 
21
30
  export function useObjectSubscriptions(subscriptionArgs) {
22
31
  const subscriptions = {};
@@ -26,23 +35,9 @@ export function useObjectSubscriptions(subscriptionArgs) {
26
35
  return subscriptions;
27
36
  }
28
37
 
29
- export function useObjectSubscription({
30
- objectInstance,
31
- props,
32
- passThroughPropertyNames = [
33
- // instance
34
- "crud",
35
- "deleted",
36
- // "error",
37
- // "errored",
38
- "id",
39
- // "loading",
40
- "object",
41
- "retrieveArgs",
42
- ],
43
- }) {
38
+ export function useObjectSubscription({ objectInstance, props, functions }) {
44
39
  if (!objectInstance) {
45
- objectInstance = useObjectInstance({ props });
40
+ objectInstance = useObjectInstance({ props, functions });
46
41
  } else {
47
42
  if (!("id" in props)) {
48
43
  console.error("id not set, must be true for intendToRetrieve or intendToSubscribe to work.");
@@ -50,9 +45,11 @@ export function useObjectSubscription({
50
45
  if (!("retrieveArgs" in props)) {
51
46
  console.error("retrieveArgs not set, must be true for intendToRetrieve or intendToSubscribe to work.");
52
47
  }
53
- }
54
- if (!objectInstance.state.crud.subscribe) {
55
- objectInstance.state.crud.subscribe = defaultCrud.subscribe;
48
+ if (functions) {
49
+ console.error(
50
+ "functions passed to useObjectSubscription, but objectInstance was passed. functions ignored."
51
+ );
52
+ }
56
53
  }
57
54
  const parentState = objectInstance.state;
58
55
  const state = reactive({
@@ -169,7 +166,7 @@ export function useObjectSubscription({
169
166
  state.errored = computed(() => parentState.errored || state.subscriptionErrored);
170
167
  state.error = computed(() => parentState.error || state.subscriptionError);
171
168
 
172
- for (const key of passThroughPropertyNames) {
169
+ for (const key of objectInstanceStateKeys.filter((key) => !["loading", "errored", "error"].includes(key))) {
173
170
  state[key] = toRef(parentState, key);
174
171
  }
175
172