cabloy 5.1.103 → 5.1.105
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/.cabloy-version +1 -1
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -1
- package/CHANGELOG.md +27 -0
- package/CLAUDE.md +1 -0
- package/cabloy-docs/backend/controller-aop-guide.md +2 -2
- package/cabloy-docs/backend/field-indexes.md +10 -1
- package/cabloy-docs/backend/menu-guide.md +30 -0
- package/cabloy-docs/frontend/a-model-under-the-hood.md +26 -4
- package/cabloy-docs/frontend/model-architecture.md +1 -1
- package/cabloy-docs/frontend/model-state-guide.md +122 -16
- package/cabloy-docs/frontend/ssr-init-data.md +12 -1
- package/cabloy-docs/frontend/use-state-data-best-practices.md +23 -0
- package/package.json +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +31 -31
- package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.activate.ts +5 -4
- package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +10 -6
- package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +1 -1
- package/vona/src/suite/a-home/modules/home-user/src/controller/passport.ts +7 -7
- package/vona/src/suite/a-home/modules/home-user/src/entity/role.ts +4 -0
- package/vona/src/suite/a-home/modules/home-user/src/service/passportAdapter.ts +2 -2
- package/vona/src/suite/a-home/modules/home-user/src/service/roleAdapter.ts +5 -5
- package/vona/src/suite/a-training/modules/training-record/src/bean/ssrMenu.record.ts +1 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrMenu.home.ts +1 -0
- package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/bean/ssrSite.admin.ts +5 -1
- package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/bean/ssrSite.web.ts +5 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/src/service/auth.ts +5 -1
- package/vona/src/suite-vendor/a-auth/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/cli/ssrSite/boilerplate/{{sceneName}}.{{beanName}}.ts_ +5 -3
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/bean/event.retrieveMenusSite.ts +2 -2
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +33 -8
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssr.ts +46 -16
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/service/ssrHandler.ts +2 -4
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/env.ts +1 -0
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrMenu.ts +10 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/types/ssrSite.ts +3 -1
- package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/.metadata/index.ts +18 -2
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +6 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/event.retrievePermissionAction.ts +16 -0
- package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/bean.passport.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/lib/passport.ts +7 -4
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/passport.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/types/role.ts +3 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/env/.env.cabloyBasicAdmin +2 -0
- package/zova/env/.env.cabloyBasicWeb +2 -0
- package/zova/packages-utils/zova-jsx/package.json +2 -2
- package/zova/packages-zova/zova/package.json +3 -3
- package/zova/packages-zova/zova-core/package.json +1 -1
- package/zova/packages-zova/zova-core/src/core/sys/sys.ts +3 -0
- package/zova/packages-zova/zova-core/src/types/utils/env.ts +1 -0
- package/zova/src/suite/a-home/modules/home-api/src/api/homeUserPassport.ts +19 -19
- package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +11 -10
- package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeUserPassport.ts +5 -5
- package/zova/src/suite/a-home/modules/home-base/src/.metadata/page/errorAccessDenied.ts +9 -0
- package/zova/src/suite/a-home/modules/home-base/src/page/errorAccessDenied/controller.tsx +40 -0
- package/zova/src/suite/a-home/modules/home-base/src/routes.ts +9 -0
- package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +21 -12
- package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +7 -1
- package/zova/src/suite/a-home/modules/home-passport/src/monkey.ts +17 -3
- package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useState.ts +6 -6
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useStateGeneral.ts +5 -5
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/monkey.ts +11 -2
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/types/query.ts +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +10 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +4 -4
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +5 -5
package/.cabloy-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.1.
|
|
1
|
+
5.1.105
|
|
@@ -24,7 +24,7 @@ After generating or extending a backend thread, check which follow-up layers app
|
|
|
24
24
|
|
|
25
25
|
- migration/version changes
|
|
26
26
|
- `meta.version`
|
|
27
|
-
- field indexes
|
|
27
|
+
- field indexes; in shared-database multitenancy, preserve ordinary lookup indexes and enforce business uniqueness in tenant-aware business logic rather than with `table.unique(...)`
|
|
28
28
|
- relations
|
|
29
29
|
- datasource choice
|
|
30
30
|
- cache behavior
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.105
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Filter SSR menus based on user roles.
|
|
8
|
+
- Add SSR site access policies.
|
|
9
|
+
- Add an event for retrieving action permissions.
|
|
10
|
+
- Update `monkeySys.ts` functionality.
|
|
11
|
+
|
|
12
|
+
## 5.1.104
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- Add update capabilities.
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
- Initialize the passport model during application startup.
|
|
21
|
+
|
|
22
|
+
### Improvements
|
|
23
|
+
|
|
24
|
+
- Rename the generic async state type.
|
|
25
|
+
- Rename async local state APIs.
|
|
26
|
+
- Document the passport SSR state bridge.
|
|
27
|
+
- Clarify memory state SSR transfer behavior.
|
|
28
|
+
- Clarify how to select model state helpers.
|
|
29
|
+
|
|
3
30
|
## 5.1.103
|
|
4
31
|
|
|
5
32
|
### Features
|
package/CLAUDE.md
CHANGED
|
@@ -67,6 +67,7 @@ Before inventing a custom implementation path:
|
|
|
67
67
|
- `src/bean` defines the global shorthand surface; classes that should not appear in `IBeanRecordGlobal` should move to `src/lib` or `src/service` rather than being filtered by `@Virtual()`.
|
|
68
68
|
- When backend code references `this.bean.xxx`, `ctx.bean.xxx`, or `app.bean.xxx`, use `IBeanRecordGlobal` and module `src/.metadata/index.ts` as the first static lookup surface; use `IBeanRecordGeneral` or `src/service` only when the target is not a global shorthand.
|
|
69
69
|
- When adding a persisted field to an existing backend resource, ask the user whether `vonaModule.fileVersion` should be incremented before changing `meta.version.ts` or the module schema path. If yes, add a new migration version and bump `fileVersion`. If no, keep the current `fileVersion` and fold the schema change into the current version path. Do not assume the versioning strategy without confirmation.
|
|
70
|
+
- In shared-database multitenancy, do not use `table.unique(...)` for business uniqueness. Keep ordinary indexes for lookup performance and enforce tenant-scoped uniqueness in the business layer.
|
|
70
71
|
- For `@Api.field(...)` and related schemaLike composition, framework guards now preserve previously attached OpenAPI metadata across schema rebuilds, but structure-shaping schemaLike is still order-sensitive. Treat `v.object(...)`, `v.array(...)`, `v.optional()`, `v.nullable()`, `v.default(...)`, and preprocess/transform wrappers as structure-shaping; keep the final structure-defining schemaLike last and verify emitted schema/OpenAPI output after such edits.
|
|
71
72
|
|
|
72
73
|
## Verification expectations
|
|
@@ -93,8 +93,8 @@ Typical jobs include:
|
|
|
93
93
|
```typescript
|
|
94
94
|
@Passport.public()
|
|
95
95
|
@Passport.activated(false)
|
|
96
|
-
@Passport.roleName({ name: '
|
|
97
|
-
@Passport.
|
|
96
|
+
@Passport.roleName({ name: 'systemAdmin' })
|
|
97
|
+
@Passport.systemAdmin()
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
These shorthands still map back to the generic aspect model.
|
|
@@ -66,6 +66,14 @@ Field indexes can also be configured through app config.
|
|
|
66
66
|
|
|
67
67
|
That means index behavior participates in the broader configuration system rather than being locked into one metadata file only.
|
|
68
68
|
|
|
69
|
+
## Shared-database multitenancy and business uniqueness
|
|
70
|
+
|
|
71
|
+
Ordinary indexes in `meta.index` improve lookup and query performance. They do not define a business uniqueness rule.
|
|
72
|
+
|
|
73
|
+
In shared-database multitenancy, do not use `table.unique(...)` for tenant-scoped business uniqueness. A database-wide unique constraint can reject the same business value when it belongs to a different tenant.
|
|
74
|
+
|
|
75
|
+
Keep the ordinary indexes needed by the access pattern, and enforce the tenant-scoped uniqueness rule in tenant-aware business logic.
|
|
76
|
+
|
|
69
77
|
## Implementation checks for persistence changes
|
|
70
78
|
|
|
71
79
|
When changing persistence design, do not stop at entity fields and model methods.
|
|
@@ -74,7 +82,8 @@ Also ask:
|
|
|
74
82
|
|
|
75
83
|
1. does this access pattern need an index?
|
|
76
84
|
2. should the index belong in `meta.index`?
|
|
77
|
-
3.
|
|
85
|
+
3. does a business key need tenant-scoped uniqueness, to be enforced in tenant-aware business logic rather than with `table.unique(...)`?
|
|
86
|
+
4. is the typed style a better fit than raw string declarations?
|
|
78
87
|
|
|
79
88
|
That leads to backend changes that are more production-aware and more aligned with Vona’s module metadata model.
|
|
80
89
|
|
|
@@ -55,6 +55,36 @@ This makes menu retrieval part of the broader backend contract surface.
|
|
|
55
55
|
|
|
56
56
|
In the current repo implementation, the out-of-the-box menu controller is public and delegates directly to `this.scope.service.menu.retrieveMenus(publicPath)`.
|
|
57
57
|
|
|
58
|
+
## Static menu visibility
|
|
59
|
+
|
|
60
|
+
`@SsrMenu(...)` items can declare static role visibility without changing the public menu DTO:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
@SsrMenu({
|
|
64
|
+
item: {
|
|
65
|
+
title: $locale('Operations'),
|
|
66
|
+
link: 'presetResource',
|
|
67
|
+
roles: ['systemAdmin'],
|
|
68
|
+
},
|
|
69
|
+
site: 'basic-siteadmin:admin',
|
|
70
|
+
})
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- Omit `roles`, or use `roles: []`, to make an item visible to anonymous and authenticated callers.
|
|
74
|
+
- A nonempty `roles` array is visible when the current Passport has at least one matching role name.
|
|
75
|
+
- `roles` is server-only declaration metadata. It is filtered out before the API response and is not part of `IMenuItem`, OpenAPI, or generated frontend clients.
|
|
76
|
+
- This controls navigation disclosure only. It never grants access to a page, controller action, API, or resource; those boundaries retain their own route and Passport/permission guards.
|
|
77
|
+
|
|
78
|
+
SSR Site menu definitions are cached structurally by Site and locale. The framework keeps static role policy in that prepared cache, then creates a filtered response for each request without mutating the cached definition.
|
|
79
|
+
|
|
80
|
+
### Frontend query lifecycle
|
|
81
|
+
|
|
82
|
+
Passport filtering does not add user or role identity to the frontend menu query key. The menu resource remains keyed by stable inputs: Site/public path and locale.
|
|
83
|
+
|
|
84
|
+
On login, `ModelPassport.afterLogin()` stores the Passport/JWT before returning to the destination layout. The layout's ordinary `$useStateData(...)` lifecycle refreshes stale menu data using the newly authenticated request context. On logout, the Passport model navigates to login and then clears query data.
|
|
85
|
+
|
|
86
|
+
A dynamic role or menu-policy change while the user remains signed in is different: the mutation owner must explicitly refresh authoritative Passport state when needed and invalidate or refetch the affected menu query. This is UI freshness behavior only; route, controller, API, and resource authorization remain enforced independently by their existing guards.
|
|
87
|
+
|
|
58
88
|
## Relationship to frontend integration
|
|
59
89
|
|
|
60
90
|
Menu retrieval is especially relevant in SSR-sensitive frontend flows.
|
|
@@ -85,9 +85,21 @@ Its main jobs are:
|
|
|
85
85
|
- create the shared `QueryClient`
|
|
86
86
|
- create the `QueryCache`
|
|
87
87
|
- install the Vue Query plugin into the app
|
|
88
|
-
- on the server, dehydrate query state after render
|
|
89
|
-
- on the client, hydrate
|
|
90
|
-
- clear the query client after
|
|
88
|
+
- on the server, dehydrate eligible query state after render into `stateDefer.query`
|
|
89
|
+
- on the client, hydrate that snapshot during SSR pre-hydration
|
|
90
|
+
- clear the server query client after the snapshot has been created
|
|
91
|
+
|
|
92
|
+
The server-to-client handoff is therefore:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
server QueryClient
|
|
96
|
+
→ dehydrate after render
|
|
97
|
+
→ stateDefer.query
|
|
98
|
+
→ deferred SSR bootstrap state
|
|
99
|
+
→ client QueryClient hydrate during SSR pre-hydration
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This is an initial SSR handoff, not browser persistence. The server cache is request-scoped for this flow and is cleared after its snapshot is taken.
|
|
91
103
|
|
|
92
104
|
This is the second important lower-level rule:
|
|
93
105
|
|
|
@@ -200,6 +212,10 @@ A practical reading rule is:
|
|
|
200
212
|
- different state families differ in persistence/storage and SSR behavior
|
|
201
213
|
- but they still participate in one model runtime vocabulary and query-key system
|
|
202
214
|
|
|
215
|
+
`$useStateMem(...)` makes the two policy axes especially clear. It returns an assignable custom-ref surface that reads and writes through the Model Query Cache, while setting `persister: false` so no browser storage adapter is used. No persistence backend does not imply no SSR transfer: a successful eligible memory query can still be included in the shared Query Cache snapshot.
|
|
216
|
+
|
|
217
|
+
A hydrated entry is reusable only when the later call resolves to the same effective key. The runtime prefixes each logical key with Model identity and, for selector-enabled Models, selector identity.
|
|
218
|
+
|
|
203
219
|
## Persister storage selection and restore/save/remove behavior
|
|
204
220
|
|
|
205
221
|
The persister layer lives in:
|
|
@@ -243,7 +259,13 @@ This file confirms default behavior such as:
|
|
|
243
259
|
- persistence max-age defaults
|
|
244
260
|
- dehydration rules for sync persister-backed queries
|
|
245
261
|
|
|
246
|
-
|
|
262
|
+
The current dehydration decision is ordered:
|
|
263
|
+
|
|
264
|
+
1. `meta.ssr.dehydrate === false` explicitly excludes a query.
|
|
265
|
+
2. A sync persister-backed query is excluded.
|
|
266
|
+
3. Remaining queries use TanStack Query's current default dehydration predicate, which accepts successful queries.
|
|
267
|
+
|
|
268
|
+
This is why `$useStateMem(...)` can participate in the initial SSR transfer despite `persister: false`, while `$useStateLocalAsync(...)` opts out explicitly. This is the place to check when the runtime feels surprising even though your page/model code looks correct.
|
|
247
269
|
|
|
248
270
|
## What this page does not re-explain
|
|
249
271
|
|
|
@@ -129,7 +129,7 @@ The `a-model` source exposes five main state families through `BeanModelBase` he
|
|
|
129
129
|
- `mem` → in-memory state through `$useStateMem(...)`
|
|
130
130
|
- `local` → local-storage state through `$useStateLocal(...)`
|
|
131
131
|
- `cookie` → cookie-backed state through `$useStateCookie(...)`
|
|
132
|
-
- `db` → async persisted state through `$
|
|
132
|
+
- `db` → async persisted state through `$useStateLocalAsync(...)`
|
|
133
133
|
|
|
134
134
|
This is why Zova Model is better understood as a **unified model-state layer** rather than only a remote-data wrapper.
|
|
135
135
|
|
|
@@ -86,7 +86,34 @@ The important point is architectural:
|
|
|
86
86
|
|
|
87
87
|
## The main helper families
|
|
88
88
|
|
|
89
|
-
The current source organizes model state around these helper families.
|
|
89
|
+
The current source organizes model state around these helper families. They share model-owned query-key and cache infrastructure, but differ in the surface returned to callers and in their persistence and restore lifecycle.
|
|
90
|
+
|
|
91
|
+
### Choose the state helper by ownership and lifecycle
|
|
92
|
+
|
|
93
|
+
Choose a helper by the state surface, persistence, restore, and SSR behavior it needs, not only by whether its value should survive a reload.
|
|
94
|
+
|
|
95
|
+
| Helper | Use it when | Caller-facing surface | Persistence and restore |
|
|
96
|
+
| -------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `$useStateData(...)` | The model owns remote or query-style async state and consumers need query status | Full query wrapper, including `data`, `error`, and readiness/status state | Normal query lifecycle; may participate in query hydration subject to metadata |
|
|
98
|
+
| `$useStateMem(...)` | The model owns reusable runtime state without a browser persistence backend | Assignable state value | No browser persistence; eligible successful state can transfer through initial SSR hydration |
|
|
99
|
+
| `$useStateLocal(...)` | The model owns a small browser value that should restore synchronously | Assignable state value | Synchronous `localStorage` restore |
|
|
100
|
+
| `$useStateCookie(...)` | The state needs cookie persistence or request-aware handling | Assignable state value | Synchronous cookie restore |
|
|
101
|
+
| `$useStateLocalAsync(...)` | The model owns longer-lived browser-local state whose restore may be asynchronous | Assignable state value | Asynchronous `localforage` restore |
|
|
102
|
+
| `$useStateComputed(...)` | The model exposes derived state | Computed value | No query fetch or persistence |
|
|
103
|
+
|
|
104
|
+
### Data, local, and async-local behavior
|
|
105
|
+
|
|
106
|
+
`$useStateData(...)`, `$useStateLocal(...)`, and `$useStateLocalAsync(...)` use the same model-owned cache foundation, but they are not interchangeable.
|
|
107
|
+
|
|
108
|
+
| Concern | `$useStateData(...)` | `$useStateLocal(...)` | `$useStateLocalAsync(...)` |
|
|
109
|
+
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| Return surface | A memoized query wrapper | An assignable state value | An assignable state value |
|
|
111
|
+
| Source or storage | `queryFn`, query cache, and query configuration | `localStorage` | `localforage` |
|
|
112
|
+
| Initial availability | Follows the query lifecycle | Restores synchronously, then falls back to `meta.defaultData` | Restores asynchronously, then falls back to `meta.defaultData` |
|
|
113
|
+
| Intended write flow | Mutation, cache update, and invalidation policy | Replace or assign the model field | Replace or assign the model field |
|
|
114
|
+
| SSR behavior | Can follow ordinary query dehydration and hydration rules | Browser storage is unavailable on the server | Browser storage is unavailable on the server and async-local state explicitly opts out of dehydration |
|
|
115
|
+
|
|
116
|
+
Use the detailed [`$useStateData` Best Practices](/frontend/use-state-data-best-practices) guide for render-versus-interaction placement, `disableSuspenseOnInit`, freshness utilities, and explicit readiness boundaries.
|
|
90
117
|
|
|
91
118
|
### 1. `$useStateData(...)`
|
|
92
119
|
|
|
@@ -155,16 +182,62 @@ The pattern to notice is that the model owns both the mutation and the follow-up
|
|
|
155
182
|
|
|
156
183
|
## 3. `$useStateMem(...)`
|
|
157
184
|
|
|
158
|
-
Use this
|
|
185
|
+
Use this for reusable runtime state that belongs to a Model but does not need a browser persistence backend. It returns an assignable value, rather than a query wrapper, while retaining Model-owned Query Cache identity.
|
|
159
186
|
|
|
160
187
|
Current-source characteristics:
|
|
161
188
|
|
|
162
|
-
-
|
|
163
|
-
- `enabled: false`
|
|
189
|
+
- `enabled: false`, so it does not define a normal remote-fetch lifecycle
|
|
164
190
|
- `staleTime: Infinity`
|
|
165
|
-
-
|
|
191
|
+
- `meta.persister: false`, so it does not read or write `localStorage`, cookies, or `localforage`
|
|
192
|
+
- reads from existing Query Cache first, then `meta.defaultData`, then `undefined`
|
|
193
|
+
- assignments update the Query Cache without a persister save
|
|
194
|
+
- automatic key prefixing isolates the state by Model identity and, when enabled, selector identity
|
|
195
|
+
|
|
196
|
+
This is useful when several consumers or Model methods need the same business state during the current frontend runtime, but the browser should not restore it from storage. For structured values, replace or assign the Model field so its custom-ref setter updates the Query Cache:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
this.selectedIds = nextSelectedIds;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
A plain Controller field is usually clearer when the state belongs only to that one Controller. Choose `$useStateLocal(...)`, `$useStateCookie(...)`, or `$useStateLocalAsync(...)` when browser persistence is part of the requirement. Choose `$useStateData(...)` when consumers need query status, errors, freshness, or a remote-fetch lifecycle.
|
|
203
|
+
|
|
204
|
+
### SSR transfer is not persistence
|
|
205
|
+
|
|
206
|
+
`meta.persister: false` means no browser persistence backend. It does not, by itself, exclude the state from the initial SSR server-to-client Query Cache handoff.
|
|
207
|
+
|
|
208
|
+
After server rendering, a successful eligible memory-state query can be dehydrated with the shared Query Cache. During client SSR pre-hydration, the snapshot is hydrated into the client QueryClient. A later `$useStateMem(...)` read can therefore receive the transferred value directly from cache when its effective key matches: the same Model, the same selector when selector mode is enabled, and the same logical `queryKey`.
|
|
209
|
+
|
|
210
|
+
This transfer has limits:
|
|
211
|
+
|
|
212
|
+
- it applies only to entries accepted by the normal dehydration policy; `meta.ssr.dehydrate: false` opts a state out
|
|
213
|
+
- it is not a replacement for `localStorage`, cookies, or async-local persistence
|
|
214
|
+
- it does not make the value survive a later browser reload without a new SSR handoff
|
|
215
|
+
- it does not make an empty or unsuccessful cache entry transfer automatically
|
|
216
|
+
|
|
217
|
+
The router-tabs Model uses memory state for current navigation keys and for tabs when tab caching is disabled. The page-data Model uses memory slots keyed by page path. Read [SSR Init Data](/frontend/ssr-init-data) for the page-side flow, or [A-Model Under the Hood](/frontend/a-model-under-the-hood) for the Query Cache and dehydration mechanics.
|
|
218
|
+
|
|
219
|
+
### SSR/CSR bridge: `ModelPassport`
|
|
220
|
+
|
|
221
|
+
`ModelPassport` shows that the state helper selected on the server and the one selected on the client do not have to be the same. Its application initialization creates the same logical state differently by environment:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
this.passport = process.env.CLIENT
|
|
225
|
+
? this.$useStateLocal({ queryKey: ['passport'] })
|
|
226
|
+
: this.$useStateMem({ queryKey: ['passport'] });
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
On the SSR server, authenticated work can assign the current passport to the memory-backed Query Cache entry. If that entry is successful and eligible, it is dehydrated with the server QueryClient. During client SSR pre-hydration, the snapshot restores the entry before the client Model consumes it.
|
|
230
|
+
|
|
231
|
+
The client then creates a `$useStateLocal(...)` wrapper for the same effective key. Its read order is Query Cache first, then `localStorage`, then `meta.defaultData`. The hydrated server passport therefore wins on the initial client read; synchronous local-storage restoration is a fallback only when the transferred cache entry is absent.
|
|
232
|
+
|
|
233
|
+
This gives authentication state two complementary properties:
|
|
234
|
+
|
|
235
|
+
- SSR uses the request-confirmed passport to keep the initial HTML and client hydration consistent.
|
|
236
|
+
- CSR-only entry and later browser sessions can restore the client-local passport value from `localStorage`.
|
|
237
|
+
|
|
238
|
+
The server `$useStateMem(...)` entry is the entry that is dehydrated. The client `$useStateLocal(...)` call is a new client-side wrapper that reuses hydrated cache because its effective key matches. Matching requires the same Model, the same selector when selector mode is enabled, and the same logical `queryKey`; the short logical key alone is not global identity.
|
|
166
239
|
|
|
167
|
-
|
|
240
|
+
Reading the hydrated value does not save it back to `localStorage`. A later assignment through the client local-state wrapper updates Query Cache and writes the local-storage record. This is an initial SSR cache handoff plus client persistence fallback, not automatic persistence of the SSR snapshot.
|
|
168
241
|
|
|
169
242
|
## 4. `$useStateLocal(...)`
|
|
170
243
|
|
|
@@ -195,9 +268,9 @@ Current-source characteristics:
|
|
|
195
268
|
|
|
196
269
|
This is particularly relevant for state that must participate in request-aware or SSR-adjacent flows.
|
|
197
270
|
|
|
198
|
-
## 6. `$
|
|
271
|
+
## 6. `$useStateLocalAsync(...)`
|
|
199
272
|
|
|
200
|
-
Use this when the model state should persist asynchronously in
|
|
273
|
+
Use this when the model state should persist asynchronously in browser-local storage backed by `localforage`.
|
|
201
274
|
|
|
202
275
|
Current-source characteristics:
|
|
203
276
|
|
|
@@ -205,10 +278,40 @@ Current-source characteristics:
|
|
|
205
278
|
- `enabled: false`
|
|
206
279
|
- `staleTime: Infinity`
|
|
207
280
|
- explicit `ssr.dehydrate = false`
|
|
208
|
-
-
|
|
281
|
+
- the first unresolved read may need async restore before the state is available
|
|
209
282
|
|
|
210
283
|
This is useful for larger persisted client state that should outlive a page session without being stored in cookies or plain local storage.
|
|
211
284
|
|
|
285
|
+
### Initialize and ensure async-local state
|
|
286
|
+
|
|
287
|
+
Assign the state property before awaiting it. When later initialization depends on the restored value, establish an explicit restore boundary with `$ensureStateLocalAsync(...)`. It waits for the pending initial restore to settle; it does not force another load and does not guarantee a defined result:
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
protected async __init__() {
|
|
291
|
+
this.tabs = this.$useStateLocalAsync({
|
|
292
|
+
queryKey: ['tabs'],
|
|
293
|
+
meta: {
|
|
294
|
+
defaultData: [],
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
await this.$ensureStateLocalAsync(this.tabs);
|
|
299
|
+
|
|
300
|
+
// Continue only after persisted tabs, or the fallback default, is available.
|
|
301
|
+
this.initializeTabs();
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`meta.defaultData` is a fallback: it initializes the state only when no persisted value is restored. If neither provides a value, the ensured result can still be `undefined`. The router-tabs model follows this assign-then-ensure sequence before it continues with route initialization.
|
|
306
|
+
|
|
307
|
+
Persisted local and async-local state should be updated by replacing or assigning the model field so its custom-ref setter can update query state and persist the new value:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
this.tabs = nextTabs;
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Do not rely on an in-place nested mutation alone to persist the change. Assigning `undefined` removes the persisted value.
|
|
314
|
+
|
|
212
315
|
## 7. `$useStateComputed(...)`
|
|
213
316
|
|
|
214
317
|
Use this when the model should expose derived state that is still model-key-oriented but computed locally.
|
|
@@ -233,6 +336,8 @@ that logical key is prefixed internally with model identity, and with selector w
|
|
|
233
336
|
|
|
234
337
|
That means model code can use short business-facing keys while still getting namespace isolation.
|
|
235
338
|
|
|
339
|
+
Automatic model namespacing does not make every varying runtime value part of the logical key. Logical keys still describe stable resource inputs. Do not add a user or role fingerprint solely because a backend response is evaluated through the current Passport; use the normal authentication lifecycle for login/logout and explicitly invalidate or refetch affected stable keys for an in-session policy change. See [use-state-data-best-practices.md](./use-state-data-best-practices.md) for the full rule.
|
|
340
|
+
|
|
236
341
|
## Persistence and restore behavior
|
|
237
342
|
|
|
238
343
|
Current source treats persistence as part of the model-state runtime.
|
|
@@ -252,16 +357,17 @@ Model state choices can affect SSR behavior.
|
|
|
252
357
|
|
|
253
358
|
Current-source behaviors to remember:
|
|
254
359
|
|
|
255
|
-
-
|
|
360
|
+
- successful eligible Query Cache state can be dehydrated on the server and hydrated on the client
|
|
361
|
+
- `$useStateMem(...)` has no browser persister but can participate in that initial SSR handoff unless excluded by metadata
|
|
256
362
|
- mutations are not dehydrated
|
|
257
|
-
- `
|
|
258
|
-
- server
|
|
259
|
-
- cookie state is special because cookie access can still exist through the app cookie surface
|
|
363
|
+
- `$useStateLocalAsync(...)` explicitly opts out of dehydration
|
|
364
|
+
- server-side sync local and cookie persister-backed Query Cache entries are excluded by the default dehydration policy; this does not prevent a client `$useStateLocal(...)` or `$useStateCookie(...)` wrapper from reusing a hydrated entry that the server created with a different eligible helper
|
|
365
|
+
- server cannot use local-storage or async-local persistence backends; cookie state is special because cookie access can still exist through the app cookie surface
|
|
260
366
|
|
|
261
367
|
Practical implication:
|
|
262
368
|
|
|
263
|
-
- do not assume every
|
|
264
|
-
- choose `mem`, `local`, `cookie`, `
|
|
369
|
+
- do not equate browser persistence with SSR transfer, or assume every state family behaves the same during SSR
|
|
370
|
+
- choose `mem`, `local`, `cookie`, `localAsync`, or `data` based on ownership, persistence, and hydration requirements, not only convenience
|
|
265
371
|
|
|
266
372
|
## Real examples to read
|
|
267
373
|
|
|
@@ -289,7 +395,7 @@ This file shows:
|
|
|
289
395
|
|
|
290
396
|
- `@Model({ enableSelector: true, ... })`
|
|
291
397
|
- richer model initialization in `__init__`
|
|
292
|
-
- mixed use of `$useStateMem(...)` and `$
|
|
398
|
+
- mixed use of `$useStateMem(...)` and `$useStateLocalAsync(...)`
|
|
293
399
|
- model-owned tab state with cache and persistence decisions
|
|
294
400
|
|
|
295
401
|
### SSR-sensitive auth model
|
|
@@ -31,7 +31,18 @@ export class ControllerPageTodo {
|
|
|
31
31
|
1. a model bean encapsulates the data access path
|
|
32
32
|
2. the controller injects the model
|
|
33
33
|
3. `__init__` prepares the data on the server
|
|
34
|
-
4.
|
|
34
|
+
4. successful eligible Query Cache state is captured in the SSR handoff
|
|
35
|
+
5. client SSR pre-hydration restores that cache before the client model consumes it
|
|
36
|
+
|
|
37
|
+
## What hydration reuses
|
|
38
|
+
|
|
39
|
+
The initial SSR handoff reuses model Query Cache data, not only `$useStateData(...)` results. A successful eligible `$useStateMem(...)` value can also transfer from the server to the initial client runtime even though it has no browser persistence backend.
|
|
40
|
+
|
|
41
|
+
Client reuse requires the model call to resolve to the same effective query key: Zova prefixes the logical key with Model identity and, for selector-enabled models, selector identity. State marked with `meta.ssr.dehydrate: false` is excluded. This handoff does not make memory state durable across a later browser reload, and it does not guarantee that every client query avoids fetching.
|
|
42
|
+
|
|
43
|
+
`ModelPassport` is a concrete SSR/CSR bridge: the server creates `passport` with `$useStateMem({ queryKey: ['passport'] })`, while the client creates `$useStateLocal({ queryKey: ['passport'] })`. The successful eligible server memory entry is what SSR transfers. Because the client local-state wrapper reads Query Cache before `localStorage`, the hydrated passport supplies the initial client value when the effective key matches. If no transferred entry exists, `$useStateLocal(...)` can instead restore its browser-local value. Hydration alone does not save the transferred value to `localStorage`; later client-side assignments do.
|
|
44
|
+
|
|
45
|
+
For helper selection and the complete passport flow, read [Model State Guide](/frontend/model-state-guide). For the dehydration filter and QueryClient lifecycle, read [A-Model Under the Hood](/frontend/a-model-under-the-hood).
|
|
35
46
|
|
|
36
47
|
## Implementation checks for SSR data-loading changes
|
|
37
48
|
|
|
@@ -325,6 +325,29 @@ Readable keys improve:
|
|
|
325
325
|
- tracing cache behavior
|
|
326
326
|
- future refactors when similar query families grow
|
|
327
327
|
|
|
328
|
+
## Practical rule 9: key stable resource inputs, not ambient caller identity
|
|
329
|
+
|
|
330
|
+
A `$useStateData(...)` query key identifies the stable variant of a resource. Include inputs that change that variant, such as an operation or resource identifier, filters, pagination, Site/public path, or locale.
|
|
331
|
+
|
|
332
|
+
Do not append the current username, authenticated flag, Passport role names or IDs, or another authorization fingerprint merely because the server evaluates the current Passport while producing the response. Those values are ambient request context, not automatically part of the frontend resource identity.
|
|
333
|
+
|
|
334
|
+
Normal authentication transitions already provide lifecycle boundaries: login stores the new Passport before navigating into the destination model, and that model's ordinary query lifecycle refreshes stale data under the new request context. Logout clears query data after leaving protected UI.
|
|
335
|
+
|
|
336
|
+
Use explicit invalidation or refetch when authorization policy changes during an otherwise continuing authenticated session, such as an administrator changing role membership, Site policy, or menu policy. Refresh authoritative Passport state when necessary, then synchronize the affected stable resource key; do not turn a policy fingerprint into the key by default.
|
|
337
|
+
|
|
338
|
+
For example, the menu resource is keyed by its stable Site/public path and locale:
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
queryKey: ['retrieveMenus', publicPath, locale];
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Do not key it by the current roles:
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
// Avoid: roles are ambient request policy, not menu resource identity.
|
|
348
|
+
queryKey: ['retrieveMenus', publicPath, locale, roleNames];
|
|
349
|
+
```
|
|
350
|
+
|
|
328
351
|
## Anti-pattern: command-first controller state
|
|
329
352
|
|
|
330
353
|
A common anti-pattern looks like this:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.74",
|
|
4
4
|
"gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
|
|
5
5
|
"description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
|
|
6
6
|
"keywords": [
|
package/vona/pnpm-lock.yaml
CHANGED
|
@@ -501,8 +501,8 @@ importers:
|
|
|
501
501
|
specifier: npm:@cabloy/zod@4.3.8
|
|
502
502
|
version: '@cabloy/zod@4.3.8'
|
|
503
503
|
zova:
|
|
504
|
-
specifier: ^5.1.
|
|
505
|
-
version: 5.1.
|
|
504
|
+
specifier: ^5.1.134
|
|
505
|
+
version: 5.1.134(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
|
|
506
506
|
zova-jsx:
|
|
507
507
|
specifier: ^1.1.77
|
|
508
508
|
version: 1.1.77(typescript@5.9.3)
|
|
@@ -528,8 +528,8 @@ importers:
|
|
|
528
528
|
specifier: ^5.1.29
|
|
529
529
|
version: 5.1.29
|
|
530
530
|
zova-module-a-model:
|
|
531
|
-
specifier: ^5.1.
|
|
532
|
-
version: 5.1.
|
|
531
|
+
specifier: ^5.1.33
|
|
532
|
+
version: 5.1.33(vue@3.5.39(typescript@5.9.3))
|
|
533
533
|
zova-module-a-openapi:
|
|
534
534
|
specifier: ^5.1.43
|
|
535
535
|
version: 5.1.43
|
|
@@ -537,8 +537,8 @@ importers:
|
|
|
537
537
|
specifier: ^5.1.29
|
|
538
538
|
version: 5.1.29
|
|
539
539
|
zova-module-a-routertabs:
|
|
540
|
-
specifier: ^5.1.
|
|
541
|
-
version: 5.1.
|
|
540
|
+
specifier: ^5.1.33
|
|
541
|
+
version: 5.1.33
|
|
542
542
|
zova-module-a-ssr:
|
|
543
543
|
specifier: ^5.1.29
|
|
544
544
|
version: 5.1.29
|
|
@@ -573,8 +573,8 @@ importers:
|
|
|
573
573
|
specifier: npm:@cabloy/zod@4.3.8
|
|
574
574
|
version: '@cabloy/zod@4.3.8'
|
|
575
575
|
zova:
|
|
576
|
-
specifier: ^5.1.
|
|
577
|
-
version: 5.1.
|
|
576
|
+
specifier: ^5.1.134
|
|
577
|
+
version: 5.1.134(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
|
|
578
578
|
zova-jsx:
|
|
579
579
|
specifier: ^1.1.77
|
|
580
580
|
version: 1.1.77(typescript@5.9.3)
|
|
@@ -600,8 +600,8 @@ importers:
|
|
|
600
600
|
specifier: ^5.1.29
|
|
601
601
|
version: 5.1.29
|
|
602
602
|
zova-module-a-model:
|
|
603
|
-
specifier: ^5.1.
|
|
604
|
-
version: 5.1.
|
|
603
|
+
specifier: ^5.1.33
|
|
604
|
+
version: 5.1.33(vue@3.5.39(typescript@5.9.3))
|
|
605
605
|
zova-module-a-openapi:
|
|
606
606
|
specifier: ^5.1.43
|
|
607
607
|
version: 5.1.43
|
|
@@ -609,8 +609,8 @@ importers:
|
|
|
609
609
|
specifier: ^5.1.29
|
|
610
610
|
version: 5.1.29
|
|
611
611
|
zova-module-a-routertabs:
|
|
612
|
-
specifier: ^5.1.
|
|
613
|
-
version: 5.1.
|
|
612
|
+
specifier: ^5.1.33
|
|
613
|
+
version: 5.1.33
|
|
614
614
|
zova-module-a-ssr:
|
|
615
615
|
specifier: ^5.1.29
|
|
616
616
|
version: 5.1.29
|
|
@@ -1517,13 +1517,13 @@ importers:
|
|
|
1517
1517
|
src/suite-vendor/a-file:
|
|
1518
1518
|
dependencies:
|
|
1519
1519
|
vona-module-a-file:
|
|
1520
|
-
specifier: ^5.0.
|
|
1520
|
+
specifier: ^5.0.5
|
|
1521
1521
|
version: link:modules/a-file
|
|
1522
1522
|
vona-module-file-cloudflare:
|
|
1523
|
-
specifier: ^5.0.
|
|
1523
|
+
specifier: ^5.0.4
|
|
1524
1524
|
version: link:modules/file-cloudflare
|
|
1525
1525
|
vona-module-file-native:
|
|
1526
|
-
specifier: ^5.0.
|
|
1526
|
+
specifier: ^5.0.4
|
|
1527
1527
|
version: link:modules/file-native
|
|
1528
1528
|
|
|
1529
1529
|
src/suite-vendor/a-file/modules/a-file:
|
|
@@ -1625,7 +1625,7 @@ importers:
|
|
|
1625
1625
|
src/suite-vendor/a-test:
|
|
1626
1626
|
dependencies:
|
|
1627
1627
|
vona-module-test-file:
|
|
1628
|
-
specifier: ^5.0.
|
|
1628
|
+
specifier: ^5.0.5
|
|
1629
1629
|
version: link:modules/test-file
|
|
1630
1630
|
|
|
1631
1631
|
src/suite-vendor/a-test/modules/test-auth:
|
|
@@ -7993,8 +7993,8 @@ packages:
|
|
|
7993
7993
|
zova-module-a-meta@5.1.21:
|
|
7994
7994
|
resolution: {integrity: sha512-7vsLOMw1UQEZ+8qbBaiz9t4n3N7AU1jxpaiSIIky7hBvKO9nuHq+e7FONpj9poa8WeHkYoflBg/8imKBy/IlNw==}
|
|
7995
7995
|
|
|
7996
|
-
zova-module-a-model@5.1.
|
|
7997
|
-
resolution: {integrity: sha512
|
|
7996
|
+
zova-module-a-model@5.1.33:
|
|
7997
|
+
resolution: {integrity: sha512-NwxCguvESPLUSA2zo5vVH3Qx29o5znmUL2qU9khwjXUmDPbOTeYTkgPCI33fTsy8VnkguoWBLMgUdOsaJF+7OA==}
|
|
7998
7998
|
|
|
7999
7999
|
zova-module-a-openapi@5.1.43:
|
|
8000
8000
|
resolution: {integrity: sha512-xJKvSPl1AZnH7EpgEd9a3u3IEpJfnou19DKre/7TL1KdiTdfNThLrmmkdP1UNYlUHUgCczcGUwZDdMiE9gdxwA==}
|
|
@@ -8005,8 +8005,8 @@ packages:
|
|
|
8005
8005
|
zova-module-a-routerstack@5.1.26:
|
|
8006
8006
|
resolution: {integrity: sha512-uu4tFw2DUruanPR7cojM5p6rvyCIh+tnwPmq7s0jZdg+5XBr+YMy1RGjnE8vPFSLHW8C71hlNbps6VpKvKMiiQ==}
|
|
8007
8007
|
|
|
8008
|
-
zova-module-a-routertabs@5.1.
|
|
8009
|
-
resolution: {integrity: sha512-
|
|
8008
|
+
zova-module-a-routertabs@5.1.33:
|
|
8009
|
+
resolution: {integrity: sha512-u5YIFc7OfUsxruIG8QP4sH1+TCps2vAYUpAMNfT1XPkJLHdFGkjEc6++KMCpv4jGpNDoQ42/LefEQGg7vqnQuw==}
|
|
8010
8010
|
|
|
8011
8011
|
zova-module-a-ssr@5.1.29:
|
|
8012
8012
|
resolution: {integrity: sha512-wlxLSy+Wjh/UFEVqsKQ105bvXceXPdIDmJQPKF0hSwiNY1R8HUottADfXPwYOatzZAayZ4AU4vQIpG92F2GJiA==}
|
|
@@ -8032,11 +8032,11 @@ packages:
|
|
|
8032
8032
|
zova-module-rest-resource@5.1.41:
|
|
8033
8033
|
resolution: {integrity: sha512-7Y8rLmHdw0pynlWqsyHPWuCWFLwr/0HsNvfef64cPw91LRujf/7OlulVWqH8ZoFNioZZUpfumB+t/+mICoYfFg==}
|
|
8034
8034
|
|
|
8035
|
-
zova-suite-a-zova@5.1.
|
|
8036
|
-
resolution: {integrity: sha512-
|
|
8035
|
+
zova-suite-a-zova@5.1.133:
|
|
8036
|
+
resolution: {integrity: sha512-N7YSmamP2eV3MBV4RnFXXUlDg9yEcvYkHDxfcgQQFjR1iQyxNbCLO1Ud4Bjcinray2KNrnOF41e+0gn7A6jzRQ==}
|
|
8037
8037
|
|
|
8038
|
-
zova@5.1.
|
|
8039
|
-
resolution: {integrity: sha512-
|
|
8038
|
+
zova@5.1.134:
|
|
8039
|
+
resolution: {integrity: sha512-nnieXjXy0+94FKZCT05dGvwASJQ7PiM387r+dToLAuSFRCqgQwaLvYyrOXN2RhKt8Z5nefWDMwA9LPWgBksnLg==}
|
|
8040
8040
|
|
|
8041
8041
|
zwitch@1.0.5:
|
|
8042
8042
|
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
|
|
@@ -13935,7 +13935,7 @@ snapshots:
|
|
|
13935
13935
|
|
|
13936
13936
|
zova-module-a-meta@5.1.21: {}
|
|
13937
13937
|
|
|
13938
|
-
zova-module-a-model@5.1.
|
|
13938
|
+
zova-module-a-model@5.1.33(vue@3.5.39(typescript@5.9.3)):
|
|
13939
13939
|
dependencies:
|
|
13940
13940
|
'@tanstack/query-core': 5.101.2
|
|
13941
13941
|
'@tanstack/query-persist-client-core': 5.101.2
|
|
@@ -13957,7 +13957,7 @@ snapshots:
|
|
|
13957
13957
|
|
|
13958
13958
|
zova-module-a-routerstack@5.1.26: {}
|
|
13959
13959
|
|
|
13960
|
-
zova-module-a-routertabs@5.1.
|
|
13960
|
+
zova-module-a-routertabs@5.1.33: {}
|
|
13961
13961
|
|
|
13962
13962
|
zova-module-a-ssr@5.1.29:
|
|
13963
13963
|
dependencies:
|
|
@@ -14010,7 +14010,7 @@ snapshots:
|
|
|
14010
14010
|
|
|
14011
14011
|
zova-module-rest-resource@5.1.41: {}
|
|
14012
14012
|
|
|
14013
|
-
zova-suite-a-zova@5.1.
|
|
14013
|
+
zova-suite-a-zova@5.1.133(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
|
|
14014
14014
|
dependencies:
|
|
14015
14015
|
zova-module-a-api: 5.1.21
|
|
14016
14016
|
zova-module-a-app: 5.1.24
|
|
@@ -14025,11 +14025,11 @@ snapshots:
|
|
|
14025
14025
|
zova-module-a-interceptor: 5.1.29
|
|
14026
14026
|
zova-module-a-logger: 5.1.26
|
|
14027
14027
|
zova-module-a-meta: 5.1.21
|
|
14028
|
-
zova-module-a-model: 5.1.
|
|
14028
|
+
zova-module-a-model: 5.1.33(vue@3.5.39(typescript@5.9.3))
|
|
14029
14029
|
zova-module-a-openapi: 5.1.43
|
|
14030
14030
|
zova-module-a-router: 5.1.29
|
|
14031
14031
|
zova-module-a-routerstack: 5.1.26
|
|
14032
|
-
zova-module-a-routertabs: 5.1.
|
|
14032
|
+
zova-module-a-routertabs: 5.1.33
|
|
14033
14033
|
zova-module-a-ssr: 5.1.29
|
|
14034
14034
|
zova-module-a-ssrhmr: 5.1.22
|
|
14035
14035
|
zova-module-a-ssrserver: 5.1.22
|
|
@@ -14044,10 +14044,10 @@ snapshots:
|
|
|
14044
14044
|
- typescript
|
|
14045
14045
|
- vue
|
|
14046
14046
|
|
|
14047
|
-
zova@5.1.
|
|
14047
|
+
zova@5.1.134(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
|
|
14048
14048
|
dependencies:
|
|
14049
14049
|
zova-core: 5.1.77(patch_hash=0f4164c4d2bbb16d671beb5c26759dff37769be0709df941bc7b90b94261ac54)(typescript@5.9.3)
|
|
14050
|
-
zova-suite-a-zova: 5.1.
|
|
14050
|
+
zova-suite-a-zova: 5.1.133(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
|
|
14051
14051
|
transitivePeerDependencies:
|
|
14052
14052
|
- '@vue/composition-api'
|
|
14053
14053
|
- debug
|