@voltro/cli 0.15.0 → 0.17.0

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/dist/{apiBuild-CHItlwPO.js → apiBuild-ChdlLqGv.js} +2 -2
  3. package/dist/apiBuild-D5WB119b.js +2 -0
  4. package/dist/bin.js +3 -3
  5. package/dist/{commands-CPQuQRXh.js → commands-DYQbv-DG.js} +2333 -2292
  6. package/dist/dbCommand-C3R5LrBZ.js +2 -0
  7. package/dist/{dbCommand-B8F29zV0.js → dbCommand-DJSxnjPt.js} +225 -211
  8. package/dist/{dev-BHLM3RPX.js → dev-BCmoJfBm.js} +1 -1
  9. package/dist/{dev-C2lCUhYI.js → dev-DB7pbLob.js} +893 -892
  10. package/dist/{fileConventions-Cu0tM-Bl.js → fileConventions-CBNPZVOV.js} +1 -1
  11. package/dist/frameworkTableAssembly-DRJrAVr1.js +2 -0
  12. package/dist/{frameworkTableAssembly-BA2bAmYN.js → frameworkTableAssembly-sg41s14F.js} +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/{inspectMetrics-CYDSO3za.js → inspectMetrics-DWh56Qas.js} +205 -205
  15. package/dist/{serveCommand-DBzQcCuv.js → serveCommand-DO6qr5Ok.js} +7 -5
  16. package/dist/serveEntry.js +2 -2
  17. package/dist/{start-BtgatJN3.js → start-ksY0wMZG.js} +379 -379
  18. package/dist/startEntry.js +2 -2
  19. package/package.json +17 -17
  20. package/templates/AGENTS.core.md +24 -9
  21. package/templates/AGENTS.md +25 -10
  22. package/templates/agent-docs/_index.md +1 -1
  23. package/templates/agent-docs/cli.md +2 -2
  24. package/templates/agent-docs/data.md +9 -1
  25. package/templates/agent-docs/database/migrations.md +3 -3
  26. package/templates/agent-docs/internationalization.md +3 -3
  27. package/templates/agent-docs/introduction.md +2 -2
  28. package/templates/agent-docs/plugins.md +1 -1
  29. package/templates/agent-docs/reference.md +4 -4
  30. package/templates/agent-docs/routing.md +40 -40
  31. package/templates/agent-docs/templates/appshells.md +24 -24
  32. package/templates/agent-docs/whats-new.md +31 -253
  33. package/templates/apps/api-ai/package.json +7 -7
  34. package/templates/apps/api-auth/package.json +8 -8
  35. package/templates/apps/api-backend/package.json +7 -7
  36. package/templates/apps/api-backend-deactivation/package.json +7 -7
  37. package/templates/apps/api-backend-mail/package.json +8 -8
  38. package/templates/apps/api-backend-mariadb/package.json +9 -9
  39. package/templates/apps/api-backend-storage/package.json +8 -8
  40. package/templates/apps/api-data-advanced/package.json +8 -8
  41. package/templates/apps/api-durable/package.json +8 -8
  42. package/templates/apps/api-feature-flags/package.json +9 -9
  43. package/templates/apps/api-governance/package.json +8 -8
  44. package/templates/apps/api-kv/package.json +8 -8
  45. package/templates/apps/api-moderation/package.json +8 -8
  46. package/templates/apps/api-observability/package.json +8 -8
  47. package/templates/apps/api-ratelimit/package.json +8 -8
  48. package/templates/apps/api-rbac/package.json +8 -8
  49. package/templates/apps/api-rest/package.json +7 -7
  50. package/templates/apps/api-saas/package.json +11 -11
  51. package/templates/apps/api-search/package.json +8 -8
  52. package/templates/apps/api-versioning/package.json +8 -8
  53. package/templates/apps/api-webhooks/package.json +9 -9
  54. package/templates/apps/changelog/package.json +6 -6
  55. package/templates/apps/changelog/src/pages/[locale]/{[slug].page.tsx → [slug]/page.tsx} +4 -4
  56. package/templates/apps/changelog/src/pages/[locale]/mirrors.test.tsx +2 -2
  57. package/templates/apps/changelog/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  58. package/templates/apps/changelog/src/pages/{[slug].page.test.tsx → [slug]/page.test.tsx} +1 -1
  59. package/templates/apps/changelog/src/pages/{[slug].page.tsx → [slug]/page.tsx} +2 -2
  60. package/templates/apps/changelog/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  61. package/templates/apps/edge-functions/package.json +2 -2
  62. package/templates/apps/frontend-admin/package.json +8 -8
  63. package/templates/apps/frontend-admin/src/pages/(marketing)/{login.page.test.tsx → login/page.test.tsx} +2 -2
  64. package/templates/apps/frontend-admin/src/pages/(marketing)/{login.page.tsx → login/page.tsx} +2 -2
  65. package/templates/apps/frontend-admin/src/pages/(marketing)/{index.page.test.tsx → page.test.tsx} +1 -1
  66. package/templates/apps/frontend-admin/src/pages/admin/{[entity].page.tsx → [entity]/page.tsx} +1 -1
  67. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +1 -1
  68. package/templates/apps/frontend-admin/src/pages/admin/{index.page.test.tsx → page.test.tsx} +1 -1
  69. package/templates/apps/frontend-app/package.json +8 -8
  70. package/templates/apps/frontend-app/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  71. package/templates/apps/frontend-app/src/pages/{schema-ui.page.test.tsx → schema-ui/page.test.tsx} +2 -2
  72. package/templates/apps/frontend-app/src/pages/{schema-ui.page.tsx → schema-ui/page.tsx} +1 -1
  73. package/templates/apps/frontend-blank/package.json +7 -7
  74. package/templates/apps/frontend-blank/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  75. package/templates/apps/frontend-contact/package.json +7 -7
  76. package/templates/apps/frontend-contact/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  77. package/templates/apps/frontend-contact/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  78. package/templates/apps/frontend-dashboard/package.json +7 -7
  79. package/templates/apps/frontend-dashboard/src/pages/(marketing)/{login.page.test.tsx → login/page.test.tsx} +2 -2
  80. package/templates/apps/frontend-dashboard/src/pages/(marketing)/{login.page.tsx → login/page.tsx} +2 -2
  81. package/templates/apps/frontend-dashboard/src/pages/(marketing)/{index.page.test.tsx → page.test.tsx} +1 -1
  82. package/templates/apps/frontend-dashboard/src/pages/dashboard/{index.page.test.tsx → page.test.tsx} +1 -1
  83. package/templates/apps/frontend-dashboard/src/pages/dashboard/{settings.page.test.tsx → settings/page.test.tsx} +2 -2
  84. package/templates/apps/frontend-dashboard/src/pages/dashboard/{settings.page.tsx → settings/page.tsx} +2 -2
  85. package/templates/apps/frontend-docs/package.json +7 -7
  86. package/templates/apps/frontend-docs/src/pages/[locale]/docs/{[...slug].page.tsx → [...slug]/page.tsx} +4 -4
  87. package/templates/apps/frontend-docs/src/pages/[locale]/mirrors.test.tsx +2 -2
  88. package/templates/apps/frontend-docs/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  89. package/templates/apps/frontend-docs/src/pages/docs/{[...slug].page.test.tsx → [...slug]/page.test.tsx} +3 -3
  90. package/templates/apps/frontend-docs/src/pages/docs/{[...slug].page.tsx → [...slug]/page.tsx} +1 -1
  91. package/templates/apps/frontend-docs/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  92. package/templates/apps/frontend-i18n/package.json +6 -6
  93. package/templates/apps/frontend-i18n/src/pages/[locale]/{about.page.tsx → about/page.tsx} +3 -3
  94. package/templates/apps/frontend-i18n/src/pages/[locale]/mirrors.test.tsx +2 -2
  95. package/templates/apps/frontend-i18n/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  96. package/templates/apps/frontend-i18n/src/pages/{about.page.test.tsx → about/page.test.tsx} +3 -3
  97. package/templates/apps/frontend-i18n/src/pages/{about.page.tsx → about/page.tsx} +1 -1
  98. package/templates/apps/frontend-i18n/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  99. package/templates/apps/frontend-landing/package.json +7 -7
  100. package/templates/apps/frontend-landing/src/pages/[locale]/mirrors.test.tsx +1 -1
  101. package/templates/apps/frontend-landing/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  102. package/templates/apps/frontend-landing/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  103. package/templates/apps/frontend-spa/package.json +7 -7
  104. package/templates/apps/frontend-spa/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  105. package/templates/apps/frontend-ssr/package.json +7 -7
  106. package/templates/apps/frontend-ssr/src/pages/{feed.page.test.tsx → feed/page.test.tsx} +2 -2
  107. package/templates/apps/frontend-ssr/src/pages/{feed.page.tsx → feed/page.tsx} +1 -1
  108. package/templates/apps/frontend-ssr/src/pages/{feed-swr.page.test.tsx → feed-swr/page.test.tsx} +2 -2
  109. package/templates/apps/frontend-ssr/src/pages/{feed-swr.page.tsx → feed-swr/page.tsx} +1 -1
  110. package/templates/apps/frontend-ssr/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  111. package/templates/apps/frontend-ssr-api/package.json +8 -8
  112. package/templates/apps/frontend-ssr-api/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  113. package/templates/apps/frontend-static-blog/package.json +6 -6
  114. package/templates/apps/frontend-static-blog/src/pages/[locale]/blog/{[slug].page.tsx → [slug]/page.tsx} +4 -4
  115. package/templates/apps/frontend-static-blog/src/pages/[locale]/mirrors.test.tsx +2 -2
  116. package/templates/apps/frontend-static-blog/src/pages/[locale]/{index.page.tsx → page.tsx} +2 -2
  117. package/templates/apps/frontend-static-blog/src/pages/blog/{[slug].page.test.tsx → [slug]/page.test.tsx} +3 -3
  118. package/templates/apps/frontend-static-blog/src/pages/blog/{[slug].page.tsx → [slug]/page.tsx} +3 -3
  119. package/templates/apps/frontend-static-blog/src/pages/{index.page.test.tsx → page.test.tsx} +1 -1
  120. package/dist/apiBuild-D8juhYsS.js +0 -2
  121. package/dist/dbCommand-Dt7BtdMd.js +0 -2
  122. package/dist/frameworkTableAssembly-D1zJSgOU.js +0 -2
  123. /package/templates/apps/changelog/src/pages/{index.page.tsx → page.tsx} +0 -0
  124. /package/templates/apps/frontend-admin/src/pages/(marketing)/{index.page.tsx → page.tsx} +0 -0
  125. /package/templates/apps/frontend-admin/src/pages/admin/{index.page.tsx → page.tsx} +0 -0
  126. /package/templates/apps/frontend-app/src/pages/{index.page.tsx → page.tsx} +0 -0
  127. /package/templates/apps/frontend-blank/src/pages/{index.page.tsx → page.tsx} +0 -0
  128. /package/templates/apps/frontend-contact/src/pages/{index.page.tsx → page.tsx} +0 -0
  129. /package/templates/apps/frontend-dashboard/src/pages/(marketing)/{index.page.tsx → page.tsx} +0 -0
  130. /package/templates/apps/frontend-dashboard/src/pages/dashboard/{index.page.tsx → page.tsx} +0 -0
  131. /package/templates/apps/frontend-docs/src/pages/{index.page.tsx → page.tsx} +0 -0
  132. /package/templates/apps/frontend-i18n/src/pages/{index.page.tsx → page.tsx} +0 -0
  133. /package/templates/apps/frontend-landing/src/pages/{index.page.tsx → page.tsx} +0 -0
  134. /package/templates/apps/frontend-spa/src/pages/{index.page.tsx → page.tsx} +0 -0
  135. /package/templates/apps/frontend-ssr/src/pages/{index.page.tsx → page.tsx} +0 -0
  136. /package/templates/apps/frontend-ssr-api/src/pages/{index.page.tsx → page.tsx} +0 -0
  137. /package/templates/apps/frontend-static-blog/src/pages/{index.page.tsx → page.tsx} +0 -0
@@ -1,4 +1,4 @@
1
- import { d as e, u as t, x as n } from "./fileConventions-Cu0tM-Bl.js";
1
+ import { d as e, u as t, x as n } from "./fileConventions-CBNPZVOV.js";
2
2
  import { D as r, E as i, T as a, a as o, p as s, w as c } from "./inspect-Dwx0_tUj.js";
3
3
  import { basename as l, dirname as u, isAbsolute as d, join as f, relative as p, resolve as m } from "node:path";
4
4
  import { fileURLToPath as h, pathToFileURL as g } from "node:url";
@@ -1076,7 +1076,7 @@ __installPublicEnv(publicEnvValues)
1076
1076
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1077
1077
  interactive: "it decides how much client JS the server ships",
1078
1078
  tenantAware: "it is part of the server-side cache key"
1079
- }, hn = Object.keys(mn), gn = (e) => n.test(e), _n = (e) => e.replace(t, ".page.test.tsx"), vn = (t) => t.endsWith(".tsx") && !e.has(t) && !gn(t), yn = "virtual:voltro-route-refresh", bn = `\0${yn}`, xn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, Sn = () => `
1079
+ }, hn = Object.keys(mn), gn = (e) => n.test(e), _n = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), vn = "virtual:voltro-route-refresh", yn = `\0${vn}`, bn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, xn = () => `
1080
1080
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1081
1081
 
1082
1082
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1152,7 +1152,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1152
1152
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1153
1153
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1154
1154
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1155
- `, Cn = (e) => `
1155
+ `, Sn = (e) => `
1156
1156
  if (import.meta.hot) {
1157
1157
  // Self-import to read our OWN exports, the same technique the react plugin
1158
1158
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1179,45 +1179,45 @@ import {
1179
1179
  registerRouteModule as __voltro_registerRouteModule,
1180
1180
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1181
1181
  serverEffectOf as __voltro_serverEffect,
1182
- } from '${yn}'
1183
- `, wn = (e) => e.replace(/\\/g, "/"), Tn = (n, r) => {
1184
- let [i = "", a] = wn(n).split("?");
1185
- if (!i.endsWith(".tsx") || a !== void 0 && xn.test(a)) return !1;
1186
- let o = wn(r).replace(/\/$/, "");
1182
+ } from '${vn}'
1183
+ `, Cn = (e) => e.replace(/\\/g, "/"), wn = (n, r) => {
1184
+ let [i = "", a] = Cn(n).split("?");
1185
+ if (!i.endsWith(".tsx") || a !== void 0 && bn.test(a)) return !1;
1186
+ let o = Cn(r).replace(/\/$/, "");
1187
1187
  return i.startsWith(`${o}/`) ? t.test(i) || e.has(i.slice(i.lastIndexOf("/") + 1)) : !1;
1188
- }, En = (e, t, n) => Tn(t, n) ? `${e}${Cn(wn(t).split("?")[0] ?? t)}` : null, Dn = (e) => ({
1188
+ }, Tn = (e, t, n) => wn(t, n) ? `${e}${Sn(Cn(t).split("?")[0] ?? t)}` : null, En = (e) => ({
1189
1189
  name: "voltro:route-fast-refresh",
1190
1190
  enforce: "pre",
1191
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? bn : void 0,
1192
- load: (e) => e === bn ? Sn() : void 0,
1191
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? yn : void 0,
1192
+ load: (e) => e === yn ? xn() : void 0,
1193
1193
  transform: (t, n, r) => {
1194
1194
  if (r?.ssr === !0) return null;
1195
- let i = En(t, n, e);
1195
+ let i = Tn(t, n, e);
1196
1196
  return i === null ? null : {
1197
1197
  code: i,
1198
1198
  map: null
1199
1199
  };
1200
1200
  }
1201
- }), On = [
1201
+ }), Dn = [
1202
1202
  "static",
1203
1203
  "spa",
1204
1204
  "ssr",
1205
1205
  "isr"
1206
- ], kn = (e) => typeof e == "string" && On.includes(e), An = On.map((e) => `'${e}'`).join(" | "), jn = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${An}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, Mn = class extends Error {
1206
+ ], On = (e) => typeof e == "string" && Dn.includes(e), kn = Dn.map((e) => `'${e}'`).join(" | "), An = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${kn}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, jn = class extends Error {
1207
1207
  page;
1208
1208
  value;
1209
1209
  name = "InvalidRenderModeError";
1210
1210
  constructor(e, t) {
1211
- super(jn(e, t)), this.page = e, this.value = t;
1211
+ super(An(e, t)), this.page = e, this.value = t;
1212
1212
  }
1213
- }, Nn = (e, t = "<page>") => {
1213
+ }, Mn = (e, t = "<page>") => {
1214
1214
  if (e.renderMode !== void 0 && e.renderMode !== null) {
1215
- if (!kn(e.renderMode)) throw new Mn(t, String(e.renderMode));
1215
+ if (!On(e.renderMode)) throw new jn(t, String(e.renderMode));
1216
1216
  return e.renderMode;
1217
1217
  }
1218
1218
  return e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static");
1219
- }, Pn = (e, t = "<page>") => ({
1220
- renderMode: Nn(e, t),
1219
+ }, Nn = (e, t = "<page>") => ({
1220
+ renderMode: Mn(e, t),
1221
1221
  tenantAware: e.tenantAware === !0,
1222
1222
  revalidateMs: J(e.revalidate),
1223
1223
  staleWhileRevalidateMs: J(e.staleWhileRevalidate) ?? 0,
@@ -1226,7 +1226,7 @@ import {
1226
1226
  hasLoader: typeof e.loader == "function",
1227
1227
  hasMeta: e.meta != null,
1228
1228
  hasGetStaticPaths: typeof e.getStaticPaths == "function"
1229
- }), Fn = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, In = (e) => Fn.exec(e)?.[1] ?? null, Ln = /export\s+default\b|export\s*\{[^}]*\bas\s+default\b/, Rn = async (e, t) => {
1229
+ }), Pn = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, Fn = (e) => Pn.exec(e)?.[1] ?? null, In = /export\s+default\b|export\s*\{[^}]*\bas\s+default\b/, Ln = async (e, t) => {
1230
1230
  let n = (await Promise.all(t.map(async (t) => {
1231
1231
  let n;
1232
1232
  try {
@@ -1234,18 +1234,18 @@ import {
1234
1234
  } catch {
1235
1235
  return null;
1236
1236
  }
1237
- let r = In(n);
1238
- return r !== null && !kn(r) ? jn(f("src", "pages", t.file), r) : Ln.test(n) ? null : `${f("src", "pages", t.file)} is a route (it ends in .page.tsx) but exports no default.\n\n A page's default export IS its component — the router has nothing to render without it,\n and the failure would otherwise surface only in \`voltro build\`'s prerender as\n "SSR received a descriptor with no Component", long after the file was written.\n\n Fix: \`export default function Page() { … }\`, or — if this file is NOT a route —\n drop the .page suffix. Anything under src/pages/ without it is ordinary code and may\n live beside the page that uses it.`;
1237
+ let r = Fn(n);
1238
+ return r !== null && !On(r) ? An(f("src", "pages", t.file), r) : In.test(n) ? null : `${f("src", "pages", t.file)} is a route (it ends in .page.tsx) but exports no default.\n\n A page's default export IS its component — the router has nothing to render without it,\n and the failure would otherwise surface only in \`voltro build\`'s prerender as\n "SSR received a descriptor with no Component", long after the file was written.\n\n Fix: \`export default function Page() { … }\`, or — if this file is NOT a route —\n drop the .page suffix. Anything under src/pages/ without it is ordinary code and may\n live beside the page that uses it.`;
1239
1239
  }))).filter((e) => e !== null);
1240
1240
  if (n.length !== 0) throw Error(n.join("\n\n"));
1241
- }, zn = f(ie(), ".voltro"), Bn = f(zn, "runtime-registry.json"), Vn = 3e4, Hn = () => {
1241
+ }, Rn = f(ie(), ".voltro"), zn = f(Rn, "runtime-registry.json"), Bn = 3e4, Vn = () => {
1242
1242
  let e = Math.random().toString(36).slice(2, 10);
1243
- return `${Bn}.${process.pid}.${Date.now()}.${e}.tmp`;
1243
+ return `${zn}.${process.pid}.${Date.now()}.${e}.tmp`;
1244
+ }, Hn = async () => {
1245
+ await j.mkdir(Rn, { recursive: !0 });
1244
1246
  }, Un = async () => {
1245
- await j.mkdir(zn, { recursive: !0 });
1246
- }, Wn = async () => {
1247
1247
  try {
1248
- let e = await j.readFile(Bn, "utf8"), t = JSON.parse(e);
1248
+ let e = await j.readFile(zn, "utf8"), t = JSON.parse(e);
1249
1249
  return t.version !== 1 || !Array.isArray(t.apps) ? {
1250
1250
  version: 1,
1251
1251
  apps: []
@@ -1256,34 +1256,34 @@ import {
1256
1256
  apps: []
1257
1257
  };
1258
1258
  }
1259
- }, Gn = async (e) => {
1260
- await Un();
1261
- let t = Hn();
1259
+ }, Wn = async (e) => {
1260
+ await Hn();
1261
+ let t = Vn();
1262
1262
  try {
1263
1263
  await j.writeFile(t, JSON.stringify(e, null, 2), {
1264
1264
  encoding: "utf8",
1265
1265
  mode: 384
1266
- }), await j.rename(t, Bn), await j.chmod(Bn, 384).catch(() => {});
1266
+ }), await j.rename(t, zn), await j.chmod(zn, 384).catch(() => {});
1267
1267
  } catch (e) {
1268
1268
  try {
1269
1269
  await j.unlink(t);
1270
1270
  } catch {}
1271
1271
  throw e;
1272
1272
  }
1273
- }, Kn = (e) => {
1273
+ }, Gn = (e) => {
1274
1274
  try {
1275
1275
  return process.kill(e, 0), !0;
1276
1276
  } catch {
1277
1277
  return !1;
1278
1278
  }
1279
- }, qn = (e) => {
1279
+ }, Kn = (e) => {
1280
1280
  let t = Date.now();
1281
- return e.filter((e) => Kn(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Vn : !1);
1282
- }, Jn = async () => {
1283
- let e = await Wn(), t = qn(e.apps);
1281
+ return e.filter((e) => Gn(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Bn : !1);
1282
+ }, qn = async () => {
1283
+ let e = await Un(), t = Kn(e.apps);
1284
1284
  if (t.length === e.apps.length) return e;
1285
1285
  try {
1286
- await Gn({
1286
+ await Wn({
1287
1287
  version: 1,
1288
1288
  apps: t
1289
1289
  });
@@ -1292,33 +1292,33 @@ import {
1292
1292
  version: 1,
1293
1293
  apps: t
1294
1294
  };
1295
- }, Yn = async (e) => {
1296
- let t = await Wn(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
1295
+ }, Jn = async (e) => {
1296
+ let t = await Un(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
1297
1297
  ...e,
1298
1298
  ...i !== void 0 && i !== "" ? { inspectToken: i } : {},
1299
1299
  registeredAt: r >= 0 ? t.apps[r].registeredAt : n,
1300
1300
  heartbeatAt: n
1301
1301
  };
1302
- await Gn({
1302
+ await Wn({
1303
1303
  version: 1,
1304
1304
  apps: r >= 0 ? t.apps.map((e, t) => t === r ? a : e) : [...t.apps, a]
1305
1305
  });
1306
- }, Xn = async (e) => {
1306
+ }, Yn = async (e) => {
1307
1307
  try {
1308
- let t = await Wn(), n = t.apps.filter((t) => t.id !== e);
1308
+ let t = await Un(), n = t.apps.filter((t) => t.id !== e);
1309
1309
  if (n.length === t.apps.length) return;
1310
- await Gn({
1310
+ await Wn({
1311
1311
  version: 1,
1312
1312
  apps: n
1313
1313
  });
1314
1314
  } catch {}
1315
- }, Zn = (e, t, n) => `${e}:${t}:${n}`, X = f(ie(), ".voltro", "logs"), Qn = () => {
1315
+ }, Xn = (e, t, n) => `${e}:${t}:${n}`, X = f(ie(), ".voltro", "logs"), Zn = () => {
1316
1316
  let e = Number(process.env.VOLTRO_LOG_FILE_TTL_MS);
1317
1317
  return Number.isFinite(e) && e > 0 ? e : 3600 * 1e3;
1318
- }, $n = !1, er = () => {
1319
- if ($n) return;
1320
- $n = !0;
1321
- let e = Date.now() - Qn(), t = [];
1318
+ }, Qn = !1, $n = () => {
1319
+ if (Qn) return;
1320
+ Qn = !0;
1321
+ let e = Date.now() - Zn(), t = [];
1322
1322
  try {
1323
1323
  t = N(X);
1324
1324
  } catch {
@@ -1331,8 +1331,8 @@ import {
1331
1331
  P(t).mtimeMs < e && ee(t);
1332
1332
  } catch {}
1333
1333
  }
1334
- }, tr = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), nr = (e, t) => f(X, `${tr(e)}-${t}.log`), rr = (e) => {
1335
- let t = tr(e), n = [];
1334
+ }, er = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), tr = (e, t) => f(X, `${er(e)}-${t}.log`), nr = (e) => {
1335
+ let t = er(e), n = [];
1336
1336
  try {
1337
1337
  n = N(X);
1338
1338
  } catch {
@@ -1349,12 +1349,12 @@ import {
1349
1349
  } catch {}
1350
1350
  }
1351
1351
  return i;
1352
- }, ir = (e) => {
1352
+ }, rr = (e) => {
1353
1353
  try {
1354
1354
  k(X, { recursive: !0 });
1355
1355
  } catch {}
1356
- er();
1357
- let t = nr(e, process.pid), n = A(t, "w"), r = (e) => {
1356
+ $n();
1357
+ let t = tr(e, process.pid), n = A(t, "w"), r = (e) => {
1358
1358
  let t = {
1359
1359
  ts: e.ts.getTime(),
1360
1360
  level: e.level,
@@ -1395,7 +1395,7 @@ import {
1395
1395
  a(), o(), process.off("exit", o), process.off("uncaughtException", s), process.off("unhandledRejection", s);
1396
1396
  }
1397
1397
  };
1398
- }, ar = async (e, t) => {
1398
+ }, ir = async (e, t) => {
1399
1399
  let n;
1400
1400
  try {
1401
1401
  n = await j.readFile(e, "utf8");
@@ -1409,11 +1409,11 @@ import {
1409
1409
  i.push(t);
1410
1410
  } catch {}
1411
1411
  return t?.max !== void 0 && i.length > t.max ? i.slice(i.length - t.max) : i;
1412
- }, or = T({ scope: "voltro:dashboard" }), sr = re(import.meta.url), cr = 5179, lr = (e) => {
1412
+ }, ar = T({ scope: "voltro:dashboard" }), or = re(import.meta.url), sr = 5179, cr = (e) => {
1413
1413
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1414
1414
  if (t && O(f(m(t), "app.config.ts"))) return m(t);
1415
1415
  try {
1416
- let e = u(sr.resolve("@voltro/dashboard/package.json"));
1416
+ let e = u(or.resolve("@voltro/dashboard/package.json"));
1417
1417
  if (O(f(e, "app.config.ts"))) return e;
1418
1418
  } catch {}
1419
1419
  let n = f("voltro-devtools", "apps", "dashboard"), r = m(e);
@@ -1425,7 +1425,7 @@ import {
1425
1425
  r = t;
1426
1426
  }
1427
1427
  return null;
1428
- }, ur = "VOLTRO_IS_DASHBOARD", dr = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1428
+ }, lr = "VOLTRO_IS_DASHBOARD", ur = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1429
1429
  let i = _e({
1430
1430
  port: e,
1431
1431
  host: t
@@ -1433,45 +1433,45 @@ import {
1433
1433
  a || (a = !0, i.destroy(), r(e));
1434
1434
  };
1435
1435
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
1436
- }), fr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), pr = () => process.env[ur] === "1", mr = () => process.stdout.isTTY === !0, hr = f(ie(), ".voltro", "dashboard-launch.lock"), gr = 1e4, _r = async () => {
1436
+ }), dr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), fr = () => process.env[lr] === "1", pr = () => process.stdout.isTTY === !0, mr = f(ie(), ".voltro", "dashboard-launch.lock"), hr = 1e4, gr = async () => {
1437
1437
  try {
1438
- await j.mkdir(u(hr), { recursive: !0 });
1439
- let e = await j.open(hr, "wx");
1438
+ await j.mkdir(u(mr), { recursive: !0 });
1439
+ let e = await j.open(mr, "wx");
1440
1440
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1441
1441
  } catch {
1442
1442
  try {
1443
- let e = await j.stat(hr);
1444
- if (Date.now() - e.mtimeMs > gr) return await j.unlink(hr).catch(() => void 0), _r();
1443
+ let e = await j.stat(mr);
1444
+ if (Date.now() - e.mtimeMs > hr) return await j.unlink(mr).catch(() => void 0), gr();
1445
1445
  } catch {}
1446
1446
  return !1;
1447
1447
  }
1448
- }, vr = async () => {
1448
+ }, _r = async () => {
1449
1449
  try {
1450
- await j.unlink(hr);
1450
+ await j.unlink(mr);
1451
1451
  } catch {}
1452
- }, yr = async (e) => {
1452
+ }, vr = async (e) => {
1453
1453
  let t = e.port ?? 5179;
1454
- if (fr()) return {
1454
+ if (dr()) return {
1455
1455
  status: "skipped",
1456
1456
  reason: "disabled by flag/env",
1457
1457
  port: t
1458
1458
  };
1459
- if (pr()) return {
1459
+ if (fr()) return {
1460
1460
  status: "skipped",
1461
1461
  reason: "this process IS the dashboard",
1462
1462
  port: t
1463
1463
  };
1464
- if (!mr()) return {
1464
+ if (!pr()) return {
1465
1465
  status: "skipped",
1466
1466
  reason: "stdout is not a TTY (CI/smoke)",
1467
1467
  port: t
1468
1468
  };
1469
- if (!await _r()) return {
1469
+ if (!await gr()) return {
1470
1470
  status: "skipped",
1471
1471
  reason: "another voltro process is currently launching the dashboard",
1472
1472
  port: t
1473
1473
  };
1474
- if (await dr(t)) return await vr(), {
1474
+ if (await ur(t)) return await _r(), {
1475
1475
  status: "already-running",
1476
1476
  port: t
1477
1477
  };
@@ -1488,7 +1488,7 @@ import {
1488
1488
  stdio: "ignore",
1489
1489
  env: {
1490
1490
  ...process.env,
1491
- [ur]: "1",
1491
+ [lr]: "1",
1492
1492
  VOLTRO_DASHBOARD_PORT: String(t)
1493
1493
  }
1494
1494
  });
@@ -1496,22 +1496,22 @@ import {
1496
1496
  if (a.exitCode === null && a.signalCode === null) try {
1497
1497
  a.kill("SIGTERM");
1498
1498
  } catch {}
1499
- }), or.info(`auto-launching dashboard at http://localhost:${t}`, {
1499
+ }), ar.info(`auto-launching dashboard at http://localhost:${t}`, {
1500
1500
  port: t,
1501
1501
  mode: i,
1502
1502
  prebuilt: r
1503
- }), r || or.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), or.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1504
- vr();
1503
+ }), r || ar.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), ar.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1504
+ _r();
1505
1505
  }, 4e3).unref(), {
1506
1506
  status: "launched",
1507
1507
  port: t
1508
1508
  };
1509
- }, br = class extends Error {
1509
+ }, yr = class extends Error {
1510
1510
  _voltroDeferral = !0;
1511
1511
  constructor(e) {
1512
1512
  super(e), this.name = "DeferralNotSupportedError";
1513
1513
  }
1514
- }, xr = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Sr = (e) => {
1514
+ }, br = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, xr = (e) => {
1515
1515
  let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1516
1516
  for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1517
1517
  let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
@@ -1526,7 +1526,7 @@ import {
1526
1526
  ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
1527
1527
  });
1528
1528
  } catch (e) {
1529
- throw new br(e instanceof Error ? e.message : String(e));
1529
+ throw new yr(e instanceof Error ? e.message : String(e));
1530
1530
  }
1531
1531
  return {
1532
1532
  loaderData: n.renderData,
@@ -1542,8 +1542,8 @@ import {
1542
1542
  ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1543
1543
  }
1544
1544
  };
1545
- }, Cr = (e) => {
1546
- let { helpers: t, renderInput: n } = e, r = Sr({
1545
+ }, Sr = (e) => {
1546
+ let { helpers: t, renderInput: n } = e, r = xr({
1547
1547
  helpers: t,
1548
1548
  page: e.page,
1549
1549
  pathname: n.pathname,
@@ -1564,37 +1564,37 @@ import {
1564
1564
  stateScript: t.renderRouterStateScript(r.stateInput),
1565
1565
  hasDeferred: r.hasDeferred
1566
1566
  };
1567
- }, wr = (e) => {
1567
+ }, Cr = (e) => {
1568
1568
  let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
1569
1569
  return {
1570
1570
  body: t,
1571
1571
  meta: n
1572
1572
  };
1573
- }, Tr = (e) => [
1573
+ }, wr = (e) => [
1574
1574
  ...e.extra ?? [],
1575
1575
  e.helpers.renderMetaToHtml(e.meta),
1576
1576
  `<meta name="voltro-interactive" content="${e.interactive}" />`,
1577
1577
  ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
1578
1578
  e.prepared.stateScript
1579
- ].filter((e) => e.length > 0).join("\n "), Er = "<div id=\"root\"></div>", Dr = "<div id=\"root\">", Or = "</div>", kr = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Ar = /\bsrc=["']([^"']+)["']/i, jr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Mr = (e) => {
1580
- let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(kr, (e) => {
1581
- let r = Ar.exec(e)?.[1];
1579
+ ].filter((e) => e.length > 0).join("\n "), Tr = "<div id=\"root\"></div>", Er = "<div id=\"root\">", Dr = "</div>", Or = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, kr = /\bsrc=["']([^"']+)["']/i, Ar = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, jr = (e) => {
1580
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Or, (e) => {
1581
+ let r = kr.exec(e)?.[1];
1582
1582
  return r === void 0 || t(r) ? e : (n.push(r), "");
1583
1583
  });
1584
- e.inlineModuleScriptsAsync && (r = r.replace(jr, "<script async$1>"));
1585
- let i = r.indexOf(Er);
1586
- if (i === -1) throw Error(`[voltro] the generated shell has no \`${Er}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1584
+ e.inlineModuleScriptsAsync && (r = r.replace(Ar, "<script async$1>"));
1585
+ let i = r.indexOf(Tr);
1586
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${Tr}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1587
1587
  return {
1588
- head: `${r.slice(0, i)}${Dr}`,
1589
- tail: `${Or}${r.slice(i + 21)}`,
1588
+ head: `${r.slice(0, i)}${Er}`,
1589
+ tail: `${Dr}${r.slice(i + 21)}`,
1590
1590
  bootstrapModules: n
1591
1591
  };
1592
- }, Nr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Pr = (e) => {
1592
+ }, Mr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Nr = (e) => {
1593
1593
  let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1594
1594
  if (s || !o || a === null) return;
1595
1595
  s = !0, t.statusCode = e.statusCode ?? 200;
1596
1596
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1597
- t.flushHeaders?.(), t.write(Nr({
1597
+ t.flushHeaders?.(), t.write(Mr({
1598
1598
  head: n.head,
1599
1599
  headInjection: i(a.meta),
1600
1600
  htmlLang: r
@@ -1624,14 +1624,14 @@ import {
1624
1624
  return;
1625
1625
  }
1626
1626
  c();
1627
- }, Z = T({ scope: "voltro:dev:web" }), Fr = T({ scope: "vite" }), Ir = await (async () => {
1627
+ }, Z = T({ scope: "voltro:dev:web" }), Pr = T({ scope: "vite" }), Fr = await (async () => {
1628
1628
  try {
1629
1629
  let e = f(u(h(import.meta.url)), "..", "package.json"), t = await j.readFile(e, "utf8");
1630
1630
  return JSON.parse(t).version ?? "0.0.0";
1631
1631
  } catch {
1632
1632
  return "0.0.0";
1633
1633
  }
1634
- })(), Lr = async () => {
1634
+ })(), Ir = async () => {
1635
1635
  try {
1636
1636
  let e = u(h(import.meta.url)), t = m(e, "..", "..", "devtools");
1637
1637
  if (O(f(t, "package.json"))) return t;
@@ -1640,7 +1640,7 @@ import {
1640
1640
  } catch {
1641
1641
  return null;
1642
1642
  }
1643
- }, Rr = (e, t) => e.disableDevtools || !t ? [] : [
1643
+ }, Lr = (e, t) => e.disableDevtools || !t ? [] : [
1644
1644
  "",
1645
1645
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1646
1646
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1650,12 +1650,12 @@ import {
1650
1650
  " await import('@voltro/devtools/styles.css')",
1651
1651
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1652
1652
  "}"
1653
- ], zr = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Br = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Vr = (e) => e.sentry ? [
1653
+ ], Rr = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], zr = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Br = (e) => e.sentry ? [
1654
1654
  "",
1655
1655
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1656
1656
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1657
1657
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1658
- ] : [], Hr = (e) => e.env ? ["import './env.public'"] : [], Ur = (e) => {
1658
+ ] : [], Vr = (e) => e.env ? ["import './env.public'"] : [], Hr = (e) => {
1659
1659
  let t = [], n = m(e);
1660
1660
  for (;;) {
1661
1661
  O(f(n, "pnpm-workspace.yaml")) && t.push(n);
@@ -1664,14 +1664,14 @@ import {
1664
1664
  n = e;
1665
1665
  }
1666
1666
  return t;
1667
- }, Wr = gn, Gr = (e) => {
1667
+ }, Ur = gn, Wr = (e) => {
1668
1668
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1669
1669
  let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1670
1670
  if (t) return `island-${t[1]}`;
1671
- }, Kr = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, qr = (e) => e.startsWith("(") && e.endsWith(")"), Jr = (e) => e.filter((e) => !qr(e)), Yr = (e) => {
1672
- let n = e.replace(t, "").split("/").filter(Boolean).filter((e) => !qr(e)), r = n.length > 0 && n[n.length - 1] === "index" ? n.slice(0, -1) : n;
1673
- return r.length === 0 ? "/" : "/" + r.join("/");
1674
- }, Xr = (e) => `${e.replace(t, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Q = (e, t) => e === "" ? `Root${t}` : `${e.split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Root"}${t}`, $ = async (n) => {
1671
+ }, Gr = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Kr = (e) => e.startsWith("(") && e.endsWith(")"), qr = (e) => e.filter((e) => !Kr(e)), Jr = (e) => {
1672
+ let n = e.replace(t, "").split("/").filter(Boolean).filter((e) => !Kr(e));
1673
+ return n.length === 0 ? "/" : "/" + n.join("/");
1674
+ }, Yr = (e) => `${e.replace(t, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Q = (e, t) => e === "" ? `Root${t}` : `${e.split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Root"}${t}`, $ = async (n) => {
1675
1675
  let r = [], i = [], a = async (n, o) => {
1676
1676
  let s = [];
1677
1677
  try {
@@ -1679,17 +1679,17 @@ import {
1679
1679
  } catch {
1680
1680
  return;
1681
1681
  }
1682
- let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Wr(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1682
+ let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Ur(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1683
1683
  if (l.some((t) => e.has(t))) {
1684
1684
  let t = u.has("layout.tsx"), r = !1;
1685
1685
  if (t) try {
1686
1686
  let e = await j.readFile(f(n, "layout.tsx"), "utf8");
1687
- r = Kr.test(e);
1687
+ r = Gr.test(e);
1688
1688
  } catch {}
1689
1689
  i.push({
1690
1690
  dir: d,
1691
1691
  chain: o,
1692
- contributesToUrl: o.length === 0 || !qr(o[o.length - 1]),
1692
+ contributesToUrl: o.length === 0 || !Kr(o[o.length - 1]),
1693
1693
  hasLayout: t,
1694
1694
  hasLayoutLoader: r,
1695
1695
  hasError: u.has("error.tsx"),
@@ -1703,8 +1703,8 @@ import {
1703
1703
  let n = d ? `${d}/${e}` : e;
1704
1704
  r.push({
1705
1705
  file: n,
1706
- pattern: Yr(n),
1707
- ident: Xr(n),
1706
+ pattern: Jr(n),
1707
+ ident: Yr(n),
1708
1708
  dirChain: o
1709
1709
  });
1710
1710
  }
@@ -1723,14 +1723,14 @@ import {
1723
1723
  dirs: s,
1724
1724
  orphanedSpecials: c
1725
1725
  };
1726
- }, Zr = (e, t) => {
1726
+ }, Xr = (e, t) => {
1727
1727
  let n = [];
1728
1728
  for (let r = 0; r <= t.length; r++) {
1729
1729
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1730
1730
  a && n.push(a);
1731
1731
  }
1732
1732
  return n;
1733
- }, Qr = async (e) => {
1733
+ }, Zr = async (e) => {
1734
1734
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1735
1735
  return {
1736
1736
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1752,10 +1752,10 @@ import {
1752
1752
  })),
1753
1753
  segmentLoaderData: o
1754
1754
  };
1755
- }, $r = (e) => {
1756
- let t = Jr(e);
1755
+ }, Qr = (e) => {
1756
+ let t = qr(e);
1757
1757
  return t.length === 0 ? "" : "/" + t.join("/");
1758
- }, ei = [
1758
+ }, $r = [
1759
1759
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1760
1760
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1761
1761
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1848,7 +1848,7 @@ import {
1848
1848
  " _vdtErrorStart('Build error')",
1849
1849
  " })",
1850
1850
  "}"
1851
- ].join("\n"), ti = (e) => {
1851
+ ].join("\n"), ei = (e) => {
1852
1852
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1853
1853
  for (let e of r) e.startsWith("[[...") && e.endsWith("]]") ? (i.push("(.*)"), t.push(e.slice(5, -2)), n += 2) : e.startsWith("[...") && e.endsWith("]") ? (i.push("(.+)"), t.push(e.slice(4, -1)), n += 3) : e.startsWith("[") && e.endsWith("]") ? (i.push("([^/]+)"), t.push(e.slice(1, -1)), n += 1) : i.push(e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
1854
1854
  let a = i.join("/");
@@ -1857,8 +1857,8 @@ import {
1857
1857
  paramNames: t,
1858
1858
  priority: n
1859
1859
  };
1860
- }, ni = (e) => e.map((e) => {
1861
- let { regex: t, paramNames: n, priority: r } = ti(e.pattern);
1860
+ }, ti = (e) => e.map((e) => {
1861
+ let { regex: t, paramNames: n, priority: r } = ei(e.pattern);
1862
1862
  return {
1863
1863
  pattern: e.pattern,
1864
1864
  file: e.file,
@@ -1867,7 +1867,7 @@ import {
1867
1867
  paramNames: n,
1868
1868
  priority: r
1869
1869
  };
1870
- }).slice().sort((e, t) => e.priority - t.priority), ri = (e, t) => {
1870
+ }).slice().sort((e, t) => e.priority - t.priority), ni = (e, t) => {
1871
1871
  for (let n of t) {
1872
1872
  let t = n.regex.exec(e);
1873
1873
  if (!t) continue;
@@ -1879,7 +1879,7 @@ import {
1879
1879
  };
1880
1880
  }
1881
1881
  return null;
1882
- }, ii = async (e, t) => {
1882
+ }, ri = async (e, t) => {
1883
1883
  let n = e;
1884
1884
  for (;;) {
1885
1885
  let e = f(n, "node_modules", t);
@@ -1893,7 +1893,7 @@ import {
1893
1893
  if (r === n) return null;
1894
1894
  n = r;
1895
1895
  }
1896
- }, ai = async (e) => {
1896
+ }, ii = async (e) => {
1897
1897
  try {
1898
1898
  let t = await import(g(f(e, "app.config.ts")).href), n = t.default?.port, r = typeof n == "number" ? n : 4e3, i = t.default?.transport?.wsPath, a = typeof i == "string" && i.startsWith("/") ? i : void 0;
1899
1899
  return a ? {
@@ -1902,7 +1902,7 @@ import {
1902
1902
  } : { port: r };
1903
1903
  } catch {}
1904
1904
  return { port: 4e3 };
1905
- }, oi = (e, t) => ({
1905
+ }, ai = (e, t) => ({
1906
1906
  name: e,
1907
1907
  pkg: t.package,
1908
1908
  browserWsUrl: t.url,
@@ -1910,7 +1910,7 @@ import {
1910
1910
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1911
1911
  ...t.headers ? { headers: t.headers } : {},
1912
1912
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1913
- }), si = (e, t, n) => {
1913
+ }), oi = (e, t, n) => {
1914
1914
  let r = t.transport?.wsPath ?? n.wsPath;
1915
1915
  return {
1916
1916
  name: e,
@@ -1922,7 +1922,7 @@ import {
1922
1922
  ...t.headers ? { headers: t.headers } : {},
1923
1923
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1924
1924
  };
1925
- }, ci = (e) => {
1925
+ }, si = (e) => {
1926
1926
  let t = /* @__PURE__ */ new Map();
1927
1927
  for (let n of e) {
1928
1928
  if (n.proxyTarget === void 0) continue;
@@ -1930,43 +1930,43 @@ import {
1930
1930
  if (e) throw Error(`[voltro] api ${JSON.stringify(n.name)} and ${JSON.stringify(e)} both resolve the same-origin WS path ${JSON.stringify(n.browserWsUrl)}. A custom transport.wsPath must be unique per origin (one api per origin may use a fixed path). Give each a distinct wsPath, or drop the override to use the default /ws/<name>.`);
1931
1931
  t.set(n.browserWsUrl, n.name);
1932
1932
  }
1933
- }, li = async (e, t) => {
1933
+ }, ci = async (e, t) => {
1934
1934
  let n = Object.entries(t.apis ?? {}), r = [];
1935
1935
  for (let [t, i] of n) {
1936
1936
  if (i.url) {
1937
- r.push(oi(t, i));
1937
+ r.push(ai(t, i));
1938
1938
  continue;
1939
1939
  }
1940
- let n = await ii(e, i.package);
1940
+ let n = await ri(e, i.package);
1941
1941
  if (!n) throw Error(`[voltro dev] api ${JSON.stringify(t)} (package ${JSON.stringify(i.package)}) is not a workspace dep and has no \`url\` set in app.config.ts. External apis need an explicit \`url\` because the framework can't discover their dev port.`);
1942
- r.push(si(t, i, await ai(n)));
1942
+ r.push(oi(t, i, await ii(n)));
1943
1943
  }
1944
- return ci(r), r;
1945
- }, ui = (e) => {
1944
+ return si(r), r;
1945
+ }, li = (e) => {
1946
1946
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
1947
1947
  let t = new URL(e);
1948
1948
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
1949
1949
  } catch {
1950
1950
  return;
1951
1951
  }
1952
- }, di = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, fi = (e) => process.env[di(e)] ?? process.env.VOLTRO_API_ORIGIN, pi = (e, t) => {
1952
+ }, ui = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, di = (e) => process.env[ui(e)] ?? process.env.VOLTRO_API_ORIGIN, fi = (e, t) => {
1953
1953
  if (!e) return;
1954
- let n = fi(e.name) ?? e.serverOrigin;
1954
+ let n = di(e.name) ?? e.serverOrigin;
1955
1955
  if (n) {
1956
- let e = ui(n);
1956
+ let e = li(n);
1957
1957
  if (e) return e;
1958
1958
  }
1959
1959
  if (t?.allowDevProxy && e.proxyTarget) {
1960
- let t = ui(e.proxyTarget);
1960
+ let t = li(e.proxyTarget);
1961
1961
  if (t) return t;
1962
1962
  }
1963
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return ui(e.browserWsUrl);
1964
- }, mi = (e, t, n) => {
1963
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return li(e.browserWsUrl);
1964
+ }, pi = (e, t, n) => {
1965
1965
  if (!e) {
1966
1966
  if (n?.apiName === void 0) return;
1967
1967
  let e = n.apiName;
1968
1968
  return async () => {
1969
- throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${di(e)} (or VOLTRO_API_ORIGIN, or apis.${e}.serverUrl in app.config.ts) to the api's internal origin, e.g. http://api.<namespace>.svc.cluster.local. The browser transport is unaffected.`);
1969
+ throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${ui(e)} (or VOLTRO_API_ORIGIN, or apis.${e}.serverUrl in app.config.ts) to the api's internal origin, e.g. http://api.<namespace>.svc.cluster.local. The browser transport is unaffected.`);
1970
1970
  };
1971
1971
  }
1972
1972
  return async (r, i) => {
@@ -1988,7 +1988,7 @@ import {
1988
1988
  });
1989
1989
  } catch (t) {
1990
1990
  let i = t?.cause?.code ?? String(t?.message ?? t);
1991
- throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${di(n.apiName)} / VOLTRO_API_ORIGIN` : "Set the api server origin"} to the api's SSR-reachable origin (internal cluster DNS in a split deployment).`, { cause: t });
1991
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${ui(n.apiName)} / VOLTRO_API_ORIGIN` : "Set the api server origin"} to the api's SSR-reachable origin (internal cluster DNS in a split deployment).`, { cause: t });
1992
1992
  }
1993
1993
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
1994
1994
  let s = await o.json();
@@ -2006,8 +2006,8 @@ import {
2006
2006
  }
2007
2007
  if (u) return l;
2008
2008
  };
2009
- }, hi = async (e, t, n, r = {}) => {
2010
- let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = O(f(e, "node_modules", "@voltro", "devtools", "package.json")) || await Lr() !== null, s = t.theme === "system" ? [
2009
+ }, mi = async (e, t, n, r = {}) => {
2010
+ let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = O(f(e, "node_modules", "@voltro", "devtools", "package.json")) || await Ir() !== null, s = t.theme === "system" ? [
2011
2011
  " <script>",
2012
2012
  " (function () {",
2013
2013
  " var root = document.documentElement",
@@ -2046,8 +2046,8 @@ import {
2046
2046
  "</html>",
2047
2047
  ""
2048
2048
  ].join("\n"), l = f(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: p } = await $(l);
2049
- await Rn(l, u);
2050
- for (let e of p) Z.warn(`src/pages/${e.dir || "."}/ contains ${e.files.join(", ")} but no *.page.tsx at or below it — ${e.files.length > 1 ? "those files are" : "that file is"} inert. A layout/error/loading/not-found file only applies to routes in its own directory tree; if this is an ordinary component, rename it so it does not read as a route boundary.`);
2049
+ await Ln(l, u);
2050
+ for (let e of p) Z.warn(`src/pages/${e.dir || "."}/ contains ${e.files.join(", ")} but no page.tsx at or below it — ${e.files.length > 1 ? "those files are" : "that file is"} inert. A layout/error/loading/not-found file only applies to routes in its own directory tree; if this is an ordinary component, rename it so it does not read as a route boundary.`);
2051
2051
  let m = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppGroup`, h = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppDescriptors`, g = n.map((e) => `import { appGroup as ${m(e.name)}, appDescriptors as ${h(e.name)} } from '${e.pkg}/rpcGroup'`);
2052
2052
  n.some((e) => e.hasAuthHeaders) && (g.push("import __voltroAppConfig from '../app.config'"), g.push("const __voltroAuthHeaders = (__voltroAppConfig as { readonly apis?: Record<string, { readonly authHeaders?: () => Record<string, string> | Promise<Record<string, string>> }> }).apis"));
2053
2053
  let _ = n.map((e) => {
@@ -2061,13 +2061,13 @@ import {
2061
2061
  e.hasLayout && e.hasLayoutLoader ? n.push(`import * as ${Q(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && n.push(`import ${Q(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && n.push(`import ${Q(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && n.push(`import ${Q(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && n.push(`import ${Q(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2062
2062
  }
2063
2063
  let r = u.map((e) => {
2064
- let t = Zr(d, e.dirChain).map((e) => {
2064
+ let t = Xr(d, e.dirChain).map((e) => {
2065
2065
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2066
2066
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasLayoutLoader && t.push(`loader: refs.layoutLoaders[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), e.hasPending && t.push(`Pending: refs.pendings[${n}]`), ` { ${t.join(", ")} }`;
2067
2067
  }).join(",\n");
2068
2068
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2069
2069
  }), i = d.filter((e) => e.hasNotFound).map((e) => {
2070
- let t = $r(e.chain), n = Zr(d, e.chain).map((e) => {
2070
+ let t = Qr(e.chain), n = Xr(d, e.chain).map((e) => {
2071
2071
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2072
2072
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2073
2073
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
@@ -2306,14 +2306,14 @@ import {
2306
2306
  "// resolved apis map. Side-effect only — no local component definitions —",
2307
2307
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2308
2308
  "",
2309
- ...Hr(t),
2309
+ ...Vr(t),
2310
2310
  "import { mount } from '@voltro/web'",
2311
2311
  ...g,
2312
2312
  "import { App } from './app'",
2313
2313
  "import { preloadCurrentRoute } from './routeTable'",
2314
+ ...zr(t),
2315
+ ...Lr(t, o),
2314
2316
  ...Br(t),
2315
- ...Rr(t, o),
2316
- ...Vr(t),
2317
2317
  "",
2318
2318
  "// Preload the current route's page chunk BEFORE hydration so the first",
2319
2319
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2330,10 +2330,10 @@ import {
2330
2330
  " apis: {",
2331
2331
  ..._,
2332
2332
  " },",
2333
- ...zr(t, o),
2333
+ ...Rr(t, o),
2334
2334
  "})",
2335
2335
  "",
2336
- ei
2336
+ $r
2337
2337
  ].join("\n");
2338
2338
  } else v = "", y = "", b = [
2339
2339
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2341,22 +2341,22 @@ import {
2341
2341
  "// and calls mount(). Side-effect only, no component definitions, so the",
2342
2342
  "// user's component file remains the Fast Refresh boundary.",
2343
2343
  "",
2344
- ...Hr(t),
2344
+ ...Vr(t),
2345
2345
  "import { mount } from '@voltro/web'",
2346
2346
  ...g,
2347
2347
  "import App from '../src/App'",
2348
+ ...zr(t),
2349
+ ...Lr(t, o),
2348
2350
  ...Br(t),
2349
- ...Rr(t, o),
2350
- ...Vr(t),
2351
2351
  "",
2352
2352
  "mount(App, {",
2353
2353
  " apis: {",
2354
2354
  ..._,
2355
2355
  " },",
2356
- ...zr(t, o),
2356
+ ...Rr(t, o),
2357
2357
  "})",
2358
2358
  "",
2359
- ei
2359
+ $r
2360
2360
  ].join("\n");
2361
2361
  let x = f(e, ".framework");
2362
2362
  await j.mkdir(x, { recursive: !0 }), t.env ? await Qe(x, r) : await j.rm(f(x, "env.public.ts"), { force: !0 }), await j.writeFile(f(x, "index.html"), c, "utf8"), await j.writeFile(f(x, "main.tsx"), b, "utf8"), v ? (await j.writeFile(f(x, "app.tsx"), v, "utf8"), await j.writeFile(f(x, "routeTable.ts"), y, "utf8")) : (await j.rm(f(x, "app.tsx"), { force: !0 }), await j.rm(f(x, "routeTable.ts"), { force: !0 }));
@@ -2373,7 +2373,7 @@ import {
2373
2373
  Z.warn(`could not add ${E.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2374
2374
  }
2375
2375
  }
2376
- }, gi = async (e, t) => {
2376
+ }, hi = async (e, t) => {
2377
2377
  try {
2378
2378
  let n = f(u(e), "project.json");
2379
2379
  if (!O(n)) return;
@@ -2386,16 +2386,16 @@ import {
2386
2386
  projectJson: n
2387
2387
  });
2388
2388
  } catch {}
2389
- }, _i = (e) => f(e, ".framework", "dist", "server", "appConfig.js"), vi = async (e) => {
2390
- let t = _i(e), n = O(t) ? t : f(e, "app.config.ts");
2389
+ }, gi = (e) => f(e, ".framework", "dist", "server", "appConfig.js"), _i = async (e) => {
2390
+ let t = gi(e), n = O(t) ? t : f(e, "app.config.ts");
2391
2391
  try {
2392
2392
  let e = (await import(g(n).href)).default;
2393
2393
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2394
2394
  } catch {
2395
2395
  return null;
2396
2396
  }
2397
- }, yi = async (e) => {
2398
- let t = await vi(e);
2397
+ }, vi = async (e) => {
2398
+ let t = await _i(e);
2399
2399
  if (!t) return {
2400
2400
  ran: !1,
2401
2401
  exitCode: 0
@@ -2403,7 +2403,7 @@ import {
2403
2403
  pn();
2404
2404
  let n = It();
2405
2405
  Kt(n), Z.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2406
- let u = await li(e, t);
2406
+ let u = await ci(e, t);
2407
2407
  for (let e of u) Z.info("api wired", {
2408
2408
  name: e.name,
2409
2409
  pkg: e.pkg,
@@ -2422,13 +2422,13 @@ import {
2422
2422
  log: Z,
2423
2423
  generateTypes: !0
2424
2424
  }), h = d.publicValues;
2425
- await hi(e, t, u, h), Z.debug("generated framework entry files", { files: [
2425
+ await mi(e, t, u, h), Z.debug("generated framework entry files", { files: [
2426
2426
  "index.html",
2427
2427
  ".framework/main.tsx",
2428
2428
  ...t.env ? [".framework/env.public.ts"] : []
2429
2429
  ] });
2430
- let g = process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT ? Number(process.env.VOLTRO_DASHBOARD_PORT) : t.port ?? 5173, _ = t.name ?? "unnamed", v = Zn("web", _, g), y = ir(_);
2431
- await Yn({
2430
+ let g = process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT ? Number(process.env.VOLTRO_DASHBOARD_PORT) : t.port ?? 5173, _ = t.name ?? "unnamed", v = Xn("web", _, g), y = rr(_);
2431
+ await Jn({
2432
2432
  id: v,
2433
2433
  name: _,
2434
2434
  kind: "web",
@@ -2436,7 +2436,7 @@ import {
2436
2436
  pid: process.pid,
2437
2437
  status: "booting",
2438
2438
  logFile: y.path
2439
- }).catch(() => {}), await gi(e, g);
2439
+ }).catch(() => {}), await hi(e, g);
2440
2440
  let { pages: b, dirs: x } = await $(f(e, "src", "pages")), S = x.map((e) => ({
2441
2441
  dir: e.dir,
2442
2442
  hasLayout: e.hasLayout,
@@ -2472,7 +2472,7 @@ import {
2472
2472
  ...r.devDependencies
2473
2473
  });
2474
2474
  await Promise.all(i.map(async (n) => {
2475
- let r = await ii(e, n);
2475
+ let r = await ri(e, n);
2476
2476
  if (!r) return;
2477
2477
  let i = f(r, "src");
2478
2478
  try {
@@ -2484,7 +2484,7 @@ import {
2484
2484
  }, P = f(e, "src", "pages"), ee = (e) => e.endsWith(".tsx") && (e === P || e.startsWith(P + "/")), F = (e) => e === P || e.startsWith(P + "/"), te = async (n) => {
2485
2485
  try {
2486
2486
  let r = Date.now();
2487
- await hi(e, t, u, h);
2487
+ await mi(e, t, u, h);
2488
2488
  let { pages: i } = await $(P);
2489
2489
  await Pt({
2490
2490
  appRoot: e,
@@ -2578,7 +2578,7 @@ import {
2578
2578
  }
2579
2579
  try {
2580
2580
  let n = Date.now();
2581
- await hi(e, r, await li(e, r)), re = r, t.ws && t.ws.send({
2581
+ await mi(e, r, await ci(e, r)), re = r, t.ws && t.ws.send({
2582
2582
  type: "full-reload",
2583
2583
  path: "*"
2584
2584
  }), Z.info("app.config.ts soft-regen", {
@@ -2618,7 +2618,7 @@ import {
2618
2618
  let n = /* @__PURE__ */ new Map();
2619
2619
  for (let r of u) {
2620
2620
  if (!r.proxyTarget) continue;
2621
- let i = await ii(e, r.pkg);
2621
+ let i = await ri(e, r.pkg);
2622
2622
  if (!i) continue;
2623
2623
  let a = f(i, "rpcGroup.generated.ts");
2624
2624
  try {
@@ -2704,7 +2704,7 @@ import {
2704
2704
  pattern: n.pattern,
2705
2705
  file: n.file,
2706
2706
  dirChain: n.dirChain,
2707
- renderMode: Nn(r, f("src", "pages", n.file)),
2707
+ renderMode: Mn(r, f("src", "pages", n.file)),
2708
2708
  interactive: r.interactive ?? "full",
2709
2709
  tenantAware: r.tenantAware === !0,
2710
2710
  revalidateMs: J(r.revalidate),
@@ -2892,7 +2892,7 @@ import {
2892
2892
  kind: "web",
2893
2893
  meta: {
2894
2894
  name: t.name ?? "(unnamed)",
2895
- voltroVersion: Ir,
2895
+ voltroVersion: Fr,
2896
2896
  port: g,
2897
2897
  mode: "dev",
2898
2898
  apis: Object.entries(t.apis ?? {}).map(([e, t]) => {
@@ -2927,14 +2927,14 @@ import {
2927
2927
  e.middlewares.use(async (e, t, n) => {
2928
2928
  if (!(e.url ?? "").startsWith("/api/dashboard/registry")) return n();
2929
2929
  try {
2930
- let e = await Jn();
2930
+ let e = await qn();
2931
2931
  t.statusCode = 200, t.setHeader("content-type", "application/json; charset=utf-8"), t.end(JSON.stringify(e));
2932
2932
  } catch (e) {
2933
2933
  t.statusCode = 500, t.setHeader("content-type", "text/plain"), t.end(`registry read error: ${e.message}`);
2934
2934
  }
2935
2935
  });
2936
2936
  }
2937
- } : null, fe = ni(b), pe = /* @__PURE__ */ new Set(), B = St(), me = wt({
2937
+ } : null, fe = ti(b), pe = /* @__PURE__ */ new Set(), B = St(), me = wt({
2938
2938
  limit: B,
2939
2939
  onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
2940
2940
  onColdEnd: (e) => Z.debug("ssr cold-compile end", { id: e })
@@ -2948,7 +2948,7 @@ import {
2948
2948
  if (r.method !== "GET" && r.method !== "HEAD") return a();
2949
2949
  let o = r.url ?? "/", s = o.indexOf("?"), c = (s === -1 ? o : o.slice(0, s)) || "/";
2950
2950
  if (c.startsWith("/@") || c.startsWith("/node_modules/") || c.startsWith("/.framework/") || c.startsWith("/_voltro/") || c === "/main.tsx" || c === "/index.html" || c === "/sw.js" || c === "/favicon.ico" || c === "/robots.txt" || /\.[a-z0-9]+$/i.test(c)) return a();
2951
- let l = ri(c, fe);
2951
+ let l = ni(c, fe);
2952
2952
  if (!l) return a();
2953
2953
  let d = !pe.has(l.route.pattern), p = Date.now();
2954
2954
  d && Z.info(`ssr compiling ${l.route.pattern}`, {
@@ -2970,15 +2970,15 @@ import {
2970
2970
  }
2971
2971
  };
2972
2972
  try {
2973
- let s = await h("loadPage", async () => await n(f(e, "src", "pages", l.route.file))), _ = Nn(s, f("src", "pages", l.route.file)), v = Zr(x, l.route.dirChain), y = _ === "spa" && v.some((e) => e.hasLayout);
2973
+ let s = await h("loadPage", async () => await n(f(e, "src", "pages", l.route.file))), _ = Mn(s, f("src", "pages", l.route.file)), v = Xr(x, l.route.dirChain), y = _ === "spa" && v.some((e) => e.hasLayout);
2974
2974
  if (_ !== "ssr" && _ !== "isr" && !y) return a();
2975
2975
  let b = {};
2976
2976
  for (let [e, t] of Object.entries(r.headers ?? {})) typeof t == "string" ? b[e] = t : Array.isArray(t) && (b[e] = t.join(", "));
2977
- let S = mi(pi(u[0], { allowDevProxy: !0 }), b.cookie, { apiName: u[0]?.name }), C = new AbortController(), w = () => C.abort();
2977
+ let S = pi(fi(u[0], { allowDevProxy: !0 }), b.cookie, { apiName: u[0]?.name }), C = new AbortController(), w = () => C.abort();
2978
2978
  i.once("close", w);
2979
2979
  let T = null, E = [], D = {};
2980
2980
  try {
2981
- (await n("@voltro/web/ssr")).beginStoreSeeds(), {chain: E, segmentLoaderData: D} = await h("loadChain", () => Qr({
2981
+ (await n("@voltro/web/ssr")).beginStoreSeeds(), {chain: E, segmentLoaderData: D} = await h("loadChain", () => Zr({
2982
2982
  entries: v,
2983
2983
  loadLayout: (t) => n(f(e, "src", "pages", t.dir, "layout.tsx")),
2984
2984
  loadError: (t) => n(f(e, "src", "pages", t.dir, "error.tsx")),
@@ -3015,7 +3015,7 @@ import {
3015
3015
  cookies: O.parseCookieHeader(b.cookie),
3016
3016
  headers: b,
3017
3017
  url: o
3018
- }, j = s.interactive ?? "full", M = y ? Cr({
3018
+ }, j = s.interactive ?? "full", M = y ? Sr({
3019
3019
  helpers: O,
3020
3020
  page: `src/pages/${l.route.file}`,
3021
3021
  interactive: j,
@@ -3027,7 +3027,7 @@ import {
3027
3027
  segmentLoaderData: D,
3028
3028
  requestContext: A
3029
3029
  }
3030
- }) : null, N = y ? null : Sr({
3030
+ }) : null, N = y ? null : xr({
3031
3031
  helpers: O,
3032
3032
  page: `src/pages/${l.route.file}`,
3033
3033
  pathname: c,
@@ -3051,16 +3051,16 @@ import {
3051
3051
  });
3052
3052
  let ee = await h("readShell", _e), F = await h("transformShell", () => t.transformIndexHtml(o, ee)), te = P.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), I = A.cookies["voltro:locale"] ?? "en", L = Date.now();
3053
3053
  if (M) {
3054
- let e = (e) => Tr({
3054
+ let e = (e) => wr({
3055
3055
  helpers: O,
3056
3056
  prepared: M,
3057
3057
  meta: e,
3058
3058
  interactive: j,
3059
3059
  extra: [te]
3060
3060
  });
3061
- if (M.hasDeferred) Pr({
3061
+ if (M.hasDeferred) Nr({
3062
3062
  res: i,
3063
- shell: Mr({
3063
+ shell: jr({
3064
3064
  shell: F,
3065
3065
  inlineModuleScriptsAsync: !0
3066
3066
  }),
@@ -3082,7 +3082,7 @@ import {
3082
3082
  }
3083
3083
  });
3084
3084
  else {
3085
- let t = wr({
3085
+ let t = Cr({
3086
3086
  helpers: O,
3087
3087
  prepared: M
3088
3088
  }), n = F.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${I}"`);
@@ -3103,9 +3103,9 @@ import {
3103
3103
  segmentLoaderData: N.segmentLoaderData,
3104
3104
  requestContext: A
3105
3105
  };
3106
- if (_ === "ssr" && j === "full") Pr({
3106
+ if (_ === "ssr" && j === "full") Nr({
3107
3107
  res: i,
3108
- shell: Mr({
3108
+ shell: jr({
3109
3109
  shell: F,
3110
3110
  inlineModuleScriptsAsync: !0
3111
3111
  }),
@@ -3147,7 +3147,7 @@ import {
3147
3147
  phases: m
3148
3148
  });
3149
3149
  } catch (e) {
3150
- if (xr(e)) {
3150
+ if (br(e)) {
3151
3151
  Z.error("ssr-dev render refused", {
3152
3152
  pathname: c,
3153
3153
  pattern: l.route.pattern
@@ -3161,11 +3161,11 @@ import {
3161
3161
  }
3162
3162
  });
3163
3163
  }
3164
- }, ye = Date.now(), H = w.version ?? "?", U = await Lr(), be = f(e, "node_modules", "@voltro", "ui-shadcn"), W = O(f(be, "package.json")) ? be : null, xe = [], G = await (async () => {
3164
+ }, ye = Date.now(), H = w.version ?? "?", U = await Ir(), be = f(e, "node_modules", "@voltro", "ui-shadcn"), W = O(f(be, "package.json")) ? be : null, xe = [], G = await (async () => {
3165
3165
  let t = [];
3166
3166
  for (let n of u) {
3167
3167
  if (!n.proxyTarget) continue;
3168
- let r = await ii(e, n.pkg);
3168
+ let r = await ri(e, n.pkg);
3169
3169
  if (r) try {
3170
3170
  t.push(await j.readFile(f(r, "rpcGroup.generated.ts"), "utf8"));
3171
3171
  } catch {}
@@ -3222,7 +3222,7 @@ import {
3222
3222
  },
3223
3223
  customLogger: xt(),
3224
3224
  plugins: [
3225
- Dn(f(e, "src", "pages")),
3225
+ En(f(e, "src", "pages")),
3226
3226
  T(),
3227
3227
  D(),
3228
3228
  N,
@@ -3240,12 +3240,12 @@ import {
3240
3240
  host: !0,
3241
3241
  allowedHosts: t.allowedHosts === !0 || [...t.allowedHosts ?? []],
3242
3242
  proxy: z,
3243
- fs: { allow: [e, ...Ur(e)] }
3243
+ fs: { allow: [e, ...Hr(e)] }
3244
3244
  },
3245
3245
  appType: "spa",
3246
3246
  cacheDir: f(k, ".vite"),
3247
3247
  publicDir: f(e, "public")
3248
- })).listen(), Fr.info(`v${H} ready in ${Date.now() - ye}ms`, {
3248
+ })).listen(), Pr.info(`v${H} ready in ${Date.now() - ye}ms`, {
3249
3249
  version: H,
3250
3250
  bootMs: Date.now() - ye
3251
3251
  }), Z.info(`listening on http://localhost:${g}`, {
@@ -3257,7 +3257,7 @@ import {
3257
3257
  target: e.proxyTarget
3258
3258
  }), Z.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3259
3259
  try {
3260
- await Yn({
3260
+ await Jn({
3261
3261
  id: v,
3262
3262
  name: _,
3263
3263
  kind: "web",
@@ -3266,13 +3266,13 @@ import {
3266
3266
  status: "live",
3267
3267
  logFile: y.path
3268
3268
  });
3269
- let t = lr(e);
3269
+ let t = cr(e);
3270
3270
  if (t) {
3271
- let e = await yr({ dashboardAppPath: t });
3271
+ let e = await vr({ dashboardAppPath: t });
3272
3272
  e.status === "launched" ? Z.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && Z.debug(`dashboard already running on :${e.port}`, { port: e.port });
3273
3273
  }
3274
3274
  setInterval(() => {
3275
- Yn({
3275
+ Jn({
3276
3276
  id: v,
3277
3277
  name: _,
3278
3278
  kind: "web",
@@ -3283,7 +3283,7 @@ import {
3283
3283
  }).catch(() => {});
3284
3284
  }, 1e4).unref();
3285
3285
  let n = () => {
3286
- Xn(v), y.dispose();
3286
+ Yn(v), y.dispose();
3287
3287
  };
3288
3288
  process.on("SIGINT", n), process.on("SIGTERM", n);
3289
3289
  } catch (e) {
@@ -3295,21 +3295,21 @@ import {
3295
3295
  url: `http://localhost:${g}`,
3296
3296
  bootMs: Date.now() - ye
3297
3297
  }), new Promise(() => {});
3298
- }, bi = async (e) => {
3298
+ }, yi = async (e) => {
3299
3299
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
3300
- let t = await vi(e);
3300
+ let t = await _i(e);
3301
3301
  if (!t) return {
3302
3302
  ran: !1,
3303
3303
  exitCode: 0
3304
3304
  };
3305
3305
  let n = Date.now(), r = Z.child("serve");
3306
3306
  r.info("booting voltro serve (preview)", { app: t.name ?? "(unnamed)" });
3307
- let i = await li(e, t);
3307
+ let i = await ci(e, t);
3308
3308
  for (let e of i) r.info("api wired", {
3309
3309
  name: e.name,
3310
3310
  pkg: e.pkg
3311
3311
  });
3312
- await hi(e, t, i);
3312
+ await mi(e, t, i);
3313
3313
  {
3314
3314
  let { pages: t } = await $(f(e, "src", "pages"));
3315
3315
  await Pt({
@@ -3326,7 +3326,7 @@ import {
3326
3326
  resolve: { dedupe: ["react", "react-dom"] },
3327
3327
  build: {
3328
3328
  outDir: "dist",
3329
- rollupOptions: { output: { manualChunks: Gr } }
3329
+ rollupOptions: { output: { manualChunks: Wr } }
3330
3330
  },
3331
3331
  publicDir: f(e, "public")
3332
3332
  });
@@ -3346,14 +3346,14 @@ import {
3346
3346
  extras: d,
3347
3347
  bootMs: Date.now() - n
3348
3348
  }), new Promise(() => {});
3349
- }, xi = 5e3, Si = 6e4, Ci = (e, t) => {
3349
+ }, bi = 5e3, xi = 6e4, Si = (e, t) => {
3350
3350
  if (e.length === 0) return 0;
3351
3351
  if (e.length === 1) return e[0];
3352
3352
  let n = t * (e.length - 1), r = Math.floor(n), i = Math.ceil(n);
3353
3353
  if (r === i) return e[r];
3354
3354
  let a = n - r;
3355
3355
  return e[r] * (1 - a) + e[i] * a;
3356
- }, wi = (e) => {
3356
+ }, Ci = (e) => {
3357
3357
  if (e.length === 0) return {
3358
3358
  p50: 0,
3359
3359
  p95: 0,
@@ -3365,15 +3365,15 @@ import {
3365
3365
  let t = e.slice().sort((e, t) => e - t), n = 0;
3366
3366
  for (let e of t) n += e;
3367
3367
  return {
3368
- p50: Ci(t, .5),
3369
- p95: Ci(t, .95),
3370
- p99: Ci(t, .99),
3368
+ p50: Si(t, .5),
3369
+ p95: Si(t, .95),
3370
+ p99: Si(t, .99),
3371
3371
  mean: n / t.length,
3372
3372
  min: t[0],
3373
3373
  max: t[t.length - 1]
3374
3374
  };
3375
- }, Ti = (e = {}) => {
3376
- let t = e.maxSamples ?? xi, n = e.defaultWindowMs ?? Si, r = [];
3375
+ }, wi = (e = {}) => {
3376
+ let t = e.maxSamples ?? bi, n = e.defaultWindowMs ?? xi, r = [];
3377
3377
  return {
3378
3378
  record(e) {
3379
3379
  R(e), r.push({
@@ -3402,7 +3402,7 @@ import {
3402
3402
  tag: e.tag,
3403
3403
  count: e.samples.length,
3404
3404
  errorCount: n,
3405
- latencyMs: wi(t)
3405
+ latencyMs: Ci(t)
3406
3406
  });
3407
3407
  }
3408
3408
  return c.sort((e, t) => t.count - e.count), {
@@ -3415,4 +3415,4 @@ import {
3415
3415
  };
3416
3416
  };
3417
3417
  //#endregion
3418
- export { ut as $, Xn as A, dn as B, yr as C, ar as D, ir as E, jn as F, Wt as G, tn as H, Nn as I, Rt as J, Lt as K, gn as L, On as M, Pn as N, Zn as O, kn as P, ft as Q, _n as R, cr as S, rr as T, $t as U, on as V, Kt as W, wt as X, Pt as Y, St as Z, Sr as _, Qr as a, J as at, Tr as b, li as c, $e as ct, Gr as d, Ke as dt, lt as et, $ as f, We as ft, xr as g, W as gt, Pr as h, be as ht, mi as i, rt as it, Yn as j, Jn as k, yi as l, Ze as lt, Mr as m, He as mt, Kr as n, at as nt, Zr as o, tt as ot, hi as p, Ve as pt, It as q, pi as r, ot as rt, vi as s, nt as st, Ti as t, it as tt, bi as u, Xe as ut, Cr as v, lr as w, ur as x, wr as y, vn as z };
3418
+ export { lt as $, Yn as A, on as B, vr as C, ir as D, rr as E, An as F, Lt as G, $t as H, Mn as I, Pt as J, It as K, gn as L, Dn as M, Nn as N, Xn as O, On as P, ut as Q, _n as R, sr as S, nr as T, Kt as U, tn as V, Wt as W, St as X, wt as Y, ft as Z, xr as _, Zr as a, tt as at, wr as b, ci as c, Ze as ct, Wr as d, We as dt, it as et, $ as f, Ve as ft, br as g, Nr as h, W as ht, pi as i, J as it, Jn as j, qn as k, vi as l, Xe as lt, jr as m, be as mt, Gr as n, ot as nt, Xr as o, nt as ot, mi as p, He as pt, Rt as q, fi as r, rt, _i as s, $e as st, wi as t, at as tt, yi as u, Ke as ut, Sr as v, cr as w, lr as x, Cr as y, dn as z };