@vertz/ui-server 0.2.36 → 0.2.38

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.
@@ -1814,7 +1814,8 @@ function createRequestContext(url) {
1814
1814
  queryCache: new MemoryCache({ maxSize: Infinity }),
1815
1815
  inflight: new Map,
1816
1816
  queries: [],
1817
- errors: []
1817
+ errors: [],
1818
+ cssTracker: new Set
1818
1819
  };
1819
1820
  }
1820
1821
  var domShimInstalled = false;
@@ -1839,7 +1840,9 @@ function collectCSS(themeCss, module) {
1839
1840
  for (const s of module.styles)
1840
1841
  alreadyIncluded.add(s);
1841
1842
  }
1842
- const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
1843
+ const ssrCtx = ssrStorage.getStore();
1844
+ const rawComponentCss = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : module.getInjectedCSS?.() ?? [];
1845
+ const componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
1843
1846
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
1844
1847
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
1845
1848
  `)}</style>` : "";
@@ -2456,7 +2459,9 @@ function collectCSS2(themeCss, module) {
2456
2459
  for (const s of module.styles)
2457
2460
  alreadyIncluded.add(s);
2458
2461
  }
2459
- const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
2462
+ const ssrCtx = ssrStorage.getStore();
2463
+ const rawComponentCss = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : module.getInjectedCSS?.() ?? [];
2464
+ const componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
2460
2465
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
2461
2466
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
2462
2467
  `)}</style>` : "";
@@ -1159,6 +1159,7 @@ function createVertzBunPlugin(options) {
1159
1159
  if (imageQueue.length > 0) {
1160
1160
  await Promise.all(imageQueue.map((opts) => processImage({ ...opts, fit: opts.fit })));
1161
1161
  }
1162
+ let nativeCss;
1162
1163
  const compileResult = nativeCompiler ? (() => {
1163
1164
  if (!nativeManifestWarningLogged && manifests.size > 0) {
1164
1165
  nativeManifestWarningLogged = true;
@@ -1172,6 +1173,9 @@ function createVertzBunPlugin(options) {
1172
1173
  target: options?.target,
1173
1174
  fastRefresh: false
1174
1175
  });
1176
+ if (nativeResult.css) {
1177
+ nativeCss = nativeResult.css;
1178
+ }
1175
1179
  return {
1176
1180
  code: nativeResult.code,
1177
1181
  map: nativeResult.map ? JSON.parse(nativeResult.map) : { version: 3, sources: [], mappings: "", names: [] },
@@ -1197,8 +1201,15 @@ function createVertzBunPlugin(options) {
1197
1201
  mapsToChain.push(routeSplitMap);
1198
1202
  }
1199
1203
  const remapped = remapping(mapsToChain, () => null);
1200
- const extraction = cssExtractor.extract(source, args.path);
1204
+ const extraction = nativeCss ? { css: nativeCss, blockNames: [] } : cssExtractor.extract(source, args.path);
1201
1205
  let cssImportLine = "";
1206
+ let nativeCssInjection = "";
1207
+ if (nativeCss && extraction.css.length > 0) {
1208
+ const escaped = extraction.css.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
1209
+ nativeCssInjection = `import { injectCSS as __injectCSS } from '@vertz/ui';
1210
+ __injectCSS(\`${escaped}\`);
1211
+ `;
1212
+ }
1202
1213
  if (extraction.css.length > 0) {
1203
1214
  fileExtractions.set(args.path, extraction);
1204
1215
  if (hmr) {
@@ -1224,6 +1235,9 @@ function createVertzBunPlugin(options) {
1224
1235
  }
1225
1236
  }
1226
1237
  let contents = "";
1238
+ if (nativeCssInjection) {
1239
+ contents += nativeCssInjection;
1240
+ }
1227
1241
  if (cssImportLine) {
1228
1242
  contents += cssImportLine;
1229
1243
  }
package/dist/index.d.ts CHANGED
@@ -513,8 +513,10 @@ interface AotRouteMapEntry {
513
513
  renderFn: string;
514
514
  /** Component names that need runtime fallback rendering. */
515
515
  holes: string[];
516
- /** Query cache keys this route reads via ctx.getData(). */
516
+ /** Query cache keys this route reads via ctx.getData(). May contain ${paramName} placeholders. */
517
517
  queryKeys: string[];
518
+ /** Route param names referenced in queryKeys. Present only when queryKeys have ${...} placeholders. */
519
+ paramBindings?: string[];
518
520
  }
519
521
  interface AotBuildManifest {
520
522
  components: Record<string, AotBuildComponentEntry>;
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createSSRHandler,
3
3
  loadAotManifest
4
- } from "./shared/chunk-hjsbx25c.js";
4
+ } from "./shared/chunk-595trxsn.js";
5
5
  import {
6
6
  createNodeHandler
7
- } from "./shared/chunk-9s2dppdh.js";
7
+ } from "./shared/chunk-d1a3ygv6.js";
8
8
  import {
9
9
  collectStreamChunks,
10
10
  compileThemeCached,
@@ -34,7 +34,7 @@ import {
34
34
  ssrRenderToString,
35
35
  streamToString,
36
36
  toPrefetchSession
37
- } from "./shared/chunk-wq2ke61r.js";
37
+ } from "./shared/chunk-2ymwre0k.js";
38
38
  import {
39
39
  clearGlobalSSRTimeout,
40
40
  createSSRAdapter,
@@ -109,11 +109,22 @@ function buildAotRouteMap(components, routes) {
109
109
  const comp = components[route.componentName];
110
110
  if (!comp || comp.tier === "runtime-fallback")
111
111
  continue;
112
- routeMap[route.pattern] = {
112
+ const paramNames = new Set;
113
+ for (const key of comp.queryKeys) {
114
+ const matches = key.matchAll(/\$\{(\w+)\}/g);
115
+ for (const m of matches) {
116
+ paramNames.add(m[1]);
117
+ }
118
+ }
119
+ const entry = {
113
120
  renderFn: `__ssr_${route.componentName}`,
114
121
  holes: comp.holes,
115
122
  queryKeys: comp.queryKeys
116
123
  };
124
+ if (paramNames.size > 0) {
125
+ entry.paramBindings = [...paramNames];
126
+ }
127
+ routeMap[route.pattern] = entry;
117
128
  }
118
129
  return routeMap;
119
130
  }
@@ -484,7 +495,8 @@ async function twoPassRender(options) {
484
495
  }
485
496
  const pendingQueries = queries.filter((q) => !q.resolved);
486
497
  const vnode = options.app();
487
- const collectedCSS = getInjectedCSS();
498
+ const ssrCtx = ssrStorage.getStore();
499
+ const collectedCSS = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : getInjectedCSS();
488
500
  const themeCss = options.theme ? compileThemeCached(options.theme, options.fallbackMetrics).css : "";
489
501
  const allStyles = [themeCss, ...options.styles ?? [], ...collectedCSS].filter(Boolean);
490
502
  const styleTags = allStyles.length > 0 ? `<style>${allStyles.join(`
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createNodeHandler
3
- } from "./shared/chunk-9s2dppdh.js";
4
- import"./shared/chunk-wq2ke61r.js";
3
+ } from "./shared/chunk-d1a3ygv6.js";
4
+ import"./shared/chunk-2ymwre0k.js";
5
5
  import"./shared/chunk-ybftdw1r.js";
6
6
  export {
7
7
  createNodeHandler
@@ -359,7 +359,8 @@ function createRequestContext(url) {
359
359
  queryCache: new MemoryCache({ maxSize: Infinity }),
360
360
  inflight: new Map,
361
361
  queries: [],
362
- errors: []
362
+ errors: [],
363
+ cssTracker: new Set
363
364
  };
364
365
  }
365
366
  var domShimInstalled = false;
@@ -384,7 +385,9 @@ function collectCSS(themeCss, module) {
384
385
  for (const s of module.styles)
385
386
  alreadyIncluded.add(s);
386
387
  }
387
- const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
388
+ const ssrCtx = ssrStorage.getStore();
389
+ const rawComponentCss = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : module.getInjectedCSS?.() ?? [];
390
+ const componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
388
391
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
389
392
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
390
393
  `)}</style>` : "";
@@ -1004,7 +1007,9 @@ function collectCSS2(themeCss, module) {
1004
1007
  for (const s of module.styles)
1005
1008
  alreadyIncluded.add(s);
1006
1009
  }
1007
- const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
1010
+ const ssrCtx = ssrStorage.getStore();
1011
+ const rawComponentCss = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : module.getInjectedCSS?.() ?? [];
1012
+ const componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
1008
1013
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
1009
1014
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
1010
1015
  `)}</style>` : "";
@@ -1076,14 +1081,15 @@ async function ssrRenderAot(module, url, options) {
1076
1081
  return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
1077
1082
  }
1078
1083
  const queryCache = new Map;
1079
- if (aotEntry.queryKeys && aotEntry.queryKeys.length > 0 && manifest?.routeEntries) {
1084
+ const resolvedQueryKeys = aotEntry.queryKeys ? resolveParamQueryKeys(aotEntry.queryKeys, match.params) : undefined;
1085
+ if (resolvedQueryKeys && resolvedQueryKeys.length > 0 && manifest?.routeEntries) {
1080
1086
  const apiClient = module.api;
1081
1087
  if (apiClient) {
1082
- await prefetchForAot(aotEntry.queryKeys, manifest.routeEntries, match, apiClient, ssrTimeout, queryCache);
1088
+ await prefetchForAot(resolvedQueryKeys, manifest.routeEntries, match, apiClient, ssrTimeout, queryCache);
1083
1089
  }
1084
1090
  }
1085
- if (aotEntry.queryKeys && aotEntry.queryKeys.length > 0 && options.aotDataResolver) {
1086
- const unresolvedKeys = aotEntry.queryKeys.filter((k) => !queryCache.has(k));
1091
+ if (resolvedQueryKeys && resolvedQueryKeys.length > 0 && options.aotDataResolver) {
1092
+ const unresolvedKeys = resolvedQueryKeys.filter((k) => !queryCache.has(k));
1087
1093
  if (unresolvedKeys.length > 0) {
1088
1094
  try {
1089
1095
  const resolved = await options.aotDataResolver(match.pattern, match.params, unresolvedKeys);
@@ -1095,8 +1101,8 @@ async function ssrRenderAot(module, url, options) {
1095
1101
  }
1096
1102
  }
1097
1103
  }
1098
- if (aotEntry.queryKeys && aotEntry.queryKeys.length > 0) {
1099
- const allKeysResolved = aotEntry.queryKeys.every((k) => queryCache.has(k));
1104
+ if (resolvedQueryKeys && resolvedQueryKeys.length > 0) {
1105
+ const allKeysResolved = resolvedQueryKeys.every((k) => queryCache.has(k));
1100
1106
  if (!allKeysResolved) {
1101
1107
  return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
1102
1108
  }
@@ -1114,7 +1120,13 @@ async function ssrRenderAot(module, url, options) {
1114
1120
  for (const [key, value] of queryCache) {
1115
1121
  data[key] = value;
1116
1122
  }
1117
- const html = aotEntry.render(data, ctx);
1123
+ let html;
1124
+ try {
1125
+ html = aotEntry.render(data, ctx);
1126
+ } catch (renderErr) {
1127
+ console.error("[SSR] AOT render failed for", match.pattern, "— falling back to single-pass:", renderErr instanceof Error ? renderErr.message : renderErr);
1128
+ return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
1129
+ }
1118
1130
  if (options.diagnostics && isAotDebugEnabled()) {
1119
1131
  try {
1120
1132
  const domResult = await ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
@@ -1180,6 +1192,9 @@ function unwrapResult2(result) {
1180
1192
  }
1181
1193
  return result;
1182
1194
  }
1195
+ function resolveParamQueryKeys(queryKeys, params) {
1196
+ return queryKeys.map((key) => key.replace(/\$\{(\w+)\}/g, (_, paramName) => params[paramName] ?? ""));
1197
+ }
1183
1198
  function isAotDebugEnabled() {
1184
1199
  const env = process.env.VERTZ_DEBUG;
1185
1200
  if (!env)
@@ -1212,7 +1227,9 @@ function collectCSSFromModule(module, fallbackMetrics) {
1212
1227
  for (const s of module.styles)
1213
1228
  alreadyIncluded.add(s);
1214
1229
  }
1215
- const componentCss = module.getInjectedCSS ? module.getInjectedCSS().filter((s) => !alreadyIncluded.has(s)) : [];
1230
+ const ssrCtx = ssrStorage.getStore();
1231
+ const rawComponentCss = ssrCtx?.cssTracker?.size ? Array.from(ssrCtx.cssTracker) : module.getInjectedCSS?.() ?? [];
1232
+ const componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
1216
1233
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
1217
1234
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
1218
1235
  `)}</style>` : "";
@@ -11,7 +11,7 @@ import {
11
11
  ssrRenderSinglePass,
12
12
  ssrStreamNavQueries,
13
13
  toPrefetchSession
14
- } from "./chunk-wq2ke61r.js";
14
+ } from "./chunk-2ymwre0k.js";
15
15
 
16
16
  // src/aot-manifest-loader.ts
17
17
  import { existsSync, readFileSync } from "node:fs";
@@ -10,7 +10,7 @@ import {
10
10
  ssrRenderSinglePass,
11
11
  ssrStreamNavQueries,
12
12
  toPrefetchSession
13
- } from "./chunk-wq2ke61r.js";
13
+ } from "./chunk-2ymwre0k.js";
14
14
 
15
15
  // src/node-handler.ts
16
16
  function createNodeHandler(options) {
package/dist/ssr/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createSSRHandler,
3
3
  loadAotManifest
4
- } from "../shared/chunk-hjsbx25c.js";
4
+ } from "../shared/chunk-595trxsn.js";
5
5
  import {
6
6
  injectIntoTemplate,
7
7
  ssrDiscoverQueries,
8
8
  ssrRenderToString
9
- } from "../shared/chunk-wq2ke61r.js";
9
+ } from "../shared/chunk-2ymwre0k.js";
10
10
  import"../shared/chunk-ybftdw1r.js";
11
11
  // src/prerender.ts
12
12
  async function discoverRoutes(module) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/ui-server",
3
- "version": "0.2.36",
3
+ "version": "0.2.38",
4
4
  "description": "Vertz UI server-side rendering runtime",
5
5
  "license": "MIT",
6
6
  "repository": {