@vertz/ui-server 0.2.22 → 0.2.23

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.
@@ -72,6 +72,16 @@ interface BunDevServerOptions {
72
72
  * optionally `window.__VERTZ_ACCESS_SET__` for instant auth hydration.
73
73
  */
74
74
  sessionResolver?: SessionResolver;
75
+ /**
76
+ * Watch workspace-linked package dist directories for changes.
77
+ * When a dist directory changes, automatically restart the server.
78
+ *
79
+ * Accepts an array of package names (e.g., ['@vertz/theme-shadcn', '@vertz/ui'])
80
+ * or `true` to auto-detect all `@vertz/*` packages linked via workspace symlinks.
81
+ *
82
+ * @default false
83
+ */
84
+ watchDeps?: boolean | string[];
75
85
  }
76
86
  interface ErrorDetail {
77
87
  message: string;
@@ -9,7 +9,7 @@ import {
9
9
 
10
10
  // src/bun-dev-server.ts
11
11
  import { execSync } from "child_process";
12
- import { existsSync, mkdirSync, readFileSync as readFileSync2, watch, writeFileSync as writeFileSync2 } from "fs";
12
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, watch as watch2, writeFileSync as writeFileSync2 } from "fs";
13
13
  import { dirname, normalize, resolve } from "path";
14
14
 
15
15
  // src/debug-logger.ts
@@ -286,6 +286,7 @@ function runWithScopedFetch(interceptor, fn) {
286
286
  }
287
287
 
288
288
  // src/font-metrics.ts
289
+ import { access as fsAccess } from "fs/promises";
289
290
  import { readFile } from "fs/promises";
290
291
  import { join as join2 } from "path";
291
292
  import { fromBuffer } from "@capsizecss/unpack";
@@ -354,9 +355,15 @@ function getPrimarySrcPath(descriptor) {
354
355
  return first.path;
355
356
  return null;
356
357
  }
357
- function resolveFilePath(urlPath, rootDir) {
358
+ async function resolveFilePath(urlPath, rootDir) {
358
359
  const cleaned = urlPath.startsWith("/") ? urlPath.slice(1) : urlPath;
359
- return join2(rootDir, cleaned);
360
+ const direct = join2(rootDir, cleaned);
361
+ try {
362
+ await fsAccess(direct);
363
+ return direct;
364
+ } catch {
365
+ return join2(rootDir, "public", cleaned);
366
+ }
360
367
  }
361
368
  async function extractFontMetrics(fonts, rootDir) {
362
369
  const result = {};
@@ -370,7 +377,7 @@ async function extractFontMetrics(fonts, rootDir) {
370
377
  if (!srcPath.toLowerCase().endsWith(".woff2"))
371
378
  continue;
372
379
  try {
373
- const filePath = resolveFilePath(srcPath, rootDir);
380
+ const filePath = await resolveFilePath(srcPath, rootDir);
374
381
  const buffer = await readFile(filePath);
375
382
  const metrics = await fromBuffer(buffer);
376
383
  const fallbackFont = typeof adjustFontFallback === "string" ? adjustFontFallback : detectFallbackFont(descriptor.fallback);
@@ -953,6 +960,16 @@ class SSRElement extends SSRNode {
953
960
  delete this.attrs.checked;
954
961
  }
955
962
  }
963
+ get selected() {
964
+ return "selected" in this.attrs;
965
+ }
966
+ set selected(value) {
967
+ if (value) {
968
+ this.attrs.selected = "";
969
+ } else {
970
+ delete this.attrs.selected;
971
+ }
972
+ }
956
973
  get rows() {
957
974
  return Number(this.attrs.rows) || 0;
958
975
  }
@@ -1604,15 +1621,95 @@ function escapeAttr3(s) {
1604
1621
  return s.replace(/[&"'<>]/g, (c) => `&#${c.charCodeAt(0)};`);
1605
1622
  }
1606
1623
 
1624
+ // src/upstream-watcher.ts
1625
+ import { existsSync, lstatSync, readdirSync, realpathSync, watch } from "fs";
1626
+ import { join as join3 } from "path";
1627
+ function resolveWorkspacePackages(projectRoot, filter) {
1628
+ const results = [];
1629
+ const packageNames = filter === true ? discoverVertzPackages(projectRoot) : parsePackageNames(filter);
1630
+ for (const { scope, name } of packageNames) {
1631
+ const nmPath = join3(projectRoot, "node_modules", scope, name);
1632
+ if (!existsSync(nmPath))
1633
+ continue;
1634
+ const stat = lstatSync(nmPath);
1635
+ if (!stat.isSymbolicLink())
1636
+ continue;
1637
+ const realPath = realpathSync(nmPath);
1638
+ const distPath = join3(realPath, "dist");
1639
+ if (!existsSync(distPath))
1640
+ continue;
1641
+ const fullName = scope ? `${scope}/${name}` : name;
1642
+ results.push({ name: fullName, distPath });
1643
+ }
1644
+ return results;
1645
+ }
1646
+ function discoverVertzPackages(projectRoot) {
1647
+ const scopeDir = join3(projectRoot, "node_modules", "@vertz");
1648
+ if (!existsSync(scopeDir))
1649
+ return [];
1650
+ return readdirSync(scopeDir).filter((entry) => !entry.startsWith(".")).map((entry) => ({ scope: "@vertz", name: entry }));
1651
+ }
1652
+ function parsePackageNames(names) {
1653
+ return names.map((pkg) => {
1654
+ const match = pkg.match(/^(@[^/]+)\/(.+)$/);
1655
+ if (match?.[1] && match[2])
1656
+ return { scope: match[1], name: match[2] };
1657
+ return { scope: "", name: pkg };
1658
+ });
1659
+ }
1660
+ function createUpstreamWatcher(options) {
1661
+ const { projectRoot, watchDeps, onDistChanged, debounceMs = 1000, persistent = false } = options;
1662
+ const packages = resolveWorkspacePackages(projectRoot, watchDeps);
1663
+ const watchers = [];
1664
+ const debounceTimers = new Map;
1665
+ let closed = false;
1666
+ for (const pkg of packages) {
1667
+ try {
1668
+ const watcher = watch(pkg.distPath, { recursive: true, persistent }, () => {
1669
+ if (closed)
1670
+ return;
1671
+ const existing = debounceTimers.get(pkg.name);
1672
+ if (existing)
1673
+ clearTimeout(existing);
1674
+ debounceTimers.set(pkg.name, setTimeout(() => {
1675
+ debounceTimers.delete(pkg.name);
1676
+ if (!closed) {
1677
+ onDistChanged(pkg.name);
1678
+ }
1679
+ }, debounceMs));
1680
+ });
1681
+ watcher.on("error", () => {});
1682
+ watchers.push(watcher);
1683
+ } catch {}
1684
+ }
1685
+ return {
1686
+ packages,
1687
+ close() {
1688
+ closed = true;
1689
+ for (const w of watchers) {
1690
+ try {
1691
+ w.close();
1692
+ } catch {}
1693
+ }
1694
+ watchers.length = 0;
1695
+ for (const timer of debounceTimers.values()) {
1696
+ clearTimeout(timer);
1697
+ }
1698
+ debounceTimers.clear();
1699
+ }
1700
+ };
1701
+ }
1702
+
1607
1703
  // src/bun-dev-server.ts
1608
1704
  function detectFaviconTag(projectRoot) {
1609
1705
  const faviconPath = resolve(projectRoot, "public", "favicon.svg");
1610
- return existsSync(faviconPath) ? '<link rel="icon" type="image/svg+xml" href="/favicon.svg">' : "";
1706
+ return existsSync2(faviconPath) ? '<link rel="icon" type="image/svg+xml" href="/favicon.svg">' : "";
1611
1707
  }
1612
1708
  var STALE_GRAPH_PATTERNS = [
1613
1709
  /Export named ['"].*['"] not found in module/i,
1614
1710
  /No matching export in ['"].*['"] for import/i,
1615
- /does not provide an export named/i
1711
+ /does not provide an export named/i,
1712
+ /Failed to resolve module specifier/i
1616
1713
  ];
1617
1714
  function isStaleGraphError(message) {
1618
1715
  return STALE_GRAPH_PATTERNS.some((pattern) => pattern.test(message));
@@ -1712,7 +1809,7 @@ function buildErrorChannelScript(editor) {
1712
1809
  "V._hadClientError=false;",
1713
1810
  "V._needsReload=false;",
1714
1811
  "V._restarting=false;",
1715
- `V.isStaleGraph=function(m){return/Export named ['"].*['"] not found in module/i.test(m)||/No matching export in ['"].*['"] for import/i.test(m)||/does not provide an export named/i.test(m)};`,
1812
+ `V.isStaleGraph=function(m){return/Export named ['"].*['"] not found in module/i.test(m)||/No matching export in ['"].*['"] for import/i.test(m)||/does not provide an export named/i.test(m)||/Failed to resolve module specifier/i.test(m)};`,
1716
1813
  "V._canAutoRestart=function(){",
1717
1814
  "var raw=sessionStorage.getItem('__vertz_auto_restart');",
1718
1815
  "var ts;try{ts=raw?JSON.parse(raw):[]}catch(e){ts=[]}",
@@ -1984,7 +2081,8 @@ function createBunDevServer(options) {
1984
2081
  logRequests = true,
1985
2082
  editor: editorOption,
1986
2083
  headTags: headTagsOption = "",
1987
- sessionResolver
2084
+ sessionResolver,
2085
+ watchDeps
1988
2086
  } = options;
1989
2087
  const faviconTag = detectFaviconTag(projectRoot);
1990
2088
  const headTags = [faviconTag, headTagsOption].filter(Boolean).join(`
@@ -2216,7 +2314,7 @@ function createBunDevServer(options) {
2216
2314
  }
2217
2315
  };
2218
2316
  const setupOpenAPIWatcher = () => {
2219
- if (!openapi || !existsSync(openapi.specPath))
2317
+ if (!openapi || !existsSync2(openapi.specPath))
2220
2318
  return;
2221
2319
  cachedSpec = loadOpenAPISpec();
2222
2320
  if (cachedSpec === null)
@@ -2224,7 +2322,7 @@ function createBunDevServer(options) {
2224
2322
  try {
2225
2323
  const specDir = dirname(openapi.specPath);
2226
2324
  const specFile = openapi.specPath.split("/").pop() || "openapi.json";
2227
- specWatcher = watch(specDir, { persistent: false }, (eventType, filename) => {
2325
+ specWatcher = watch2(specDir, { persistent: false }, (eventType, filename) => {
2228
2326
  if (filename === specFile && (eventType === "change" || eventType === "rename")) {
2229
2327
  if (logRequests) {
2230
2328
  console.log("[Server] OpenAPI spec file changed, reloading...");
@@ -2242,7 +2340,7 @@ function createBunDevServer(options) {
2242
2340
  headers: { "Content-Type": "application/json" }
2243
2341
  });
2244
2342
  }
2245
- if (openapi && existsSync(openapi.specPath)) {
2343
+ if (openapi && existsSync2(openapi.specPath)) {
2246
2344
  cachedSpec = loadOpenAPISpec();
2247
2345
  if (cachedSpec) {
2248
2346
  return new Response(JSON.stringify(cachedSpec), {
@@ -2255,6 +2353,42 @@ function createBunDevServer(options) {
2255
2353
  let isRestarting = false;
2256
2354
  let pluginsRegistered = false;
2257
2355
  let stableUpdateManifest = null;
2356
+ let upstreamWatcherRef = null;
2357
+ let pendingDistRestart = false;
2358
+ let restartFn = null;
2359
+ if (watchDeps) {
2360
+ upstreamWatcherRef = createUpstreamWatcher({
2361
+ projectRoot,
2362
+ watchDeps,
2363
+ onDistChanged: (pkgName) => {
2364
+ if (!restartFn || stopped)
2365
+ return;
2366
+ if (logRequests) {
2367
+ console.log(`[Server] Upstream package rebuilt: ${pkgName} \u2014 restarting...`);
2368
+ }
2369
+ if (isRestarting) {
2370
+ pendingDistRestart = true;
2371
+ return;
2372
+ }
2373
+ restartFn().then(() => {
2374
+ if (pendingDistRestart && restartFn && !stopped) {
2375
+ pendingDistRestart = false;
2376
+ restartFn().catch((err) => {
2377
+ const msg = err instanceof Error ? err.message : String(err);
2378
+ console.error(`[Server] Pending upstream restart failed: ${msg}`);
2379
+ });
2380
+ }
2381
+ }).catch((err) => {
2382
+ const msg = err instanceof Error ? err.message : String(err);
2383
+ console.error(`[Server] Upstream restart failed: ${msg}`);
2384
+ });
2385
+ }
2386
+ });
2387
+ if (logRequests && upstreamWatcherRef.packages.length > 0) {
2388
+ const names = upstreamWatcherRef.packages.map((p) => p.name).join(", ");
2389
+ console.log(`[Server] Watching upstream packages: ${names}`);
2390
+ }
2391
+ }
2258
2392
  async function start() {
2259
2393
  const { plugin } = await Promise.resolve(globalThis.Bun);
2260
2394
  const { createVertzBunPlugin } = await import("./bun-plugin/index.js");
@@ -2720,8 +2854,8 @@ data: {}
2720
2854
  }
2721
2855
  const srcDir = resolve(projectRoot, "src");
2722
2856
  stopped = false;
2723
- if (existsSync(srcDir)) {
2724
- srcWatcherRef = watch(srcDir, { recursive: true }, (_event, filename) => {
2857
+ if (existsSync2(srcDir)) {
2858
+ srcWatcherRef = watch2(srcDir, { recursive: true }, (_event, filename) => {
2725
2859
  if (!filename)
2726
2860
  return;
2727
2861
  if (refreshTimeout)
@@ -2880,6 +3014,10 @@ data: {}
2880
3014
  server.stop(true);
2881
3015
  server = null;
2882
3016
  }
3017
+ if (upstreamWatcherRef) {
3018
+ upstreamWatcherRef.close();
3019
+ upstreamWatcherRef = null;
3020
+ }
2883
3021
  },
2884
3022
  async restart() {
2885
3023
  if (isRestarting) {
@@ -2939,6 +3077,7 @@ data: {}
2939
3077
  isRestarting = false;
2940
3078
  }
2941
3079
  };
3080
+ restartFn = () => devServer.restart();
2942
3081
  return devServer;
2943
3082
  }
2944
3083
  export {
@@ -102,6 +102,8 @@ declare class SSRElement extends SSRNode {
102
102
  set disabled(value: boolean);
103
103
  get checked(): boolean;
104
104
  set checked(value: boolean);
105
+ get selected(): boolean;
106
+ set selected(value: boolean);
105
107
  get rows(): number;
106
108
  set rows(value: number);
107
109
  get scope(): string;
@@ -7,7 +7,7 @@ import {
7
7
  installDomShim,
8
8
  removeDomShim,
9
9
  toVNode
10
- } from "../shared/chunk-1363r1qw.js";
10
+ } from "../shared/chunk-bm16zy8d.js";
11
11
  export {
12
12
  toVNode,
13
13
  removeDomShim,
package/dist/index.d.ts CHANGED
@@ -80,6 +80,7 @@ declare function renderAssetTags(assets: AssetDescriptor[]): string;
80
80
  * Returns an empty string if the CSS is empty.
81
81
  */
82
82
  declare function inlineCriticalCss(css: string): string;
83
+ import { FallbackFontName as FallbackFontName2, FontFallbackMetrics as FontFallbackMetrics5 } from "@vertz/ui";
83
84
  import { FallbackFontName, FontDescriptor, FontFallbackMetrics } from "@vertz/ui";
84
85
  /**
85
86
  * Auto-detect which system font to use as fallback base.
@@ -589,4 +590,4 @@ declare function collectStreamChunks(stream: ReadableStream<Uint8Array>): Promis
589
590
  * @param nonce - Optional CSP nonce to add to the inline script tag.
590
591
  */
591
592
  declare function createTemplateChunk(slotId: number, resolvedHtml: string, nonce?: string): string;
592
- export { wrapWithHydrationMarkers, streamToString, ssrStorage, ssrRenderToString, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, rawHtml, isInSSR, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, extractFontMetrics, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, VNode, SessionResolver, SessionData, SSRSessionInfo, SSRRenderResult, SSRQueryEntry2 as SSRQueryEntry, SSRModule, SSRHandlerOptions, SSRDiscoverResult, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, RawHtml, PageOptions, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, AssetDescriptor };
593
+ export { wrapWithHydrationMarkers, streamToString, ssrStorage, ssrRenderToString, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, rawHtml, isInSSR, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, extractFontMetrics, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, VNode, SessionResolver, SessionData, SSRSessionInfo, SSRRenderResult, SSRQueryEntry2 as SSRQueryEntry, SSRModule, SSRHandlerOptions, SSRDiscoverResult, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, RawHtml, PageOptions, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, FontFallbackMetrics5 as FontFallbackMetrics, FallbackFontName2 as FallbackFontName, AssetDescriptor };
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  ssrDiscoverQueries,
20
20
  ssrRenderToString,
21
21
  streamToString
22
- } from "./shared/chunk-qzdhe6bn.js";
22
+ } from "./shared/chunk-5cny4vzm.js";
23
23
  import {
24
24
  clearGlobalSSRTimeout,
25
25
  createSSRAdapter,
@@ -31,7 +31,7 @@ import {
31
31
  registerSSRQuery,
32
32
  setGlobalSSRTimeout,
33
33
  ssrStorage
34
- } from "./shared/chunk-1363r1qw.js";
34
+ } from "./shared/chunk-bm16zy8d.js";
35
35
 
36
36
  // src/asset-pipeline.ts
37
37
  function renderAssetTags(assets) {
@@ -59,6 +59,7 @@ function inlineCriticalCss(css) {
59
59
  return `<style>${safeCss}</style>`;
60
60
  }
61
61
  // src/font-metrics.ts
62
+ import { access as fsAccess } from "node:fs/promises";
62
63
  import { readFile } from "node:fs/promises";
63
64
  import { join } from "node:path";
64
65
  import { fromBuffer } from "@capsizecss/unpack";
@@ -127,9 +128,15 @@ function getPrimarySrcPath(descriptor) {
127
128
  return first.path;
128
129
  return null;
129
130
  }
130
- function resolveFilePath(urlPath, rootDir) {
131
+ async function resolveFilePath(urlPath, rootDir) {
131
132
  const cleaned = urlPath.startsWith("/") ? urlPath.slice(1) : urlPath;
132
- return join(rootDir, cleaned);
133
+ const direct = join(rootDir, cleaned);
134
+ try {
135
+ await fsAccess(direct);
136
+ return direct;
137
+ } catch {
138
+ return join(rootDir, "public", cleaned);
139
+ }
133
140
  }
134
141
  async function extractFontMetrics(fonts, rootDir) {
135
142
  const result = {};
@@ -143,7 +150,7 @@ async function extractFontMetrics(fonts, rootDir) {
143
150
  if (!srcPath.toLowerCase().endsWith(".woff2"))
144
151
  continue;
145
152
  try {
146
- const filePath = resolveFilePath(srcPath, rootDir);
153
+ const filePath = await resolveFilePath(srcPath, rootDir);
147
154
  const buffer = await readFile(filePath);
148
155
  const metrics = await fromBuffer(buffer);
149
156
  const fallbackFont = typeof adjustFontFallback === "string" ? adjustFontFallback : detectFallbackFont(descriptor.fallback);
@@ -6,7 +6,7 @@ import {
6
6
  setGlobalSSRTimeout,
7
7
  ssrStorage,
8
8
  toVNode
9
- } from "./chunk-1363r1qw.js";
9
+ } from "./chunk-bm16zy8d.js";
10
10
 
11
11
  // src/html-serializer.ts
12
12
  var VOID_ELEMENTS = new Set([
@@ -403,6 +403,16 @@ class SSRElement extends SSRNode {
403
403
  delete this.attrs.checked;
404
404
  }
405
405
  }
406
+ get selected() {
407
+ return "selected" in this.attrs;
408
+ }
409
+ set selected(value) {
410
+ if (value) {
411
+ this.attrs.selected = "";
412
+ } else {
413
+ delete this.attrs.selected;
414
+ }
415
+ }
406
416
  get rows() {
407
417
  return Number(this.attrs.rows) || 0;
408
418
  }
@@ -1,4 +1,4 @@
1
- import { CompiledRoute as CompiledRoute2 } from "@vertz/ui";
1
+ import { CompiledRoute as CompiledRoute2, FontFallbackMetrics as FontFallbackMetrics2 } from "@vertz/ui";
2
2
  import { CompiledRoute, FontFallbackMetrics, Theme } from "@vertz/ui";
3
3
  import { SSRAuth as SSRAuth_jq1nwm } from "@vertz/ui/internals";
4
4
  interface SSRModule {
@@ -76,6 +76,8 @@ interface PrerenderOptions {
76
76
  routes: string[];
77
77
  /** CSP nonce for inline scripts. */
78
78
  nonce?: string;
79
+ /** Pre-computed font fallback metrics for zero-CLS font loading. */
80
+ fallbackMetrics?: Record<string, FontFallbackMetrics2>;
79
81
  }
80
82
  /**
81
83
  * Discover all route patterns from an SSR module.
@@ -124,7 +126,7 @@ declare function stripScriptsFromStaticHTML(html: string): string;
124
126
  * - Routes without `prerender` or `generateParams` are not collected
125
127
  */
126
128
  declare function collectPrerenderPaths(routes: CompiledRoute2[], prefix?: string): Promise<string[]>;
127
- import { FontFallbackMetrics as FontFallbackMetrics2 } from "@vertz/ui";
129
+ import { FontFallbackMetrics as FontFallbackMetrics3 } from "@vertz/ui";
128
130
  import { AccessSet } from "@vertz/ui/auth";
129
131
  interface SessionData {
130
132
  user: {
@@ -178,7 +180,7 @@ interface SSRHandlerOptions {
178
180
  */
179
181
  nonce?: string;
180
182
  /** Pre-computed font fallback metrics (computed at server startup). */
181
- fallbackMetrics?: Record<string, FontFallbackMetrics2>;
183
+ fallbackMetrics?: Record<string, FontFallbackMetrics3>;
182
184
  /** Paths to inject as `<link rel="modulepreload">` in `<head>`. */
183
185
  modulepreload?: string[];
184
186
  /**
package/dist/ssr/index.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  injectIntoTemplate,
4
4
  ssrDiscoverQueries,
5
5
  ssrRenderToString
6
- } from "../shared/chunk-qzdhe6bn.js";
7
- import"../shared/chunk-1363r1qw.js";
6
+ } from "../shared/chunk-5cny4vzm.js";
7
+ import"../shared/chunk-bm16zy8d.js";
8
8
 
9
9
  // src/prerender.ts
10
10
  async function discoverRoutes(module) {
@@ -28,7 +28,9 @@ async function prerenderRoutes(module, template, options) {
28
28
  for (const routePath of options.routes) {
29
29
  let renderResult;
30
30
  try {
31
- renderResult = await ssrRenderToString(module, routePath);
31
+ renderResult = await ssrRenderToString(module, routePath, {
32
+ fallbackMetrics: options.fallbackMetrics
33
+ });
32
34
  } catch (error) {
33
35
  const message = error instanceof Error ? error.message : String(error);
34
36
  throw new Error(`Pre-render failed for ${routePath}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/ui-server",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Vertz UI server-side rendering runtime",
@@ -58,15 +58,15 @@
58
58
  "@ampproject/remapping": "^2.3.0",
59
59
  "@capsizecss/unpack": "^4.0.0",
60
60
  "@jridgewell/trace-mapping": "^0.3.31",
61
- "@vertz/core": "^0.2.21",
62
- "@vertz/ui": "^0.2.21",
63
- "@vertz/ui-compiler": "^0.2.21",
61
+ "@vertz/core": "^0.2.22",
62
+ "@vertz/ui": "^0.2.22",
63
+ "@vertz/ui-compiler": "^0.2.22",
64
64
  "magic-string": "^0.30.0",
65
65
  "sharp": "^0.34.5",
66
66
  "ts-morph": "^27.0.2"
67
67
  },
68
68
  "devDependencies": {
69
- "@vertz/codegen": "^0.2.21",
69
+ "@vertz/codegen": "^0.2.22",
70
70
  "@vertz/ui-auth": "^0.2.19",
71
71
  "bun-types": "^1.3.10",
72
72
  "bunup": "^0.16.31",