@arrai-innovations/reactive-helpers 15.0.0 → 16.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.
@@ -66,19 +66,27 @@ const defaultCrud = {
66
66
  */
67
67
 
68
68
  /**
69
- * @typedef {(ListFnArgs)=>void} ListFn
69
+ * @typedef {object} ExecuteActionFnArgs
70
+ * @property {object} crudArgs - The arguments to be passed to the crud functions.
71
+ * @property {string[]} pks - The ids of the objects to be acted upon.
72
+ * @property {string} pkKey - The key name of the primary key.
73
+ * @property {string} action - The action to execute.
74
+ */
75
+
76
+ /**
77
+ * @typedef {(ListFnArgs)=>Promise<boolean> & { cancel: () => Promise<void>|void }} ListFn - The list function to get a list of items, returning a boolean indicating success.
70
78
  */
71
79
 
72
80
  /**
73
- * @typedef {(DeleteFnArgs)=>void} BulkDeleteFn
81
+ * @typedef {(DeleteFnArgs)=>Promise<boolean> & { cancel: () => Promise<void>|void }} BulkDeleteFn - The delete function to bulk delete a list of items.
74
82
  */
75
83
 
76
84
  /**
77
- * @typedef {(SubscribeFnArgs)=>void} SubscribeFn
85
+ * @typedef {(SubscribeFnArgs)=>Promise<boolean> & { cancel: () => Promise<void>|void }} SubscribeFn - The subscribe function to set up a subscription to a list of items.
78
86
  */
79
87
 
80
88
  /**
81
- * @typedef {(ExecuteActionFnArgs)=>void} ExecuteActionFn
89
+ * @typedef {(ExecuteActionFnArgs)=>Promise<import('./objectCrud.js').ResponseData|false> & { cancel: () => Promise<void>|void }} ExecuteActionFn - The function to execute a certain action on a list of items, returning the response data or false.
82
90
  */
83
91
 
84
92
  /**
@@ -79,7 +79,7 @@ const defaultCrud = {
79
79
  */
80
80
 
81
81
  /**
82
- * @typedef {Promise<object|string>} ResponseData
82
+ * @typedef {Promise<object|string> & { cancel: () => Promise<void>|void }} ResponseData
83
83
  */
84
84
 
85
85
  /**
@@ -91,7 +91,7 @@ const defaultCrud = {
91
91
  * @property {(UpdateDetailArgs)=>ResponseData} [update] - A function to be used instead of the default crud update function.
92
92
  * @property {(DeleteDetailArgs)=>ResponseData} [delete] - A function to be used instead of the default crud delete function.
93
93
  * @property {(PartialDetailArgs)=>ResponseData} [patch] - A function to be used instead of the default crud patch function.
94
- * @property {(SubscribeArgs)=>void} [subscribe] - A function to be used instead of the default crud subscribe function.
94
+ * @property {(SubscribeArgs)=>void & { cancel: () => Promise<void>|void }} [subscribe] - A function to be used instead of the default crud subscribe function.
95
95
  */
96
96
 
97
97
  /**
package/docs/README.md CHANGED
@@ -35,6 +35,7 @@
35
35
  - [utils/deleteKey](utils/deleteKey.md)
36
36
  - [utils/flattenPaths](utils/flattenPaths.md)
37
37
  - [utils/getFakePk](utils/getFakePk.md)
38
+ - [utils/keepAliveTry](utils/keepAliveTry.md)
38
39
  - [utils/keyDiff](utils/keyDiff.md)
39
40
  - [utils/loadingCombine](utils/loadingCombine.md)
40
41
  - [utils/proxyRunning](utils/proxyRunning.md)
@@ -32,6 +32,36 @@ The ids of the objects to be deleted.
32
32
 
33
33
  ***
34
34
 
35
+ ### ExecuteActionFnArgs
36
+
37
+ #### Properties
38
+
39
+ ##### action
40
+
41
+ > **action**: `string`
42
+
43
+ The action to execute.
44
+
45
+ ##### crudArgs
46
+
47
+ > **crudArgs**: `any`
48
+
49
+ The arguments to be passed to the crud functions.
50
+
51
+ ##### pkKey
52
+
53
+ > **pkKey**: `string`
54
+
55
+ The key name of the primary key.
56
+
57
+ ##### pks
58
+
59
+ > **pks**: `string`[]
60
+
61
+ The ids of the objects to be acted upon.
62
+
63
+ ***
64
+
35
65
  ### ListCrudArgs
36
66
 
37
67
  #### Properties
@@ -179,7 +209,9 @@ The method to call when new data is received.
179
209
 
180
210
  ### BulkDeleteFn()
181
211
 
182
- > **BulkDeleteFn**\<\>: (`DeleteFnArgs`) => `void`
212
+ > **BulkDeleteFn**\<\>: (`DeleteFnArgs`) => `Promise`\<`boolean`\> & `object`
213
+
214
+ The delete function to bulk delete a list of items.
183
215
 
184
216
  #### Type Parameters
185
217
 
@@ -189,13 +221,15 @@ The method to call when new data is received.
189
221
 
190
222
  #### Returns
191
223
 
192
- `void`
224
+ `Promise`\<`boolean`\> & `object`
193
225
 
194
226
  ***
195
227
 
196
228
  ### ExecuteActionFn()
197
229
 
198
- > **ExecuteActionFn**\<\>: (`ExecuteActionFnArgs`) => `void`
230
+ > **ExecuteActionFn**\<\>: (`ExecuteActionFnArgs`) => `Promise`\<[`config/objectCrud`](objectCrud.md) \| `false`\> & `object`
231
+
232
+ The function to execute a certain action on a list of items, returning the response data or false.
199
233
 
200
234
  #### Type Parameters
201
235
 
@@ -205,13 +239,15 @@ The method to call when new data is received.
205
239
 
206
240
  #### Returns
207
241
 
208
- `void`
242
+ `Promise`\<[`config/objectCrud`](objectCrud.md) \| `false`\> & `object`
209
243
 
210
244
  ***
211
245
 
212
246
  ### ListFn()
213
247
 
214
- > **ListFn**\<\>: (`ListFnArgs`) => `void`
248
+ > **ListFn**\<\>: (`ListFnArgs`) => `Promise`\<`boolean`\> & `object`
249
+
250
+ The list function to get a list of items, returning a boolean indicating success.
215
251
 
216
252
  #### Type Parameters
217
253
 
@@ -221,7 +257,7 @@ The method to call when new data is received.
221
257
 
222
258
  #### Returns
223
259
 
224
- `void`
260
+ `Promise`\<`boolean`\> & `object`
225
261
 
226
262
  ***
227
263
 
@@ -245,7 +281,9 @@ The method to call when new data is received.
245
281
 
246
282
  ### SubscribeFn()
247
283
 
248
- > **SubscribeFn**\<\>: (`SubscribeFnArgs`) => `void`
284
+ > **SubscribeFn**\<\>: (`SubscribeFnArgs`) => `Promise`\<`boolean`\> & `object`
285
+
286
+ The subscribe function to set up a subscription to a list of items.
249
287
 
250
288
  #### Type Parameters
251
289
 
@@ -255,7 +293,7 @@ The method to call when new data is received.
255
293
 
256
294
  #### Returns
257
295
 
258
- `void`
296
+ `Promise`\<`boolean`\> & `object`
259
297
 
260
298
  ***
261
299
 
@@ -142,7 +142,7 @@ A function to be used instead of the default crud retrieve function.
142
142
 
143
143
  ##### subscribe()
144
144
 
145
- > **subscribe**: (`SubscribeArgs`) => `void`
145
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
146
146
 
147
147
  A function to be used instead of the default crud subscribe function.
148
148
 
@@ -152,7 +152,7 @@ A function to be used instead of the default crud subscribe function.
152
152
 
153
153
  ###### Returns
154
154
 
155
- `void`
155
+ `void` & `object`
156
156
 
157
157
  ##### update()
158
158
 
@@ -322,7 +322,17 @@ The arguments to be passed to the retrieve function.
322
322
 
323
323
  ### ResponseData
324
324
 
325
- > **ResponseData**\<\>: `Promise`\<`object` \| `string`\>
325
+ > **ResponseData**\<\>: `Promise`\<`object` \| `string`\> & `object`
326
+
327
+ #### Type declaration
328
+
329
+ ##### cancel()
330
+
331
+ > **cancel**: () => `Promise`\<`void`\> \| `void`
332
+
333
+ ###### Returns
334
+
335
+ `Promise`\<`void`\> \| `void`
326
336
 
327
337
  #### Type Parameters
328
338
 
@@ -79,13 +79,13 @@ Adds an object to the list.
79
79
 
80
80
  ##### bulkDelete()
81
81
 
82
- > **bulkDelete**: () => `Promise`\<`void`\>
82
+ > **bulkDelete**: () => `Promise`\<`boolean`\>
83
83
 
84
- Initiates a bulk delete operation on all objects in the list.
84
+ Initiates a bulk delete operation on all objects in the list, returning a promise to a boolean indicating success.
85
85
 
86
86
  ###### Returns
87
87
 
88
- `Promise`\<`void`\>
88
+ `Promise`\<`boolean`\>
89
89
 
90
90
  ##### clearList()
91
91
 
@@ -127,13 +127,13 @@ Deletes an object from the list by pk.
127
127
 
128
128
  ##### executeAction()
129
129
 
130
- > **executeAction**: () => `Promise`\<`void`\>
130
+ > **executeAction**: () => `Promise`\<`any`\>
131
131
 
132
- Initiates an action on all objects in the list.
132
+ Initiates an action on all objects in the list, returning the response, or false if the action failed.
133
133
 
134
134
  ###### Returns
135
135
 
136
- `Promise`\<`void`\>
136
+ `Promise`\<`any`\>
137
137
 
138
138
  ##### getFakePk()
139
139
 
@@ -147,13 +147,13 @@ Generates a unique fake pk for use within the list.
147
147
 
148
148
  ##### list()
149
149
 
150
- > **list**: () => `Promise`\<`void`\>
150
+ > **list**: () => `Promise`\<`boolean`\>
151
151
 
152
- Initiates a fetch to retrieve objects according to the CRUD configuration.
152
+ Initiates a fetch to retrieve objects according to the CRUD configuration, returning a promise to a boolean indicating success.
153
153
 
154
154
  ###### Returns
155
155
 
156
- `Promise`\<`void`\>
156
+ `Promise`\<`boolean`\>
157
157
 
158
158
  ##### pageCallback()
159
159
 
@@ -52,16 +52,12 @@ Set the loading state.
52
52
 
53
53
  #### Properties
54
54
 
55
- ##### clearError()
55
+ ##### clearError
56
56
 
57
- > **clearError**: () => `void`
57
+ > **clearError**: [`ClearErrorFn`](loadingError.md#clearerrorfn)
58
58
 
59
59
  Clear the error state.
60
60
 
61
- ###### Returns
62
-
63
- `void`
64
-
65
61
  ##### error
66
62
 
67
63
  > **error**: `Readonly`\<`Ref`\<`Error`\>\>
@@ -82,6 +78,20 @@ Whether the component is loading.
82
78
 
83
79
  ## Type Aliases
84
80
 
81
+ ### ClearErrorFn()
82
+
83
+ > **ClearErrorFn**\<\>: () => `void`
84
+
85
+ Clear the error state.
86
+
87
+ #### Type Parameters
88
+
89
+ #### Returns
90
+
91
+ `void`
92
+
93
+ ***
94
+
85
95
  ### LoadingError
86
96
 
87
97
  > **LoadingError**\<\>: [`LoadingErrorStatus`](loadingError.md#loadingerrorstatus) & [`LoadingErrorMutations`](loadingError.md#loadingerrormutations)
@@ -100,7 +100,7 @@ A function to be used instead of the default crud retrieve function.
100
100
 
101
101
  ###### crudArgs.subscribe()
102
102
 
103
- > **subscribe**: (`SubscribeArgs`) => `void`
103
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
104
104
 
105
105
  A function to be used instead of the default crud subscribe function.
106
106
 
@@ -110,7 +110,7 @@ A function to be used instead of the default crud subscribe function.
110
110
 
111
111
  ###### Returns
112
112
 
113
- `void`
113
+ `void` & `object`
114
114
 
115
115
  ###### crudArgs.update()
116
116
 
@@ -284,7 +284,7 @@ A function to be used instead of the default crud retrieve function.
284
284
 
285
285
  ###### crud.subscribe()
286
286
 
287
- > **subscribe**: (`SubscribeArgs`) => `void`
287
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
288
288
 
289
289
  A function to be used instead of the default crud subscribe function.
290
290
 
@@ -294,7 +294,7 @@ A function to be used instead of the default crud subscribe function.
294
294
 
295
295
  ###### Returns
296
296
 
297
- `void`
297
+ `void` & `object`
298
298
 
299
299
  ###### crud.update()
300
300
 
@@ -94,7 +94,7 @@ A function to be used instead of the default crud retrieve function.
94
94
 
95
95
  ###### crud.subscribe()
96
96
 
97
- > **subscribe**: (`SubscribeArgs`) => `void`
97
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
98
98
 
99
99
  A function to be used instead of the default crud subscribe function.
100
100
 
@@ -104,7 +104,7 @@ A function to be used instead of the default crud subscribe function.
104
104
 
105
105
  ###### Returns
106
106
 
107
- `void`
107
+ `void` & `object`
108
108
 
109
109
  ###### crud.update()
110
110
 
@@ -348,7 +348,7 @@ A function to be used instead of the default crud retrieve function.
348
348
 
349
349
  ###### crud.subscribe()
350
350
 
351
- > **subscribe**: (`SubscribeArgs`) => `void`
351
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
352
352
 
353
353
  A function to be used instead of the default crud subscribe function.
354
354
 
@@ -358,7 +358,7 @@ A function to be used instead of the default crud subscribe function.
358
358
 
359
359
  ###### Returns
360
360
 
361
- `void`
361
+ `void` & `object`
362
362
 
363
363
  ###### crud.update()
364
364
 
@@ -63,48 +63,90 @@ The error code.
63
63
 
64
64
  #### Properties
65
65
 
66
- ##### clear
66
+ ##### clear()
67
67
 
68
- > **clear**: `Function`
68
+ > **clear**: () => `void`
69
69
 
70
70
  Called to clear the object state.
71
71
 
72
+ ###### Returns
73
+
74
+ `void`
75
+
72
76
  ##### clearError
73
77
 
74
- > **clearError**: `Function`
78
+ > **clearError**: [`ClearErrorFn`](loadingError.md#clearerrorfn)
75
79
 
76
80
  Called to clear the error state.
77
81
 
78
- ##### create
82
+ ##### create()
79
83
 
80
- > **create**: `Function`
84
+ > **create**: (`args`) => `Promise`\<`boolean`\>
81
85
 
82
86
  Called to turn the current object into a new object on the server.
83
87
 
84
- ##### delete
88
+ ###### Parameters
89
+
90
+ • **args**
91
+
92
+ • **args.object**: `any`
93
+
94
+ ###### Returns
85
95
 
86
- > **delete**: `Function`
96
+ `Promise`\<`boolean`\>
97
+
98
+ ##### delete()
99
+
100
+ > **delete**: () => `Promise`\<`boolean`\>
87
101
 
88
102
  Called to delete the current object on the server.
89
103
 
90
- ##### patch
104
+ ###### Returns
105
+
106
+ `Promise`\<`boolean`\>
91
107
 
92
- > **patch**: `Function`
108
+ ##### patch()
109
+
110
+ > **patch**: (`args`) => `Promise`\<`boolean`\>
93
111
 
94
112
  Called to patch the current object on the server.
95
113
 
96
- ##### retrieve
114
+ ###### Parameters
115
+
116
+ • **args**
97
117
 
98
- > **retrieve**: `Function`
118
+ **args.partialObject**: [`CrudObject`](objectInstance.md#crudobject)
119
+
120
+ ###### Returns
121
+
122
+ `Promise`\<`boolean`\>
123
+
124
+ ##### retrieve()
125
+
126
+ > **retrieve**: () => `Promise`\<`boolean`\>
99
127
 
100
128
  Called to retrieve the current object by pk from the server.
101
129
 
102
- ##### update
130
+ ###### Returns
131
+
132
+ `Promise`\<`boolean`\>
103
133
 
104
- > **update**: `Function`
134
+ ##### update()
135
+
136
+ > **update**: (`args`) => `Promise`\<`boolean`\>
105
137
 
106
138
  Called to update the current object on the server.
107
139
 
140
+ ###### Parameters
141
+
142
+ • **args**
143
+
144
+ • **args.object**: [`CrudObject`](objectInstance.md#crudobject)
145
+
146
+ ###### Returns
147
+
148
+ `Promise`\<`boolean`\>
149
+
108
150
  ***
109
151
 
110
152
  ### ObjectInstanceOptions
@@ -193,7 +235,7 @@ A function to be used instead of the default crud retrieve function.
193
235
 
194
236
  ###### crudArgs.subscribe()
195
237
 
196
- > **subscribe**: (`SubscribeArgs`) => `void`
238
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
197
239
 
198
240
  A function to be used instead of the default crud subscribe function.
199
241
 
@@ -203,7 +245,7 @@ A function to be used instead of the default crud subscribe function.
203
245
 
204
246
  ###### Returns
205
247
 
206
- `void`
248
+ `void` & `object`
207
249
 
208
250
  ###### crudArgs.update()
209
251
 
@@ -319,7 +361,7 @@ A function to be used instead of the default crud retrieve function.
319
361
 
320
362
  ###### crud.subscribe()
321
363
 
322
- > **subscribe**: (`SubscribeArgs`) => `void`
364
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
323
365
 
324
366
  A function to be used instead of the default crud subscribe function.
325
367
 
@@ -329,7 +371,7 @@ A function to be used instead of the default crud subscribe function.
329
371
 
330
372
  ###### Returns
331
373
 
332
- `void`
374
+ `void` & `object`
333
375
 
334
376
  ###### crud.update()
335
377
 
@@ -94,7 +94,7 @@ A function to be used instead of the default crud retrieve function.
94
94
 
95
95
  ###### crud.subscribe()
96
96
 
97
- > **subscribe**: (`SubscribeArgs`) => `void`
97
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
98
98
 
99
99
  A function to be used instead of the default crud subscribe function.
100
100
 
@@ -104,7 +104,7 @@ A function to be used instead of the default crud subscribe function.
104
104
 
105
105
  ###### Returns
106
106
 
107
- `void`
107
+ `void` & `object`
108
108
 
109
109
  ###### crud.update()
110
110
 
@@ -280,7 +280,7 @@ A function to be used instead of the default crud retrieve function.
280
280
 
281
281
  ###### crud.subscribe()
282
282
 
283
- > **subscribe**: (`SubscribeArgs`) => `void`
283
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
284
284
 
285
285
  A function to be used instead of the default crud subscribe function.
286
286
 
@@ -290,7 +290,7 @@ A function to be used instead of the default crud subscribe function.
290
290
 
291
291
  ###### Returns
292
292
 
293
- `void`
293
+ `void` & `object`
294
294
 
295
295
  ###### crud.update()
296
296
 
@@ -225,7 +225,7 @@ A function to be used instead of the default crud retrieve function.
225
225
 
226
226
  ###### crud.subscribe()
227
227
 
228
- > **subscribe**: (`SubscribeArgs`) => `void`
228
+ > **subscribe**: (`SubscribeArgs`) => `void` & `object`
229
229
 
230
230
  A function to be used instead of the default crud subscribe function.
231
231
 
@@ -235,7 +235,7 @@ A function to be used instead of the default crud subscribe function.
235
235
 
236
236
  ###### Returns
237
237
 
238
- `void`
238
+ `void` & `object`
239
239
 
240
240
  ###### crud.update()
241
241
 
@@ -59,7 +59,7 @@ Normalize various ways of specifying CSS classes into an object for use in Vue.j
59
59
 
60
60
  #### Parameters
61
61
 
62
- • ...**classes**: (`string` \| `string`[] \| `string`[][] \| `object` \| `Ref`\<`string` \| `string`[] \| `string`[][]\>)[]
62
+ • ...**classes**: (`string` \| `string`[] \| `object` \| `string`[][] \| `Ref`\<`string` \| `string`[] \| `string`[][]\>)[]
63
63
 
64
64
  A mixed array containing multiple ways of specifying CSS classes.
65
65
 
@@ -0,0 +1,51 @@
1
+ [**@arrai-innovations/reactive-helpers**](../README.md) • **Docs**
2
+
3
+ ***
4
+
5
+ [@arrai-innovations/reactive-helpers](../README.md) / utils/keepAliveTry
6
+
7
+ # utils/keepAliveTry
8
+
9
+ ## Functions
10
+
11
+ ### tryOnActivated()
12
+
13
+ > **tryOnActivated**(`fn`, `target`?): `void`
14
+
15
+ If there is an active component, set up an onActivated hook.
16
+
17
+ #### Parameters
18
+
19
+ • **fn**: `Function`
20
+
21
+ The function to call.
22
+
23
+ • **target?**: `any`
24
+
25
+ The target to call the function on.
26
+
27
+ #### Returns
28
+
29
+ `void`
30
+
31
+ ***
32
+
33
+ ### tryOnDeactivated()
34
+
35
+ > **tryOnDeactivated**(`fn`, `target`?): `void`
36
+
37
+ If there is an active component, set up an onDeactivated hook.
38
+
39
+ #### Parameters
40
+
41
+ • **fn**: `Function`
42
+
43
+ The function to call.
44
+
45
+ • **target?**: `any`
46
+
47
+ The target to call the function on.
48
+
49
+ #### Returns
50
+
51
+ `void`
package/index.js CHANGED
@@ -28,6 +28,7 @@ export * from "./utils/compact.js";
28
28
  export * from "./utils/deleteKey.js";
29
29
  export * from "./utils/flattenPaths.js";
30
30
  export * from "./utils/getFakePk.js";
31
+ export * from "./utils/keepAliveTry.js";
31
32
  export * from "./utils/keyDiff.js";
32
33
  export * from "./utils/loadingCombine.js";
33
34
  export * from "./utils/relatedCalculatedHelpers.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrai-innovations/reactive-helpers",
3
- "version": "15.0.0",
3
+ "version": "16.0.0",
4
4
  "description": "VueJS 3 utility composition functions to help manipulate objects and lists.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -65,6 +65,7 @@
65
65
  "vue-deepunref": "^1.0.1"
66
66
  },
67
67
  "peerDependencies": {
68
+ "@vueuse/core": "^11.2.0",
68
69
  "lodash-es": "^4.17.21",
69
70
  "vue": "^3.4.30"
70
71
  }
@@ -12,19 +12,43 @@ afterAll(() => {
12
12
 
13
13
  const fields = ["id", "__str__", "name"];
14
14
  describe("use/listInstance.spec.js", function () {
15
- let useListInstance, ListInstanceError, useListInstances, globalList, globalbulkDelete, globalexecuteAction;
15
+ let useListInstance,
16
+ ListInstanceError,
17
+ useListInstances,
18
+ globalList,
19
+ globalBulkDelete,
20
+ globalExecuteAction,
21
+ globalListCancel,
22
+ globalBulkDeleteCancel,
23
+ globalExecuteActionCancel;
16
24
  beforeEach(async () => {
17
25
  const listCrud = await import("../../../config/listCrud.js");
18
26
  const imported = await import("../../../use/listInstance.js");
27
+ globalListCancel = vi.fn();
28
+ globalBulkDeleteCancel = vi.fn();
29
+ globalExecuteActionCancel = vi.fn();
19
30
  globalList = vi.fn();
20
- globalbulkDelete = vi.fn(() => Promise.resolve(true));
21
- globalexecuteAction = vi.fn(() => Promise.resolve(true));
22
- // @ts-ignore
23
- globalList.cancel = vi.fn();
31
+ globalBulkDelete = vi.fn(
32
+ (() => {
33
+ const fn = () => Promise.resolve(true);
34
+ fn.cancel = globalBulkDeleteCancel;
35
+ return fn;
36
+ })()
37
+ );
38
+ globalExecuteAction = vi.fn(
39
+ (() => {
40
+ const fn = () => Promise.resolve(true);
41
+ fn.cancel = globalExecuteActionCancel;
42
+ return fn;
43
+ })()
44
+ );
24
45
  listCrud.setListCrud({
46
+ // @ts-ignore - mock is an acceptable substitute
25
47
  list: globalList,
26
- bulkDelete: globalbulkDelete,
27
- executeAction: globalexecuteAction,
48
+ // @ts-ignore - mock is an acceptable substitute
49
+ bulkDelete: globalBulkDelete,
50
+ // @ts-ignore - mock is an acceptable substitute
51
+ executeAction: globalExecuteAction,
28
52
  args: { stream: "test_stream" },
29
53
  });
30
54
  useListInstance = imported.useListInstance;
@@ -675,19 +699,19 @@ describe("use/listInstance.spec.js", function () {
675
699
  expectErrorToBeNull(listInstance.state.error);
676
700
  expect(listInstance.state.errored).toBe(false);
677
701
  expect(listInstance.state.loading).toBe(true);
678
- expect(globalexecuteAction).toHaveBeenCalledWith({
702
+ expect(globalExecuteAction).toHaveBeenCalledWith({
679
703
  crudArgs: { stream: "test_stream" },
680
704
  pkKey: "id",
681
705
  pks: Object.keys(crudListResolvedObjects2).map(Number),
682
706
  });
683
707
 
684
- expect(globalexecuteAction).toHaveBeenCalledTimes(1);
708
+ expect(globalExecuteAction).toHaveBeenCalledTimes(1);
685
709
 
686
710
  // @ts-ignore - executeAction is set in a promise, since we await this will be set
687
711
  crudListResolve();
688
712
  await flushPromises();
689
713
  await expect(executeActionResolve).resolves.toBe(true);
690
- expect({ ...listInstance.state.objects }).toEqual({});
714
+ expect({ ...listInstance.state.objects }).toEqual(crudListResolvedObjects2);
691
715
  });
692
716
  it("succeeds with non-standard primary key", async function () {
693
717
  const listArgs = reactive({
@@ -723,19 +747,19 @@ describe("use/listInstance.spec.js", function () {
723
747
  expectErrorToBeNull(listInstance.state.error);
724
748
  expect(listInstance.state.errored).toBe(false);
725
749
  expect(listInstance.state.loading).toBe(true);
726
- expect(globalexecuteAction).toHaveBeenCalledWith({
750
+ expect(globalExecuteAction).toHaveBeenCalledWith({
727
751
  crudArgs: { stream: "test_stream" },
728
752
  pkKey: "unique",
729
753
  pks: Object.keys(crudListResolvedObjectsNonStandardPK).map(Number),
730
754
  });
731
755
 
732
- expect(globalexecuteAction).toHaveBeenCalledTimes(1);
756
+ expect(globalExecuteAction).toHaveBeenCalledTimes(1);
733
757
 
734
- // @ts-ignore - globalexecuteAction is set in a promise, since we await this will be set
758
+ // @ts-ignore - globalExecuteAction is set in a promise, since we await this will be set
735
759
  crudListResolve();
736
760
  await flushPromises();
737
761
  await expect(executeActionResolve).resolves.toBe(true);
738
- expect({ ...listInstance.state.objects }).toEqual({});
762
+ expect({ ...listInstance.state.objects }).toEqual(crudListResolvedObjectsNonStandardPK);
739
763
  });
740
764
  it("already loading", async function () {
741
765
  const listArgs = reactive({
@@ -752,7 +776,7 @@ describe("use/listInstance.spec.js", function () {
752
776
  expect(listInstance.state.errored).toBe(false);
753
777
  expect(listInstance.state.loading).toBeUndefined();
754
778
  expect({ ...listInstance.state.objects }).toEqual({});
755
- globalexecuteAction.mockImplementation(() => new Promise(() => {}));
779
+ globalExecuteAction.mockImplementation(() => new Promise(() => {}));
756
780
  listInstance.executeAction();
757
781
  expectErrorToBeNull(listInstance.state.error);
758
782
  expect(listInstance.state.errored).toBe(false);
@@ -778,7 +802,7 @@ describe("use/listInstance.spec.js", function () {
778
802
  crudListReject = reject;
779
803
  });
780
804
  let passedPageCallback;
781
- globalexecuteAction.mockImplementation(({ pageCallback }) => {
805
+ globalExecuteAction.mockImplementation(({ pageCallback }) => {
782
806
  passedPageCallback = pageCallback;
783
807
  return crudListPromise;
784
808
  });
@@ -808,12 +832,12 @@ describe("use/listInstance.spec.js", function () {
808
832
  expect(listInstance.state.errored).toBe(true);
809
833
  expect(listInstance.state.loading).toBe(false);
810
834
  expect({ ...listInstance.state.objects }).toEqual({});
811
- expect(globalexecuteAction).toHaveBeenCalledWith({
835
+ expect(globalExecuteAction).toHaveBeenCalledWith({
812
836
  crudArgs: { stream: "test_stream" },
813
837
  pkKey: "id",
814
838
  pks: [],
815
839
  });
816
- expect(globalexecuteAction).toHaveBeenCalledTimes(1);
840
+ expect(globalExecuteAction).toHaveBeenCalledTimes(1);
817
841
  });
818
842
  });
819
843
  describe("bulkDelete", function () {
@@ -851,13 +875,13 @@ describe("use/listInstance.spec.js", function () {
851
875
  expectErrorToBeNull(listInstance.state.error);
852
876
  expect(listInstance.state.errored).toBe(false);
853
877
  expect(listInstance.state.loading).toBe(true);
854
- expect(globalbulkDelete).toHaveBeenCalledWith({
878
+ expect(globalBulkDelete).toHaveBeenCalledWith({
855
879
  crudArgs: { stream: "test_stream" },
856
880
  pkKey: "id",
857
881
  pks: Object.keys(crudListResolvedObjects2).map(Number),
858
882
  });
859
883
 
860
- expect(globalbulkDelete).toHaveBeenCalledTimes(1);
884
+ expect(globalBulkDelete).toHaveBeenCalledTimes(1);
861
885
 
862
886
  // @ts-ignore - bulkDeleteResolve is set in a promise, since we await this will be set
863
887
  crudListResolve();
@@ -899,13 +923,13 @@ describe("use/listInstance.spec.js", function () {
899
923
  expectErrorToBeNull(listInstance.state.error);
900
924
  expect(listInstance.state.errored).toBe(false);
901
925
  expect(listInstance.state.loading).toBe(true);
902
- expect(globalbulkDelete).toHaveBeenCalledWith({
926
+ expect(globalBulkDelete).toHaveBeenCalledWith({
903
927
  crudArgs: { stream: "test_stream" },
904
928
  pkKey: "unique",
905
929
  pks: Object.keys(crudListResolvedObjectsNonStandardPK).map(Number),
906
930
  });
907
931
 
908
- expect(globalbulkDelete).toHaveBeenCalledTimes(1);
932
+ expect(globalBulkDelete).toHaveBeenCalledTimes(1);
909
933
 
910
934
  // @ts-ignore - bulkDeleteResolve is set in a promise, since we await this will be set
911
935
  crudListResolve();
@@ -928,7 +952,7 @@ describe("use/listInstance.spec.js", function () {
928
952
  expect(listInstance.state.errored).toBe(false);
929
953
  expect(listInstance.state.loading).toBeUndefined();
930
954
  expect({ ...listInstance.state.objects }).toEqual({});
931
- globalbulkDelete.mockImplementation(() => new Promise(() => {}));
955
+ globalBulkDelete.mockImplementation(() => new Promise(() => {}));
932
956
  expectErrorToBeNull(listInstance.state.error);
933
957
  expect(listInstance.state.errored).toBe(false);
934
958
  expect(listInstance.state.loading).toBeUndefined();
@@ -957,7 +981,7 @@ describe("use/listInstance.spec.js", function () {
957
981
  crudListReject = reject;
958
982
  });
959
983
  let passedPageCallback;
960
- globalbulkDelete.mockImplementation(({ pageCallback }) => {
984
+ globalBulkDelete.mockImplementation(({ pageCallback }) => {
961
985
  passedPageCallback = pageCallback;
962
986
  return crudListPromise;
963
987
  });
@@ -987,12 +1011,12 @@ describe("use/listInstance.spec.js", function () {
987
1011
  expect(listInstance.state.errored).toBe(true);
988
1012
  expect(listInstance.state.loading).toBe(false);
989
1013
  expect({ ...listInstance.state.objects }).toEqual({});
990
- expect(globalbulkDelete).toHaveBeenCalledWith({
1014
+ expect(globalBulkDelete).toHaveBeenCalledWith({
991
1015
  crudArgs: { stream: "test_stream" },
992
1016
  pkKey: "id",
993
1017
  pks: [],
994
1018
  });
995
- expect(globalbulkDelete).toHaveBeenCalledTimes(1);
1019
+ expect(globalBulkDelete).toHaveBeenCalledTimes(1);
996
1020
  });
997
1021
  });
998
1022
  describe("getFakePk", function () {
package/tsconfig.json CHANGED
@@ -12,8 +12,8 @@
12
12
  "moduleResolution": "nodenext",
13
13
  "esModuleInterop": true,
14
14
  "target": "es2023",
15
- "types": ["vitest/globals"]
15
+ "types": ["vitest/globals"],
16
+ "skipLibCheck": true
16
17
  },
17
- // match with ./makeTypeDoc.sh
18
18
  "include": ["config/**/*.js", "use/**/*.js", "utils/**/*.js", "tests/**/*.js", "index.js"]
19
19
  }
package/typedoc.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "entryPoints": ["config/**/*.js", "use/**/*.js", "utils/**/*.js"],
3
3
  "out": "docs",
4
- "exclude": [],
5
4
  "excludeExternals": true,
6
5
  "excludePrivate": true,
7
6
  "excludeProtected": true,
@@ -3,6 +3,7 @@ import isEmpty from "lodash-es/isEmpty.js";
3
3
  import isEqual from "lodash-es/isEqual.js";
4
4
  import { computed, effectScope, nextTick, onScopeDispose, reactive, readonly, watch } from "vue";
5
5
  import { deepUnref } from "vue-deepunref";
6
+ import { tryOnActivated, tryOnDeactivated } from "../utils/keepAliveTry.js";
6
7
 
7
8
  /**
8
9
  * @module use/cancellableIntent.js - A composable function for handling cancellable intents.
@@ -209,6 +210,17 @@ export function useCancellableIntent({
209
210
  }
210
211
  };
211
212
 
213
+ const cleanup = () => {
214
+ // cancel the intent when the component is deactivated
215
+ cancel();
216
+ if (state.clearActiveOnResolved) {
217
+ // otherwise it clears when resolved
218
+ cancelFunction = null;
219
+ }
220
+ // reset the previous watch values for the next activation
221
+ previousWatchValues = null;
222
+ };
223
+
212
224
  es.run(() => {
213
225
  state.active = computed(() => {
214
226
  if (state.activeCount === undefined) {
@@ -233,9 +245,16 @@ export function useCancellableIntent({
233
245
  deep: true,
234
246
  });
235
247
 
236
- nextTick().then(intentWatch);
248
+ tryOnActivated(() => {
249
+ state.activeCount = 0;
250
+ state.resolvingCount = 0;
251
+ // trigger the intent watch manually to get current watch values
252
+ intentWatch();
253
+ });
254
+ tryOnDeactivated(cleanup);
255
+ onScopeDispose(cleanup);
237
256
 
238
- onScopeDispose(cancel);
257
+ nextTick().then(intentWatch);
239
258
  });
240
259
  return {
241
260
  state,
@@ -117,9 +117,9 @@ export class ListInstanceError extends Error {
117
117
  * @property {(objectId: string) => void} deleteListObject - Deletes an object from the list by pk.
118
118
  * @property {() => void} clearList - Clears all objects and errors from the list.
119
119
  * @property {() => string} getFakePk - Generates a unique fake pk for use within the list.
120
- * @property {() => Promise<void>} list - Initiates a fetch to retrieve objects according to the CRUD configuration.
121
- * @property {() => Promise<void>} bulkDelete - Initiates a bulk delete operation on all objects in the list.
122
- * @property {() => Promise<void>} executeAction - Initiates an action on all objects in the list.
120
+ * @property {() => Promise<boolean>} list - Initiates a fetch to retrieve objects according to the CRUD configuration, returning a promise to a boolean indicating success.
121
+ * @property {() => Promise<boolean>} bulkDelete - Initiates a bulk delete operation on all objects in the list, returning a promise to a boolean indicating success.
122
+ * @property {() => Promise<object|string|false>} executeAction - Initiates an action on all objects in the list, returning the response, or false if the action failed.
123
123
  */
124
124
 
125
125
  /**
@@ -344,10 +344,9 @@ export function useListInstance({ props, functions = {}, keepOldPages }) {
344
344
  pks: Object.keys(state.objects).map(Number),
345
345
  pkKey: state.pkKey,
346
346
  })
347
- .then(() => {
348
- assignReactiveObject(state.objects, {});
347
+ .then((responseData) => {
349
348
  loadingError.clearError();
350
- return Promise.resolve(true);
349
+ return Promise.resolve(responseData);
351
350
  })
352
351
  .catch((error) => {
353
352
  loadingError.setError(error);
@@ -493,6 +492,7 @@ export function useListInstance({ props, functions = {}, keepOldPages }) {
493
492
  state.order = computed(() => Object.keys(state.objects));
494
493
  });
495
494
 
495
+ // This isn't a direct return because we want the live returnedObject.pageCallback in list()
496
496
  const returnedObject = {
497
497
  state,
498
498
  list,
@@ -4,6 +4,10 @@ import { readonly, ref } from "vue";
4
4
  * @module use/loadingError.js - A composable function for managing loading and error states.
5
5
  */
6
6
 
7
+ /**
8
+ * @typedef {() => void} ClearErrorFn - Clear the error state.
9
+ */
10
+
7
11
  /**
8
12
  * The common API for loading and error states.
9
13
  *
@@ -11,7 +15,7 @@ import { readonly, ref } from "vue";
11
15
  * @property {Readonly<import("vue").Ref<boolean|undefined>>} loading - Whether the component is loading.
12
16
  * @property {Readonly<import("vue").Ref<Error|null>>} error - The error that occurred.
13
17
  * @property {Readonly<import("vue").Ref<boolean>>} errored - Whether an error has occurred.
14
- * @property {() => void} clearError - Clear the error state.
18
+ * @property {ClearErrorFn} clearError - Clear the error state.
15
19
  */
16
20
 
17
21
  /**
@@ -200,47 +200,51 @@ export function useObjectCalculated({ parentState, calculatedObjectRules }) {
200
200
  state[key] = toRef(parentState, key);
201
201
  }
202
202
 
203
- watch([() => state.calculatedObjectRules && Object.keys(state.calculatedObjectRules)], () => {
204
- /** @type {Set<string>|undefined} */
205
- let addedKeys = undefined,
203
+ watch(
204
+ [() => state.calculatedObjectRules && Object.keys(state.calculatedObjectRules)],
205
+ () => {
206
206
  /** @type {Set<string>|undefined} */
207
- removedKeys = undefined,
208
- /** @type {Set<string>|undefined} */
209
- sameKeys = undefined;
210
- if (!state.calculatedObjectRules) {
211
- removedKeys = new Set(Object.keys(calculatedObjectOriginalFunctions));
212
- addedKeys = new Set();
213
- sameKeys = new Set();
214
- } else {
215
- ({ addedKeys, removedKeys, sameKeys } = keyDiff(
216
- Object.keys(state.calculatedObjectRules),
217
- Object.keys(calculatedObjectOriginalFunctions)
218
- ));
219
- }
220
- for (const sameKey of sameKeys) {
221
- if (calculatedObjectOriginalFunctions[sameKey] !== state.calculatedObjectRules[sameKey]) {
222
- removedKeys.add(sameKey);
223
- addedKeys.add(sameKey);
207
+ let addedKeys = undefined,
208
+ /** @type {Set<string>|undefined} */
209
+ removedKeys = undefined,
210
+ /** @type {Set<string>|undefined} */
211
+ sameKeys = undefined;
212
+ if (!state.calculatedObjectRules) {
213
+ removedKeys = new Set(Object.keys(calculatedObjectOriginalFunctions));
214
+ addedKeys = new Set();
215
+ sameKeys = new Set();
216
+ } else {
217
+ ({ addedKeys, removedKeys, sameKeys } = keyDiff(
218
+ Object.keys(state.calculatedObjectRules),
219
+ Object.keys(calculatedObjectOriginalFunctions)
220
+ ));
224
221
  }
225
- }
226
- for (const removedKey of removedKeys) {
227
- delete calculatedObjectOriginalFunctions[removedKey];
228
- delete state.calculatedObject[removedKey];
229
- if (calculatedObjectEffectScopes[removedKey]) {
230
- calculatedObjectEffectScopes[removedKey].stop();
231
- delete calculatedObjectEffectScopes[removedKey];
222
+ for (const sameKey of sameKeys) {
223
+ if (calculatedObjectOriginalFunctions[sameKey] !== state.calculatedObjectRules[sameKey]) {
224
+ removedKeys.add(sameKey);
225
+ addedKeys.add(sameKey);
226
+ }
232
227
  }
233
- }
234
- for (const addedKey of addedKeys) {
235
- calculatedObjectOriginalFunctions[addedKey] = state.calculatedObjectRules[addedKey];
236
- calculatedObjectEffectScopes[addedKey] = effectScope();
237
- calculatedObjectEffectScopes[addedKey].run(() => {
238
- state.calculatedObject[addedKey] = computed(() =>
239
- calculatedObjectOriginalFunctions[addedKey](state.object, state.relatedObject)
240
- );
241
- });
242
- }
243
- });
228
+ for (const removedKey of removedKeys) {
229
+ delete calculatedObjectOriginalFunctions[removedKey];
230
+ delete state.calculatedObject[removedKey];
231
+ if (calculatedObjectEffectScopes[removedKey]) {
232
+ calculatedObjectEffectScopes[removedKey].stop();
233
+ delete calculatedObjectEffectScopes[removedKey];
234
+ }
235
+ }
236
+ for (const addedKey of addedKeys) {
237
+ calculatedObjectOriginalFunctions[addedKey] = state.calculatedObjectRules[addedKey];
238
+ calculatedObjectEffectScopes[addedKey] = effectScope();
239
+ calculatedObjectEffectScopes[addedKey].run(() => {
240
+ state.calculatedObject[addedKey] = computed(() =>
241
+ calculatedObjectOriginalFunctions[addedKey](state.object, state.relatedObject)
242
+ );
243
+ });
244
+ }
245
+ },
246
+ { immediate: true }
247
+ );
244
248
 
245
249
  watchesRunning = useWatchesRunning({
246
250
  triggerRefs: [computed(() => (!isEmpty(state.calculatedObjectRules) ? parentState.loading : false))],
@@ -59,13 +59,13 @@ import { reactive, toRef } from "vue";
59
59
  * The functions available on the object instance.
60
60
  *
61
61
  * @typedef {object} ObjectInstanceFunctions
62
- * @property {Function} create - Called to turn the current object into a new object on the server.
63
- * @property {Function} retrieve - Called to retrieve the current object by pk from the server.
64
- * @property {Function} update - Called to update the current object on the server.
65
- * @property {Function} delete - Called to delete the current object on the server.
66
- * @property {Function} patch - Called to patch the current object on the server.
67
- * @property {Function} clearError - Called to clear the error state.
68
- * @property {Function} clear - Called to clear the object state.
62
+ * @property {(args: { object: object }) => Promise<boolean>} create - Called to turn the current object into a new object on the server.
63
+ * @property {() => Promise<boolean>} retrieve - Called to retrieve the current object by pk from the server.
64
+ * @property {(args: { object: CrudObject }) => Promise<boolean>} update - Called to update the current object on the server.
65
+ * @property {() => Promise<boolean>} delete - Called to delete the current object on the server.
66
+ * @property {(args: { partialObject: CrudObject }) => Promise<boolean>} patch - Called to patch the current object on the server.
67
+ * @property {import('./loadingError.js').ClearErrorFn} clearError - Called to clear the error state.
68
+ * @property {() => void} clear - Called to clear the object state.
69
69
  */
70
70
 
71
71
  /**
@@ -362,7 +362,7 @@ export function useObjectInstance({ props, functions = {} }) {
362
362
  assignReactiveObject(state.object, {});
363
363
  }
364
364
 
365
- return reactive({
365
+ return {
366
366
  state,
367
367
  create,
368
368
  retrieve,
@@ -371,5 +371,5 @@ export function useObjectInstance({ props, functions = {} }) {
371
371
  patch,
372
372
  clearError: loadingError.clearError,
373
373
  clear,
374
- });
374
+ };
375
375
  }
@@ -0,0 +1,28 @@
1
+ import { onActivated, onDeactivated } from "vue";
2
+ import { getLifeCycleTarget } from "@vueuse/core";
3
+
4
+ /**
5
+ * If there is an active component, set up an onActivated hook.
6
+ *
7
+ * @param {Function} fn - The function to call.
8
+ * @param {any} [target] - The target to call the function on.
9
+ */
10
+ export function tryOnActivated(fn, target) {
11
+ const instance = getLifeCycleTarget(target);
12
+ if (instance) {
13
+ onActivated(fn, target);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * If there is an active component, set up an onDeactivated hook.
19
+ *
20
+ * @param {Function} fn - The function to call.
21
+ * @param {any} [target] - The target to call the function on.
22
+ */
23
+ export function tryOnDeactivated(fn, target) {
24
+ const instance = getLifeCycleTarget(target);
25
+ if (instance) {
26
+ onDeactivated(fn, target);
27
+ }
28
+ }