@jskit-ai/agent-docs 0.1.126 → 0.1.128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guide/agent/app-extras/realtime.md +13 -13
- package/guide/agent/app-setup/a-more-interesting-shell.md +5 -3
- package/guide/agent/app-setup/upgrade-beta-1-to-final.md +108 -5
- package/guide/agent/app-setup/users.md +1 -1
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +6 -1
- package/guide/agent/generators/advanced-cruds.md +19 -14
- package/guide/agent/generators/crud-generators.md +1 -1
- package/guide/agent/generators/row-policies.md +2 -10
- package/package.json +1 -1
- package/patterns/INDEX.md +1 -1
- package/patterns/client-requests.md +6 -4
- package/patterns/generated-ui-contract-tracking.md +2 -2
- package/patterns/live-actions.md +1 -1
- package/reference/autogen/KERNEL_MAP.md +3 -96
- package/reference/autogen/README.md +1 -0
- package/reference/autogen/packages/assistant-core.md +0 -11
- package/reference/autogen/packages/assistant-runtime.md +7 -0
- package/reference/autogen/packages/crud-core.md +0 -72
- package/reference/autogen/packages/http-web.md +624 -0
- package/reference/autogen/packages/kernel.md +7 -98
- package/reference/autogen/packages/resource-crud-core.md +94 -0
- package/reference/autogen/packages/users-web.md +0 -593
- package/reference/autogen/packages/workspaces-web.md +30 -42
- package/reference/autogen/tooling/create-app.md +0 -10
- package/reference/autogen/tooling/jskit-cli.md +0 -12
- package/skills/jskit/references/crud-operations.md +3 -2
- package/skills/jskit/references/ui-operations.md +3 -0
|
@@ -47,7 +47,7 @@ So the first visible value of the package is not a whole new screen. It is a tin
|
|
|
47
47
|
|
|
48
48
|
The app already had a browser dev server on `5173` and a backend runtime on `3000`.
|
|
49
49
|
|
|
50
|
-
`realtime`
|
|
50
|
+
`realtime` declares a websocket proxy for `/socket.io` in its published `package.json.jskit` metadata. The JSKIT Vite plugin reads that declaration from the installed npm graph and forwards websocket traffic from the frontend dev server on `5173` to the backend runtime on `3000`.
|
|
51
51
|
|
|
52
52
|
So one of the main values of this package is that you do **not** have to hand-edit Vite config just to make socket.io work in local development.
|
|
53
53
|
|
|
@@ -210,26 +210,26 @@ REALTIME_REDIS_URL=
|
|
|
210
210
|
|
|
211
211
|
That empty value is deliberate. It means the app can start with the in-memory adapter locally, and you can fill in a real Redis URL later if you need cross-instance fan-out.
|
|
212
212
|
|
|
213
|
-
###
|
|
213
|
+
### Package metadata declares the websocket proxy
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
The installed `@jskit-ai/realtime` package declares:
|
|
216
216
|
|
|
217
217
|
```json
|
|
218
218
|
{
|
|
219
|
-
"
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
219
|
+
"jskit": {
|
|
220
|
+
"vite": {
|
|
221
|
+
"proxy": {
|
|
222
|
+
"/socket.io": {
|
|
223
|
+
"changeOrigin": true,
|
|
224
|
+
"ws": true
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
227
|
}
|
|
228
|
-
|
|
228
|
+
}
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
`createJskitClientBootstrapPlugin({ proxyTarget })` reads that metadata directly. The application owns only its normal Vite config and proxy target; installing or removing the npm package changes the active proxy on the next Vite start without generated project state.
|
|
233
233
|
|
|
234
234
|
### `src/placement.js` includes the shell status placement
|
|
235
235
|
|
|
@@ -577,6 +577,8 @@ Request connectivity failures use a separate shell recovery path. Generated apps
|
|
|
577
577
|
|
|
578
578
|
That recovery path is intentionally a safe `GET`/`HEAD` read refetch system, not a general HTTP replay system. User-visible reads should go through Query-backed JSKIT primitives such as `useEndpointResource()`, `useList()`, `useView()`, `useAddEdit()`, or generated CRUD screen composables. Those primitives mark Query entries with `jskit.requestRecoveryMethod`, so the shell only offers Retry for safe reads. Do not catch raw `fetch(...)` failures in each panel just to call the shell recovery runtime manually.
|
|
579
579
|
|
|
580
|
+
These neutral request and CRUD client APIs are exported by `@jskit-ai/http-web`. They do not require the users, authentication, uploads, storage, or database products.
|
|
581
|
+
|
|
580
582
|
For a custom endpoint read, attach the recovery label to the Query-backed resource:
|
|
581
583
|
|
|
582
584
|
```js
|
|
@@ -611,9 +613,9 @@ Writes are different. JSKIT does not automatically replay `POST`, `PATCH`, `PUT`
|
|
|
611
613
|
Some apps need API URLs to be scoped by the active route before the browser request is sent. Configure that once at app startup instead of replacing `fetchImpl` in a local transport wrapper:
|
|
612
614
|
|
|
613
615
|
```js
|
|
614
|
-
import {
|
|
616
|
+
import { configureHttpWebClient } from "@jskit-ai/http-web/client/lib/httpClient";
|
|
615
617
|
|
|
616
|
-
|
|
618
|
+
configureHttpWebClient({
|
|
617
619
|
csrf: {
|
|
618
620
|
enabled: false
|
|
619
621
|
},
|
|
@@ -628,7 +630,7 @@ configureUsersWebHttpClient({
|
|
|
628
630
|
});
|
|
629
631
|
```
|
|
630
632
|
|
|
631
|
-
Call `
|
|
633
|
+
Call `configureHttpWebClient()` before Vue mounts or before JSKIT composables are created. The resolver can close over the app router/store when it needs route data, and the `context` argument carries request details such as `originalUrl`, `method`, `requestOptions`, and whether the request is a stream. After configuration, normal `useEndpointResource()`, `useList()`, `useView()`, `useAddEdit()`, and `useCommand()` calls use the configured client. `resolveRequestUrl` runs after JSKIT adds query strings and before the underlying browser `fetch`, so request recovery metadata, JSON:API transport, credentials, CSRF, and command feedback stay on the standard path.
|
|
632
634
|
|
|
633
635
|
For packages that create their own client, use the same lower-level hook directly:
|
|
634
636
|
|
|
@@ -54,7 +54,7 @@ Move every package relationship from `jskit.dependsOn` to the appropriate standa
|
|
|
54
54
|
|
|
55
55
|
Pin `@jskit-ai/*` packages to exact versions. Remove `jskit.dependsOn` completely.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Rename provider-class `static dependsOn` to `static startsAfter`, then audit every entry. Keep only providers whose registration or boot must complete before the declaring provider reaches the same phase. JSKIT completes registration for the entire graph before beginning any boot method, so a lazily consumed service does not justify an ordering edge.
|
|
58
58
|
|
|
59
59
|
## 4. Remove Beta 1 project state
|
|
60
60
|
|
|
@@ -63,11 +63,22 @@ Delete these paths from the application:
|
|
|
63
63
|
```text
|
|
64
64
|
.jskit/lock.json
|
|
65
65
|
.jskit/verification/
|
|
66
|
+
.jskit/vite.dev.proxy.json
|
|
66
67
|
```
|
|
67
68
|
|
|
68
69
|
Remove ignore rules created solely for `.jskit/verification/`.
|
|
69
70
|
|
|
70
|
-
Do not translate
|
|
71
|
+
Do not translate these paths into replacements. Final Release derives package state from `package.json`, `package-lock.json`, installed package manifests, application config, migration files, and generated CI.
|
|
72
|
+
|
|
73
|
+
Delete the app-local Vite proxy loader and any `vite.shared.mjs` file used only for that generated JSON. Pass the application's API target to the standard plugin instead:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
createJskitClientBootstrapPlugin({
|
|
77
|
+
proxyTarget: apiProxyTarget
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Installed packages now declare development proxies in `package.json.jskit.vite.proxy`, and the plugin derives the active proxy table directly whenever Vite starts.
|
|
71
82
|
|
|
72
83
|
## 5. Replace command usage
|
|
73
84
|
|
|
@@ -95,7 +106,99 @@ npm ls
|
|
|
95
106
|
|
|
96
107
|
Resolve npm peer or capability errors as package-graph errors. Do not add overrides that mix Beta 1 and Final Release packages.
|
|
97
108
|
|
|
98
|
-
## 7.
|
|
109
|
+
## 7. Move neutral web operations out of users-web
|
|
110
|
+
|
|
111
|
+
Final Release owns browser request, command, list, view, add/edit, permission,
|
|
112
|
+
paging, and generated CRUD UI APIs in `@jskit-ai/http-web`. There are no
|
|
113
|
+
`users-web` compatibility exports.
|
|
114
|
+
|
|
115
|
+
Add the coordinated `@jskit-ai/http-web` version to every application or
|
|
116
|
+
workspace that uses these APIs. Keep `@jskit-ai/users-web` only where the code
|
|
117
|
+
actually uses account, profile, or user-specific shell UI.
|
|
118
|
+
|
|
119
|
+
Update imports as follows:
|
|
120
|
+
|
|
121
|
+
| Beta 1 import or API | Final Release import or API |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| `@jskit-ai/users-web/client/composables/useCommand` | `@jskit-ai/http-web/client/composables/useCommand` |
|
|
124
|
+
| `@jskit-ai/users-web/client/composables/useEndpointResource` | `@jskit-ai/http-web/client/composables/useEndpointResource` |
|
|
125
|
+
| `@jskit-ai/users-web/client/composables/useList` | `@jskit-ai/http-web/client/composables/useList` |
|
|
126
|
+
| `@jskit-ai/users-web/client/composables/useView` | `@jskit-ai/http-web/client/composables/useView` |
|
|
127
|
+
| `@jskit-ai/users-web/client/composables/useAddEdit` | `@jskit-ai/http-web/client/composables/useAddEdit` |
|
|
128
|
+
| `@jskit-ai/users-web/client/composables/useAccess` | `@jskit-ai/http-web/client/composables/useAccess` |
|
|
129
|
+
| `@jskit-ai/users-web/client/composables/usePagedCollection` | `@jskit-ai/http-web/client/composables/usePagedCollection` |
|
|
130
|
+
| `@jskit-ai/users-web/client/composables/useRealtimeQueryInvalidation` | `@jskit-ai/http-web/client/composables/useRealtimeQueryInvalidation` |
|
|
131
|
+
| `@jskit-ai/users-web/client/composables/runtime/useUiFeedback` | `@jskit-ai/http-web/client/composables/useUiFeedback` |
|
|
132
|
+
| `@jskit-ai/users-web/client/composables/useCrud*` | `@jskit-ai/http-web/client/composables/useCrud*` |
|
|
133
|
+
| `@jskit-ai/users-web/client/components/Crud*` | `@jskit-ai/http-web/client/components/Crud*` |
|
|
134
|
+
| `@jskit-ai/users-web/client/filters` | `@jskit-ai/http-web/client/filters` |
|
|
135
|
+
| `@jskit-ai/users-web/client/bulkActions` | `@jskit-ai/http-web/client/bulkActions` |
|
|
136
|
+
| `@jskit-ai/users-web/client/rowActions` | `@jskit-ai/http-web/client/rowActions` |
|
|
137
|
+
| `@jskit-ai/users-web/client/lib/permissions` | `@jskit-ai/http-web/client/lib/permissions` |
|
|
138
|
+
| `@jskit-ai/users-web/client/support/contractGuards` | `@jskit-ai/http-web/client/support/contractGuards` |
|
|
139
|
+
| `configureUsersWebHttpClient(...)` | `configureHttpWebClient(...)` from `@jskit-ai/http-web/client/lib/httpClient` |
|
|
140
|
+
| `usersWebHttpClient` | `httpWebClient` from `@jskit-ai/http-web/client/lib/httpClient` |
|
|
141
|
+
|
|
142
|
+
Search every application workspace, generated route tree, test fixture, and
|
|
143
|
+
app bootstrap. An application that leaves even one removed import will fail at
|
|
144
|
+
module resolution; this is intentional because Final Release contains no
|
|
145
|
+
forwarding bridge.
|
|
146
|
+
|
|
147
|
+
`crud-ui-generator` now installs `@jskit-ai/http-web`. `ui-generator` installs
|
|
148
|
+
no users product. Existing generated files are application-owned, so update
|
|
149
|
+
their imports directly or deliberately regenerate them and review the diff.
|
|
150
|
+
|
|
151
|
+
After all imports are updated, remove `@jskit-ai/users-web` from any workspace
|
|
152
|
+
that used it only for neutral client APIs. This prevents those applications
|
|
153
|
+
from activating users, authentication, uploads, storage, or database
|
|
154
|
+
capabilities accidentally.
|
|
155
|
+
|
|
156
|
+
## 8. Use the separated CRUD package boundaries
|
|
157
|
+
|
|
158
|
+
Final Release separates shared resource contracts, browser CRUD, and
|
|
159
|
+
database-backed CRUD:
|
|
160
|
+
|
|
161
|
+
- `@jskit-ai/resource-crud-core` owns environment-neutral CRUD resource,
|
|
162
|
+
field, lookup, namespace, and list-filter contracts;
|
|
163
|
+
- `@jskit-ai/http-web` owns browser request runtimes and generated CRUD UI;
|
|
164
|
+
- `@jskit-ai/crud-core` owns database-backed server CRUD services and
|
|
165
|
+
repositories.
|
|
166
|
+
|
|
167
|
+
Update shared-contract imports as follows:
|
|
168
|
+
|
|
169
|
+
| Beta 1 import | Final Release import |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| `@jskit-ai/kernel/shared/support/crudFieldContract` | `@jskit-ai/resource-crud-core/shared/crudFieldContract` |
|
|
172
|
+
| `@jskit-ai/kernel/shared/support/crudLookup` | `@jskit-ai/resource-crud-core/shared/crudLookup` |
|
|
173
|
+
| `@jskit-ai/kernel/shared/support/crudListFilters` | `@jskit-ai/resource-crud-core/shared/crudListFilters` |
|
|
174
|
+
| `@jskit-ai/crud-core/shared/crudResource` | `@jskit-ai/resource-crud-core/shared/crudResource` |
|
|
175
|
+
| `@jskit-ai/crud-core/shared/crudNamespaceSupport` | `@jskit-ai/resource-crud-core/shared/crudNamespaceSupport` |
|
|
176
|
+
| `checkCrudLookupFormControl` from `@jskit-ai/crud-core/shared/crudFieldSupport` | `checkCrudLookupFormControl` from `@jskit-ai/resource-crud-core/shared/crudFieldContract` |
|
|
177
|
+
| `isCrudRuntimeOutputOnlyFieldKey` from `@jskit-ai/crud-core/shared/crudFieldSupport` | `isCrudRuntimeOutputOnlyFieldKey` from `@jskit-ai/resource-crud-core/shared/crudLookup` |
|
|
178
|
+
|
|
179
|
+
There is no `@jskit-ai/crud-core/client` surface. Replace browser imports from
|
|
180
|
+
that surface with the corresponding `@jskit-ai/http-web` API. Add
|
|
181
|
+
`@jskit-ai/resource-crud-core` directly wherever application code imports its
|
|
182
|
+
contracts. Remove `@jskit-ai/crud-core` from client-only and generator-only
|
|
183
|
+
workspaces; retain it only where database-backed server CRUD is used.
|
|
184
|
+
|
|
185
|
+
The current CRUD UI templates import `@jskit-ai/http-web`, and the CRUD UI
|
|
186
|
+
generator no longer installs the server CRUD runtime. Existing generated files
|
|
187
|
+
are application-owned, so update their imports directly or deliberately
|
|
188
|
+
regenerate them and review the diff.
|
|
189
|
+
|
|
190
|
+
If application tests or package tooling refer to workspaces-web mutation IDs,
|
|
191
|
+
rename the `users-web-*` prefix on workspaces-web-owned mutations to
|
|
192
|
+
`workspaces-web-*`. Package-internal `UsersWorkspace*` component paths are not
|
|
193
|
+
public APIs; remove any direct imports and use the exported workspaces-web
|
|
194
|
+
provider surface.
|
|
195
|
+
|
|
196
|
+
If application code imported repository persistence helpers from
|
|
197
|
+
`@jskit-ai/assistant-core/server`, keep those helpers with the repository that
|
|
198
|
+
uses them or use the matching database-runtime primitive. Assistant core no
|
|
199
|
+
longer owns database persistence utilities.
|
|
200
|
+
|
|
201
|
+
## 9. Generate deterministic projections
|
|
99
202
|
|
|
100
203
|
Synchronize package migration files without applying them:
|
|
101
204
|
|
|
@@ -118,7 +221,7 @@ npx jskit ci generate
|
|
|
118
221
|
|
|
119
222
|
Move application-specific CI into separate workflow files. The generated JSKIT workflow is replaced in full whenever this command runs.
|
|
120
223
|
|
|
121
|
-
##
|
|
224
|
+
## 10. Verify the application
|
|
122
225
|
|
|
123
226
|
```bash
|
|
124
227
|
npx jskit lint-packages
|
|
@@ -138,7 +241,7 @@ npm run db:migrate
|
|
|
138
241
|
|
|
139
242
|
Commit package manifests, `package-lock.json`, synchronized migrations, generated CI, and required application changes together.
|
|
140
243
|
|
|
141
|
-
##
|
|
244
|
+
## 11. Update strict resource boundaries
|
|
142
245
|
|
|
143
246
|
Applications that pass JavaScript `Date` objects into resource validation must convert them to strings. `date` uses `YYYY-MM-DD`; `time` uses offset-free `HH:MM[:SS[.fraction]]`; and `dateTime` uses RFC 3339 with seconds and a `Z` or numeric offset. Select `epochMilliseconds` or `epochSeconds` explicitly for numeric epochs and preserve `temporalPrecision`.
|
|
144
247
|
|
|
@@ -25,7 +25,7 @@ npm run db:migrate
|
|
|
25
25
|
|
|
26
26
|
The first command adds `users-web`, but the important part is what arrives with it through its dependency chain.
|
|
27
27
|
|
|
28
|
-
- `users-web` adds
|
|
28
|
+
- `users-web` adds account, profile, and user-specific shell UI
|
|
29
29
|
- `users-core` arrives as a dependency and adds the persistent users/account server layer and schema migrations
|
|
30
30
|
|
|
31
31
|
`jskit add` installs those runtime packages and their dependencies. `npm run db:migrate` is the separate step that makes the new tables real in MySQL.
|
|
@@ -40,6 +40,9 @@ A JSKIT package is an ordinary npm package with a `jskit` object in `package.jso
|
|
|
40
40
|
"providers": []
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
+
"vite": {
|
|
44
|
+
"proxy": {}
|
|
45
|
+
},
|
|
43
46
|
"mutations": {
|
|
44
47
|
"dependencies": {
|
|
45
48
|
"runtime": {},
|
|
@@ -63,7 +66,9 @@ needed by generated application-owned source or application-level tooling. It
|
|
|
63
66
|
does not declare relationships between JSKIT packages and does not affect
|
|
64
67
|
package ordering.
|
|
65
68
|
|
|
66
|
-
`runtime.server.providers` and `runtime.client.providers` declare runtime entrypoints. A provider class may use `static
|
|
69
|
+
`runtime.server.providers` and `runtime.client.providers` declare runtime entrypoints. A provider class may use `static startsAfter` when its own registration or boot genuinely requires another provider to have completed the same lifecycle phase first. JSKIT registers every provider before booting any provider, so later service consumption does not require an ordering declaration.
|
|
70
|
+
|
|
71
|
+
`jskit.vite.proxy` declares development proxy requirements as path-keyed metadata. `createJskitClientBootstrapPlugin({ proxyTarget })` reads those declarations directly from the installed npm graph when Vite starts. Package installation does not generate an intermediate proxy file.
|
|
67
72
|
|
|
68
73
|
Use exact versions for `@jskit-ai/*` dependencies. npm's `package-lock.json` remains the reproducible installation record.
|
|
69
74
|
|
|
@@ -49,7 +49,9 @@ After those two commands, the important thing to understand is ownership:
|
|
|
49
49
|
|
|
50
50
|
- `crud-server-generator` creates a runtime package that your app owns locally
|
|
51
51
|
- `crud-ui-generator` creates route files that your app owns locally
|
|
52
|
-
- `crud-core
|
|
52
|
+
- `crud-core` provides the server CRUD runtime, `resource-crud-core` owns shared
|
|
53
|
+
CRUD contracts, and `http-web` provides browser operations and generated
|
|
54
|
+
screen components
|
|
53
55
|
|
|
54
56
|
The generated pages are intentionally thin. Most of the heavy lifting lives uphill in shared runtime composables, action execution, validation, lookup hydration, and repository helpers.
|
|
55
57
|
|
|
@@ -480,7 +482,8 @@ Its job is usually to:
|
|
|
480
482
|
- resolve list/view/edit/new URLs
|
|
481
483
|
- pass route query state through when navigating deeper
|
|
482
484
|
|
|
483
|
-
The actual list machinery lives in `
|
|
485
|
+
The actual list machinery lives in `http-web` screen composables and the shared
|
|
486
|
+
resource contract lives in `resource-crud-core`.
|
|
484
487
|
|
|
485
488
|
### `[contactId]/index.vue`
|
|
486
489
|
|
|
@@ -703,17 +706,19 @@ Why this is the standard JSKIT shape:
|
|
|
703
706
|
|
|
704
707
|
- `useCommand()` resolves the correct scoped API path for the current route and surface.
|
|
705
708
|
- The higher-level list, view, add/edit, and command runtimes send requests through the standard HTTP runtime instead of ad hoc request code.
|
|
706
|
-
- The default client runtime uses `
|
|
709
|
+
- The default client runtime uses `httpWebClient`, which already handles credentials and CSRF token behavior.
|
|
707
710
|
- `useEndpointResource()` gives the shared endpoint primitive for loading, saving, and standard load/save error handling. Higher-level runtimes like `useCommand()` and `useAddEdit()` layer UI feedback and field-error behavior on top of that primitive.
|
|
708
711
|
- `shell-web` observes the shared TanStack Query client for recoverable transport failures. Generated CRUD reads and custom reads built with `useEndpointResource()`, `useList()`, `useView()`, or `useAddEdit()` get the shell recovery banner with a Retry action that refetches the failed query.
|
|
709
712
|
- Automatic shell request recovery is only for safe `GET`/`HEAD` read refetches. JSKIT read composables mark Query entries with `jskit.requestRecoveryMethod`, and the shell ignores unmarked or unsafe methods. Do not rely on it to replay `POST`, `PATCH`, `PUT`, or `DELETE`; mutation screens own save state, field errors, and user feedback.
|
|
710
713
|
|
|
711
|
-
|
|
714
|
+
The request composables and generated CRUD client surfaces above come from `@jskit-ai/http-web`. That package is neutral: installing it does not install users, authentication, uploads, storage, or a database.
|
|
715
|
+
|
|
716
|
+
When an app needs all JSKIT reads and commands to rewrite API URLs before fetch, configure the http-web client once instead of passing custom paths or replacing `fetchImpl` in each local helper:
|
|
712
717
|
|
|
713
718
|
```js
|
|
714
|
-
import {
|
|
719
|
+
import { configureHttpWebClient } from "@jskit-ai/http-web/client/lib/httpClient";
|
|
715
720
|
|
|
716
|
-
|
|
721
|
+
configureHttpWebClient({
|
|
717
722
|
csrf: {
|
|
718
723
|
enabled: false
|
|
719
724
|
},
|
|
@@ -787,7 +792,7 @@ The safe mental model is:
|
|
|
787
792
|
- do not raw `fetch(...)` for normal app work
|
|
788
793
|
- do not invent ad hoc local AJAX helpers
|
|
789
794
|
- use the operation/runtime composable that matches the UI interaction
|
|
790
|
-
- drop to `
|
|
795
|
+
- drop to `httpWebClient.request(...)` only for exceptional low-level cases
|
|
791
796
|
- use `usePaths().api(...)` when you need a custom scoped API path and the higher-level runtime does not already resolve it for you
|
|
792
797
|
- keep `apiUrlTemplate` path-only and put endpoint query strings in `requestQueryParams`
|
|
793
798
|
|
|
@@ -800,7 +805,7 @@ It owns:
|
|
|
800
805
|
- which set of generated form fields is rendered in `new` vs `edit`
|
|
801
806
|
- lookup field prop forwarding into those fields
|
|
802
807
|
|
|
803
|
-
It does **not** own persistence logic or the shared screen chrome. `CrudAddEditScreen` from
|
|
808
|
+
It does **not** own persistence logic or the shared screen chrome. `CrudAddEditScreen` from `@jskit-ai/http-web` owns the common title, load state, retry action, save/cancel action row, and form surface.
|
|
804
809
|
|
|
805
810
|
### `src/components/.../CrudAddEditFormFields.js`
|
|
806
811
|
|
|
@@ -824,7 +829,7 @@ That is navigation wiring, not CRUD logic.
|
|
|
824
829
|
A generated CRUD works because several layers cooperate:
|
|
825
830
|
|
|
826
831
|
1. the route page calls `useCrudListScreen()`, `useCrudViewScreen()`, or `useCrudAddEditScreen()`
|
|
827
|
-
2. those screen composables configure the lower-level list/view/add-edit runtimes from
|
|
832
|
+
2. those screen composables configure the lower-level list/view/add-edit runtimes from `@jskit-ai/http-web`
|
|
828
833
|
3. the request hits the HTTP route from `registerRoutes.js`
|
|
829
834
|
4. the route executes an action from `actions.js`
|
|
830
835
|
5. the action delegates to the service in `service.js`
|
|
@@ -847,7 +852,7 @@ Use this rule of thumb when deciding where to edit:
|
|
|
847
852
|
| Change SQL, joins, parent filters, or advanced search | `repository.js` | This is the data-access layer |
|
|
848
853
|
| Add mandatory SQL visibility that must run before count and pagination | server policy module plus the provider's `createJsonRestResourceScopeOptions(..., { rowPolicy })` call | The internal JSON REST host applies the policy to every storage query for that resource |
|
|
849
854
|
| Add cross-record or domain rules on save/delete | `service.js` | This is business logic |
|
|
850
|
-
| Change shared CRUD screen chrome, load states, or retry behavior | `
|
|
855
|
+
| Change shared CRUD screen chrome, load states, or retry behavior | `http-web` shared screen components | Generated pages consume the shared screen contract |
|
|
851
856
|
| Add per-row commands to a generated list page | page-local `listRowActions.js`, usually calling `useCommand()`-backed composables | The shared list screen renders action chrome; the page owns explicit mutation behavior |
|
|
852
857
|
| Add non-CRUD display rows to a generated list page | route page `syntheticRows` input | Synthetic rows are presentation rows, not repository records |
|
|
853
858
|
| Change page-specific display behavior | the route pages, generated slots, and app-owned composables | This is presentation |
|
|
@@ -869,7 +874,7 @@ That is the right direction of growth:
|
|
|
869
874
|
- server customizations stay in the CRUD package
|
|
870
875
|
- presentation and page-specific UI state stay in app-owned client files
|
|
871
876
|
- shared structured list filters live best in a CRUD-package shared module that both server and client can import
|
|
872
|
-
- shared generated screen chrome stays in `
|
|
877
|
+
- shared generated screen chrome stays in `http-web`; adapted pages feed it definitions, slots, and explicit command handlers
|
|
873
878
|
|
|
874
879
|
### Shared screen read options and detail slots
|
|
875
880
|
|
|
@@ -1191,7 +1196,7 @@ Instead:
|
|
|
1191
1196
|
For example, a generated page-local filter-definition module can look like this:
|
|
1192
1197
|
|
|
1193
1198
|
```js
|
|
1194
|
-
import { defineCrudListFilters } from "@jskit-ai/
|
|
1199
|
+
import { defineCrudListFilters } from "@jskit-ai/http-web/client/filters";
|
|
1195
1200
|
|
|
1196
1201
|
const listFilters = defineCrudListFilters({
|
|
1197
1202
|
onlyStaff: {
|
|
@@ -1222,7 +1227,7 @@ Use this first when adding selected-record actions. JSKIT does not invent server
|
|
|
1222
1227
|
For example:
|
|
1223
1228
|
|
|
1224
1229
|
```js
|
|
1225
|
-
import { defineCrudListBulkActions } from "@jskit-ai/
|
|
1230
|
+
import { defineCrudListBulkActions } from "@jskit-ai/http-web/client/bulkActions";
|
|
1226
1231
|
|
|
1227
1232
|
const listBulkActions = defineCrudListBulkActions([
|
|
1228
1233
|
{
|
|
@@ -1259,7 +1264,7 @@ Use row actions for explicit commands on one record. JSKIT renders the action me
|
|
|
1259
1264
|
For example:
|
|
1260
1265
|
|
|
1261
1266
|
```js
|
|
1262
|
-
import { defineCrudListRowActions } from "@jskit-ai/
|
|
1267
|
+
import { defineCrudListRowActions } from "@jskit-ai/http-web/client/rowActions";
|
|
1263
1268
|
|
|
1264
1269
|
const listRowActions = defineCrudListRowActions([
|
|
1265
1270
|
{
|
|
@@ -510,7 +510,7 @@ route after success. It supports custom `--id-param` names.
|
|
|
510
510
|
|
|
511
511
|
The generator rejects this option when list or view is omitted, or when the
|
|
512
512
|
shared resource has no `DELETE` operation. Without the flag, no delete control
|
|
513
|
-
is generated. Do not substitute raw `fetch()` or import private `
|
|
513
|
+
is generated. Do not substitute raw `fetch()` or import private `http-web`
|
|
514
514
|
modules.
|
|
515
515
|
|
|
516
516
|
Generated list, view, and lookup reads use the resource contract as their
|
|
@@ -251,13 +251,7 @@ The owning provider creates the visibility object during `register()` and consum
|
|
|
251
251
|
class OrganisationUnitsProvider {
|
|
252
252
|
static id = "crud.organisation_units";
|
|
253
253
|
|
|
254
|
-
static
|
|
255
|
-
"runtime.actions",
|
|
256
|
-
"runtime.database",
|
|
257
|
-
"auth.policy.fastify",
|
|
258
|
-
"local.main",
|
|
259
|
-
"json-rest-api.core"
|
|
260
|
-
];
|
|
254
|
+
static startsAfter = ["json-rest-api.core", "local.main", "runtime.actions"];
|
|
261
255
|
|
|
262
256
|
register(app) {
|
|
263
257
|
app.instance(
|
|
@@ -345,8 +339,6 @@ The safety package depends on organisation-units and registers its grant:
|
|
|
345
339
|
class SafetyProvider {
|
|
346
340
|
static id = "safety.core";
|
|
347
341
|
|
|
348
|
-
static dependsOn = ["crud.organisation_units"];
|
|
349
|
-
|
|
350
342
|
register(app) {
|
|
351
343
|
registerOrganisationUnitVisibility(app, {
|
|
352
344
|
id: "safety-manager-descendants",
|
|
@@ -360,7 +352,7 @@ class SafetyProvider {
|
|
|
360
352
|
|
|
361
353
|
The organisation-units package never imports safety. Installing safety adds the grant; omitting safety leaves that grant absent.
|
|
362
354
|
|
|
363
|
-
|
|
355
|
+
No provider start-order declaration is needed here. JSKIT completes every provider's `register()` phase before any provider begins `boot()`, so safety's contribution is present before organisation-units seals the registry. The normal npm dependency points from safety to organisation-units because safety imports its registration API.
|
|
364
356
|
|
|
365
357
|
## Descendant visibility with a recursive CTE
|
|
366
358
|
|
package/package.json
CHANGED
package/patterns/INDEX.md
CHANGED
|
@@ -26,7 +26,7 @@ How to use it:
|
|
|
26
26
|
- `page-redirects.md`
|
|
27
27
|
- live actions, checkbox, toggle, patch button, delete confirmation, destructive action, inline action, `useCommand()`, `useCrudDeleteAction()`
|
|
28
28
|
- `live-actions.md`
|
|
29
|
-
- ajax, fetch, API call, request, endpoint, HTTP client, `useCrudListScreen()`, `useCrudViewScreen()`, `useCrudAddEditScreen()`, `useList()`, `useView()`, `useAddEdit()`, `useEndpointResource()`, `
|
|
29
|
+
- ajax, fetch, API call, request, endpoint, HTTP client, `useCrudListScreen()`, `useCrudViewScreen()`, `useCrudAddEditScreen()`, `useList()`, `useView()`, `useAddEdit()`, `useEndpointResource()`, `httpWebClient`
|
|
30
30
|
- `client-requests.md`
|
|
31
31
|
- playwright, browser test, e2e, ui verification, baseline test, authenticated ui test, test auth, dev login as, dev auth bypass
|
|
32
32
|
- `ui-testing.md`
|
|
@@ -14,7 +14,7 @@ Rules:
|
|
|
14
14
|
- Do not hand-roll local AJAX helpers when an existing JSKIT runtime already fits.
|
|
15
15
|
- Do not use raw `fetch(...)` for normal app work.
|
|
16
16
|
- Use `usePaths().api(...)` from `@jskit-ai/shell-web/client/navigation/usePaths` for custom scoped API paths instead of concatenating route params into URLs by hand.
|
|
17
|
-
- Drop to `
|
|
17
|
+
- Drop to `httpWebClient.request(...)` only for exceptional low-level cases.
|
|
18
18
|
|
|
19
19
|
Choose the function like this:
|
|
20
20
|
|
|
@@ -64,13 +64,13 @@ Use the CRUD wrappers when they fit:
|
|
|
64
64
|
CRUD hook transport defaults:
|
|
65
65
|
|
|
66
66
|
- CRUD hooks derive the standard JSON:API transport from the shared CRUD `resource` automatically.
|
|
67
|
-
- Do not pass `transport` to CRUD hooks. If you need a non-standard wire contract, drop to `useList()`, `useView()`, `useAddEdit()`, or `
|
|
67
|
+
- Do not pass `transport` to CRUD hooks. If you need a non-standard wire contract, drop to `useList()`, `useView()`, `useAddEdit()`, or `httpWebClient.request(...)` instead of the CRUD wrappers.
|
|
68
68
|
|
|
69
69
|
Why this is the standard JSKIT shape:
|
|
70
70
|
|
|
71
71
|
- `useCommand()` resolves the scoped API path for the current route and surface.
|
|
72
72
|
- The higher-level list, view, add/edit, and command runtimes send requests through the shared HTTP runtime.
|
|
73
|
-
- `
|
|
73
|
+
- `httpWebClient` already handles credentials and CSRF behavior.
|
|
74
74
|
- `useEndpointResource()` is the shared endpoint primitive for loading, saving, and standard load/save error handling. Higher-level runtimes add UI feedback and field-error handling on top.
|
|
75
75
|
- Use `requestQueryParams` for endpoint query strings on list, view, and add/edit runtimes.
|
|
76
76
|
- Generated CRUD and lookup reads use all resource-defined output fields by default. Hydrated relationships use the target resource's output contract. Generated pages and lookup controls do not repeat those definitions as request fieldsets.
|
|
@@ -79,7 +79,9 @@ Why this is the standard JSKIT shape:
|
|
|
79
79
|
- Sparse fieldsets are a serialization boundary, not an authorization mechanism. Server resources reject unknown fields, never serialize hidden fields, and preserve the fields needed internally for relationship linkage.
|
|
80
80
|
- Fields that must never be exposed do not belong in the resource output schema.
|
|
81
81
|
- Keep `apiUrlTemplate` path-only. Do not put `?include=...` or other query strings in URL templates.
|
|
82
|
-
-
|
|
82
|
+
- Import neutral request and CRUD client APIs from `@jskit-ai/http-web`. `users-web` owns only account, profile, and user-specific shell UI.
|
|
83
|
+
- Keep shared CRUD resource, field, lookup, namespace, and filter contracts in `@jskit-ai/resource-crud-core`; keep database-backed CRUD services and repositories in `@jskit-ai/crud-core`.
|
|
84
|
+
- If an app needs route-aware API URL rewriting, configure the http-web client once with `configureHttpWebClient({ resolveRequestUrl })` before mounting the app. Do not replace `fetchImpl` just to rewrite paths.
|
|
83
85
|
- `resolveRequestUrl` belongs at the HTTP client boundary. It runs after JSKIT encodes query params and before browser `fetch`, so reads, commands, request recovery metadata, JSON:API transport, credentials, and CSRF behavior stay on the standard path.
|
|
84
86
|
|
|
85
87
|
Error presentation rules:
|
|
@@ -38,7 +38,7 @@ Generated JSKIT apps should feel like real adaptive apps by default, not framewo
|
|
|
38
38
|
- [x] `npm test --workspace @jskit-ai/ui-generator`
|
|
39
39
|
- [x] `npm test --workspace @jskit-ai/crud-ui-generator`
|
|
40
40
|
- [x] `npm test --workspace @jskit-ai/shell-web`
|
|
41
|
-
- [x] `npm test --workspace @jskit-ai/
|
|
41
|
+
- [x] `npm test --workspace @jskit-ai/http-web`
|
|
42
42
|
- [x] `npm test --workspace @jskit-ai/workspaces-web`
|
|
43
43
|
- [x] `npm test --workspace @jskit-ai/jskit-cli`
|
|
44
44
|
- [x] `npm test --workspace @jskit-ai/create-app`
|
|
@@ -59,7 +59,7 @@ Generated JSKIT apps should feel like real adaptive apps by default, not framewo
|
|
|
59
59
|
- CRUD bulk actions are client-side by default: generated list pages create a page-local `listBulkActions.js` and pass it into `useCrudListScreen(...)`; the shared list screen wires `useCrudListBulkActions(...)` and keeps selection controls hidden until actions are declared.
|
|
60
60
|
- CRUD row actions are client-side by default: generated list pages can create a page-local `listRowActions.js` with `defineCrudListRowActions(...)` and pass it into `useCrudListScreen(...)`; the shared list screen renders per-row actions in card and table layouts while action handlers stay explicit and page-owned.
|
|
61
61
|
- CRUD synthetic rows are display-only: pass `syntheticRows` into `useCrudListScreen(...)` for owner/master rows that are not repository records. Synthetic rows render through the shared list screen, skip standard Open/Edit links, and are excluded from bulk selection unless explicitly marked selectable.
|
|
62
|
-
- Generated CRUD page templates delegate their screen chrome to shared `
|
|
62
|
+
- Generated CRUD page templates delegate their screen chrome to shared `http-web` screen components (`CrudListScreen`, `CrudViewScreen`, and `CrudAddEditScreen`) so list/view/form load states, retry actions, responsive shell layout, filters, bulk actions, row actions, and detail slots do not drift across generated pages.
|
|
63
63
|
- Generated CRUD list pages should use `useCrudListScreen({ requestQueryParams, readEnabled })` for list read pass-throughs instead of replacing the shared list chrome for includes or permission-gated reads.
|
|
64
64
|
- Generated CRUD detail pages should use `useCrudViewScreen({ requestQueryParams, readEnabled, queryKeyFactory })` for read pass-throughs and `CrudViewScreen` slots (`before-fields`, `fields`, `after-fields`, `supporting-content`) for domain sections instead of replacing the shared detail chrome.
|
|
65
65
|
- Routine resource-load errors stay local to the generated screen and retry affordance. Action feedback uses the shell error policy through `action-feedback`.
|
package/patterns/live-actions.md
CHANGED
|
@@ -50,6 +50,6 @@ Examples:
|
|
|
50
50
|
Avoid:
|
|
51
51
|
|
|
52
52
|
- manually hand-rolling fetch logic for a standard live action when `useCommand()` fits
|
|
53
|
-
- inspecting private `
|
|
53
|
+
- inspecting private `http-web` internals or creating a page-local transport
|
|
54
54
|
for generated record deletion
|
|
55
55
|
- pushing derived write rules into the client just because the action is small
|