@arrai-innovations/reactive-helpers 22.0.0 → 22.1.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.
Files changed (46) hide show
  1. package/README.md +3 -3
  2. package/config/commonCrud.js +3 -4
  3. package/config/listCrud.js +13 -11
  4. package/config/objectCrud.js +36 -24
  5. package/package.json +11 -1
  6. package/types/config/listCrud.d.ts +6 -8
  7. package/types/config/objectCrud.d.ts +33 -22
  8. package/types/tests/benchmarks/fixtures.d.ts +60 -0
  9. package/types/tests/benchmarks/listLayers.bench.d.ts +1 -0
  10. package/types/tests/benchmarks/listPush.bench.d.ts +1 -0
  11. package/types/tests/benchmarks/listStream.bench.d.ts +1 -0
  12. package/types/tests/unit/use/lifecycleCleanup.spec.d.ts +1 -0
  13. package/types/tests/unit/use/listPerformance.spec.d.ts +1 -0
  14. package/types/tests/unit/utils/cancellablePromise.spec.d.ts +1 -0
  15. package/types/use/cancellableIntent.d.ts +9 -2
  16. package/types/use/combineClasses.d.ts +1 -1
  17. package/types/use/listCalculated.d.ts +21 -20
  18. package/types/use/listInstance.d.ts +6 -1
  19. package/types/use/listRelated.d.ts +15 -15
  20. package/types/use/listSort.d.ts +6 -1
  21. package/types/use/listSubscription.d.ts +6 -2
  22. package/types/use/objectCalculated.d.ts +18 -14
  23. package/types/use/objectInstance.d.ts +4 -2
  24. package/types/use/objectRelated.d.ts +11 -9
  25. package/types/use/objectSubscription.d.ts +6 -5
  26. package/types/utils/cancellableFetch.d.ts +2 -3
  27. package/types/utils/cancellablePromise.d.ts +39 -5
  28. package/types/utils/getFakePk.d.ts +2 -2
  29. package/use/cancellableIntent.js +9 -2
  30. package/use/combineClasses.js +1 -1
  31. package/use/listCalculated.js +22 -17
  32. package/use/listFilter.js +4 -3
  33. package/use/listInstance.js +76 -16
  34. package/use/listRelated.js +9 -9
  35. package/use/listSearch.js +1 -1
  36. package/use/listSort.js +68 -23
  37. package/use/listSubscription.js +10 -1
  38. package/use/object.js +7 -8
  39. package/use/objectCalculated.js +13 -11
  40. package/use/objectInstance.js +9 -3
  41. package/use/objectRelated.js +6 -5
  42. package/use/objectSubscription.js +7 -5
  43. package/use/proxyLoadingError.js +3 -0
  44. package/utils/cancellableFetch.js +3 -3
  45. package/utils/cancellablePromise.js +21 -4
  46. package/utils/getFakePk.js +2 -2
@@ -14,7 +14,7 @@
14
14
  * @example
15
15
  * ```vue
16
16
  * <script setup>
17
- * import { useCombineClasses } from "@vueda/use/combineClasses.js";
17
+ * import { useCombineClasses } from "@arrai-innovations/reactive-helpers";
18
18
  * import { ref } from "vue";
19
19
  * const myClasses = useCombineClasses(
20
20
  * "class1",
@@ -14,16 +14,16 @@
14
14
  * [rule: string]: any,
15
15
  * },
16
16
  * calculatedObjects: {
17
- * [rule: string]: import('vue').ComputedRef<any>,
17
+ * [rule: string]: any,
18
18
  * }
19
19
  * ) => any,
20
- * }} ListCalculatedRules - Defines rules for dynamically calculating new properties for objects in a list. Each rule is a function that takes an object from the list, optionally its related objects, and previously calculated properties to compute a new property. These functions are reactive and re-evaluate when underlying dependencies change.
20
+ * }} ListCalculatedRules - Defines rules for dynamically calculating new properties for objects in a list. Each rule is a function that takes an object from the list, optionally its related objects, and previously calculated properties to compute a new property. These functions are reactive and re-evaluate when underlying dependencies change. Each entry of the third argument is backed by a computed, but it is read through a reactive proxy that unwraps it, so a rule reads `calculatedObjects.otherRule` directly and never `.value`.
21
21
  */
22
22
  /**
23
23
  * The raw state for a list calculated.
24
24
  *
25
25
  * @typedef {object} ListCalculatedRawState - The raw state for a list calculated property.
26
- * @property {{[pk: import('../config/commonCrud.js').Pk]: {[rule: string]: import('vue').ComputedRef<any>}}} calculatedObjects - The calculated objects.
26
+ * @property {{[pk: import('../config/commonCrud.js').Pk]: {[rule: string]: any}}} calculatedObjects - The calculated objects, by object pk and then rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the calculated value and never carry a `.value`.
27
27
  * @property {ListCalculatedRules} calculatedObjectsRules - The rules for the calculated objects.
28
28
  * @property {boolean} calculatedObjectsParentStateObjectsWatchRunning - Whether the parent state objects watch is running.
29
29
  * @property {boolean} calculatedObjectsWatchRunning - Whether the calculated objects watch is running.
@@ -54,7 +54,7 @@
54
54
  /**
55
55
  * The options to create a list calculated composition function.
56
56
  *
57
- * @typedef {object} ListCalculatedOptions - Options to configure the behavior of the list calculated properties.
57
+ * @typedef {object} ListCalculatedOptions - Options to configure the behaviour of the list calculated properties.
58
58
  * @property {ListCalculatedParentState} parentState - The parent state that interacts with the calculated objects.
59
59
  * @property {import('vue').Ref<ListCalculatedRules>} calculatedObjectsRules - A reactive reference to rules used for dynamic calculations
60
60
  * within list objects. Proper setup of this reference ensures that updates are managed reactively, including deep
@@ -93,7 +93,7 @@ export function useListCalculateds(listCalculatedArgs: {
93
93
  * ```vue
94
94
  * <script setup>
95
95
  * import { useListSubscription, useListCalculated } from "@arrai-innovations/reactive-helpers";
96
- * import { reactive, toRef } from "vue";
96
+ * import { reactive } from "vue";
97
97
  *
98
98
  * const listSubscriptionProps = reactive({
99
99
  * // whatever props you need to get the list to work with your crud implementation
@@ -102,14 +102,15 @@ export function useListCalculateds(listCalculatedArgs: {
102
102
  * pkKey: "pk",
103
103
  * intendToList: true,
104
104
  * });
105
- * const listSubscription = useListSubscription(listSubscriptionProps);
105
+ * const listSubscription = useListSubscription({ props: listSubscriptionProps });
106
106
  * const listCalculatedProps = reactive({
107
107
  * parentState: listSubscription.state,
108
- * computedObjectsRules: {
109
- * someRule: (object, relatedObjects, calculatedObjects) => {
110
- * // some complex calculation, relatedObjects would be assuming there was a listRelated between the two
111
- * // calculatedObjects would be the other calculated objects in the list
112
- * // including yourself, so try not to create circular dependencies
108
+ * calculatedObjectsRules: {
109
+ * someRule: (object, relatedObject, calculatedObjects) => {
110
+ * // some complex calculation. relatedObject holds this object's related objects, and is only
111
+ * // populated when a useListRelated sits between the list and this composable.
112
+ * // calculatedObjects holds the other calculated values for this same object,
113
+ * // including this rule, so try not to create circular dependencies.
113
114
  * // this is used as a computed body.
114
115
  * return object.someProperty + object.someOtherProperty;
115
116
  * }
@@ -119,12 +120,12 @@ export function useListCalculateds(listCalculatedArgs: {
119
120
  * </script>
120
121
  * <template>
121
122
  * <ul>
122
- * <!-- reactive list of objects, re-retrieving the list as someListFilter changes. -->
123
- * <li v-for="obj in listInstance.state.objectsInOrder">
123
+ * <!-- reactive list of objects, kept current by the configured subscription function. -->
124
+ * <li v-for="obj in listSubscription.state.objectsInOrder">
124
125
  * {{ obj }}
125
126
  * <div>
126
- * <!-- the computed object or objects based on the rule -->
127
- * {{ listCalculated.state.computedObjects[obj.pk].someRule }}
127
+ * <!-- the calculated value for this object, based on the rule -->
128
+ * {{ listCalculated.state.calculatedObjects[obj.pk].someRule }}
128
129
  * </div>
129
130
  * </li>
130
131
  * </ul>
@@ -139,13 +140,13 @@ export function useListCalculateds(listCalculatedArgs: {
139
140
  */
140
141
  export function useListCalculated({ parentState, calculatedObjectsRules }: ListCalculatedOptions): ListCalculated;
141
142
  /**
142
- * Defines rules for dynamically calculating new properties for objects in a list. Each rule is a function that takes an object from the list, optionally its related objects, and previously calculated properties to compute a new property. These functions are reactive and re-evaluate when underlying dependencies change.
143
+ * Defines rules for dynamically calculating new properties for objects in a list. Each rule is a function that takes an object from the list, optionally its related objects, and previously calculated properties to compute a new property. These functions are reactive and re-evaluate when underlying dependencies change. Each entry of the third argument is backed by a computed, but it is read through a reactive proxy that unwraps it, so a rule reads `calculatedObjects.otherRule` directly and never `.value`.
143
144
  */
144
145
  export type ListCalculatedRules = {
145
146
  [rule: string]: (object: import("../use/objectInstance.js").ExistingCrudObject, relatedObject: {
146
147
  [rule: string]: any;
147
148
  }, calculatedObjects: {
148
- [rule: string]: import("vue").ComputedRef<any>;
149
+ [rule: string]: any;
149
150
  }) => any;
150
151
  };
151
152
  /**
@@ -153,11 +154,11 @@ export type ListCalculatedRules = {
153
154
  */
154
155
  export type ListCalculatedRawState = {
155
156
  /**
156
- * The calculated objects.
157
+ * The calculated objects, by object pk and then rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the calculated value and never carry a `.value`.
157
158
  */
158
159
  calculatedObjects: {
159
160
  [pk: import("../config/commonCrud.js").Pk]: {
160
- [rule: string]: import("vue").ComputedRef<any>;
161
+ [rule: string]: any;
161
162
  };
162
163
  };
163
164
  /**
@@ -194,7 +195,7 @@ export type ListCalculatedState = import("vue").UnwrapNestedRefs<ListCalculatedP
194
195
  */
195
196
  export type ListCalculatedParentState = import("vue").UnwrapNestedRefs<(import("./listInstance.js").ListInstanceRawState & Partial<import("./listSubscription.js").ListSubscriptionRawState> & Partial<import("./listRelated.js").ListRelatedRawState>)>;
196
197
  /**
197
- * Options to configure the behavior of the list calculated properties.
198
+ * Options to configure the behaviour of the list calculated properties.
198
199
  */
199
200
  export type ListCalculatedOptions = {
200
201
  /**
@@ -54,6 +54,7 @@
54
54
  * @property {object} params - Arguments passed to the server for listing operations.
55
55
  * @property {ObjectsMap} objectsMap - The map of objects stored by their pks.
56
56
  * @property {ObjectsByPk} objects - The list objects stored by their pks.
57
+ * @property {number} objectsVersion - Increments when the set of object keys changes.
57
58
  * @property {ListOrder} order - The order of objects in the list.
58
59
  * @property {ObjectsInOrder} objectsInOrder - The objects in the order specified by the list.
59
60
  * @property {import('vue').ShallowReactive<PaginateInfo>} paginateInfo - Pagination information for the list.
@@ -166,7 +167,7 @@ export function useListInstances(listInstanceArgs: {
166
167
  * ```
167
168
  *
168
169
  * @param {ListInstanceOptions} options - Specifies the configuration options for creating a list instance, including
169
- * properties for CRUD operations and UI behaviors like page persistence.
170
+ * properties for CRUD operations and UI behaviours like page persistence.
170
171
  * @returns {ListInstance} The list instance.
171
172
  * @throws {ListInstanceError} If the props are missing.
172
173
  */
@@ -319,6 +320,10 @@ export type ListInstanceRawMyState = {
319
320
  * The list objects stored by their pks.
320
321
  */
321
322
  objects: ObjectsByPk;
323
+ /**
324
+ * Increments when the set of object keys changes.
325
+ */
326
+ objectsVersion: number;
322
327
  /**
323
328
  * The order of objects in the list.
324
329
  */
@@ -6,8 +6,8 @@
6
6
  */
7
7
  /**
8
8
  * @typedef {object} ListRelatedRule - The rule for defining relationships for objects in a list.
9
- * @property {string} pkKey - Specifies the foreign key used to link objects across lists. Planned to be renamed to
10
- * 'fkKey' to better reflect its usage.
9
+ * @property {string} [pkKey] - Specifies the foreign key used to link objects across lists. Defaults to the rule's
10
+ * own key when omitted. Planned to be renamed to 'fkKey' to better reflect its usage.
11
11
  * @property {string[]} [order] - Specifies the order in which related objects should be sorted, if applicable.
12
12
  * @property {import('./listInstance.js').ObjectsByPk} objects - The objects that can be related based on the foreign key.
13
13
  */
@@ -20,20 +20,20 @@
20
20
  * @typedef {object} ListRelatedRawState - Represents the internal state used by the list related composition function. It manages and computes the relationships between objects based on specified rules, providing real-time updates to related objects as the parent state changes.
21
21
  * @property {{
22
22
  * [pk: import('../config/commonCrud.js').Pk]: {
23
- * [rule: string]: import('vue').ComputedRef<any>,
23
+ * [rule: string]: any,
24
24
  * },
25
- * }} relatedObjects - Stores computed references to related objects, allowing for dynamic access based on object pk and specific rules.
25
+ * }} relatedObjects - The related objects, by object pk and then rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the related object (or array of related objects) and never carry a `.value`.
26
26
  * @property {ListRelatedRules} relatedObjectsRules - Defines the rules for establishing relationships, such as foreign key links and sorting orders.
27
27
  * @property {{
28
28
  * [pk: import('../config/commonCrud.js').Pk]: {
29
29
  * [rule: string]: import('vue').ComputedRef<[object, string]>,
30
30
  * },
31
- * }} objAndKeyForPkAndRule - Maps each object pk and rule to a tuple consisting of the related object and its respective key, facilitating direct data manipulation.
31
+ * }} objAndKeyForPkAndRule - Maps each object pk and rule to a tuple consisting of the related object and its respective key, facilitating direct data manipulation. Reads through the reactive state unwrap the computed to the tuple itself, so `.value` is not used.
32
32
  * @property {{
33
33
  * [pk: import('../config/commonCrud.js').Pk]: {
34
- * [rule: string]: import('vue').ComputedRef<any>,
34
+ * [rule: string]: any,
35
35
  * },
36
- * }} fkForPkAndRule - Maintains computed references to the foreign keys for each object pk and rule, crucial for navigating complex data relationships.
36
+ * }} fkForPkAndRule - The foreign key for each object pk and rule, crucial for navigating complex data relationships. Each entry is backed by a computed that the reactive proxy unwraps on read.
37
37
  * @property {boolean} relatedObjectsParentStateObjectsWatchRunning - Flags whether the watch on parent state objects is currently active, ensuring updates trigger as needed.
38
38
  * @property {boolean} relatedObjectsWatchRunning - Indicates if watches on the related objects themselves are active, managing updates efficiently.
39
39
  * @property {boolean} relatedRunning - Signals whether any computations related to object relationships are currently in progress.
@@ -163,10 +163,10 @@ export function useListRelated({ parentState, relatedObjectsRules }: ListRelated
163
163
  */
164
164
  export type ListRelatedRule = {
165
165
  /**
166
- * Specifies the foreign key used to link objects across lists. Planned to be renamed to
167
- * 'fkKey' to better reflect its usage.
166
+ * Specifies the foreign key used to link objects across lists. Defaults to the rule's
167
+ * own key when omitted. Planned to be renamed to 'fkKey' to better reflect its usage.
168
168
  */
169
- pkKey: string;
169
+ pkKey?: string;
170
170
  /**
171
171
  * Specifies the order in which related objects should be sorted, if applicable.
172
172
  */
@@ -187,11 +187,11 @@ export type ListRelatedRules = {
187
187
  */
188
188
  export type ListRelatedRawState = {
189
189
  /**
190
- * Stores computed references to related objects, allowing for dynamic access based on object pk and specific rules.
190
+ * The related objects, by object pk and then rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the related object (or array of related objects) and never carry a `.value`.
191
191
  */
192
192
  relatedObjects: {
193
193
  [pk: import("../config/commonCrud.js").Pk]: {
194
- [rule: string]: import("vue").ComputedRef<any>;
194
+ [rule: string]: any;
195
195
  };
196
196
  };
197
197
  /**
@@ -199,7 +199,7 @@ export type ListRelatedRawState = {
199
199
  */
200
200
  relatedObjectsRules: ListRelatedRules;
201
201
  /**
202
- * Maps each object pk and rule to a tuple consisting of the related object and its respective key, facilitating direct data manipulation.
202
+ * Maps each object pk and rule to a tuple consisting of the related object and its respective key, facilitating direct data manipulation. Reads through the reactive state unwrap the computed to the tuple itself, so `.value` is not used.
203
203
  */
204
204
  objAndKeyForPkAndRule: {
205
205
  [pk: import("../config/commonCrud.js").Pk]: {
@@ -207,11 +207,11 @@ export type ListRelatedRawState = {
207
207
  };
208
208
  };
209
209
  /**
210
- * Maintains computed references to the foreign keys for each object pk and rule, crucial for navigating complex data relationships.
210
+ * The foreign key for each object pk and rule, crucial for navigating complex data relationships. Each entry is backed by a computed that the reactive proxy unwraps on read.
211
211
  */
212
212
  fkForPkAndRule: {
213
213
  [pk: import("../config/commonCrud.js").Pk]: {
214
- [rule: string]: import("vue").ComputedRef<any>;
214
+ [rule: string]: any;
215
215
  };
216
216
  };
217
217
  /**
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Sets default configuration options for all list sorting operations within the application. This function allows
3
- * global settings to be specified that affect the behavior of sorting operations unless overridden by specific
3
+ * global settings to be specified that affect the behaviour of sorting operations unless overridden by specific
4
4
  * instance configurations.
5
5
  *
6
6
  * @param {object} options - Configuration options to set as defaults for list sorting.
@@ -22,6 +22,7 @@ export function setListSortDefaultOptions({ sortThrottleWait }: {
22
22
  * @typedef {object} ListSortRawState - Represents the raw state used by the list sorting functionality. Includes all configurations and state necessary to manage sorting operations within a Vue application.
23
23
  * @property {OrderByRule[]} orderByRules - Current sorting rules applied to the list.
24
24
  * @property {boolean[]} orderByDesc - Flags indicating whether each sort criterion is in descending order.
25
+ * @property {import('vue').ComputedRef<boolean|undefined>} running - Whether the sort is settling a pending reorder, combined with the upstream running state so it propagates through the composed list state. True from when a new order is computed until the throttled reorder lands.
25
26
  */
26
27
  /**
27
28
  *
@@ -136,6 +137,10 @@ export type ListSortRawState = {
136
137
  * Flags indicating whether each sort criterion is in descending order.
137
138
  */
138
139
  orderByDesc: boolean[];
140
+ /**
141
+ * Whether the sort is settling a pending reorder, combined with the upstream running state so it propagates through the composed list state. True from when a new order is computed until the throttled reorder lands.
142
+ */
143
+ running: import("vue").ComputedRef<boolean | undefined>;
139
144
  };
140
145
  /**
141
146
  * The raw, pre-unwrapped parent state consumed by the list sort mixin, aggregating the upstream list composable states.
@@ -16,7 +16,9 @@
16
16
  * @typedef {import('vue').Reactive<ListSubscriptionRawState>} ListSubscriptionState - A reactive object that manages a list of objects, as returned by `useListInstance`.
17
17
  */
18
18
  /**
19
- * @typedef {Pick<import('./loadingError.js').LoadingErrorStatus, "clearError">} ListSubscriptionFunctions - The methods available on a list subscription.
19
+ * @typedef {Pick<import('./loadingError.js').LoadingErrorStatus, "clearError"> & {
20
+ * stop: () => void
21
+ * }} ListSubscriptionFunctions - The methods available on a list subscription.
20
22
  */
21
23
  /**
22
24
  * @typedef {{
@@ -151,7 +153,9 @@ export type ListSubscriptionState = import("vue").Reactive<ListSubscriptionRawSt
151
153
  /**
152
154
  * The methods available on a list subscription.
153
155
  */
154
- export type ListSubscriptionFunctions = Pick<import("./loadingError.js").LoadingErrorStatus, "clearError">;
156
+ export type ListSubscriptionFunctions = Pick<import("./loadingError.js").LoadingErrorStatus, "clearError"> & {
157
+ stop: () => void;
158
+ };
155
159
  /**
156
160
  * The context (state, list instance, and loading/error status) bound to the shared list subscription functions.
157
161
  */
@@ -20,7 +20,7 @@ export function useObjectCalculateds(objectCalculatedArgs: {
20
20
  * ```vue
21
21
  * <script setup>
22
22
  * import { useObjectCalculated, useObjectSubscription } from "@arrai-innovations/reactive-helpers";
23
- * import { ref, reactive } from "vue";
23
+ * import { reactive } from "vue";
24
24
  *
25
25
  * const objectSubscriptionProps = reactive({
26
26
  * // whatever object subscription props you need to work with your crud implementation
@@ -29,21 +29,21 @@ export function useObjectCalculateds(objectCalculatedArgs: {
29
29
  * pk: '1',
30
30
  * pkKey: 'id',
31
31
  * intendToRetrieve: true,
32
- * };
33
- * const objectSubscription = useObjectSubscription(objectSubscriptionProps);
32
+ * });
33
+ * const objectSubscription = useObjectSubscription({ props: objectSubscriptionProps });
34
34
  * const objectCalculatedProps = reactive({
35
35
  * parentState: objectSubscription.state,
36
36
  * calculatedObjectRules: {
37
- * someRule: (object, relatedObject, calculatedObjects) => {
38
- * // some complex calculation, relatedObjects would be assuming there was a listRelated between the two
39
- * // calculatedObjects would be the other calculated objects in the list
40
- * // including yourself, so try not to create circular dependencies
37
+ * someRule: (object, relatedObject) => {
38
+ * // some complex calculation. relatedObject holds the managed object's related objects, and is
39
+ * // only populated when a useObjectRelated sits between the object and this composable.
41
40
  * // this is used as a computed body.
42
41
  * return object.someProperty + object.someOtherProperty;
43
42
  * },
44
- * ...
43
+ * // ...further rules
45
44
  * },
46
45
  * });
46
+ * const objectCalculated = useObjectCalculated(objectCalculatedProps);
47
47
  * </script>
48
48
  * <template>
49
49
  * <div>
@@ -65,14 +65,16 @@ export function useObjectCalculated({ parentState, calculatedObjectRules }: Obje
65
65
  /**
66
66
  * @typedef {{
67
67
  * [ruleKey: string]: (object: any, relatedObject: any) => any
68
- * }} ObjectCalculatedRules - The object calculated state keys.
68
+ * }} ObjectCalculatedRules - Rules for calculating values from the managed object, keyed by rule name. Each rule is used
69
+ * as a computed body and receives exactly two arguments: the managed object and its related objects (the latter only
70
+ * populated when a useObjectRelated sits upstream).
69
71
  */
70
72
  /**
71
73
  * @typedef {object} ObjectCalculatedRawState - The raw state for object calculated.
72
74
  * @property {ObjectCalculatedRules} calculatedObjectRules - The calculated object rules.
73
75
  * @property {{
74
- * [ruleKey: string]: import('vue').ComputedRef<any>
75
- * }} calculatedObject - The calculated object.
76
+ * [ruleKey: string]: any
77
+ * }} calculatedObject - The calculated values, by rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the calculated value and never carry a `.value`.
76
78
  * @property {boolean} calculatedObjectWatchRunning - Whether the calculated object watch is running.
77
79
  * @property {boolean} parentStateObjectWatchRunning - Whether the parent state object watch is running.
78
80
  * @property {boolean} calculatedRunning - Whether the calculated is running.
@@ -126,7 +128,9 @@ export const objectCalculatedStateKeys: string[];
126
128
  /** @internal */
127
129
  export const objectCalculatedFunctions: any[];
128
130
  /**
129
- * The object calculated state keys.
131
+ * Rules for calculating values from the managed object, keyed by rule name. Each rule is used
132
+ * as a computed body and receives exactly two arguments: the managed object and its related objects (the latter only
133
+ * populated when a useObjectRelated sits upstream).
130
134
  */
131
135
  export type ObjectCalculatedRules = {
132
136
  [ruleKey: string]: (object: any, relatedObject: any) => any;
@@ -140,10 +144,10 @@ export type ObjectCalculatedRawState = {
140
144
  */
141
145
  calculatedObjectRules: ObjectCalculatedRules;
142
146
  /**
143
- * The calculated object.
147
+ * The calculated values, by rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the calculated value and never carry a `.value`.
144
148
  */
145
149
  calculatedObject: {
146
- [ruleKey: string]: import("vue").ComputedRef<any>;
150
+ [ruleKey: string]: any;
147
151
  };
148
152
  /**
149
153
  * Whether the calculated object watch is running.
@@ -106,7 +106,8 @@ export function useObjectInstance({ props, handlers }: ObjectInstanceOptions): O
106
106
  * @property {import('vue').Ref<string|undefined>} pkKey - The pk key of the object.
107
107
  * @property {import('vue').Ref<{[key:string]: any}>} params - The arguments to be passed to the retrieve function.
108
108
  * @property {import('vue').Reactive<CrudObject>} object - The object.
109
- * @property {boolean} deleted - Whether the object is deleted.
109
+ * @property {boolean} deleted - Whether the object was deleted by the delete action or a subscription delete
110
+ * event. Cleared when a later create, retrieve, update, or patch repopulates the object, and by `clear()`.
110
111
  */
111
112
  /**
112
113
  * @typedef {ObjectInstanceRawMyState & import('./loadingError.js').LoadingErrorProperties} ObjectInstanceRawState - The raw state of the object instance.
@@ -275,7 +276,8 @@ export type ObjectInstanceRawMyState = {
275
276
  */
276
277
  object: import("vue").Reactive<CrudObject>;
277
278
  /**
278
- * Whether the object is deleted.
279
+ * Whether the object was deleted by the delete action or a subscription delete
280
+ * event. Cleared when a later create, retrieve, update, or patch repopulates the object, and by `clear()`.
279
281
  */
280
282
  deleted: boolean;
281
283
  };
@@ -83,7 +83,7 @@ export function useObjectRelateds(objectRelatedArgs: {
83
83
  * order: ['3','1','2'],
84
84
  * },
85
85
  * secondOrder: {
86
- * pkKey: 'relatedObject.secondOrderId',
86
+ * pkKey: 'relatedItem.firstOrder.secondOrderId',
87
87
  * objects: someOtherObjectsSource.objects,
88
88
  * },
89
89
  * },
@@ -115,9 +115,10 @@ export function useObjectRelated({ parentState, relatedObjectRules }: ObjectRela
115
115
  */
116
116
  /**
117
117
  * @typedef {object} ObjectRelatedRule - The rule for defining relationships for the managed object to other collections of objects.
118
- * @property {string} pkKey - The key in the managed object that corresponds to the key in the related object.
118
+ * @property {string} [pkKey] - The key in the managed object that corresponds to the key in the related object.
119
+ * Defaults to the rule's own key when omitted.
119
120
  * @property {import('./listInstance.js').ObjectsByPk} objects - The related objects, indexed by the key in the related object.
120
- * @property {string[]} order - The order of the related objects, if the related objects are an array.
121
+ * @property {string[]} [order] - The order of the related objects, if the related objects are an array.
121
122
  */
122
123
  /**
123
124
  * @typedef {{
@@ -130,8 +131,8 @@ export function useObjectRelated({ parentState, relatedObjectRules }: ObjectRela
130
131
  * @typedef {object} ObjectRelatedRawState - The raw reactive state of the object related composable, holding its rules, computed relations, and running flags.
131
132
  * @property {ObjectRelatedRawRules} relatedObjectRules - The rules for defining relationships for the managed object to other collections of objects.
132
133
  * @property {{
133
- * [rule: string]: import('vue').ComputedRef<any>,
134
- * }} relatedObject - The related objects, indexed by the key in the related object.
134
+ * [rule: string]: any,
135
+ * }} relatedObject - The related objects, by rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the related object (or array of related objects) and never carry a `.value`.
135
136
  * @property {boolean} relatedObjectWatchRunning - Whether the related object watch is running.
136
137
  * @property {boolean} parentStateObjectWatchRunning - Whether the parent state object watch is running.
137
138
  * @property {boolean} relatedRunning - Whether the related objects are loading.
@@ -204,8 +205,9 @@ export type ObjectRelatedOptions = {
204
205
  export type ObjectRelatedRule = {
205
206
  /**
206
207
  * The key in the managed object that corresponds to the key in the related object.
208
+ * Defaults to the rule's own key when omitted.
207
209
  */
208
- pkKey: string;
210
+ pkKey?: string;
209
211
  /**
210
212
  * The related objects, indexed by the key in the related object.
211
213
  */
@@ -213,7 +215,7 @@ export type ObjectRelatedRule = {
213
215
  /**
214
216
  * The order of the related objects, if the related objects are an array.
215
217
  */
216
- order: string[];
218
+ order?: string[];
217
219
  };
218
220
  /**
219
221
  * The rules for defining relationships for the managed object to other collections of objects.
@@ -230,10 +232,10 @@ export type ObjectRelatedRawState = {
230
232
  */
231
233
  relatedObjectRules: ObjectRelatedRawRules;
232
234
  /**
233
- * The related objects, indexed by the key in the related object.
235
+ * The related objects, by rule name. Each entry is backed by a computed, but it is read through a reactive proxy that unwraps it, so reads yield the related object (or array of related objects) and never carry a `.value`.
234
236
  */
235
237
  relatedObject: {
236
- [rule: string]: import("vue").ComputedRef<any>;
238
+ [rule: string]: any;
237
239
  };
238
240
  /**
239
241
  * Whether the related object watch is running.
@@ -66,7 +66,7 @@ export function useObjectSubscriptions(subscriptionArgs: {
66
66
  * ```
67
67
  * <script setup>
68
68
  * import { useObjectSubscription } from "@arrai-innovations/reactive-helpers";
69
- * import { reactive, ref, toRef } from "vue";
69
+ * import { reactive, toRef } from "vue";
70
70
  *
71
71
  * const pkKey = "id";
72
72
  * const props = defineProps({
@@ -85,11 +85,12 @@ export function useObjectSubscriptions(subscriptionArgs: {
85
85
  * params: {
86
86
  * fields: ['foo', 'bar'],
87
87
  * },
88
- * intendToRetrieve: false,
89
- * intendToSubscribe: false,
88
+ * intendToRetrieve: true,
89
+ * intendToSubscribe: true,
90
+ * });
91
+ * const objectSubscription = useObjectSubscription({
92
+ * props: objectSubscriptionProps,
90
93
  * });
91
- * objectSubscriptionProps.intendToRetrieve = objectSubscriptionProps.intendToSubscribe = computed(()=> !!props.pk);
92
- * const objectSubscription = useObjectSubscription(objectSubscriptionProps);
93
94
  * </script>
94
95
  * <template>
95
96
  * <div v-if="objectSubscription.state.loading">Loading...</div>
@@ -5,7 +5,6 @@
5
5
  * @param {RequestInfo} input - The URL or Request object to fetch.
6
6
  * @param {RequestInit} init - The options for the fetch request.
7
7
  * @param {(response: Response) => Promise<T>} transform - A function to transform the response.
8
- * @returns {CancellablePromise<T>} A cancellable promise that resolves to the transformed response.
8
+ * @returns {import("./cancellablePromise.js").CancellablePromise<T>} A cancellable promise that resolves to the transformed response.
9
9
  */
10
- export function cancellableFetch<T>(input: RequestInfo, init: RequestInit, transform: (response: Response) => Promise<T>): CancellablePromise<T>;
11
- import { CancellablePromise } from "./cancellablePromise.js";
10
+ export function cancellableFetch<T>(input: RequestInfo, init: RequestInit, transform: (response: Response) => Promise<T>): import("./cancellablePromise.js").CancellablePromise<T>;
@@ -1,12 +1,33 @@
1
1
  /**
2
- * Wraps a promise and optionally adds a cancel method if provided.
2
+ * A Promise that can be cancelled.
3
3
  *
4
4
  * @template T
5
- * @param {Promise<T>} inner - The inner promise to wrap.
6
- * @param {((reason?: any) => Promise<void> | void)=} cancel - Optional cancel function.
7
- * @returns {MaybeCancellablePromise<T>} The wrapped promise with an optional cancel method.
5
+ * @typedef {Promise<T> & { cancel: (reason?: any) => Promise<void> | void }} CancellablePromise - A promise augmented with a cancel method to abort the pending operation.
6
+ */
7
+ /**
8
+ * A possibly cancellable promise.
9
+ *
10
+ * @template T
11
+ * @typedef {Promise<T> & { cancel?: (reason?: any) => Promise<void> | void }} MaybeCancellablePromise - A promise that may optionally carry a cancel method to abort the pending operation.
12
+ */
13
+ /**
14
+ * Adds a cancel method to a promise.
15
+ *
16
+ * @template T
17
+ * @param {Promise<T>} promise - The promise to make cancellable.
18
+ * @param {(reason?: any) => (Promise<void>|void)} cancel - The function to cancel the promise.
19
+ * @returns {CancellablePromise<T>} The cancellable promise.
20
+ */
21
+ export function makeCancellable<T>(promise: Promise<T>, cancel: (reason?: any) => (Promise<void> | void)): CancellablePromise<T>;
22
+ /**
23
+ * Adds a cancel method to a promise.
24
+ *
25
+ * @deprecated Use {@link makeCancellable} instead.
26
+ * @template T
27
+ * @param {Promise<T>} promise - The promise to make cancellable.
28
+ * @param {(reason?: any) => (Promise<void>|void)} cancel - The function to cancel the promise.
29
+ * @returns {CancellablePromise<T>} The cancellable promise.
8
30
  */
9
- export function wrapMaybeCancellable<T>(inner: Promise<T>, cancel?: ((reason?: any) => Promise<void> | void) | undefined): MaybeCancellablePromise<T>;
10
31
  export function CancellablePromise<T>(promise: Promise<T>, cancel: (reason?: any) => (Promise<void> | void)): CancellablePromise<T>;
11
32
  /**
12
33
  * A promise augmented with a cancel method to abort the pending operation.
@@ -18,6 +39,8 @@ export namespace CancellablePromise {
18
39
  /**
19
40
  * Creates a rejected 'cancellable' promise.
20
41
  *
42
+ * @deprecated Use `Promise.reject` directly; a plain rejected promise already
43
+ * satisfies {@link MaybeCancellablePromise}.
21
44
  * @param {any} reason - The reason for the rejection.
22
45
  * @returns {MaybeCancellablePromise<never>} A rejected 'cancellable' promise.
23
46
  */
@@ -25,12 +48,23 @@ export namespace CancellablePromise {
25
48
  /**
26
49
  * Creates a resolved 'cancellable' promise.
27
50
  *
51
+ * @deprecated Use `Promise.resolve` directly; a plain resolved promise already
52
+ * satisfies {@link MaybeCancellablePromise}.
28
53
  * @template T
29
54
  * @param {T} value - The value to resolve the promise with.
30
55
  * @returns {MaybeCancellablePromise<T>} A resolved 'cancellable' promise.
31
56
  */
32
57
  function resolve<T_1>(value: T_1): MaybeCancellablePromise<T_1>;
33
58
  }
59
+ /**
60
+ * Wraps a promise and optionally adds a cancel method if provided.
61
+ *
62
+ * @template T
63
+ * @param {Promise<T>} inner - The inner promise to wrap.
64
+ * @param {((reason?: any) => Promise<void> | void)=} cancel - Optional cancel function.
65
+ * @returns {MaybeCancellablePromise<T>} The wrapped promise with an optional cancel method.
66
+ */
67
+ export function wrapMaybeCancellable<T>(inner: Promise<T>, cancel?: ((reason?: any) => Promise<void> | void) | undefined): MaybeCancellablePromise<T>;
34
68
  /**
35
69
  * A promise that may optionally carry a cancel method to abort the pending operation.
36
70
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Get a fake pk that is not in the array, set, map, or object. The fake pk is negative number, so they can be
3
- * differentiated from real ids. They are returned as strings, as javascript object property keys are always strings.
2
+ * Get a random safe integer at or below zero and return it as a string. A candidate is redrawn when its numeric value
3
+ * exists in an array field, Set, or Map, or when its string property key exists in an object.
4
4
  *
5
5
  * @param {Array|Set|Map|object} arraySetMapOrObject - The array, set, map, or object to check for the fake pk.
6
6
  * An array is assumed to be an array of objects.
@@ -98,12 +98,19 @@ export class CancellableIntentError extends Error {
98
98
  /**
99
99
  * Calls your awaitable function with the arguments you pass in when the watch arguments change and are all truthy.
100
100
  * Watch arguments should be a reactive object.
101
- * If the promise is not resolved before the watch arguments change again, the previous promise is cancelled.
101
+ *
102
+ * If the watch arguments change again before the promise resolves, the in-flight promise is cancelled only when it
103
+ * carries a `cancel` method (a `MaybeCancellablePromise`); a plain promise is left to run to completion. That
104
+ * distinction is visible through the composables built on this one. `useObjectSubscription` calls
105
+ * `objectInstance.retrieve()` again for the new key, and that call returns the promise already in flight for the
106
+ * previous key, so the stale record is assigned and the new key is never fetched. `useListSubscription` guards its
107
+ * list intent on the list's own loading state, so the superseded run is left to finish and the list is then listed
108
+ * again with the current arguments.
102
109
  *
103
110
  * @example
104
111
  * ```vue
105
112
  * <script setup>
106
- * import { useCancellableIntent } from "@vueda/use/cancellableIntent.js";
113
+ * import { useCancellableIntent } from "@arrai-innovations/reactive-helpers";
107
114
  * import { ref, computed, onMounted, onUnmounted } from "vue";
108
115
  *
109
116
  * const myValue = ref(0);
@@ -32,7 +32,7 @@ const isRefOrReactive = (v) => isRef(v) || isReactive(v);
32
32
  * @example
33
33
  * ```vue
34
34
  * <script setup>
35
- * import { useCombineClasses } from "@vueda/use/combineClasses.js";
35
+ * import { useCombineClasses } from "@arrai-innovations/reactive-helpers";
36
36
  * import { ref } from "vue";
37
37
  * const myClasses = useCombineClasses(
38
38
  * "class1",