@arrai-innovations/reactive-helpers 22.0.0 → 23.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.
Files changed (53) hide show
  1. package/README.md +66 -89
  2. package/config/commonCrud.js +3 -4
  3. package/config/listCrud.js +19 -11
  4. package/config/objectCrud.js +39 -25
  5. package/package.json +22 -6
  6. package/types/config/listCrud.d.ts +28 -10
  7. package/types/config/objectCrud.d.ts +36 -23
  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/matchers.spec.d.ts +1 -0
  13. package/types/tests/unit/use/lifecycleCleanup.spec.d.ts +1 -0
  14. package/types/tests/unit/use/listPerformance.spec.d.ts +1 -0
  15. package/types/tests/unit/use/ruleOptionNames.spec.d.ts +1 -0
  16. package/types/tests/unit/utils/cancellablePromise.spec.d.ts +1 -0
  17. package/types/use/cancellableIntent.d.ts +8 -2
  18. package/types/use/combineClasses.d.ts +1 -1
  19. package/types/use/listCalculated.d.ts +22 -21
  20. package/types/use/listInstance.d.ts +24 -19
  21. package/types/use/listRelated.d.ts +44 -23
  22. package/types/use/listSort.d.ts +6 -1
  23. package/types/use/listSubscription.d.ts +6 -2
  24. package/types/use/objectCalculated.d.ts +19 -15
  25. package/types/use/objectInstance.d.ts +7 -5
  26. package/types/use/objectRelated.d.ts +36 -13
  27. package/types/use/objectSubscription.d.ts +6 -5
  28. package/types/utils/cancellableFetch.d.ts +2 -3
  29. package/types/utils/cancellablePromise.d.ts +54 -5
  30. package/types/utils/getFakePk.d.ts +5 -2
  31. package/types/utils/refIfReactive.d.ts +14 -0
  32. package/types/utils/relatedCalculatedHelpers.d.ts +63 -0
  33. package/use/cancellableIntent.js +8 -2
  34. package/use/combineClasses.js +1 -1
  35. package/use/list.js +3 -0
  36. package/use/listCalculated.js +27 -18
  37. package/use/listFilter.js +14 -10
  38. package/use/listInstance.js +189 -71
  39. package/use/listRelated.js +64 -21
  40. package/use/listSearch.js +16 -12
  41. package/use/listSort.js +87 -27
  42. package/use/listSubscription.js +13 -3
  43. package/use/object.js +12 -10
  44. package/use/objectCalculated.js +17 -12
  45. package/use/objectInstance.js +95 -47
  46. package/use/objectRelated.js +68 -25
  47. package/use/objectSubscription.js +21 -10
  48. package/use/proxyLoadingError.js +3 -0
  49. package/utils/cancellableFetch.js +3 -3
  50. package/utils/cancellablePromise.js +47 -4
  51. package/utils/getFakePk.js +8 -3
  52. package/utils/refIfReactive.js +27 -9
  53. package/utils/relatedCalculatedHelpers.js +123 -0
package/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # reactive-helpers
2
2
 
3
- ![Tests](https://docs.arrai.dev/reactive-helpers/artifacts/main/tests.svg)
4
- [![Coverage](https://docs.arrai.dev/reactive-helpers/artifacts/main/tests.coverage.svg)](https://docs.arrai.dev/reactive-helpers/artifacts/main/coverage_tests/)
5
- ![ESLint](https://docs.arrai.dev/reactive-helpers/artifacts/main/eslint.svg)
6
- ![Prettier](https://docs.arrai.dev/reactive-helpers/artifacts/main/prettier.svg)
7
- ![Audit](https://docs.arrai.dev/reactive-helpers/artifacts/main/pnpm-audit.svg)
3
+ [![npm](https://img.shields.io/npm/v/%40arrai-innovations%2Freactive-helpers.svg?style=for-the-badge)](https://www.npmjs.com/package/@arrai-innovations/reactive-helpers)
4
+ ![Tests](https://reactive-helpers.arrai.dev/artifacts/main/tests.svg)
5
+ [![Coverage](https://reactive-helpers.arrai.dev/artifacts/main/tests.coverage.svg)](https://reactive-helpers.arrai.dev/artifacts/main/coverage_tests/)
6
+ ![ESLint](https://reactive-helpers.arrai.dev/artifacts/main/eslint.svg)
7
+ ![Prettier](https://reactive-helpers.arrai.dev/artifacts/main/prettier.svg)
8
+ ![Audit](https://reactive-helpers.arrai.dev/artifacts/main/pnpm-audit.svg)
8
9
  [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD--3--Clause-blue.svg?style=for-the-badge)](./LICENSE)
9
10
 
10
11
  Vue.js 3 composition utilities to manage reactive lists, objects, loading and error state, and the small helpers that
@@ -18,12 +19,11 @@ reaches your backend), so the package stays transport agnostic.
18
19
  - [Features](#features)
19
20
  - [Requirements](#requirements)
20
21
  - [Install](#install)
21
- - [Usage](#usage)
22
- - [Quick start](#quick-start)
23
- - [Wiring a data layer](#wiring-a-data-layer)
22
+ - [Documentation](#documentation)
24
23
  - [Changelog](#changelog)
25
24
  - [Contributing](#contributing)
26
25
  - [Development](#development)
26
+ - [Deploy documentation](#deploy-documentation)
27
27
  - [License](#license)
28
28
 
29
29
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -31,25 +31,18 @@ reaches your backend), so the package stays transport agnostic.
31
31
 
32
32
  ## Features
33
33
 
34
- - **List composables** for managing collections of objects: `useListInstance`, `useList`, `useListFilter`,
35
- `useListSort`, `useListSearch`, `useListCalculated`, `useListRelated`, and `useListSubscription`.
36
- - **Object composables** for managing single objects: `useObjectInstance`, `useObject`, `useObjectCalculated`,
37
- `useObjectRelated`, and `useObjectSubscription`.
38
- - **Loading and error state** as small, composable primitives: `useLoading`, `useError`, `useLoadingError`, and their
39
- read-only proxy variants `useProxyLoading`, `useProxyError`, `useProxyLoadingError`.
40
- - **Standalone helpers** such as `useSearch` (FlexSearch-backed), `useCancellableIntent`, and `useCombineClasses`.
41
- - **Pluggable CRUD configuration** via `setListCrud` / `setObjectCrud`, so the same composables can drive any backend.
42
- - **Reactive and object utilities**: `deepUnref`, `assignReactiveObject`, `refIfReactive`, `toRefsIfReactive`,
43
- `isReactiveTyped`, `set`, `deleteKey`, `keyDiff`, `flattenPaths`, `cancellablePromise`, `cancellableFetch`, and more.
44
-
45
- Most list and object composables also ship a plural batch variant (for example `useListInstances`,
46
- `useObjectInstances`) for creating several keyed instances at once. See the full API in
47
- [docs/README.md](./docs/README.md).
34
+ - **Reactive lists** with stable identity, ordering, filtering, sorting, searching, related data, calculated values, and
35
+ subscriptions.
36
+ - **Reactive objects** that retrieve, edit, create, delete, and subscribe through transport-neutral handlers.
37
+ - **Loading and error state** as small primitives that can be composed across asynchronous work.
38
+ - **Pluggable CRUD configuration** so instances can share app-wide handlers for any backend.
39
+ - **Focused utilities** for reactive data, cancellable work, object paths, classes, and search.
48
40
 
49
41
  ## Requirements
50
42
 
51
43
  - **Vue** `^3.5.13` (peer dependency).
52
- - **Node.js** with ES module support. This package is ESM only (`"type": "module"`); there is no CommonJS build.
44
+ - **Node.js** `>=22`. Node 20 reached end of life in April 2026, so the supported lines are 22 and 24. This package is
45
+ ESM only (`"type": "module"`); there is no CommonJS build.
53
46
  - Peer dependencies you install alongside it: [`vue`](https://www.npmjs.com/package/vue),
54
47
  [`@vueuse/core`](https://www.npmjs.com/package/@vueuse/core), and
55
48
  [`lodash-es`](https://www.npmjs.com/package/lodash-es).
@@ -60,67 +53,17 @@ Most list and object composables also ship a plural batch variant (for example `
60
53
  $ npm install @arrai-innovations/reactive-helpers vue @vueuse/core lodash-es
61
54
  ```
62
55
 
63
- ## Usage
56
+ ## Documentation
64
57
 
65
- ### Quick start
58
+ The [reactive-helpers documentation](https://reactive-helpers.arrai.dev/v23/) is versioned by package major.
66
59
 
67
- The loading and error composables are self contained and need no configuration. They return readonly reactive state
68
- plus actions to drive it, which is handy for wiring UI to any asynchronous work:
69
-
70
- ```javascript
71
- import { useLoadingError } from "@arrai-innovations/reactive-helpers";
72
-
73
- const { loading, error, errored, setLoading, clearLoading, setError, clearError } = useLoadingError();
74
-
75
- async function save() {
76
- setLoading();
77
- try {
78
- await doWork();
79
- clearError();
80
- } catch (e) {
81
- setError(e);
82
- } finally {
83
- clearLoading();
84
- }
85
- }
86
-
87
- // `loading`, `error`, and `errored` are readonly refs you can render or watch.
88
- ```
89
-
90
- ### Wiring a data layer
91
-
92
- The list and object instance composables manage reactive collections but stay transport agnostic: you provide the CRUD
93
- handlers that reach your backend. A list handler receives a `pushObjects` callback to feed results (one or more pages)
94
- into the reactive state and resolves when it is done:
95
-
96
- ```javascript
97
- import { useListInstance } from "@arrai-innovations/reactive-helpers";
98
- import { reactive } from "vue";
99
-
100
- const contacts = useListInstance({
101
- props: {
102
- pkKey: "id",
103
- params: reactive({ fields: ["id", "name"] }),
104
- target: { stream: "contacts" }, // implementation-specific args passed through to your handlers
105
- },
106
- handlers: {
107
- list: async ({ pushObjects }) => {
108
- const rows = await fetch("/api/contacts").then((r) => r.json());
109
- pushObjects(rows);
110
- return true;
111
- },
112
- },
113
- });
114
-
115
- await contacts.list();
116
- console.log(contacts.state.objects);
117
- ```
118
-
119
- To share one data layer across every instance instead of passing `handlers` each time, register defaults once with
120
- `setListCrud` (and `setObjectCrud` for object instances).
121
-
122
- See [docs/README.md](./docs/README.md) for the full list of modules, composables, and utilities, along with their
123
- arguments and properties.
60
+ - [Get started](https://reactive-helpers.arrai.dev/v23/guide/) with installation and a complete reactive list.
61
+ - [Build a reactive list](https://reactive-helpers.arrai.dev/v23/tutorials/build-a-reactive-list) step by step.
62
+ - [Pass backend arguments](https://reactive-helpers.arrai.dev/v23/guide/data-layer) or
63
+ [register app-wide CRUD defaults](https://reactive-helpers.arrai.dev/v23/guide/register-crud-defaults).
64
+ - Read about [instances and transport](https://reactive-helpers.arrai.dev/v23/concepts/instances-and-transport) to
65
+ understand the library's core boundary.
66
+ - Use the [API reference](https://reactive-helpers.arrai.dev/v23/reference/api/) for exact signatures and return values.
124
67
 
125
68
  ## Changelog
126
69
 
@@ -133,8 +76,9 @@ Issues and pull requests are welcome. A few things to know before you start:
133
76
  - Commits follow [Conventional Commits](https://www.conventionalcommits.org/) and are validated by commitlint through a
134
77
  git hook (installed automatically by `pnpm install`).
135
78
  - Run the tests, linters, and formatter before opening a pull request (see [Development](#development)).
136
- - Generated output under `docs/` and `types/` is committed and checked in CI; regenerate it with `pnpm run docs` and
137
- `pnpm run types` when you change public APIs or their JSDoc.
79
+ - Generated output under `types/` and `docs/reference/api/` is committed and checked in CI. Regenerate it with
80
+ `pnpm run docs` when you change public APIs or their JSDoc. Everything else under `docs/` is hand-authored; see
81
+ [`docs/README.md`](./docs/README.md) before editing it.
138
82
 
139
83
  ## Development
140
84
 
@@ -144,16 +88,17 @@ Issues and pull requests are welcome. A few things to know before you start:
144
88
  $ git clone git@github.com:arrai-innovations/reactive-helpers.git
145
89
  ```
146
90
 
147
- 2. Install dependencies:
91
+ 2. Install dependencies. Development needs Node `>=22.13`, above the `>=22` the package itself declares, because
92
+ `eslint-plugin-jsdoc` and `vite` require it:
148
93
 
149
94
  ```bash
150
95
  $ pnpm install
151
96
  ```
152
97
 
153
- 3. Run tests via vitest:
98
+ 3. Run tests via vitest. Pass `run` for a single pass; `pnpm test` on its own starts watch mode:
154
99
 
155
100
  ```bash
156
- $ pnpm test
101
+ $ pnpm test run
157
102
  ```
158
103
 
159
104
  4. Run tests with coverage output:
@@ -162,13 +107,21 @@ Issues and pull requests are welcome. A few things to know before you start:
162
107
  $ pnpm coverage
163
108
  ```
164
109
 
165
- 5. Generate types and typedocs:
110
+ 5. Lint and format. Both rewrite files in place, and a git hook runs them on staged files:
111
+
112
+ ```bash
113
+ $ pnpm eslint
114
+ $ pnpm prettier
115
+ ```
116
+
117
+ 6. Generate types and typedocs, then confirm the committed output matches:
166
118
 
167
119
  ```bash
168
120
  $ pnpm run docs
121
+ $ pnpm run docs:check
169
122
  ```
170
123
 
171
- 6. Type-only workflows:
124
+ 7. Type-only workflows:
172
125
 
173
126
  - Generate types without docs:
174
127
  ```bash
@@ -179,6 +132,30 @@ Issues and pull requests are welcome. A few things to know before you start:
179
132
  $ pnpm run types:check -- --skip-gen
180
133
  ```
181
134
 
135
+ 8. Preview the documentation site. The build fails on dead links, so run it before proposing documentation changes:
136
+
137
+ ```bash
138
+ $ pnpm run docs:site:dev
139
+ $ pnpm run docs:site:build
140
+ ```
141
+
142
+ ### Deploy documentation
143
+
144
+ Tagging a release publishes the documentation. The `docs-site` CircleCI job runs after the npm publish succeeds, takes
145
+ the major from the tag, and deploys to `https://reactive-helpers.arrai.dev/v<major>/`. Releasing needs no separate
146
+ documentation step.
147
+
148
+ Publishing between releases is the out-of-band case: a correction or a new page that should not wait for the next tag.
149
+ Authenticate the CircleCI CLI with `circleci setup`, then run:
150
+
151
+ ```bash
152
+ $ pnpm run docs:site:deploy
153
+ ```
154
+
155
+ This triggers a docs-only pipeline against `main`. It derives the major from `package.json`, deploys to that same
156
+ per-major path, and does not publish the npm package. The script reuses the CLI's authentication. `CIRCLECI_TOKEN`
157
+ remains available as an override for automation.
158
+
182
159
  ## License
183
160
 
184
161
  [BSD-3-Clause](./LICENSE) © Arrai Innovations Inc.
@@ -1,4 +1,4 @@
1
- import { CancellablePromise } from "../utils/cancellablePromise.js";
1
+ import { makeCancellable } from "../utils/cancellablePromise.js";
2
2
  import cloneDeep from "lodash-es/cloneDeep.js";
3
3
  import { addOrUpdateReactiveObject } from "../utils/assignReactiveObject.js";
4
4
  import isFunction from "lodash-es/isFunction.js";
@@ -17,8 +17,7 @@ import { refIfReactive } from "../utils/refIfReactive.js";
17
17
  * @param {string} name - The name of the method.
18
18
  * @returns {(...args: any[]) => import('../utils/cancellablePromise.js').MaybeCancellablePromise<any>} - A function that returns a rejected promise with an error message.
19
19
  */
20
- export const missingMethod = (name) => () =>
21
- CancellablePromise.reject(new Error(`Crud method "${name}" is not implemented.`));
20
+ export const missingMethod = (name) => () => Promise.reject(new Error(`Crud method "${name}" is not implemented.`));
22
21
 
23
22
  // HACK: eslint, tsc, webstorm all can't agree on how to do this right
24
23
  // noinspection JSValidateTypes,JSUnusedLocalSymbols
@@ -34,7 +33,7 @@ export const requiredCancelMissingMethod =
34
33
  /* eslint-disable no-unused-vars */
35
34
  // @ts-ignore - refuses to accept returned CancellablePromise<void> = imported CancellablePromise<void>
36
35
  (..._args) =>
37
- CancellablePromise(Promise.reject(new Error(`Crud method "${name}" is not implemented.`)), () => {});
36
+ makeCancellable(Promise.reject(new Error(`Crud method "${name}" is not implemented.`)), () => {});
38
37
  /* eslint-enable no-unused-vars */
39
38
 
40
39
  /**
@@ -28,11 +28,10 @@ import { readonly } from "vue";
28
28
  * @typedef {object} ListArgsRaw - Raw arguments for a list operation before run-tracking and additional list CRUD arguments are merged in.
29
29
  * @property {import('../config/objectCrud.js').TargetArgs} target - The arguments to be passed to the crud handlers.
30
30
  * @property {string} pkKey - The key name of the primary key.
31
- * @property {object} params - The arguments to be passed for list crud handlers.
31
+ * @property {object} params - Your listing or retrieval arguments, passed through to the crud handlers.
32
32
  * @property {import("../use/listInstance.js").PushObjectsFn} pushObjects - The method to call with new page(s) of data received.
33
33
  * @property {ClearObjectsFn} clearObjects - The method to call to clear the objects.
34
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to a boolean indicating whether the request has
35
- * been cancelled.
34
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
36
35
  * @property {SetPaginateInfo} setPaginateInfo - The method to update pagination information.
37
36
  * @property {SetColumnTotals} setColumnTotals - The method to update column totals.
38
37
  */
@@ -44,8 +43,10 @@ import { readonly } from "vue";
44
43
  /**
45
44
  * @typedef {object} BulkDeleteArgsRaw - Raw arguments for a bulk-delete operation before additional list CRUD arguments are merged in.
46
45
  * @property {import('../config/objectCrud.js').TargetArgs} target - The arguments to be passed to the crud handlers.
47
- * @property {import('./commonCrud.js').Pk[]} pks - The ids of the objects to be deleted.
46
+ * @property {import('./commonCrud.js').Pk[]} pks - The pks of the objects to be deleted.
48
47
  * @property {string} pkKey - The key name of the primary key.
48
+ * @property {{[key:string]: any}} params - Your listing arguments, passed through to the crud handlers.
49
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
49
50
  */
50
51
 
51
52
  /**
@@ -63,10 +64,9 @@ import { readonly } from "vue";
63
64
  * @typedef {object} ListSubscribeArgsRaw - Raw arguments for a list subscribe operation before run-tracking and additional list CRUD arguments are merged in.
64
65
  * @property {import('../config/objectCrud.js').TargetArgs} target - The arguments to be passed to the crud handlers.
65
66
  * @property {string} pkKey - The key name of the primary key.
66
- * @property {object} params - The arguments to be passed for list crud handlers.
67
+ * @property {object} params - Your listing or retrieval arguments, passed through to the crud handlers.
67
68
  * @property {applyObjectEvent} applyObjectEvent - The method to call when new data is received.
68
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to a boolean indicating whether the request has
69
- * been cancelled.
69
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
70
70
  */
71
71
 
72
72
  /**
@@ -76,9 +76,11 @@ import { readonly } from "vue";
76
76
  /**
77
77
  * @typedef {object} ExecuteActionArgsRaw - Raw arguments for a list execute-action operation before additional list CRUD arguments are merged in.
78
78
  * @property {import('../config/objectCrud.js').TargetArgs} target - The arguments to be passed to the crud handlers.
79
- * @property {import('./commonCrud.js').Pk[]} pks - The ids of the objects to be acted upon.
79
+ * @property {import('./commonCrud.js').Pk[]} pks - The pks of the objects to be acted upon.
80
80
  * @property {string} pkKey - The key name of the primary key.
81
81
  * @property {string} action - The action to execute.
82
+ * @property {{[key:string]: any}} params - Your listing arguments, passed through to the crud handlers.
83
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
82
84
  */
83
85
 
84
86
  /**
@@ -88,13 +90,17 @@ import { readonly } from "vue";
88
90
  /**
89
91
  * @callback CrudListFn - Signature for the handler that lists objects from the backing store.
90
92
  * @param {ListArgs} args - The arguments to be passed to the crud handlers.
91
- * @returns {import('../utils/cancellablePromise.js').MaybeCancellablePromise<void>} - A cancellable promise for the list request.
93
+ * @returns {import('../utils/cancellablePromise.js').MaybeCancellablePromise<void>} - A promise whose resolution means
94
+ * the fetch is complete. Rows reach the list only through `pushObjects`, so the resolved value is ignored. Carry a
95
+ * `cancel` method to let the library abandon a superseded run.
92
96
  */
93
97
 
94
98
  /**
95
99
  * @callback CrudBulkDeleteFn - Signature for the handler that bulk-deletes objects from the backing store.
96
100
  * @param {BulkDeleteArgs} args - The arguments to be passed to the crud handlers.
97
- * @returns {Promise<boolean>} - A promise that resolves to a boolean indicating success.
101
+ * @returns {import('../utils/cancellablePromise.js').MaybeCancellablePromise<boolean>} - A promise whose resolution
102
+ * means the bulk delete succeeded; the resolved value is not inspected, and the instance then empties the list.
103
+ * Carry a `cancel` method to let the caller abandon the run.
98
104
  */
99
105
 
100
106
  /**
@@ -106,7 +112,9 @@ import { readonly } from "vue";
106
112
  /**
107
113
  * @callback CrudExecuteActionFn - Signature for the handler that executes an action on a list of objects in the backing store.
108
114
  * @param {ExecuteActionArgs} args - The arguments to be passed to the crud handlers.
109
- * @returns {Promise<object|string|null>} - A promise that resolves the result of the action, returned to the executor.
115
+ * @returns {import('../utils/cancellablePromise.js').MaybeCancellablePromise<object|string|null>} - A promise
116
+ * resolving the action's result, which `listInstance.executeAction` passes through to its caller. Carry a `cancel`
117
+ * method to let the caller abandon the run.
110
118
  */
111
119
 
112
120
  /**
@@ -29,10 +29,10 @@ import { readonly } from "vue";
29
29
  /**
30
30
  * @typedef {object} CreateArgsRaw - Raw arguments for an object create operation before additional CRUD arguments are merged in.
31
31
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
32
- * @property {{[key:string]: any}} object - The data to be acted upon.
33
- * @property {{[key:string]: any}} params - The arguments to be passed to the retrieve function.
32
+ * @property {{[key:string]: any}} object - The new object to create; it carries no primary key yet.
33
+ * @property {{[key:string]: any}} params - Your listing or retrieval arguments, passed through to the crud handlers.
34
34
  * @property {string} pkKey - The key name of the primary key.
35
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
35
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
36
36
  */
37
37
 
38
38
  /**
@@ -44,8 +44,8 @@ import { readonly } from "vue";
44
44
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
45
45
  * @property {import('./commonCrud.js').Pk} pk - The pk of the object to be acted upon.
46
46
  * @property {string} pkKey - The key name of the primary key.
47
- * @property {{[key:string]: any}} params - The arguments to be passed to the retrieve function.
48
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
47
+ * @property {{[key:string]: any}} params - Your listing or retrieval arguments, passed through to the crud handlers.
48
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
49
49
  */
50
50
 
51
51
  /**
@@ -55,10 +55,10 @@ import { readonly } from "vue";
55
55
  /**
56
56
  * @typedef {object} UpdateArgsRaw - Raw arguments for an object update operation before additional CRUD arguments are merged in.
57
57
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
58
- * @property {import('../use/objectInstance.js').ExistingCrudObject} object - The data to be acted upon.
59
- * @property {{[key:string]: any}} params - The arguments to be passed to the retrieve function.
58
+ * @property {import('../use/objectInstance.js').ExistingCrudObject} object - The complete object to update; its primary key rides inside it, at `object[pkKey]`.
59
+ * @property {{[key:string]: any}} params - Your listing or retrieval arguments, passed through to the crud handlers.
60
60
  * @property {string} pkKey - The key name of the primary key.
61
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
61
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
62
62
  */
63
63
 
64
64
  /**
@@ -70,7 +70,7 @@ import { readonly } from "vue";
70
70
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
71
71
  * @property {import('./commonCrud.js').Pk} pk - The pk of the object to be acted upon.
72
72
  * @property {string} pkKey - The key name of the primary key.
73
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
73
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
74
74
  */
75
75
 
76
76
  /**
@@ -82,9 +82,9 @@ import { readonly } from "vue";
82
82
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
83
83
  * @property {import('./commonCrud.js').Pk} pk - The pk of the object to be acted upon.
84
84
  * @property {string} pkKey - The key name of the primary key.
85
- * @property {{[key:string]: any}} partialObject - The data to be acted upon.
86
- * @property {{[key:string]: any}} params - The arguments to be passed to the retrieve function.
87
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
85
+ * @property {{[key:string]: any}} partialObject - The changed fields only.
86
+ * @property {{[key:string]: any}} params - Your listing or retrieval arguments, passed through to the crud handlers.
87
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
88
88
  */
89
89
  /**
90
90
  * @typedef {PartialArgsRaw & AdditionalCrudArgs} PartialArgs - Arguments for an object patch (partial update) operation, combining the raw arguments with any additional CRUD arguments.
@@ -92,11 +92,11 @@ import { readonly } from "vue";
92
92
 
93
93
  /**
94
94
  * @typedef {object} ObjectExecuteActionArgsRaw - Raw arguments for a single-object execute-action operation before additional CRUD arguments are merged in.
95
- * @property {import('../config/objectCrud.js').TargetArgs} target - The arguments to be passed to the crud handlers.
96
- * @property {string} pk - The id of the objects to be acted upon.
95
+ * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
96
+ * @property {import('./commonCrud.js').Pk} pk - The pk of the object to be acted upon.
97
97
  * @property {string} pkKey - The key name of the primary key.
98
98
  * @property {string} action - The action to execute.
99
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
99
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
100
100
  */
101
101
 
102
102
  /**
@@ -114,9 +114,9 @@ import { readonly } from "vue";
114
114
  * @property {TargetArgs} target - The arguments to be passed to the crud handlers.
115
115
  * @property {import('./commonCrud.js').Pk} pk - The pk of the object to be acted upon.
116
116
  * @property {string} pkKey - The key name of the primary key.
117
- * @property {{[key:string]: any}} params - The arguments to be passed to the retrieve function.
117
+ * @property {{[key:string]: any}} params - Your listing or retrieval arguments, passed through to the crud handlers.
118
118
  * @property {CrudSubscribeCallback} callback - The callback to be called when the object is updated.
119
- * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A ref to indicate if the request was cancelled.
119
+ * @property {Readonly<import('vue').Ref<boolean>>} isCancelled - A readonly ref that becomes true once the request is cancelled.
120
120
  */
121
121
 
122
122
  /**
@@ -124,43 +124,57 @@ import { readonly } from "vue";
124
124
  */
125
125
 
126
126
  /**
127
- * @typedef {import('../utils/cancellablePromise.js').MaybeCancellablePromise<object|string>} CrudResponse - The value returned by an object CRUD handler, a possibly-cancellable promise resolving to an object or string.
127
+ * @typedef {import('../utils/cancellablePromise.js').MaybeCancellablePromise<object>} CrudResponse -
128
+ * The value returned by an object CRUD handler whose resolved value becomes the record: create, retrieve, update, and
129
+ * patch. A possibly-cancellable promise resolving to the complete record. The instance mirrors the resolved value
130
+ * into `state.object`, so a partial record drops the fields it omits, and a resolved value that is not an object (a
131
+ * bare primary key string, for instance) fails the assignment and is stored in `state.error`.
132
+ */
133
+
134
+ /**
135
+ * @typedef {import('../utils/cancellablePromise.js').MaybeCancellablePromise<object|string|void>} CrudCompletionResponse -
136
+ * The value returned by an object CRUD handler that does not populate the managed record: delete, and
137
+ * executeAction. A possibly-cancellable promise that may resolve a record, a primary key string, or nothing at
138
+ * all. `delete` ignores the resolved value, treating resolution alone as success. `executeAction` passes the
139
+ * resolved value through to its caller, and resolves `null` instead when the action failed.
128
140
  */
129
141
 
130
142
  /**
131
143
  * @callback CrudCreateFn - Signature for the handler that creates an object in the backing store.
132
144
  * @param {CreateArgs} args - The arguments to be passed to the create function.
133
- * @returns {CrudResponse} - The response data from the create function.
145
+ * @returns {CrudResponse} - A promise resolving the created record in full.
134
146
  */
135
147
 
136
148
  /**
137
149
  * @callback CrudRetrieveFn - Signature for the handler that retrieves an object from the backing store.
138
150
  * @param {RetrieveArgs} args - The arguments to be passed to the retrieve function.
139
- * @returns {CrudResponse} - The response data from the retrieve function.
151
+ * @returns {CrudResponse} - A promise resolving the retrieved record in full.
140
152
  */
141
153
 
142
154
  /**
143
155
  * @callback CrudUpdateFn - Signature for the handler that updates an object in the backing store.
144
156
  * @param {UpdateArgs} args - The arguments to be passed to the update function.
145
- * @returns {CrudResponse} - The response data from the update function.
157
+ * @returns {CrudResponse} - A promise resolving the updated record in full.
146
158
  */
147
159
 
148
160
  /**
149
161
  * @callback CrudPatchFn - Signature for the handler that partially updates (patches) an object in the backing store.
150
162
  * @param {PartialArgs} args - The arguments to be passed to the patch function.
151
- * @returns {CrudResponse} - The response data from the patch function.
163
+ * @returns {CrudResponse} - A promise resolving the patched record in full, not just the changed fields.
152
164
  */
153
165
 
154
166
  /**
155
167
  * @callback CrudDeleteFn - Signature for the handler that deletes an object from the backing store.
156
168
  * @param {DeleteArgs} args - The arguments to be passed to the delete function.
157
- * @returns {CrudResponse} - The response data from the delete function.
169
+ * @returns {CrudCompletionResponse} - A promise whose resolution means the delete succeeded; its value is ignored.
158
170
  */
159
171
 
160
172
  /**
161
- * @callback CrudObjectExecuteActionFn - Signature for the handler that executes an action on a single object in the backing store.
173
+ * @callback CrudObjectExecuteActionFn - Signature for the handler that executes an action on a single object in the
174
+ * backing store. Its resolved value is passed through to the caller of `objectInstance.executeAction`.
162
175
  * @param {ObjectExecuteActionArgs} args - The arguments to be passed to the executeAction function.
163
- * @returns {CrudResponse} - The response data from the delete function.
176
+ * @returns {CrudCompletionResponse} - A promise resolving the action's result, which
177
+ * `objectInstance.executeAction` passes through to its caller. A stored failure resolves `null` instead.
164
178
  */
165
179
 
166
180
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrai-innovations/reactive-helpers",
3
- "version": "22.0.0",
3
+ "version": "23.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",
@@ -37,10 +37,15 @@
37
37
  "bugs": {
38
38
  "url": "https://github.com/arrai-innovations/reactive-helpers/issues"
39
39
  },
40
- "homepage": "https://github.com/arrai-innovations/reactive-helpers#readme",
40
+ "homepage": "https://reactive-helpers.arrai.dev/v23/",
41
+ "engines": {
42
+ "node": ">=22"
43
+ },
41
44
  "devDependencies": {
42
- "@arrai-innovations/commitlint-config": "^2.1.0",
43
- "@commitlint/cli": "^19.8.1",
45
+ "@arrai-innovations/commitlint-config": "^3.0.0",
46
+ "@arrai-innovations/diction-md": "^1.0.0",
47
+ "@arrai-innovations/vitepress-theme": "1.0.1",
48
+ "@commitlint/cli": "^21.2.1",
44
49
  "@eslint/js": "9.39.4",
45
50
  "@godaddy/dmd": "^1.0.4",
46
51
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
@@ -60,13 +65,14 @@
60
65
  "eslint-plugin-vue": "^10.9.2",
61
66
  "flush-promises": "^1.0.2",
62
67
  "globals": "^16.5.0",
63
- "jsdom": "^26.1.0",
68
+ "jsdom": "^30.0.1",
64
69
  "lefthook": "^1.13.6",
65
- "prettier": "^3.8.4",
70
+ "prettier": "^3.9.6",
66
71
  "typedoc": "^0.28.19",
67
72
  "typedoc-plugin-markdown": "^4.12.0",
68
73
  "typescript": "^5.9.3",
69
74
  "vite": "^8.0.16",
75
+ "vitepress": "^1.6.4",
70
76
  "vitest": "^4.1.9",
71
77
  "vue-eslint-parser": "^10.4.1"
72
78
  },
@@ -82,6 +88,12 @@
82
88
  "vue": "^3.5.13"
83
89
  },
84
90
  "scripts": {
91
+ "benchmark": "vitest bench --run",
92
+ "benchmark:list": "vitest bench --run tests/benchmarks/listPush.bench.js",
93
+ "benchmark:list:ci": "vitest bench --run tests/benchmarks/listPush.bench.js --outputJson benchmark-results/list-push.json",
94
+ "benchmark:check": "node check_benchmark.js",
95
+ "benchmark:layers": "vitest bench --run tests/benchmarks/listLayers.bench.js",
96
+ "benchmark:stream": "vitest bench --run tests/benchmarks/listStream.bench.js",
85
97
  "test": "vitest",
86
98
  "eslint": "eslint --fix index.js config/**/*.js tests/**/*.js use/**/*.js utils/**/*.js",
87
99
  "prettier": "prettier --write .",
@@ -89,6 +101,10 @@
89
101
  "docs": "node make_type_doc.js",
90
102
  "docs:check": "node check_type_doc.js",
91
103
  "docs:clean": "node clean_type_doc.js",
104
+ "docs:site:dev": "vitepress dev docs",
105
+ "docs:site:build": "vitepress build docs",
106
+ "docs:site:deploy": "node scripts/deploy-docs.mjs",
107
+ "docs:site:preview": "vitepress preview docs",
92
108
  "types": "node make_types.js",
93
109
  "types:check": "node check_types.js"
94
110
  }