cabloy 5.1.103 → 5.1.104

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 CHANGED
@@ -1 +1 @@
1
- 5.1.103
1
+ 5.1.104
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.104
4
+
5
+ ### Features
6
+
7
+ - Add update capabilities.
8
+
9
+ ### Bug Fixes
10
+
11
+ - Initialize the passport model during application startup.
12
+
13
+ ### Improvements
14
+
15
+ - Rename the generic async state type.
16
+ - Rename async local state APIs.
17
+ - Document the passport SSR state bridge.
18
+ - Clarify memory state SSR transfer behavior.
19
+ - Clarify how to select model state helpers.
20
+
3
21
  ## 5.1.103
4
22
 
5
23
  ### Features
@@ -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 query state during SSR pre-hydration
90
- - clear the query client after server rendering completes
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
- This is the place to check when the runtime feels surprising even though your page/model code looks correct.
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 `$useStateDb(...)`
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 when the state should stay only in memory.
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
- - no persistence
163
- - `enabled: false`
189
+ - `enabled: false`, so it does not define a normal remote-fetch lifecycle
164
190
  - `staleTime: Infinity`
165
- - still uses model-owned query cache semantics under the hood
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
+ ```
166
201
 
167
- This is useful when you want model ownership and query-key identity without local persistence.
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.
239
+
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. `$useStateDb(...)`
271
+ ## 6. `$useStateLocalAsync(...)`
199
272
 
200
- Use this when the model state should persist asynchronously in db-style client storage.
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
- - getters may need async restore flow before data is available
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.
@@ -252,16 +355,17 @@ Model state choices can affect SSR behavior.
252
355
 
253
356
  Current-source behaviors to remember:
254
357
 
255
- - query state can be dehydrated on server and hydrated on client
358
+ - successful eligible Query Cache state can be dehydrated on the server and hydrated on the client
359
+ - `$useStateMem(...)` has no browser persister but can participate in that initial SSR handoff unless excluded by metadata
256
360
  - mutations are not dehydrated
257
- - `db` state is explicitly not dehydrated
258
- - server cannot use local-storage or db persistence backends
259
- - cookie state is special because cookie access can still exist through the app cookie surface
361
+ - `$useStateLocalAsync(...)` explicitly opts out of dehydration
362
+ - 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
363
+ - 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
364
 
261
365
  Practical implication:
262
366
 
263
- - do not assume every persisted model state behaves the same during SSR
264
- - choose `mem`, `local`, `cookie`, `db`, or `data` based on ownership and hydration requirements, not only convenience
367
+ - do not equate browser persistence with SSR transfer, or assume every state family behaves the same during SSR
368
+ - choose `mem`, `local`, `cookie`, `localAsync`, or `data` based on ownership, persistence, and hydration requirements, not only convenience
265
369
 
266
370
  ## Real examples to read
267
371
 
@@ -289,7 +393,7 @@ This file shows:
289
393
 
290
394
  - `@Model({ enableSelector: true, ... })`
291
395
  - richer model initialization in `__init__`
292
- - mixed use of `$useStateMem(...)` and `$useStateDb(...)`
396
+ - mixed use of `$useStateMem(...)` and `$useStateLocalAsync(...)`
293
397
  - model-owned tab state with cache and persistence decisions
294
398
 
295
399
  ### 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. model-based SSR support synchronizes that data to the client and completes hydration automatically
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.103",
3
+ "version": "5.1.104",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -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.132
505
- version: 5.1.132(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
504
+ specifier: ^5.1.133
505
+ version: 5.1.133(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.31
532
- version: 5.1.31(vue@3.5.39(typescript@5.9.3))
531
+ specifier: ^5.1.32
532
+ version: 5.1.32(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
@@ -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.132
577
- version: 5.1.132(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
576
+ specifier: ^5.1.133
577
+ version: 5.1.133(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.31
604
- version: 5.1.31(vue@3.5.39(typescript@5.9.3))
603
+ specifier: ^5.1.32
604
+ version: 5.1.32(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
@@ -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.4
1520
+ specifier: ^5.0.5
1521
1521
  version: link:modules/a-file
1522
1522
  vona-module-file-cloudflare:
1523
- specifier: ^5.0.3
1523
+ specifier: ^5.0.4
1524
1524
  version: link:modules/file-cloudflare
1525
1525
  vona-module-file-native:
1526
- specifier: ^5.0.3
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.4
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.31:
7997
- resolution: {integrity: sha512-/6MV5xSklEkain5t0vsZ37ImyIihutCu7ymytq5RFG0QbeKtbSAI/IB6TS2mfkjLkiy97SmDJbuiLGso7Cg/Gw==}
7996
+ zova-module-a-model@5.1.32:
7997
+ resolution: {integrity: sha512-uzOXp2JlIOaBFy4pe5HyM846A2IK3zA2J8y8Je0i4EvioM36eiBhE61F8q0K59ojh3QZuinrxH6m9DIVL2EvVw==}
7998
7998
 
7999
7999
  zova-module-a-openapi@5.1.43:
8000
8000
  resolution: {integrity: sha512-xJKvSPl1AZnH7EpgEd9a3u3IEpJfnou19DKre/7TL1KdiTdfNThLrmmkdP1UNYlUHUgCczcGUwZDdMiE9gdxwA==}
@@ -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.131:
8036
- resolution: {integrity: sha512-NRPt3ahLwHg+rLuA2VXRbEmrg/bTdgwdQmU9C8nj9R0+E1f0ehbbsUWJFQFN6hJNco5+rDDSDfBlvejf4z6L1w==}
8035
+ zova-suite-a-zova@5.1.132:
8036
+ resolution: {integrity: sha512-bHyim0stshLyjEvehW8cUL0Bf/pR/sU43Dpada2g2ieGH1p34EzyLeaWimhId++sO9H3xErVX6aQXe0Xf6pELA==}
8037
8037
 
8038
- zova@5.1.132:
8039
- resolution: {integrity: sha512-lQK1VRnwthDx0qayS7kdElyfAmvPEhlt6sk/2jK5mTbqojsjuDNkrEa9Ck2Q78fag800U6pDwV83o6CRbSUTeA==}
8038
+ zova@5.1.133:
8039
+ resolution: {integrity: sha512-1tM0u0EU69/RvXmlxhVIrEY4ADVhQsEIr8UAcQ1U+Mjm3QwLJ7y7fDAQWsW7ChjEXHGrCU62fdc0tPvJ5CGntg==}
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.31(vue@3.5.39(typescript@5.9.3)):
13938
+ zova-module-a-model@5.1.32(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
@@ -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.131(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
14013
+ zova-suite-a-zova@5.1.132(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,7 +14025,7 @@ 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.31(vue@3.5.39(typescript@5.9.3))
14028
+ zova-module-a-model: 5.1.32(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
@@ -14044,10 +14044,10 @@ snapshots:
14044
14044
  - typescript
14045
14045
  - vue
14046
14046
 
14047
- zova@5.1.132(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3)):
14047
+ zova@5.1.133(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.131(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
14050
+ zova-suite-a-zova: 5.1.132(typescript@5.9.3)(vue@3.5.39(typescript@5.9.3))
14051
14051
  transitivePeerDependencies:
14052
14052
  - '@vue/composition-api'
14053
14053
  - debug
@@ -111,6 +111,13 @@ export class ControllerPassport extends BeanBase {
111
111
  return this._combineDtoPassportJwt(jwt);
112
112
  }
113
113
 
114
+ @Web.post('refreshAuthToken')
115
+ @Passport.public()
116
+ @Api.body(v.object(DtoJwtToken))
117
+ async refreshAuthToken(@Arg.body('refreshToken') refreshToken: string): Promise<DtoJwtToken> {
118
+ return await this.bean.passport.refreshAuthToken(refreshToken);
119
+ }
120
+
114
121
  @Web.post('createPassportJwtFromOauthCode')
115
122
  @Passport.public()
116
123
  @Api.body(v.object(DtoPassportJwt))
@@ -119,13 +126,6 @@ export class ControllerPassport extends BeanBase {
119
126
  return this._combineDtoPassportJwt(jwt);
120
127
  }
121
128
 
122
- @Web.post('refreshAuthToken')
123
- @Passport.public()
124
- @Api.body(v.object(DtoJwtToken))
125
- async refreshAuthToken(@Arg.body('refreshToken') refreshToken: string): Promise<DtoJwtToken> {
126
- return await this.bean.passport.refreshAuthToken(refreshToken);
127
- }
128
-
129
129
  @Web.post('createTempAuthToken')
130
130
  @Api.body(z.string())
131
131
  async createTempAuthToken(@Arg.query('path', v.optional()) path?: string): Promise<string> {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.133",
3
+ "version": "5.1.134",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "zova-core": "^5.1.77",
49
- "zova-suite-a-zova": "^5.1.132"
49
+ "zova-suite-a-zova": "^5.1.133"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -28,7 +28,9 @@ export class ModelPassport extends BeanModelBase {
28
28
  expireTime?: number;
29
29
  schemaLogin?: SchemaObject;
30
30
 
31
- protected async __init__() {
31
+ protected async __init__() {}
32
+
33
+ async appInitialize() {
32
34
  this.schemaLogin = this.$computed(() => {
33
35
  return this.apiSchemasLogin.requestBody;
34
36
  });
@@ -167,6 +169,10 @@ export class ModelPassport extends BeanModelBase {
167
169
  return this.passport?.roles;
168
170
  }
169
171
 
172
+ get isAdmin() {
173
+ return !!this.passport?.roles.some(item => item.name === 'admin');
174
+ }
175
+
170
176
  async getJwtInfo(): Promise<IJwtInfo | undefined> {
171
177
  if (!this.accessToken) return undefined;
172
178
  return {
@@ -1,11 +1,20 @@
1
1
  import type { IModule } from '@cabloy/module-info';
2
- import type { BeanBase, BeanContainer, IMonkeyBeanInit, IMonkeyModule } from 'zova';
2
+ import type {
3
+ BeanBase,
4
+ BeanContainer,
5
+ IMonkeyAppInitialize,
6
+ IMonkeyBeanInit,
7
+ IMonkeyModule,
8
+ } from 'zova';
3
9
 
4
10
  import { BeanSimple } from 'zova';
5
11
 
6
12
  import type { ModelPassport } from './model/passport.js';
7
13
 
8
- export class Monkey extends BeanSimple implements IMonkeyModule, IMonkeyBeanInit {
14
+ export class Monkey
15
+ extends BeanSimple
16
+ implements IMonkeyAppInitialize, IMonkeyModule, IMonkeyBeanInit
17
+ {
9
18
  private _moduleSelf: IModule;
10
19
  private $$modelPassport: ModelPassport;
11
20
 
@@ -14,13 +23,18 @@ export class Monkey extends BeanSimple implements IMonkeyModule, IMonkeyBeanInit
14
23
  this._moduleSelf = moduleSelf;
15
24
  }
16
25
 
17
- async getModelPassport() {
26
+ private async getModelPassport() {
18
27
  if (!this.$$modelPassport) {
19
28
  this.$$modelPassport = await this.bean._getBean('home-passport.model.passport', true);
20
29
  }
21
30
  return this.$$modelPassport;
22
31
  }
23
32
 
33
+ async appInitialize() {
34
+ const modelPassport = await this.getModelPassport();
35
+ await modelPassport.appInitialize();
36
+ }
37
+
24
38
  async moduleLoading(_module: IModule) {}
25
39
  async moduleLoaded(module: IModule) {
26
40
  // self
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-model",
3
- "version": "5.1.32",
3
+ "version": "5.1.33",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "core",
6
6
  "keywords": [
@@ -28,11 +28,11 @@ export class BeanModelUseState extends BeanModelUseQuery {
28
28
  private [SymbolUseQueries]: Record<string, unknown> = {};
29
29
  private [SymbolUseComputeds]: Record<string, unknown> = {};
30
30
 
31
- async $loadStateDb<T>(dbData: T): Promise<T> {
32
- return await dbData;
31
+ async $ensureStateLocalAsync<T>(state: T): Promise<T> {
32
+ return await state;
33
33
  }
34
34
 
35
- $useStateDb<
35
+ $useStateLocalAsync<
36
36
  TQueryFnData = unknown,
37
37
  TError = DefaultError,
38
38
  TData = TQueryFnData,
@@ -41,7 +41,7 @@ export class BeanModelUseState extends BeanModelUseQuery {
41
41
  options: UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
42
42
  queryClient?: QueryClient,
43
43
  ): TData;
44
- $useStateDb<
44
+ $useStateLocalAsync<
45
45
  TQueryFnData = unknown,
46
46
  TError = DefaultError,
47
47
  TData = TQueryFnData,
@@ -50,7 +50,7 @@ export class BeanModelUseState extends BeanModelUseQuery {
50
50
  options: DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
51
51
  queryClient?: QueryClient,
52
52
  ): TData;
53
- $useStateDb<
53
+ $useStateLocalAsync<
54
54
  TQueryFnData = unknown,
55
55
  TError = DefaultError,
56
56
  TData = TQueryFnData,
@@ -59,7 +59,7 @@ export class BeanModelUseState extends BeanModelUseQuery {
59
59
  options: UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
60
60
  queryClient?: QueryClient,
61
61
  ): TData;
62
- $useStateDb(options, queryClient) {
62
+ $useStateLocalAsync(options, queryClient) {
63
63
  options = deepExtend(
64
64
  {
65
65
  meta: {
@@ -23,7 +23,7 @@ export class BeanModelUseStateGeneral extends BeanModelUseState {
23
23
  TData = TQueryFnData,
24
24
  TQueryKey extends QueryKey = QueryKey,
25
25
  >(
26
- stateType: 'db' | 'local' | 'cookie' | 'mem',
26
+ stateType: 'localAsync' | 'local' | 'cookie' | 'mem',
27
27
  options: UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
28
28
  queryClient?: QueryClient,
29
29
  ): TData;
@@ -33,7 +33,7 @@ export class BeanModelUseStateGeneral extends BeanModelUseState {
33
33
  TData = TQueryFnData,
34
34
  TQueryKey extends QueryKey = QueryKey,
35
35
  >(
36
- stateType: 'db' | 'local' | 'cookie' | 'mem',
36
+ stateType: 'localAsync' | 'local' | 'cookie' | 'mem',
37
37
  options: DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
38
38
  queryClient?: QueryClient,
39
39
  ): TData;
@@ -43,7 +43,7 @@ export class BeanModelUseStateGeneral extends BeanModelUseState {
43
43
  TData = TQueryFnData,
44
44
  TQueryKey extends QueryKey = QueryKey,
45
45
  >(
46
- stateType: 'db' | 'local' | 'cookie' | 'mem',
46
+ stateType: 'localAsync' | 'local' | 'cookie' | 'mem',
47
47
  options: UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
48
48
  queryClient?: QueryClient,
49
49
  ): TData;
@@ -79,8 +79,8 @@ export class BeanModelUseStateGeneral extends BeanModelUseState {
79
79
  ): UnwrapNestedRefs<UseQueryReturnType<TData, TError>>;
80
80
  $useState(stateType: StateType, options, queryClient) {
81
81
  switch (stateType) {
82
- case 'db':
83
- return this.$useStateDb(options, queryClient);
82
+ case 'localAsync':
83
+ return this.$useStateLocalAsync(options, queryClient);
84
84
  case 'local':
85
85
  return this.$useStateLocal(options, queryClient);
86
86
  case 'cookie':
@@ -1,5 +1,11 @@
1
1
  import type { IModule } from '@cabloy/module-info';
2
- import type { BeanBase, BeanContainer, IMonkeyAppInitialize, IMonkeyBeanInit } from 'zova';
2
+ import type {
3
+ BeanBase,
4
+ BeanContainer,
5
+ IMonkeyAppInitialize,
6
+ IMonkeyBeanInit,
7
+ IMonkeyModule,
8
+ } from 'zova';
3
9
 
4
10
  import { useQueryClient } from '@tanstack/vue-query';
5
11
  import { markRaw } from 'vue';
@@ -7,7 +13,10 @@ import { BeanSimple } from 'zova';
7
13
 
8
14
  import { ServiceStorage } from './service/storage.js';
9
15
 
10
- export class Monkey extends BeanSimple implements IMonkeyAppInitialize, IMonkeyBeanInit {
16
+ export class Monkey
17
+ extends BeanSimple
18
+ implements IMonkeyAppInitialize, IMonkeyModule, IMonkeyBeanInit
19
+ {
11
20
  private _moduleSelf: IModule;
12
21
  private _storage: ServiceStorage;
13
22
 
@@ -63,7 +63,7 @@ export type QueryMetaPersisterCookieType =
63
63
  | 'string'
64
64
  | undefined;
65
65
 
66
- export type StateType = 'db' | 'local' | 'cookie' | 'mem' | 'data';
66
+ export type StateType = 'localAsync' | 'local' | 'cookie' | 'mem' | 'data';
67
67
 
68
68
  export type StaleTime = number;
69
69
  export type StaleTimeFunction<
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-routertabs",
3
- "version": "5.1.32",
3
+ "version": "5.1.33",
4
4
  "gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
5
5
  "description": "routertabs",
6
6
  "keywords": [
@@ -63,7 +63,7 @@ export class ModelTabs extends BeanModelBase {
63
63
  };
64
64
  this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);
65
65
  // if (this.tabsOptions.cache) {
66
- // this.tabKeyCurrent = this.$useStateDb(queryOptionsTabKeyCurrent);
66
+ // this.tabKeyCurrent = this.$useStateLocalAsync(queryOptionsTabKeyCurrent);
67
67
  // } else {
68
68
  // this.tabKeyCurrent = this.$useStateMem(queryOptionsTabKeyCurrent);
69
69
  // }
@@ -75,14 +75,14 @@ export class ModelTabs extends BeanModelBase {
75
75
  },
76
76
  };
77
77
  if (this.tabsOptions.cache) {
78
- this.tabs = this.$useStateDb(queryOptionsTabs);
78
+ this.tabs = this.$useStateLocalAsync(queryOptionsTabs);
79
79
  } else {
80
80
  this.tabs = this.$useStateMem(queryOptionsTabs);
81
81
  }
82
82
  // load cache
83
83
  if (this.tabsOptions.cache) {
84
- // await this.$loadStateDb(this.tabKeyCurrent);
85
- await this.$loadStateDb(this.tabs);
84
+ // await this.$ensureStateLocalAsync(this.tabKeyCurrent);
85
+ await this.$ensureStateLocalAsync(this.tabs);
86
86
  }
87
87
  // reset pageDirty
88
88
  this._resetAllPageDirty();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.132",
3
+ "version": "5.1.133",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -21,11 +21,11 @@
21
21
  "zova-module-a-interceptor": "^5.1.29",
22
22
  "zova-module-a-logger": "^5.1.26",
23
23
  "zova-module-a-meta": "^5.1.21",
24
- "zova-module-a-model": "^5.1.32",
24
+ "zova-module-a-model": "^5.1.33",
25
25
  "zova-module-a-openapi": "^5.1.43",
26
26
  "zova-module-a-router": "^5.1.29",
27
27
  "zova-module-a-routerstack": "^5.1.26",
28
- "zova-module-a-routertabs": "^5.1.32",
28
+ "zova-module-a-routertabs": "^5.1.33",
29
29
  "zova-module-a-ssr": "^5.1.29",
30
30
  "zova-module-a-ssrhmr": "^5.1.22",
31
31
  "zova-module-a-ssrserver": "^5.1.22",