@vertz/ui-server 0.2.38 → 0.2.41

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.
@@ -335,13 +335,102 @@ function createSSRDataChunk(key, data, nonce) {
335
335
  // src/ssr-render.ts
336
336
  import { compileTheme } from "@vertz/ui";
337
337
  import { EntityStore, MemoryCache, QueryEnvelopeStore } from "@vertz/ui/internals";
338
+
339
+ // src/css-filter.ts
340
+ function extractClassNamesFromHTML(html) {
341
+ const classes = new Set;
342
+ const attrRegex = /\bclass(?:Name)?="([^"]*)"/g;
343
+ let match;
344
+ while ((match = attrRegex.exec(html)) !== null) {
345
+ const value = match[1];
346
+ for (const cls of value.split(/\s+/)) {
347
+ if (cls)
348
+ classes.add(cls);
349
+ }
350
+ }
351
+ return classes;
352
+ }
353
+ function extractClassSelectorsFromCSS(css) {
354
+ const selectors = new Set;
355
+ const selectorRegex = /\.([\w-]+)/g;
356
+ let match;
357
+ while ((match = selectorRegex.exec(css)) !== null) {
358
+ selectors.add(match[1]);
359
+ }
360
+ return selectors;
361
+ }
362
+ function isKeyframesBlock(css) {
363
+ return /^\s*@keyframes\s/.test(css);
364
+ }
365
+ function hasOnlyClassSelectors(css) {
366
+ let stripped = css.replace(/\/\*[\s\S]*?\*\//g, "");
367
+ stripped = stripped.replace(/@keyframes\s+[\w-]+\s*\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}/g, "");
368
+ stripped = stripped.replace(/@[\w-]+\s*\([^)]*\)\s*\{/g, "").replace(/^\s*\}/gm, "");
369
+ const ruleRegex = /([^{}]+)\{/g;
370
+ let match;
371
+ let foundAnySelector = false;
372
+ while ((match = ruleRegex.exec(stripped)) !== null) {
373
+ const selector = match[1].trim();
374
+ if (!selector)
375
+ continue;
376
+ foundAnySelector = true;
377
+ if (!selector.startsWith(".")) {
378
+ return false;
379
+ }
380
+ }
381
+ return foundAnySelector;
382
+ }
383
+ function filterCSSByHTML(html, cssStrings) {
384
+ if (cssStrings.length === 0 || !html)
385
+ return [];
386
+ const htmlClasses = extractClassNamesFromHTML(html);
387
+ const kept = [];
388
+ const pendingKeyframes = [];
389
+ for (const css of cssStrings) {
390
+ if (isKeyframesBlock(css)) {
391
+ const nameMatch = /@keyframes\s+([\w-]+)/.exec(css);
392
+ if (nameMatch) {
393
+ pendingKeyframes.push({ css, name: nameMatch[1] });
394
+ }
395
+ continue;
396
+ }
397
+ if (!hasOnlyClassSelectors(css)) {
398
+ kept.push(css);
399
+ continue;
400
+ }
401
+ const cssClasses = extractClassSelectorsFromCSS(css);
402
+ let used = false;
403
+ for (const cls of cssClasses) {
404
+ if (htmlClasses.has(cls)) {
405
+ used = true;
406
+ break;
407
+ }
408
+ }
409
+ if (used)
410
+ kept.push(css);
411
+ }
412
+ if (pendingKeyframes.length > 0) {
413
+ const survivingCss = kept.join(`
414
+ `);
415
+ for (const kf of pendingKeyframes) {
416
+ if (survivingCss.includes(kf.name)) {
417
+ kept.push(kf.css);
418
+ }
419
+ }
420
+ }
421
+ return kept;
422
+ }
423
+
424
+ // src/ssr-render.ts
338
425
  var compiledThemeCache = new WeakMap;
426
+ var compiledThemeWithMetricsCache = new WeakMap;
339
427
  function compileThemeCached(theme, fallbackMetrics) {
340
- const cached = compiledThemeCache.get(theme);
428
+ const cache = fallbackMetrics ? compiledThemeWithMetricsCache : compiledThemeCache;
429
+ const cached = cache.get(theme);
341
430
  if (cached)
342
431
  return cached;
343
432
  const compiled = compileTheme(theme, { fallbackMetrics });
344
- compiledThemeCache.set(theme, compiled);
433
+ cache.set(theme, compiled);
345
434
  return compiled;
346
435
  }
347
436
  function createRequestContext(url) {
@@ -377,7 +466,7 @@ function resolveAppFactory(module) {
377
466
  }
378
467
  return createApp;
379
468
  }
380
- function collectCSS(themeCss, module) {
469
+ function collectCSS(themeCss, module, renderedHtml) {
381
470
  const alreadyIncluded = new Set;
382
471
  if (themeCss)
383
472
  alreadyIncluded.add(themeCss);
@@ -386,8 +475,13 @@ function collectCSS(themeCss, module) {
386
475
  alreadyIncluded.add(s);
387
476
  }
388
477
  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));
478
+ const tracker = ssrCtx?.cssTracker;
479
+ const useTracker = tracker && tracker.size > 0;
480
+ const rawComponentCss = useTracker ? Array.from(tracker) : module.getInjectedCSS?.() ?? [];
481
+ let componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
482
+ if (!useTracker && componentCss.length > 0 && renderedHtml) {
483
+ componentCss = filterCSSByHTML(renderedHtml, componentCss);
484
+ }
391
485
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
392
486
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
393
487
  `)}</style>` : "";
@@ -468,7 +562,7 @@ async function ssrRenderToString(module, url, options) {
468
562
  const vnode = toVNode(app);
469
563
  const stream = renderToStream(vnode);
470
564
  const html = await streamToString(stream);
471
- const css = collectCSS(themeCss, module);
565
+ const css = collectCSS(themeCss, module, html);
472
566
  const ssrData = resolvedQueries.length > 0 ? resolvedQueries.map(({ key, data }) => ({ key, data })) : [];
473
567
  return {
474
568
  html,
@@ -718,7 +812,7 @@ async function ssrRenderSinglePass(module, url, options) {
718
812
  const vnode = toVNode(app);
719
813
  const stream = renderToStream(vnode);
720
814
  const html = await streamToString(stream);
721
- const css = collectCSS2(themeCss, module);
815
+ const css = collectCSS2(themeCss, module, html);
722
816
  const ssrData = discoveredData.resolvedQueries.map(({ key, data }) => ({
723
817
  key,
724
818
  data
@@ -775,7 +869,7 @@ async function ssrRenderProgressive(module, url, options) {
775
869
  const app = createApp();
776
870
  const vnode = toVNode(app);
777
871
  const renderStream = renderToStream(vnode);
778
- const css = collectCSS2(themeCss, module);
872
+ const css = collectCSS2(themeCss, module, "");
779
873
  const ssrData = discoveryResult.resolvedQueries.map(({ key, data }) => ({
780
874
  key,
781
875
  data
@@ -926,7 +1020,7 @@ async function renderWithPrefetchedData(module, normalizedUrl, prefetchedData, o
926
1020
  matchedRoutePatterns: renderCtx.matchedRoutePatterns
927
1021
  };
928
1022
  }
929
- const css = collectCSS2(themeCss, module);
1023
+ const css = collectCSS2(themeCss, module, html);
930
1024
  const ssrData = data.resolvedQueries.map(({ key, data: d }) => ({
931
1025
  key,
932
1026
  data: d
@@ -999,7 +1093,7 @@ function extractMethodFromKey(key) {
999
1093
  const segments = cleanPath.split("/").filter(Boolean);
1000
1094
  return segments.length > 1 ? "get" : "list";
1001
1095
  }
1002
- function collectCSS2(themeCss, module) {
1096
+ function collectCSS2(themeCss, module, renderedHtml) {
1003
1097
  const alreadyIncluded = new Set;
1004
1098
  if (themeCss)
1005
1099
  alreadyIncluded.add(themeCss);
@@ -1008,8 +1102,13 @@ function collectCSS2(themeCss, module) {
1008
1102
  alreadyIncluded.add(s);
1009
1103
  }
1010
1104
  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));
1105
+ const tracker = ssrCtx?.cssTracker;
1106
+ const useTracker = tracker && tracker.size > 0;
1107
+ const rawComponentCss = useTracker ? Array.from(tracker) : module.getInjectedCSS?.() ?? [];
1108
+ let componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
1109
+ if (!useTracker && componentCss.length > 0 && renderedHtml) {
1110
+ componentCss = filterCSSByHTML(renderedHtml, componentCss);
1111
+ }
1013
1112
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
1014
1113
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
1015
1114
  `)}</style>` : "";
@@ -1081,7 +1180,8 @@ async function ssrRenderAot(module, url, options) {
1081
1180
  return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
1082
1181
  }
1083
1182
  const queryCache = new Map;
1084
- const resolvedQueryKeys = aotEntry.queryKeys ? resolveParamQueryKeys(aotEntry.queryKeys, match.params) : undefined;
1183
+ const searchParams = extractSearchParams(normalizedUrl);
1184
+ const resolvedQueryKeys = aotEntry.queryKeys ? resolveParamQueryKeys(aotEntry.queryKeys, match.params, searchParams) : undefined;
1085
1185
  if (resolvedQueryKeys && resolvedQueryKeys.length > 0 && manifest?.routeEntries) {
1086
1186
  const apiClient = module.api;
1087
1187
  if (apiClient) {
@@ -1092,7 +1192,7 @@ async function ssrRenderAot(module, url, options) {
1092
1192
  const unresolvedKeys = resolvedQueryKeys.filter((k) => !queryCache.has(k));
1093
1193
  if (unresolvedKeys.length > 0) {
1094
1194
  try {
1095
- const resolved = await options.aotDataResolver(match.pattern, match.params, unresolvedKeys);
1195
+ const resolved = await options.aotDataResolver(match.pattern, match.params, unresolvedKeys, searchParams);
1096
1196
  for (const [key, value] of resolved) {
1097
1197
  queryCache.set(key, value);
1098
1198
  }
@@ -1114,7 +1214,8 @@ async function ssrRenderAot(module, url, options) {
1114
1214
  holes,
1115
1215
  getData: (key) => queryCache.get(key),
1116
1216
  session: options.prefetchSession,
1117
- params: match.params
1217
+ params: match.params,
1218
+ searchParams
1118
1219
  };
1119
1220
  const data = {};
1120
1221
  for (const [key, value] of queryCache) {
@@ -1127,6 +1228,23 @@ async function ssrRenderAot(module, url, options) {
1127
1228
  console.error("[SSR] AOT render failed for", match.pattern, "— falling back to single-pass:", renderErr instanceof Error ? renderErr.message : renderErr);
1128
1229
  return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
1129
1230
  }
1231
+ if (aotManifest.app) {
1232
+ try {
1233
+ const appHoleNames = aotManifest.app.holes.filter((h) => h !== "RouterView");
1234
+ const appHoles = createHoles(appHoleNames, module, normalizedUrl, queryCache, options.ssrAuth);
1235
+ appHoles.RouterView = () => html;
1236
+ const appCtx = {
1237
+ holes: appHoles,
1238
+ getData: (key) => queryCache.get(key),
1239
+ session: options.prefetchSession,
1240
+ params: match.params,
1241
+ searchParams
1242
+ };
1243
+ html = aotManifest.app.render(data, appCtx);
1244
+ } catch (appErr) {
1245
+ console.error("[SSR] AOT app shell render failed — serving page without layout:", appErr instanceof Error ? appErr.message : appErr);
1246
+ }
1247
+ }
1130
1248
  if (options.diagnostics && isAotDebugEnabled()) {
1131
1249
  try {
1132
1250
  const domResult = await ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
@@ -1135,7 +1253,8 @@ async function ssrRenderAot(module, url, options) {
1135
1253
  }
1136
1254
  } catch {}
1137
1255
  }
1138
- const css = collectCSSFromModule(module, options.fallbackMetrics);
1256
+ const routeCss = mergeRouteCss(aotEntry.css, aotManifest.app?.css);
1257
+ const css = collectCSSFromModule(module, html, options.fallbackMetrics, routeCss, match.pattern);
1139
1258
  const ssrData = [];
1140
1259
  for (const [key, data2] of queryCache) {
1141
1260
  ssrData.push({ key, data: data2 });
@@ -1192,8 +1311,20 @@ function unwrapResult2(result) {
1192
1311
  }
1193
1312
  return result;
1194
1313
  }
1195
- function resolveParamQueryKeys(queryKeys, params) {
1196
- return queryKeys.map((key) => key.replace(/\$\{(\w+)\}/g, (_, paramName) => params[paramName] ?? ""));
1314
+ function resolveParamQueryKeys(queryKeys, params, searchParams) {
1315
+ return queryKeys.map((key) => key.replace(/\$\{sp:(\w+)(?:\|([^}]*))?\}/g, (_, spName, defaultVal) => {
1316
+ const value = searchParams?.get(spName);
1317
+ if (defaultVal !== undefined) {
1318
+ return value || defaultVal;
1319
+ }
1320
+ return value ?? "";
1321
+ }).replace(/\$\{(\w+)\}/g, (_, paramName) => params[paramName] ?? ""));
1322
+ }
1323
+ function extractSearchParams(url) {
1324
+ const qIdx = url.indexOf("?");
1325
+ if (qIdx === -1)
1326
+ return;
1327
+ return new URLSearchParams(url.slice(qIdx));
1197
1328
  }
1198
1329
  function isAotDebugEnabled() {
1199
1330
  const env = process.env.VERTZ_DEBUG;
@@ -1208,7 +1339,32 @@ function ensureDomShim3() {
1208
1339
  domShimInstalled3 = true;
1209
1340
  installDomShim();
1210
1341
  }
1211
- function collectCSSFromModule(module, fallbackMetrics) {
1342
+ function mergeRouteCss(routeCss, appCss) {
1343
+ if (!routeCss && !appCss)
1344
+ return;
1345
+ if (!appCss)
1346
+ return routeCss;
1347
+ if (!routeCss)
1348
+ return appCss;
1349
+ const seen = new Set(appCss);
1350
+ const merged = [...appCss];
1351
+ for (const rule of routeCss) {
1352
+ if (!seen.has(rule))
1353
+ merged.push(rule);
1354
+ }
1355
+ return merged;
1356
+ }
1357
+ var routeCssCache = new Map;
1358
+ function clearRouteCssCache() {
1359
+ routeCssCache.clear();
1360
+ }
1361
+ function collectCSSFromModule(module, renderedHtml, fallbackMetrics, routeCss, routePattern) {
1362
+ if (routePattern && routeCss) {
1363
+ const cached = routeCssCache.get(routePattern);
1364
+ if (cached) {
1365
+ return cached;
1366
+ }
1367
+ }
1212
1368
  let themeCss = "";
1213
1369
  let preloadTags = "";
1214
1370
  if (module.theme) {
@@ -1227,9 +1383,19 @@ function collectCSSFromModule(module, fallbackMetrics) {
1227
1383
  for (const s of module.styles)
1228
1384
  alreadyIncluded.add(s);
1229
1385
  }
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));
1386
+ let componentCss;
1387
+ if (routeCss && routeCss.length > 0) {
1388
+ componentCss = routeCss.filter((s) => !alreadyIncluded.has(s));
1389
+ } else {
1390
+ const ssrCtx = ssrStorage.getStore();
1391
+ const tracker = ssrCtx?.cssTracker;
1392
+ const useTracker = tracker && tracker.size > 0;
1393
+ const rawComponentCss = useTracker ? Array.from(tracker) : module.getInjectedCSS?.() ?? [];
1394
+ componentCss = rawComponentCss.filter((s) => !alreadyIncluded.has(s));
1395
+ if (!useTracker && componentCss.length > 0 && renderedHtml) {
1396
+ componentCss = filterCSSByHTML(renderedHtml, componentCss);
1397
+ }
1398
+ }
1233
1399
  const themeTag = themeCss ? `<style data-vertz-css>${themeCss}</style>` : "";
1234
1400
  const globalTag = module.styles && module.styles.length > 0 ? `<style data-vertz-css>${module.styles.join(`
1235
1401
  `)}</style>` : "";
@@ -1237,7 +1403,11 @@ function collectCSSFromModule(module, fallbackMetrics) {
1237
1403
  `)}</style>` : "";
1238
1404
  const cssString = [themeTag, globalTag, componentTag].filter(Boolean).join(`
1239
1405
  `);
1240
- return { cssString, preloadTags };
1406
+ const result = { cssString, preloadTags };
1407
+ if (routePattern && routeCss) {
1408
+ routeCssCache.set(routePattern, result);
1409
+ }
1410
+ return result;
1241
1411
  }
1242
1412
 
1243
1413
  // src/ssr-access-set.ts
@@ -1513,4 +1683,4 @@ function replaceAppDivContent(template, appHtml) {
1513
1683
  return template.slice(0, contentStart) + appHtml + template.slice(i);
1514
1684
  }
1515
1685
 
1516
- export { escapeHtml, escapeAttr, serializeToHtml, toPrefetchSession, evaluateAccessRule, reconstructDescriptors, resetSlotCounter, createSlotPlaceholder, encodeChunk, streamToString, collectStreamChunks, createTemplateChunk, renderToStream, safeSerialize, getStreamingRuntimeScript, createSSRDataChunk, compileThemeCached, createRequestContext, ssrRenderToString, ssrDiscoverQueries, ssrStreamNavQueries, matchUrlToPatterns, ssrRenderSinglePass, ssrRenderProgressive, createHoles, ssrRenderAot, isAotDebugEnabled, getAccessSetForSSR, createAccessSetScript, createSessionScript, resolveRouteModulepreload, precomputeHandlerState, resolveSession, injectIntoTemplate };
1686
+ export { escapeHtml, escapeAttr, serializeToHtml, toPrefetchSession, evaluateAccessRule, reconstructDescriptors, resetSlotCounter, createSlotPlaceholder, encodeChunk, streamToString, collectStreamChunks, createTemplateChunk, renderToStream, safeSerialize, getStreamingRuntimeScript, createSSRDataChunk, compileThemeCached, createRequestContext, ssrRenderToString, ssrDiscoverQueries, ssrStreamNavQueries, matchUrlToPatterns, ssrRenderSinglePass, ssrRenderProgressive, createHoles, ssrRenderAot, isAotDebugEnabled, clearRouteCssCache, getAccessSetForSSR, createAccessSetScript, createSessionScript, resolveRouteModulepreload, precomputeHandlerState, resolveSession, injectIntoTemplate };
@@ -10,7 +10,7 @@ import {
10
10
  ssrRenderSinglePass,
11
11
  ssrStreamNavQueries,
12
12
  toPrefetchSession
13
- } from "./chunk-2ymwre0k.js";
13
+ } from "./chunk-15kac8x8.js";
14
14
 
15
15
  // src/node-handler.ts
16
16
  function createNodeHandler(options) {
@@ -24,7 +24,8 @@ function createNodeHandler(options) {
24
24
  sessionResolver,
25
25
  manifest,
26
26
  progressiveHTML,
27
- aotManifest
27
+ aotManifest,
28
+ aotDataResolver
28
29
  } = options;
29
30
  const { template, linkHeader, modulepreloadTags, splitResult } = precomputeHandlerState(options);
30
31
  const useProgressive = progressiveHTML && splitResult && !(manifest?.routeEntries && Object.keys(manifest.routeEntries).length > 0);
@@ -60,7 +61,8 @@ function createNodeHandler(options) {
60
61
  ssrTimeout,
61
62
  fallbackMetrics,
62
63
  ssrAuth,
63
- prefetchSession
64
+ prefetchSession,
65
+ aotDataResolver
64
66
  }) : await ssrRenderSinglePass(module, url, {
65
67
  ssrTimeout,
66
68
  fallbackMetrics,
@@ -11,14 +11,16 @@ import {
11
11
  ssrRenderSinglePass,
12
12
  ssrStreamNavQueries,
13
13
  toPrefetchSession
14
- } from "./chunk-2ymwre0k.js";
14
+ } from "./chunk-15kac8x8.js";
15
15
 
16
16
  // src/aot-manifest-loader.ts
17
17
  import { existsSync, readFileSync } from "node:fs";
18
18
  import { join } from "node:path";
19
19
  async function loadAotManifest(serverDir) {
20
20
  const manifestPath = join(serverDir, "aot-manifest.json");
21
- const routesModulePath = join(serverDir, "aot-routes.js");
21
+ const routesModuleTs = join(serverDir, "aot-routes.ts");
22
+ const routesModuleJs = join(serverDir, "aot-routes.js");
23
+ const routesModulePath = existsSync(routesModuleTs) ? routesModuleTs : routesModuleJs;
22
24
  if (!existsSync(manifestPath) || !existsSync(routesModulePath)) {
23
25
  return null;
24
26
  }
@@ -46,13 +48,26 @@ async function loadAotManifest(serverDir) {
46
48
  routes[pattern] = {
47
49
  render: renderFn,
48
50
  holes: entry.holes,
49
- queryKeys: entry.queryKeys
51
+ queryKeys: entry.queryKeys,
52
+ css: entry.css
50
53
  };
51
54
  }
52
55
  if (Object.keys(routes).length === 0) {
53
56
  return null;
54
57
  }
55
- return { routes };
58
+ let app;
59
+ if (manifestJson.app) {
60
+ const appRenderFn = routesModule[manifestJson.app.renderFn];
61
+ if (typeof appRenderFn === "function") {
62
+ app = {
63
+ render: appRenderFn,
64
+ holes: manifestJson.app.holes,
65
+ queryKeys: manifestJson.app.queryKeys,
66
+ css: manifestJson.app.css
67
+ };
68
+ }
69
+ }
70
+ return { routes, app };
56
71
  }
57
72
 
58
73
  // src/ssr-progressive-response.ts
@@ -140,6 +140,8 @@ interface SSRAotContext {
140
140
  session: PrefetchSession | undefined;
141
141
  /** Route params for the current request. */
142
142
  params: Record<string, string>;
143
+ /** URL search params for the current request (used by AOT functions with ${sp:name} keys). */
144
+ searchParams: URLSearchParams | undefined;
143
145
  }
144
146
  /** An AOT render function: takes props/data and context, returns HTML string. */
145
147
  type AotRenderFn = (data: Record<string, unknown>, ctx: SSRAotContext) => string;
@@ -151,6 +153,8 @@ interface AotRouteEntry {
151
153
  holes: string[];
152
154
  /** Query cache keys this route reads via ctx.getData(). */
153
155
  queryKeys?: string[];
156
+ /** Pre-filtered CSS rules for this route, determined at build time (#1988). */
157
+ css?: string[];
154
158
  }
155
159
  /**
156
160
  * AOT manifest — maps route patterns to pre-compiled render functions.
@@ -160,6 +164,8 @@ interface AotRouteEntry {
160
164
  interface AotManifest {
161
165
  /** Route pattern → AOT entry. */
162
166
  routes: Record<string, AotRouteEntry>;
167
+ /** Root layout (App) entry — wraps page content via its RouterView hole. */
168
+ app?: AotRouteEntry;
163
169
  }
164
170
  /**
165
171
  * Resolves custom data for AOT-rendered routes.
@@ -172,7 +178,7 @@ interface AotManifest {
172
178
  * @param unresolvedKeys - Query keys not yet populated by entity prefetch
173
179
  * @returns Map of cache key → data, or empty Map to skip
174
180
  */
175
- type AotDataResolver = (pattern: string, params: Record<string, string>, unresolvedKeys: string[]) => Promise<Map<string, unknown>> | Map<string, unknown>;
181
+ type AotDataResolver = (pattern: string, params: Record<string, string>, unresolvedKeys: string[], searchParams?: URLSearchParams) => Promise<Map<string, unknown>> | Map<string, unknown>;
176
182
  /**
177
183
  * Load AOT manifest and routes module from a server build directory.
178
184
  *
package/dist/ssr/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createSSRHandler,
3
3
  loadAotManifest
4
- } from "../shared/chunk-595trxsn.js";
4
+ } from "../shared/chunk-j18fewkf.js";
5
5
  import {
6
6
  injectIntoTemplate,
7
7
  ssrDiscoverQueries,
8
8
  ssrRenderToString
9
- } from "../shared/chunk-2ymwre0k.js";
9
+ } from "../shared/chunk-15kac8x8.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.38",
3
+ "version": "0.2.41",
4
4
  "description": "Vertz UI server-side rendering runtime",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "scripts": {
60
60
  "build": "bunup",
61
- "test": "bun test src/",
61
+ "test": "bun test --timeout 60000 src/",
62
62
  "test:integration": "bun test src/__tests__/bun-dev-server.integration.local.ts",
63
63
  "test:e2e": "bunx playwright test",
64
64
  "typecheck": "tsc --noEmit"
@@ -67,9 +67,9 @@
67
67
  "@ampproject/remapping": "^2.3.0",
68
68
  "@capsizecss/unpack": "^4.0.0",
69
69
  "@jridgewell/trace-mapping": "^0.3.31",
70
- "@vertz/core": "^0.2.35",
71
- "@vertz/ui": "^0.2.35",
72
- "@vertz/ui-compiler": "^0.2.35",
70
+ "@vertz/core": "^0.2.39",
71
+ "@vertz/ui": "^0.2.39",
72
+ "@vertz/ui-compiler": "^0.2.39",
73
73
  "magic-string": "^0.30.0",
74
74
  "sharp": "^0.34.5",
75
75
  "ts-morph": "^27.0.2"
@@ -77,7 +77,7 @@
77
77
  "devDependencies": {
78
78
  "@happy-dom/global-registrator": "^20.8.3",
79
79
  "@playwright/test": "^1.58.2",
80
- "@vertz/codegen": "^0.2.35",
80
+ "@vertz/codegen": "^0.2.39",
81
81
  "@vertz/ui-auth": "^0.2.19",
82
82
  "bun-types": "^1.3.10",
83
83
  "bunup": "^0.16.31",