@vertz/ui 0.2.36 → 0.2.37

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.
@@ -86,6 +86,13 @@ class MemoryCache {
86
86
  this._refs.set(key, count);
87
87
  this._orphans.delete(key);
88
88
  }
89
+ findByPrefix(prefix) {
90
+ for (const [k, v] of this._store) {
91
+ if (k.startsWith(prefix))
92
+ return { key: k, value: v };
93
+ }
94
+ return;
95
+ }
89
96
  release(key) {
90
97
  const current = this._refs.get(key);
91
98
  if (current === undefined)
@@ -1028,6 +1035,7 @@ function query(source, options = {}) {
1028
1035
  if (!isSSR() && initialData === undefined) {
1029
1036
  let hydrationKey;
1030
1037
  const hasSSRData = !!globalThis.__VERTZ_SSR_DATA__;
1038
+ let initDescriptorKey;
1031
1039
  if (customKey) {
1032
1040
  hydrationKey = customKey;
1033
1041
  } else if (hasSSRData) {
@@ -1035,6 +1043,7 @@ function query(source, options = {}) {
1035
1043
  const raw = callThunkWithCapture();
1036
1044
  if (raw !== null) {
1037
1045
  if (isQueryDescriptor(raw)) {
1046
+ initDescriptorKey = raw._key;
1038
1047
  if (raw._entity && !entityMeta) {
1039
1048
  entityMeta = raw._entity;
1040
1049
  }
@@ -1066,6 +1075,25 @@ function query(source, options = {}) {
1066
1075
  loading.value = false;
1067
1076
  ssrHydrated = true;
1068
1077
  }
1078
+ } else {
1079
+ const cached = cache.get(hydrationKey);
1080
+ if (cached !== undefined) {
1081
+ retainKey(hydrationKey);
1082
+ normalizeToEntityStore(cached);
1083
+ rawData.value = cached;
1084
+ loading.value = false;
1085
+ ssrHydrated = true;
1086
+ } else if (initDescriptorKey && "findByPrefix" in cache) {
1087
+ const mc = cache;
1088
+ const found = mc.findByPrefix(initDescriptorKey + "&") ?? mc.findByPrefix(initDescriptorKey + ":");
1089
+ if (found) {
1090
+ retainKey(found.key);
1091
+ normalizeToEntityStore(found.value);
1092
+ rawData.value = found.value;
1093
+ loading.value = false;
1094
+ ssrHydrated = true;
1095
+ }
1096
+ }
1069
1097
  }
1070
1098
  }
1071
1099
  if (!ssrHydrated && ssrHydrationCleanup !== null && isNavPrefetchActive()) {
@@ -1229,6 +1257,20 @@ function query(source, options = {}) {
1229
1257
  isFirst = false;
1230
1258
  return;
1231
1259
  }
1260
+ if (descriptorKey && "findByPrefix" in cache) {
1261
+ const mc = cache;
1262
+ const found = untrack(() => mc.findByPrefix(descriptorKey + "&") ?? mc.findByPrefix(descriptorKey + ":"));
1263
+ if (found) {
1264
+ retainKey(found.key);
1265
+ untrack(() => {
1266
+ normalizeToEntityStore(found.value);
1267
+ rawData.value = found.value;
1268
+ loading.value = false;
1269
+ });
1270
+ isFirst = false;
1271
+ return;
1272
+ }
1273
+ }
1232
1274
  }
1233
1275
  isFirst = false;
1234
1276
  return;
@@ -9,6 +9,7 @@ import {
9
9
  isBrowser
10
10
  } from "./chunk-sjypbv24.js";
11
11
  import {
12
+ batch,
12
13
  getSSRContext,
13
14
  signal
14
15
  } from "./chunk-1yd6jfw5.js";
@@ -466,25 +467,29 @@ function createRouter(routes, initialUrlOrOptions, maybeOptions) {
466
467
  const abort = new AbortController;
467
468
  currentAbort = abort;
468
469
  const match = preMatch !== undefined ? preMatch : matchRoute(routes, url2);
470
+ if (match) {
471
+ visitedUrls.add(normalizeUrl(url2));
472
+ }
469
473
  if (transitionConfig) {
470
474
  await withViewTransition(() => {
471
- current.value = match;
475
+ batch(() => {
476
+ searchParams.value = match?.search ?? {};
477
+ current.value = match;
478
+ });
472
479
  }, transitionConfig);
473
480
  } else {
474
- current.value = match;
481
+ batch(() => {
482
+ searchParams.value = match?.search ?? {};
483
+ current.value = match;
484
+ });
475
485
  }
476
486
  if (match) {
477
- visitedUrls.add(normalizeUrl(url2));
478
- searchParams.value = match.search;
479
487
  if (!skipLoaders) {
480
488
  await runLoaders(match, gen, abort.signal);
481
489
  }
482
- } else {
483
- searchParams.value = {};
484
- if (gen === navigationGen) {
485
- loaderData.value = [];
486
- loaderError.value = null;
487
- }
490
+ } else if (gen === navigationGen) {
491
+ loaderData.value = [];
492
+ loaderError.value = null;
488
493
  }
489
494
  }
490
495
  async function navigate(input) {
@@ -680,12 +680,15 @@ var vertzSheets = new Set;
680
680
  function injectCSS(cssText) {
681
681
  if (!cssText)
682
682
  return;
683
- const isSSR = getSSRContext() !== undefined;
683
+ const ssrCtx = getSSRContext();
684
+ const isSSR = ssrCtx !== undefined;
684
685
  if (!isSSR && injectedCSS.has(cssText))
685
686
  return;
686
687
  injectedCSS.add(cssText);
687
- if (isSSR)
688
+ if (isSSR) {
689
+ ssrCtx.cssTracker?.add(cssText);
688
690
  return;
691
+ }
689
692
  if (typeof document === "undefined")
690
693
  return;
691
694
  if (typeof CSSStyleSheet !== "undefined" && document.adoptedStyleSheets !== undefined) {
@@ -1135,56 +1138,52 @@ function variants(config) {
1135
1138
  const { base, variants: variantDefs, defaultVariants, compoundVariants } = config;
1136
1139
  const filePath = deriveConfigKey(config);
1137
1140
  const baseResult = css({ base }, filePath);
1138
- const variantResults = {};
1141
+ const variantCache = new Map;
1142
+ const variantStyles = {};
1139
1143
  for (const [variantName, options] of Object.entries(variantDefs)) {
1140
- variantResults[variantName] = {};
1144
+ variantStyles[variantName] = {};
1141
1145
  for (const [optionName, styles] of Object.entries(options)) {
1142
1146
  if (styles.length > 0) {
1143
- const blockName = `${variantName}_${optionName}`;
1144
- const result = css({ [blockName]: styles }, filePath);
1145
- const className = result[blockName];
1146
- if (className) {
1147
- variantResults[variantName][optionName] = {
1148
- className,
1149
- css: result.css
1150
- };
1151
- }
1147
+ variantStyles[variantName][optionName] = styles;
1152
1148
  }
1153
1149
  }
1154
1150
  }
1155
- const compoundResults = [];
1156
- if (compoundVariants) {
1157
- for (let i = 0;i < compoundVariants.length; i++) {
1158
- const compound = compoundVariants[i];
1159
- if (!compound)
1160
- continue;
1161
- const { styles, ...conditions } = compound;
1162
- if (styles.length > 0) {
1163
- const blockName = `compound_${i}`;
1164
- const result = css({ [blockName]: styles }, filePath);
1165
- const className = result[blockName];
1166
- if (className) {
1167
- compoundResults.push({
1168
- conditions,
1169
- className,
1170
- css: result.css
1171
- });
1172
- }
1173
- }
1151
+ const compoundCache = new Map;
1152
+ function ensureVariantOption(variantName, optionName) {
1153
+ const cacheKey = `${variantName}::${optionName}`;
1154
+ const cached = variantCache.get(cacheKey);
1155
+ if (cached)
1156
+ return cached.className;
1157
+ const styles = variantStyles[variantName]?.[optionName];
1158
+ if (!styles)
1159
+ return;
1160
+ const blockName = cacheKey;
1161
+ const result = css({ [blockName]: styles }, filePath);
1162
+ const className = result[blockName];
1163
+ if (className) {
1164
+ variantCache.set(cacheKey, { className, css: result.css });
1165
+ return className;
1174
1166
  }
1167
+ return;
1175
1168
  }
1176
- const allCss = [];
1177
- if (baseResult.css)
1178
- allCss.push(baseResult.css);
1179
- for (const options of Object.values(variantResults)) {
1180
- for (const result of Object.values(options)) {
1181
- if (result.css)
1182
- allCss.push(result.css);
1169
+ function ensureCompoundVariant(index, compound, resolved) {
1170
+ const { styles, ...conditions } = compound;
1171
+ const matches = Object.entries(conditions).every(([key, value]) => resolved[key] === String(value));
1172
+ if (!matches)
1173
+ return;
1174
+ const cached = compoundCache.get(index);
1175
+ if (cached)
1176
+ return cached.className;
1177
+ if (styles.length === 0)
1178
+ return;
1179
+ const blockName = `compound_${index}`;
1180
+ const result = css({ [blockName]: styles }, filePath);
1181
+ const className = result[blockName];
1182
+ if (className) {
1183
+ compoundCache.set(index, { className, css: result.css });
1184
+ return className;
1183
1185
  }
1184
- }
1185
- for (const result of compoundResults) {
1186
- if (result.css)
1187
- allCss.push(result.css);
1186
+ return;
1188
1187
  }
1189
1188
  const fn = (props) => {
1190
1189
  const classNames = [];
@@ -1208,26 +1207,43 @@ function variants(config) {
1208
1207
  }
1209
1208
  }
1210
1209
  for (const [variantName, optionName] of Object.entries(resolved)) {
1211
- const variantGroup = variantResults[variantName];
1212
- if (variantGroup) {
1213
- const result = variantGroup[optionName];
1214
- if (result) {
1215
- classNames.push(result.className);
1216
- }
1210
+ const className = ensureVariantOption(variantName, optionName);
1211
+ if (className) {
1212
+ classNames.push(className);
1217
1213
  }
1218
1214
  }
1219
- for (const compound of compoundResults) {
1220
- const matches = Object.entries(compound.conditions).every(([key, value]) => {
1221
- return resolved[key] === String(value);
1222
- });
1223
- if (matches) {
1224
- classNames.push(compound.className);
1215
+ if (compoundVariants) {
1216
+ for (let i = 0;i < compoundVariants.length; i++) {
1217
+ const compound = compoundVariants[i];
1218
+ if (!compound)
1219
+ continue;
1220
+ const className = ensureCompoundVariant(i, compound, resolved);
1221
+ if (className) {
1222
+ classNames.push(className);
1223
+ }
1225
1224
  }
1226
1225
  }
1227
1226
  return classNames.join(" ");
1228
1227
  };
1229
- fn.css = allCss.join(`
1228
+ Object.defineProperty(fn, "css", {
1229
+ get() {
1230
+ const parts = [];
1231
+ if (baseResult.css)
1232
+ parts.push(baseResult.css);
1233
+ for (const entry of variantCache.values()) {
1234
+ if (entry.css)
1235
+ parts.push(entry.css);
1236
+ }
1237
+ for (const entry of compoundCache.values()) {
1238
+ if (entry.css)
1239
+ parts.push(entry.css);
1240
+ }
1241
+ return parts.join(`
1230
1242
  `);
1243
+ },
1244
+ enumerable: false,
1245
+ configurable: false
1246
+ });
1231
1247
  return fn;
1232
1248
  }
1233
1249
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  injectCSS
3
- } from "./chunk-zkh9sysw.js";
3
+ } from "./chunk-g60cswzm.js";
4
4
  import {
5
5
  createContext
6
6
  } from "./chunk-1yd6jfw5.js";
@@ -287,12 +287,16 @@ interface VariantsConfig<V extends VariantDefinitions> {
287
287
  /** The function returned by variants(). Takes optional variant props and returns a className string. */
288
288
  interface VariantFunction<V extends VariantDefinitions> {
289
289
  (props?: VariantProps<V>): string;
290
- /** The extracted CSS for all variant combinations. */
290
+ /** @internal The extracted CSS for variant combinations compiled so far. */
291
291
  css: string;
292
292
  }
293
293
  /**
294
294
  * Create a typed variant function from a config object.
295
295
  *
296
+ * Variant option CSS is compiled lazily on first use — only the base styles
297
+ * are compiled eagerly. This ensures unused variant options never produce CSS,
298
+ * reducing SSR response size for pages that use a subset of available variants.
299
+ *
296
300
  * @param config - Variant configuration (base, variants, defaultVariants, compoundVariants).
297
301
  * @returns A function that accepts variant props and returns a className string.
298
302
  */
@@ -8,7 +8,7 @@ import {
8
8
  globalCss,
9
9
  s,
10
10
  variants
11
- } from "../../shared/chunk-zkh9sysw.js";
11
+ } from "../../shared/chunk-g60cswzm.js";
12
12
  import"../../shared/chunk-dh32wkrv.js";
13
13
  import"../../shared/chunk-h1fsr8kv.js";
14
14
  import"../../shared/chunk-1yd6jfw5.js";
@@ -632,12 +632,16 @@ interface VariantsConfig<V extends VariantDefinitions> {
632
632
  /** The function returned by variants(). Takes optional variant props and returns a className string. */
633
633
  interface VariantFunction<V extends VariantDefinitions> {
634
634
  (props?: VariantProps<V>): string;
635
- /** The extracted CSS for all variant combinations. */
635
+ /** @internal The extracted CSS for variant combinations compiled so far. */
636
636
  css: string;
637
637
  }
638
638
  /**
639
639
  * Create a typed variant function from a config object.
640
640
  *
641
+ * Variant option CSS is compiled lazily on first use — only the base styles
642
+ * are compiled eagerly. This ensures unused variant options never produce CSS,
643
+ * reducing SSR response size for pages that use a subset of available variants.
644
+ *
641
645
  * @param config - Variant configuration (base, variants, defaultVariants, compoundVariants).
642
646
  * @returns A function that accepts variant props and returns a className string.
643
647
  */
package/dist/src/index.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  slideOutToTop,
26
26
  zoomIn,
27
27
  zoomOut
28
- } from "../shared/chunk-xyg724n1.js";
28
+ } from "../shared/chunk-rxx916ae.js";
29
29
  import {
30
30
  ErrorBoundary,
31
31
  Link,
@@ -45,7 +45,7 @@ import {
45
45
  } from "../shared/chunk-mntc8w0g.js";
46
46
  import {
47
47
  createRouter
48
- } from "../shared/chunk-pkhyqntn.js";
48
+ } from "../shared/chunk-9ybtmy8t.js";
49
49
  import {
50
50
  defineRoutes
51
51
  } from "../shared/chunk-ah86rm07.js";
@@ -66,7 +66,7 @@ import {
66
66
  query,
67
67
  registerRelationSchema,
68
68
  resetRelationSchemas_TEST_ONLY
69
- } from "../shared/chunk-7dngshyk.js";
69
+ } from "../shared/chunk-4eatzp0p.js";
70
70
  import"../shared/chunk-jrtrk5z4.js";
71
71
  import {
72
72
  ThemeProvider,
@@ -83,7 +83,7 @@ import {
83
83
  resolveChildren,
84
84
  s,
85
85
  variants
86
- } from "../shared/chunk-zkh9sysw.js";
86
+ } from "../shared/chunk-g60cswzm.js";
87
87
  import {
88
88
  RENDER_NODE_BRAND,
89
89
  __append,
@@ -609,6 +609,11 @@ declare class MemoryCache<T = unknown> implements CacheStore<T> {
609
609
  clear(): void;
610
610
  /** Mark a cache key as actively used by a query instance. */
611
611
  retain(key: string): void;
612
+ /** Find the first entry whose key starts with `prefix`. */
613
+ findByPrefix(prefix: string): {
614
+ key: string;
615
+ value: T;
616
+ } | undefined;
612
617
  /** Release a cache key when a query instance disposes or changes key. */
613
618
  release(key: string): void;
614
619
  }
@@ -1134,6 +1139,13 @@ interface SSRRenderContext {
1134
1139
  ssrRedirect?: {
1135
1140
  to: string;
1136
1141
  };
1142
+ /**
1143
+ * Per-request CSS tracker for render-scoped collection.
1144
+ * Populated by injectCSS() during SSR render. collectCSS() reads
1145
+ * from this Set instead of the global injectedCSS to ensure each
1146
+ * response only includes CSS for components actually rendered.
1147
+ */
1148
+ cssTracker?: Set<string>;
1137
1149
  }
1138
1150
  /** Auth state injected into SSRRenderContext by the server. */
1139
1151
  type SSRAuth = ({
@@ -3,7 +3,7 @@ import {
3
3
  deserializeProps,
4
4
  onAnimationsComplete,
5
5
  resolveComponent
6
- } from "../shared/chunk-xyg724n1.js";
6
+ } from "../shared/chunk-rxx916ae.js";
7
7
  import {
8
8
  __discardMountFrame,
9
9
  __flushMountFrame,
@@ -20,7 +20,7 @@ import {
20
20
  MemoryCache,
21
21
  QueryEnvelopeStore,
22
22
  deriveKey
23
- } from "../shared/chunk-7dngshyk.js";
23
+ } from "../shared/chunk-4eatzp0p.js";
24
24
  import"../shared/chunk-jrtrk5z4.js";
25
25
  import {
26
26
  ALIGNMENT_MAP,
@@ -41,7 +41,7 @@ import {
41
41
  SIZE_KEYWORDS,
42
42
  SPACING_SCALE,
43
43
  compileTheme
44
- } from "../shared/chunk-zkh9sysw.js";
44
+ } from "../shared/chunk-g60cswzm.js";
45
45
  import {
46
46
  RENDER_NODE_BRAND,
47
47
  __append,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  query
3
- } from "../../shared/chunk-7dngshyk.js";
3
+ } from "../../shared/chunk-4eatzp0p.js";
4
4
  import"../../shared/chunk-jrtrk5z4.js";
5
5
  import"../../shared/chunk-pv0apt9z.js";
6
6
  import"../../shared/chunk-sjypbv24.js";
@@ -10,7 +10,7 @@ import {
10
10
  import"../../shared/chunk-mntc8w0g.js";
11
11
  import {
12
12
  createRouter
13
- } from "../../shared/chunk-pkhyqntn.js";
13
+ } from "../../shared/chunk-9ybtmy8t.js";
14
14
  import {
15
15
  defineRoutes
16
16
  } from "../../shared/chunk-ah86rm07.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createRouter
3
- } from "../../shared/chunk-pkhyqntn.js";
3
+ } from "../../shared/chunk-9ybtmy8t.js";
4
4
  import {
5
5
  defineRoutes
6
6
  } from "../../shared/chunk-ah86rm07.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/ui",
3
- "version": "0.2.36",
3
+ "version": "0.2.37",
4
4
  "description": "Vertz UI framework — signals, components, JSX runtime",
5
5
  "license": "MIT",
6
6
  "repository": {