@vertz/ui 0.2.14 → 0.2.16
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/README.md +49 -0
- package/dist/shared/chunk-14eqne2a.js +10 -0
- package/dist/shared/{chunk-dksg08fq.js → chunk-1rxa2fz4.js} +2 -8
- package/dist/shared/{chunk-8hsz5y4a.js → chunk-4fwcwxn6.js} +14 -4
- package/dist/shared/{chunk-hw67ckr3.js → chunk-4mtn7af6.js} +230 -19
- package/dist/shared/{chunk-2sth83bd.js → chunk-6jyt4ycw.js} +67 -2
- package/dist/shared/{chunk-83g4h38e.js → chunk-6wd36w21.js} +1 -0
- package/dist/shared/{chunk-h89w580h.js → chunk-afawz764.js} +1 -1
- package/dist/shared/{chunk-nn9v1zmk.js → chunk-b0qqqk03.js} +86 -21
- package/dist/shared/{chunk-c9xxsrat.js → chunk-dhehvmj0.js} +179 -10
- package/dist/shared/{chunk-mj7b4t40.js → chunk-fkbgbf3n.js} +98 -11
- package/dist/shared/{chunk-c30eg6wn.js → chunk-j09yyh34.js} +79 -6
- package/dist/shared/chunk-mtsvrj9e.js +23 -0
- package/dist/shared/chunk-pnv25zep.js +7 -0
- package/dist/shared/{chunk-j6qyxfdc.js → chunk-vndfjfdy.js} +3 -3
- package/dist/src/auth/public.d.ts +69 -9
- package/dist/src/auth/public.js +217 -13
- package/dist/src/css/public.d.ts +110 -2
- package/dist/src/css/public.js +8 -4
- package/dist/src/form/public.d.ts +33 -7
- package/dist/src/form/public.js +2 -2
- package/dist/src/index.d.ts +311 -20
- package/dist/src/index.js +161 -14
- package/dist/src/internals.d.ts +141 -5
- package/dist/src/internals.js +17 -9
- package/dist/src/query/public.js +4 -3
- package/dist/src/router/public.d.ts +39 -9
- package/dist/src/router/public.js +17 -11
- package/dist/src/test/index.d.ts +26 -23
- package/dist/src/test/index.js +5 -4
- package/package.json +3 -3
- package/reactivity.json +1 -11
package/README.md
CHANGED
|
@@ -255,6 +255,53 @@ const compiled = compileTheme(theme);
|
|
|
255
255
|
ThemeProvider({ theme: 'dark', children: [<App />] });
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
+
### Fonts
|
|
259
|
+
|
|
260
|
+
Declare font families with `font()` and compile them into `@font-face` CSS, custom properties, and preload tags with `compileFonts()`. Only woff2 format is supported.
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
import { font, compileFonts } from '@vertz/ui/css';
|
|
264
|
+
|
|
265
|
+
const sans = font('DM Sans', {
|
|
266
|
+
weight: '100..1000',
|
|
267
|
+
src: '/fonts/dm-sans.woff2',
|
|
268
|
+
fallback: ['system-ui', 'sans-serif'],
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const mono = font('JetBrains Mono', {
|
|
272
|
+
weight: '100..800',
|
|
273
|
+
src: '/fonts/jb-mono.woff2',
|
|
274
|
+
fallback: ['monospace'],
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const compiled = compileFonts({ sans, mono });
|
|
278
|
+
|
|
279
|
+
// compiled.fontFaceCss — @font-face declarations
|
|
280
|
+
// compiled.cssVarsCss — :root { --font-sans: ...; --font-mono: ...; }
|
|
281
|
+
// compiled.cssVarLines — individual lines for merging into an existing :root
|
|
282
|
+
// compiled.preloadTags — <link rel="preload" ...> HTML tags
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Multiple font files** (e.g., normal + italic):
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
const sans = font('DM Sans', {
|
|
289
|
+
weight: '100..1000',
|
|
290
|
+
src: [
|
|
291
|
+
{ path: '/fonts/dm-sans.woff2', weight: '100..1000', style: 'normal' },
|
|
292
|
+
{ path: '/fonts/dm-sans-italic.woff2', weight: '100..1000', style: 'italic' },
|
|
293
|
+
],
|
|
294
|
+
fallback: ['system-ui', 'sans-serif'],
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Font without `src`** (system font with CSS var only):
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
const system = font('system-ui', { weight: '400' });
|
|
302
|
+
// compileFonts({ system }) generates --font-system: 'system-ui'; but no @font-face
|
|
303
|
+
```
|
|
304
|
+
|
|
258
305
|
---
|
|
259
306
|
|
|
260
307
|
## Forms
|
|
@@ -624,6 +671,8 @@ onMount(() => {
|
|
|
624
671
|
| `compileTheme` | Compile a theme to CSS |
|
|
625
672
|
| `ThemeProvider` | Provide a theme to descendants |
|
|
626
673
|
| `globalCss` | Inject global CSS |
|
|
674
|
+
| `font` | Declare a font family descriptor |
|
|
675
|
+
| `compileFonts` | Compile font descriptors into CSS, vars, and preload tags |
|
|
627
676
|
|
|
628
677
|
### Forms
|
|
629
678
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
domEffect
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4fwcwxn6.js";
|
|
4
4
|
|
|
5
5
|
// src/dom/attributes.ts
|
|
6
6
|
function __attr(el, name, fn) {
|
|
@@ -39,10 +39,4 @@ function __classList(el, classMap) {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
function __on(el, event, handler) {
|
|
44
|
-
el.addEventListener(event, handler);
|
|
45
|
-
return () => el.removeEventListener(event, handler);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { __attr, __show, __classList, __on };
|
|
42
|
+
export { __attr, __show, __classList };
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
// src/ssr/ssr-render-context.ts
|
|
2
|
-
var
|
|
2
|
+
var RESOLVER_KEY = "__VERTZ_SSR_RESOLVER__";
|
|
3
|
+
function getResolver() {
|
|
4
|
+
return globalThis[RESOLVER_KEY] ?? null;
|
|
5
|
+
}
|
|
3
6
|
function registerSSRResolver(resolver) {
|
|
4
|
-
|
|
7
|
+
if (resolver === null) {
|
|
8
|
+
delete globalThis[RESOLVER_KEY];
|
|
9
|
+
} else {
|
|
10
|
+
globalThis[RESOLVER_KEY] = resolver;
|
|
11
|
+
}
|
|
5
12
|
}
|
|
6
13
|
function getSSRContext() {
|
|
7
|
-
return
|
|
14
|
+
return getResolver()?.();
|
|
15
|
+
}
|
|
16
|
+
function hasSSRResolver() {
|
|
17
|
+
return getResolver() !== null;
|
|
8
18
|
}
|
|
9
19
|
|
|
10
20
|
// src/component/context.ts
|
|
@@ -472,4 +482,4 @@ function lifecycleEffect(fn) {
|
|
|
472
482
|
return dispose;
|
|
473
483
|
}
|
|
474
484
|
|
|
475
|
-
export { registerSSRResolver, getSSRContext, createContext, useContext, getContextScope, setContextScope, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, setReadValueCallback, untrack, batch, startSignalCollection, stopSignalCollection, signal, computed, domEffect, lifecycleEffect };
|
|
485
|
+
export { registerSSRResolver, getSSRContext, hasSSRResolver, createContext, useContext, getContextScope, setContextScope, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, setReadValueCallback, untrack, batch, startSignalCollection, stopSignalCollection, signal, computed, domEffect, lifecycleEffect };
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isNavPrefetchActive
|
|
3
3
|
} from "./chunk-jrtrk5z4.js";
|
|
4
|
+
import {
|
|
5
|
+
isBrowser
|
|
6
|
+
} from "./chunk-14eqne2a.js";
|
|
4
7
|
import {
|
|
5
8
|
getAdapter,
|
|
6
9
|
isRenderNode
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-afawz764.js";
|
|
8
11
|
import {
|
|
9
12
|
_tryOnCleanup,
|
|
10
13
|
batch,
|
|
@@ -18,22 +21,89 @@ import {
|
|
|
18
21
|
setReadValueCallback,
|
|
19
22
|
signal,
|
|
20
23
|
untrack
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4fwcwxn6.js";
|
|
22
25
|
|
|
23
26
|
// src/query/cache.ts
|
|
24
27
|
class MemoryCache {
|
|
25
28
|
_store = new Map;
|
|
29
|
+
_maxSize;
|
|
30
|
+
_refs = new Map;
|
|
31
|
+
_orphans = new Map;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
const raw = options?.maxSize ?? 1000;
|
|
34
|
+
this._maxSize = Number.isNaN(raw) ? 1000 : Math.max(0, raw);
|
|
35
|
+
}
|
|
26
36
|
get(key) {
|
|
27
|
-
|
|
37
|
+
if (!this._store.has(key))
|
|
38
|
+
return;
|
|
39
|
+
const value = this._store.get(key);
|
|
40
|
+
this._store.delete(key);
|
|
41
|
+
this._store.set(key, value);
|
|
42
|
+
return value;
|
|
28
43
|
}
|
|
29
44
|
set(key, value) {
|
|
45
|
+
if (this._store.has(key))
|
|
46
|
+
this._store.delete(key);
|
|
30
47
|
this._store.set(key, value);
|
|
48
|
+
while (this._store.size > this._maxSize) {
|
|
49
|
+
const orphan = this._orphans.keys().next();
|
|
50
|
+
if (!orphan.done) {
|
|
51
|
+
if (this._store.has(orphan.value)) {
|
|
52
|
+
this._store.delete(orphan.value);
|
|
53
|
+
this._orphans.delete(orphan.value);
|
|
54
|
+
this._refs.delete(orphan.value);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
this._orphans.delete(orphan.value);
|
|
58
|
+
this._refs.delete(orphan.value);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
let evicted = false;
|
|
62
|
+
for (const k of this._store.keys()) {
|
|
63
|
+
if (k !== key && !this._refs.has(k)) {
|
|
64
|
+
this._store.delete(k);
|
|
65
|
+
evicted = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (evicted)
|
|
70
|
+
continue;
|
|
71
|
+
const oldest = this._store.keys().next();
|
|
72
|
+
if (oldest.done)
|
|
73
|
+
break;
|
|
74
|
+
this._store.delete(oldest.value);
|
|
75
|
+
this._refs.delete(oldest.value);
|
|
76
|
+
this._orphans.delete(oldest.value);
|
|
77
|
+
}
|
|
31
78
|
}
|
|
32
79
|
delete(key) {
|
|
33
80
|
this._store.delete(key);
|
|
81
|
+
this._refs.delete(key);
|
|
82
|
+
this._orphans.delete(key);
|
|
34
83
|
}
|
|
35
84
|
clear() {
|
|
36
85
|
this._store.clear();
|
|
86
|
+
this._refs.clear();
|
|
87
|
+
this._orphans.clear();
|
|
88
|
+
}
|
|
89
|
+
retain(key) {
|
|
90
|
+
const count = (this._refs.get(key) ?? 0) + 1;
|
|
91
|
+
this._refs.set(key, count);
|
|
92
|
+
this._orphans.delete(key);
|
|
93
|
+
}
|
|
94
|
+
release(key) {
|
|
95
|
+
const current = this._refs.get(key);
|
|
96
|
+
if (current === undefined)
|
|
97
|
+
return;
|
|
98
|
+
const count = current - 1;
|
|
99
|
+
if (count <= 0) {
|
|
100
|
+
this._refs.delete(key);
|
|
101
|
+
if (this._store.has(key)) {
|
|
102
|
+
this._orphans.set(key, true);
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
this._refs.set(key, count);
|
|
106
|
+
}
|
|
37
107
|
}
|
|
38
108
|
}
|
|
39
109
|
|
|
@@ -73,6 +143,93 @@ function hashString(str) {
|
|
|
73
143
|
return (hash >>> 0).toString(36);
|
|
74
144
|
}
|
|
75
145
|
|
|
146
|
+
// src/store/field-selection-tracker.ts
|
|
147
|
+
class FieldSelectionTracker {
|
|
148
|
+
_selectInfo = new Map;
|
|
149
|
+
_warned = new Set;
|
|
150
|
+
_onMiss;
|
|
151
|
+
constructor(options) {
|
|
152
|
+
this._onMiss = options?.onMiss;
|
|
153
|
+
}
|
|
154
|
+
registerSelect(type, id, fields, querySource) {
|
|
155
|
+
const key = `${type}:${id}`;
|
|
156
|
+
let info = this._selectInfo.get(key);
|
|
157
|
+
if (!info) {
|
|
158
|
+
info = { fields: new Set, querySources: new Set, fullFetch: false };
|
|
159
|
+
this._selectInfo.set(key, info);
|
|
160
|
+
}
|
|
161
|
+
for (const field of fields) {
|
|
162
|
+
info.fields.add(field);
|
|
163
|
+
}
|
|
164
|
+
info.querySources.add(querySource);
|
|
165
|
+
}
|
|
166
|
+
registerFullFetch(type, id) {
|
|
167
|
+
const key = `${type}:${id}`;
|
|
168
|
+
let info = this._selectInfo.get(key);
|
|
169
|
+
if (!info) {
|
|
170
|
+
info = { fields: new Set, querySources: new Set, fullFetch: true };
|
|
171
|
+
this._selectInfo.set(key, info);
|
|
172
|
+
} else {
|
|
173
|
+
info.fullFetch = true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
shouldWarn(type, id, field) {
|
|
177
|
+
const key = `${type}:${id}`;
|
|
178
|
+
const info = this._selectInfo.get(key);
|
|
179
|
+
if (!info || info.fullFetch)
|
|
180
|
+
return false;
|
|
181
|
+
return !info.fields.has(field);
|
|
182
|
+
}
|
|
183
|
+
removeEntity(type, id) {
|
|
184
|
+
const key = `${type}:${id}`;
|
|
185
|
+
this._selectInfo.delete(key);
|
|
186
|
+
const prefix = `${key}:`;
|
|
187
|
+
for (const warnKey of this._warned) {
|
|
188
|
+
if (warnKey.startsWith(prefix)) {
|
|
189
|
+
this._warned.delete(warnKey);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
createDevProxy(entity, type, id) {
|
|
194
|
+
const key = `${type}:${id}`;
|
|
195
|
+
const info = this._selectInfo.get(key);
|
|
196
|
+
if (!info || info.fullFetch)
|
|
197
|
+
return entity;
|
|
198
|
+
const tracker = this;
|
|
199
|
+
return new Proxy(entity, {
|
|
200
|
+
get(target, prop, receiver) {
|
|
201
|
+
if (typeof prop === "string" && !INTERNAL_PROPS.has(prop) && tracker.shouldWarn(type, id, prop)) {
|
|
202
|
+
const warnKey = `${key}:${prop}`;
|
|
203
|
+
if (!tracker._warned.has(warnKey)) {
|
|
204
|
+
tracker._warned.add(warnKey);
|
|
205
|
+
const sources = [...info.querySources].join(", ");
|
|
206
|
+
const selectedFields = [...info.fields].sort().join(", ");
|
|
207
|
+
console.warn(`[vertz] Field "${prop}" was accessed on ${type}#${id} ` + `but was not in the select set.
|
|
208
|
+
` + ` Query: "${sources}"
|
|
209
|
+
` + ` Selected: ${selectedFields}
|
|
210
|
+
` + ` Fix: use {entity.${prop}} in JSX, ` + "or add // @vertz-select-all above the query.");
|
|
211
|
+
tracker._onMiss?.(type, id, prop, sources);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return Reflect.get(target, prop, receiver);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
clear() {
|
|
219
|
+
this._selectInfo.clear();
|
|
220
|
+
this._warned.clear();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
var INTERNAL_PROPS = new Set([
|
|
224
|
+
"then",
|
|
225
|
+
"toJSON",
|
|
226
|
+
"toString",
|
|
227
|
+
"valueOf",
|
|
228
|
+
"constructor",
|
|
229
|
+
"$$typeof",
|
|
230
|
+
"__proto__"
|
|
231
|
+
]);
|
|
232
|
+
|
|
76
233
|
// src/store/relation-registry.ts
|
|
77
234
|
var registry2 = new Map;
|
|
78
235
|
function registerRelationSchema(entityType, schema) {
|
|
@@ -241,10 +398,14 @@ class EntityStore {
|
|
|
241
398
|
_entities = new Map;
|
|
242
399
|
_typeListeners = new Map;
|
|
243
400
|
_queryIndices = new QueryResultIndex;
|
|
401
|
+
_fieldTracker = null;
|
|
244
402
|
get queryIndices() {
|
|
245
403
|
return this._queryIndices;
|
|
246
404
|
}
|
|
247
405
|
constructor(options) {
|
|
406
|
+
if (options?.devMode) {
|
|
407
|
+
this._fieldTracker = new FieldSelectionTracker;
|
|
408
|
+
}
|
|
248
409
|
if (options?.initialData) {
|
|
249
410
|
this.hydrate(options.initialData);
|
|
250
411
|
}
|
|
@@ -261,7 +422,8 @@ class EntityStore {
|
|
|
261
422
|
base: {},
|
|
262
423
|
layers: new Map,
|
|
263
424
|
refCount: 0,
|
|
264
|
-
orphanedAt: null
|
|
425
|
+
orphanedAt: null,
|
|
426
|
+
lastPlainVisible: null
|
|
265
427
|
};
|
|
266
428
|
this._getOrCreateTypeMap(type).set(id, newEntry);
|
|
267
429
|
return sig;
|
|
@@ -275,6 +437,7 @@ class EntityStore {
|
|
|
275
437
|
return;
|
|
276
438
|
}
|
|
277
439
|
batch(() => {
|
|
440
|
+
this.evictOrphans();
|
|
278
441
|
for (const item of items) {
|
|
279
442
|
const { normalized, extracted } = normalizeEntity(type, item);
|
|
280
443
|
for (const [nestedType, nestedItems] of extracted) {
|
|
@@ -286,6 +449,15 @@ class EntityStore {
|
|
|
286
449
|
}
|
|
287
450
|
});
|
|
288
451
|
}
|
|
452
|
+
mergeWithSelect(type, data, selectOptions) {
|
|
453
|
+
if (this._fieldTracker) {
|
|
454
|
+
const items = Array.isArray(data) ? data : [data];
|
|
455
|
+
for (const item of items) {
|
|
456
|
+
this._fieldTracker.registerSelect(type, item.id, selectOptions.fields, selectOptions.querySource);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
this.merge(type, data);
|
|
460
|
+
}
|
|
289
461
|
remove(type, id) {
|
|
290
462
|
const typeMap = this._entities.get(type);
|
|
291
463
|
if (!typeMap?.has(id)) {
|
|
@@ -297,6 +469,7 @@ class EntityStore {
|
|
|
297
469
|
}
|
|
298
470
|
typeMap.delete(id);
|
|
299
471
|
this._queryIndices.removeEntity(id);
|
|
472
|
+
this._fieldTracker?.removeEntity(type, id);
|
|
300
473
|
this._notifyTypeChange(type);
|
|
301
474
|
}
|
|
302
475
|
onTypeChange(type, callback) {
|
|
@@ -368,7 +541,7 @@ class EntityStore {
|
|
|
368
541
|
if (!entry)
|
|
369
542
|
return;
|
|
370
543
|
entry.layers.set(mutationId, patch);
|
|
371
|
-
this._recomputeVisible(entry);
|
|
544
|
+
this._recomputeVisible(entry, type, id);
|
|
372
545
|
}
|
|
373
546
|
addRef(type, id) {
|
|
374
547
|
const entry = this._entities.get(type)?.get(id);
|
|
@@ -391,12 +564,13 @@ class EntityStore {
|
|
|
391
564
|
evictOrphans(maxAge = 300000) {
|
|
392
565
|
const now = Date.now();
|
|
393
566
|
let count = 0;
|
|
394
|
-
for (const [
|
|
567
|
+
for (const [type, typeMap] of this._entities) {
|
|
395
568
|
for (const [id, entry] of typeMap) {
|
|
396
569
|
if (entry.refCount === 0 && entry.orphanedAt !== null && now - entry.orphanedAt >= maxAge && entry.layers.size === 0) {
|
|
397
570
|
entry.signal.value = undefined;
|
|
398
571
|
typeMap.delete(id);
|
|
399
572
|
this._queryIndices.removeEntity(id);
|
|
573
|
+
this._fieldTracker?.removeEntity(type, id);
|
|
400
574
|
count++;
|
|
401
575
|
}
|
|
402
576
|
}
|
|
@@ -420,7 +594,7 @@ class EntityStore {
|
|
|
420
594
|
if (!entry)
|
|
421
595
|
return;
|
|
422
596
|
entry.layers.delete(mutationId);
|
|
423
|
-
this._recomputeVisible(entry);
|
|
597
|
+
this._recomputeVisible(entry, type, id);
|
|
424
598
|
}
|
|
425
599
|
removeOptimistic(type, id, _mutationId) {
|
|
426
600
|
this.remove(type, id);
|
|
@@ -445,7 +619,7 @@ class EntityStore {
|
|
|
445
619
|
}
|
|
446
620
|
entry.base = normalized;
|
|
447
621
|
entry.layers.delete(mutationId);
|
|
448
|
-
this._recomputeVisible(entry);
|
|
622
|
+
this._recomputeVisible(entry, type, id);
|
|
449
623
|
}
|
|
450
624
|
_mergeOne(type, item) {
|
|
451
625
|
const id = item.id;
|
|
@@ -455,33 +629,42 @@ class EntityStore {
|
|
|
455
629
|
const mergedBase = shallowMerge(entry.base, item);
|
|
456
630
|
if (!shallowEqual(entry.base, mergedBase)) {
|
|
457
631
|
entry.base = mergedBase;
|
|
458
|
-
this._recomputeVisible(entry);
|
|
632
|
+
this._recomputeVisible(entry, type, id);
|
|
459
633
|
}
|
|
460
634
|
} else {
|
|
461
|
-
const
|
|
635
|
+
const value = this._wrapWithFieldProxy(item, type, id);
|
|
636
|
+
const newSignal = signal(value);
|
|
462
637
|
const newEntry = {
|
|
463
638
|
signal: newSignal,
|
|
464
639
|
base: item,
|
|
465
640
|
layers: new Map,
|
|
466
641
|
refCount: 0,
|
|
467
|
-
orphanedAt: null
|
|
642
|
+
orphanedAt: null,
|
|
643
|
+
lastPlainVisible: item
|
|
468
644
|
};
|
|
469
645
|
this._getOrCreateTypeMap(type).set(id, newEntry);
|
|
470
646
|
this._notifyTypeChange(type);
|
|
471
647
|
}
|
|
472
648
|
}
|
|
473
|
-
_recomputeVisible(entry) {
|
|
649
|
+
_recomputeVisible(entry, type, id) {
|
|
474
650
|
let visible = { ...entry.base };
|
|
475
651
|
for (const patch of entry.layers.values()) {
|
|
476
652
|
visible = shallowMerge(visible, patch);
|
|
477
653
|
}
|
|
478
|
-
const
|
|
479
|
-
if (
|
|
654
|
+
const lastPlain = entry.lastPlainVisible;
|
|
655
|
+
if (lastPlain == null || !shallowEqual(lastPlain, visible)) {
|
|
656
|
+
entry.lastPlainVisible = visible;
|
|
657
|
+
const wrapped = type && id ? this._wrapWithFieldProxy(visible, type, id) : visible;
|
|
480
658
|
untrack(() => {
|
|
481
|
-
entry.signal.value =
|
|
659
|
+
entry.signal.value = wrapped;
|
|
482
660
|
});
|
|
483
661
|
}
|
|
484
662
|
}
|
|
663
|
+
_wrapWithFieldProxy(entity, type, id) {
|
|
664
|
+
if (!this._fieldTracker)
|
|
665
|
+
return entity;
|
|
666
|
+
return this._fieldTracker.createDevProxy(entity, type, id);
|
|
667
|
+
}
|
|
485
668
|
_getOrCreateTypeMap(type) {
|
|
486
669
|
let typeMap = this._entities.get(type);
|
|
487
670
|
if (!typeMap) {
|
|
@@ -705,6 +888,25 @@ function query(source, options = {}) {
|
|
|
705
888
|
function getCacheKey() {
|
|
706
889
|
return cacheKeyComputed.value;
|
|
707
890
|
}
|
|
891
|
+
let currentRetainedKey = null;
|
|
892
|
+
const retainable = "retain" in cache && "release" in cache;
|
|
893
|
+
function retainKey(key) {
|
|
894
|
+
if (!retainable)
|
|
895
|
+
return;
|
|
896
|
+
if (currentRetainedKey === key)
|
|
897
|
+
return;
|
|
898
|
+
if (currentRetainedKey !== null) {
|
|
899
|
+
cache.release(currentRetainedKey);
|
|
900
|
+
}
|
|
901
|
+
cache.retain(key);
|
|
902
|
+
currentRetainedKey = key;
|
|
903
|
+
}
|
|
904
|
+
function releaseCurrentKey() {
|
|
905
|
+
if (!retainable || currentRetainedKey === null)
|
|
906
|
+
return;
|
|
907
|
+
cache.release(currentRetainedKey);
|
|
908
|
+
currentRetainedKey = null;
|
|
909
|
+
}
|
|
708
910
|
function callThunkWithCapture() {
|
|
709
911
|
const captured = [];
|
|
710
912
|
const prevCb = setReadValueCallback((v) => captured.push(v));
|
|
@@ -782,7 +984,9 @@ function query(source, options = {}) {
|
|
|
782
984
|
return raw;
|
|
783
985
|
}) : rawData;
|
|
784
986
|
if (initialData !== undefined) {
|
|
785
|
-
|
|
987
|
+
const initKey = getCacheKey();
|
|
988
|
+
cache.set(initKey, initialData);
|
|
989
|
+
retainKey(initKey);
|
|
786
990
|
}
|
|
787
991
|
const ssrTimeout = options.ssrTimeout ?? getGlobalSSRTimeout() ?? 300;
|
|
788
992
|
if (isSSR() && enabled && ssrTimeout !== 0 && initialData === undefined) {
|
|
@@ -829,6 +1033,7 @@ function query(source, options = {}) {
|
|
|
829
1033
|
if (customKey) {
|
|
830
1034
|
const cached = cache.get(customKey);
|
|
831
1035
|
if (cached !== undefined) {
|
|
1036
|
+
retainKey(customKey);
|
|
832
1037
|
normalizeToEntityStore(cached);
|
|
833
1038
|
rawData.value = cached;
|
|
834
1039
|
loading.value = false;
|
|
@@ -881,7 +1086,7 @@ function query(source, options = {}) {
|
|
|
881
1086
|
}, ms);
|
|
882
1087
|
}
|
|
883
1088
|
let visibilityHandler;
|
|
884
|
-
if (hasInterval && enabled &&
|
|
1089
|
+
if (hasInterval && enabled && isBrowser()) {
|
|
885
1090
|
visibilityHandler = () => {
|
|
886
1091
|
if (document.visibilityState === "hidden") {
|
|
887
1092
|
intervalPaused = true;
|
|
@@ -900,6 +1105,7 @@ function query(source, options = {}) {
|
|
|
900
1105
|
if (id !== fetchId)
|
|
901
1106
|
return;
|
|
902
1107
|
cache.set(key, result);
|
|
1108
|
+
retainKey(key);
|
|
903
1109
|
normalizeToEntityStore(result);
|
|
904
1110
|
rawData.value = result;
|
|
905
1111
|
loading.value = false;
|
|
@@ -937,6 +1143,7 @@ function query(source, options = {}) {
|
|
|
937
1143
|
}
|
|
938
1144
|
function refetch() {
|
|
939
1145
|
const key = getCacheKey();
|
|
1146
|
+
currentRetainedKey = null;
|
|
940
1147
|
cache.delete(key);
|
|
941
1148
|
getInflight().delete(key);
|
|
942
1149
|
refetchTrigger.value = refetchTrigger.peek() + 1;
|
|
@@ -954,6 +1161,7 @@ function query(source, options = {}) {
|
|
|
954
1161
|
if (customKey) {
|
|
955
1162
|
const cached = untrack(() => cache.get(customKey));
|
|
956
1163
|
if (cached !== undefined) {
|
|
1164
|
+
retainKey(customKey);
|
|
957
1165
|
untrack(() => {
|
|
958
1166
|
rawData.value = cached;
|
|
959
1167
|
loading.value = false;
|
|
@@ -967,6 +1175,7 @@ function query(source, options = {}) {
|
|
|
967
1175
|
const derivedKey = untrack(() => getCacheKey());
|
|
968
1176
|
const cached = untrack(() => cache.get(derivedKey));
|
|
969
1177
|
if (cached !== undefined) {
|
|
1178
|
+
retainKey(derivedKey);
|
|
970
1179
|
untrack(() => {
|
|
971
1180
|
rawData.value = cached;
|
|
972
1181
|
loading.value = false;
|
|
@@ -1020,6 +1229,7 @@ function query(source, options = {}) {
|
|
|
1020
1229
|
if (shouldCheckCache) {
|
|
1021
1230
|
const cached = untrack(() => cache.get(key));
|
|
1022
1231
|
if (cached !== undefined) {
|
|
1232
|
+
retainKey(key);
|
|
1023
1233
|
promise.catch(() => {});
|
|
1024
1234
|
untrack(() => {
|
|
1025
1235
|
rawData.value = cached;
|
|
@@ -1058,13 +1268,14 @@ function query(source, options = {}) {
|
|
|
1058
1268
|
}
|
|
1059
1269
|
referencedKeys.clear();
|
|
1060
1270
|
}
|
|
1271
|
+
releaseCurrentKey();
|
|
1061
1272
|
disposeFn?.();
|
|
1062
1273
|
unsubscribeBus?.();
|
|
1063
1274
|
unregisterFromRegistry?.();
|
|
1064
1275
|
ssrHydrationCleanup?.();
|
|
1065
1276
|
clearTimeout(debounceTimer);
|
|
1066
1277
|
clearTimeout(intervalTimer);
|
|
1067
|
-
if (visibilityHandler &&
|
|
1278
|
+
if (visibilityHandler && isBrowser()) {
|
|
1068
1279
|
document.removeEventListener("visibilitychange", visibilityHandler);
|
|
1069
1280
|
}
|
|
1070
1281
|
fetchId++;
|
|
@@ -1209,4 +1420,4 @@ function queryMatch(queryResult, handlers) {
|
|
|
1209
1420
|
return wrapper;
|
|
1210
1421
|
}
|
|
1211
1422
|
|
|
1212
|
-
export { MemoryCache, invalidate, deriveKey, registerRelationSchema, getRelationSchema, resetRelationSchemas_TEST_ONLY, EntityStore, QueryEnvelopeStore, getEntityStore, getQueryEnvelopeStore, getMutationEventBus, query, queryMatch };
|
|
1423
|
+
export { MemoryCache, invalidate, deriveKey, FieldSelectionTracker, registerRelationSchema, getRelationSchema, resetRelationSchemas_TEST_ONLY, EntityStore, QueryEnvelopeStore, getEntityStore, getQueryEnvelopeStore, getMutationEventBus, query, queryMatch };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
injectCSS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-dhehvmj0.js";
|
|
4
4
|
|
|
5
5
|
// src/dom/animation.ts
|
|
6
6
|
function onAnimationsComplete(el, callback) {
|
|
@@ -479,7 +479,72 @@ function hydrate(registry) {
|
|
|
479
479
|
autoStrategy(el, doHydrate);
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
|
+
|
|
483
|
+
// src/hydrate/island-hydrate.ts
|
|
484
|
+
var hydrationQueue = [];
|
|
485
|
+
var isProcessing = false;
|
|
486
|
+
async function processQueue() {
|
|
487
|
+
if (isProcessing)
|
|
488
|
+
return;
|
|
489
|
+
isProcessing = true;
|
|
490
|
+
while (hydrationQueue.length > 0) {
|
|
491
|
+
const task = hydrationQueue.shift();
|
|
492
|
+
await task();
|
|
493
|
+
}
|
|
494
|
+
isProcessing = false;
|
|
495
|
+
}
|
|
496
|
+
function deserializeIslandProps(container) {
|
|
497
|
+
const script = container.querySelector(":scope > script[data-v-island-props]");
|
|
498
|
+
if (!script || !script.textContent) {
|
|
499
|
+
return {};
|
|
500
|
+
}
|
|
501
|
+
try {
|
|
502
|
+
return JSON.parse(script.textContent);
|
|
503
|
+
} catch {
|
|
504
|
+
return {};
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function hydrateIslands(registry) {
|
|
508
|
+
const elements = document.querySelectorAll("[data-v-island]");
|
|
509
|
+
const registryKeys = Object.keys(registry);
|
|
510
|
+
for (const el of elements) {
|
|
511
|
+
if (el.hasAttribute("data-v-hydrated"))
|
|
512
|
+
continue;
|
|
513
|
+
const islandId = el.getAttribute("data-v-island");
|
|
514
|
+
if (!islandId)
|
|
515
|
+
continue;
|
|
516
|
+
const loader = registry[islandId];
|
|
517
|
+
if (!loader) {
|
|
518
|
+
console.error(`[vertz] Island "${islandId}" not found in registry. Available: [${registryKeys.join(", ")}]`);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
const props = deserializeIslandProps(el);
|
|
522
|
+
const doHydrate = () => {
|
|
523
|
+
hydrationQueue.push(async () => {
|
|
524
|
+
try {
|
|
525
|
+
const mod = await loader();
|
|
526
|
+
const result = mod.default(props, el);
|
|
527
|
+
if (result instanceof Node) {
|
|
528
|
+
const children = Array.from(el.childNodes);
|
|
529
|
+
for (const child of children) {
|
|
530
|
+
if (child instanceof Element && child.hasAttribute("data-v-island-props")) {
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
el.removeChild(child);
|
|
534
|
+
}
|
|
535
|
+
el.appendChild(result);
|
|
536
|
+
}
|
|
537
|
+
el.setAttribute("data-v-hydrated", "");
|
|
538
|
+
} catch (error) {
|
|
539
|
+
console.error(`[vertz] Failed to hydrate island "${islandId}":`, error);
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
processQueue();
|
|
543
|
+
};
|
|
544
|
+
autoStrategy(el, doHydrate);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
482
547
|
// src/query/index.ts
|
|
483
548
|
import { isQueryDescriptor } from "@vertz/fetch";
|
|
484
549
|
|
|
485
|
-
export { onAnimationsComplete, keyframes, ANIMATION_DURATION, ANIMATION_EASING, fadeIn, fadeOut, zoomIn, zoomOut, slideInFromTop, slideInFromBottom, slideOutToTop, slideOutToBottom, slideInFromLeft, slideInFromRight, slideOutToLeft, slideOutToRight, accordionDown, accordionUp, palettes, resolveComponent, deserializeProps, hydrate, isQueryDescriptor };
|
|
550
|
+
export { onAnimationsComplete, keyframes, ANIMATION_DURATION, ANIMATION_EASING, fadeIn, fadeOut, zoomIn, zoomOut, slideInFromTop, slideInFromBottom, slideOutToTop, slideOutToBottom, slideInFromLeft, slideInFromRight, slideOutToLeft, slideOutToRight, accordionDown, accordionUp, palettes, resolveComponent, deserializeProps, hydrate, hydrateIslands, isQueryDescriptor };
|