@voltro/cli 0.30.1 → 0.30.2

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 (77) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{apiBuild-DmkzRyv7.js → apiBuild-BUS1RfPi.js} +2 -2
  3. package/dist/apiBuild-DMlxvL8h.js +2 -0
  4. package/dist/bin.js +3 -3
  5. package/dist/checkCommand-CARZ36Tr.js +2 -0
  6. package/dist/{checkCommand-C4konUy9.js → checkCommand-D_wdOFhw.js} +346 -293
  7. package/dist/{commands-BkJft9K2.js → commands-BgGAUcku.js} +1680 -1680
  8. package/dist/{dbCommand-qn__kLEt.js → dbCommand-CbPRCD1x.js} +56 -19
  9. package/dist/dbCommand-Ht47LrV-.js +2 -0
  10. package/dist/{dev-C_NPcLDp.js → dev-GAOIot9G.js} +2169 -2153
  11. package/dist/{dev-DXhhZ7-f.js → dev-tPcOmjPJ.js} +1 -1
  12. package/dist/{frameworkTableAssembly-Cpgn2e88.js → frameworkTableAssembly-BwIrO5nv.js} +122 -103
  13. package/dist/frameworkTableAssembly-D-EebUQX.js +2 -0
  14. package/dist/index.js +1 -1
  15. package/dist/{inspectMetrics-CkB2J0Zn.js → inspectMetrics-BM1vrsga.js} +314 -314
  16. package/dist/{sdkgen-wsWLrq4l.js → sdkgen-BV4fFucu.js} +1 -1
  17. package/dist/{serveCommand-HtI4X5kj.js → serveCommand-ClqXCX1y.js} +17 -16
  18. package/dist/serveEntry.js +2 -2
  19. package/dist/{start-egkbpugc.js → start-CTnNvKlk.js} +348 -348
  20. package/dist/startEntry.js +2 -2
  21. package/package.json +17 -17
  22. package/templates/AGENTS.md +1 -1
  23. package/templates/agent-docs/_index.md +1 -1
  24. package/templates/agent-docs/cli.md +4 -2
  25. package/templates/agent-docs/internationalization.md +25 -3
  26. package/templates/agent-docs/whats-new.md +24 -47
  27. package/templates/apps/api-ai/package.json +7 -7
  28. package/templates/apps/api-auth/package.json +8 -8
  29. package/templates/apps/api-backend/package.json +7 -7
  30. package/templates/apps/api-backend-deactivation/package.json +7 -7
  31. package/templates/apps/api-backend-mail/package.json +8 -8
  32. package/templates/apps/api-backend-mariadb/package.json +9 -9
  33. package/templates/apps/api-backend-sqlite/package.json +8 -8
  34. package/templates/apps/api-backend-storage/package.json +8 -8
  35. package/templates/apps/api-cms/package.json +10 -10
  36. package/templates/apps/api-collab/package.json +8 -8
  37. package/templates/apps/api-data-advanced/package.json +8 -8
  38. package/templates/apps/api-durable/package.json +8 -8
  39. package/templates/apps/api-feature-flags/package.json +9 -9
  40. package/templates/apps/api-governance/package.json +8 -8
  41. package/templates/apps/api-kv/package.json +8 -8
  42. package/templates/apps/api-moderation/package.json +8 -8
  43. package/templates/apps/api-observability/package.json +8 -8
  44. package/templates/apps/api-ratelimit/package.json +8 -8
  45. package/templates/apps/api-rbac/package.json +8 -8
  46. package/templates/apps/api-rest/package.json +7 -7
  47. package/templates/apps/api-saas/package.json +11 -11
  48. package/templates/apps/api-saas-starter/package.json +10 -10
  49. package/templates/apps/api-search/package.json +8 -8
  50. package/templates/apps/api-status/package.json +8 -8
  51. package/templates/apps/api-versioning/package.json +8 -8
  52. package/templates/apps/api-webhooks/package.json +9 -9
  53. package/templates/apps/changelog/package.json +6 -6
  54. package/templates/apps/edge-functions/package.json +2 -2
  55. package/templates/apps/frontend-admin/package.json +8 -8
  56. package/templates/apps/frontend-app/package.json +8 -8
  57. package/templates/apps/frontend-auth/package.json +8 -8
  58. package/templates/apps/frontend-blank/package.json +7 -7
  59. package/templates/apps/frontend-cms/package.json +9 -9
  60. package/templates/apps/frontend-collab/package.json +9 -9
  61. package/templates/apps/frontend-contact/package.json +7 -7
  62. package/templates/apps/frontend-dashboard/package.json +7 -7
  63. package/templates/apps/frontend-docs/package.json +7 -7
  64. package/templates/apps/frontend-i18n/package.json +6 -6
  65. package/templates/apps/frontend-landing/package.json +7 -7
  66. package/templates/apps/frontend-portal/package.json +8 -8
  67. package/templates/apps/frontend-saas/package.json +8 -8
  68. package/templates/apps/frontend-spa/package.json +7 -7
  69. package/templates/apps/frontend-ssr/package.json +7 -7
  70. package/templates/apps/frontend-ssr-api/package.json +8 -8
  71. package/templates/apps/frontend-static-blog/package.json +6 -6
  72. package/templates/apps/frontend-status/package.json +8 -8
  73. package/templates/apps/mobile-app/package.json +2 -2
  74. package/dist/apiBuild-Ca6Sq5jy.js +0 -2
  75. package/dist/checkCommand-DHD0aBeR.js +0 -2
  76. package/dist/dbCommand-wfGi3FgG.js +0 -2
  77. package/dist/frameworkTableAssembly-Bn_c4Mnl.js +0 -2
@@ -7,22 +7,22 @@ import { FileSystem as v } from "@effect/platform";
7
7
  import { NodeContext as y } from "@effect/platform-node";
8
8
  import { Effect as b } from "effect";
9
9
  import { addSink as x, createLogger as S, printReadyBlock as C } from "@voltro/logger";
10
- import { closeSync as w, existsSync as T, mkdirSync as E, openSync as D, promises as O, readFileSync as ee, readdirSync as te, statSync as k, unlinkSync as A, unwatchFile as ne, watchFile as re, writeSync as j } from "node:fs";
11
- import { currentTraceContext as M, recordSample as ie, resolveSecret as N } from "@voltro/runtime";
12
- import { homedir as P } from "node:os";
13
- import { createRequire as F } from "node:module";
14
- import { FRAMEWORK_ENV_CATALOG as ae, appEnvEntries as I, checkEnvNaming as L, formatEnvErrors as R, installEnvSnapshot as oe, isEnvContract as z, pluginEnvEntries as se, renderDotEnvExample as B, resolveEnv as ce } from "@voltro/env";
15
- import { __installPublicEnv as le } from "@voltro/env/public";
16
- import { mkdir as V, readFile as ue, writeFile as de } from "node:fs/promises";
17
- import { createHash as fe } from "node:crypto";
18
- import { spawn as pe } from "node:child_process";
19
- import { createConnection as me } from "node:net";
20
- import { PassThrough as he } from "node:stream";
10
+ import { closeSync as w, existsSync as T, mkdirSync as E, openSync as D, promises as O, readFileSync as ee, readdirSync as k, statSync as A, unlinkSync as j, unwatchFile as te, watchFile as ne, writeSync as M } from "node:fs";
11
+ import { currentTraceContext as N, recordSample as re, resolveSecret as P } from "@voltro/runtime";
12
+ import { homedir as F } from "node:os";
13
+ import { createRequire as I } from "node:module";
14
+ import { FRAMEWORK_ENV_CATALOG as ie, appEnvEntries as L, checkEnvNaming as R, formatEnvErrors as z, installEnvSnapshot as ae, isEnvContract as B, pluginEnvEntries as oe, renderDotEnvExample as V, resolveEnv as se } from "@voltro/env";
15
+ import { __installPublicEnv as ce } from "@voltro/env/public";
16
+ import { mkdir as H, readFile as le, writeFile as ue } from "node:fs/promises";
17
+ import { createHash as de } from "node:crypto";
18
+ import { spawn as fe } from "node:child_process";
19
+ import { createConnection as pe } from "node:net";
20
+ import { PassThrough as me } from "node:stream";
21
21
  //#region src/agentsMd.ts
22
- var H = d(g(import.meta.url)), U = [h(H, "..", "templates"), h(H, "..", "..", "templates")], ge = (e) => ({
22
+ var U = d(g(import.meta.url)), W = [h(U, "..", "templates"), h(U, "..", "..", "templates")], he = (e) => ({
23
23
  _tag: "TemplateNotFoundError",
24
24
  searched: e
25
- }), W = ["AGENTS.md", "CLAUDE.md"], _e = "voltro:agents-md:keep", ve = 2048, G = "<!-- VOLTRO:INDEX -->", K = (e, t) => e.exists(t).pipe(b.orElseSucceed(() => !1)), q = (e, t) => e.readFileString(t).pipe(b.orElseSucceed(() => "")), ye = (e, t) => e.readFileString(t).pipe(b.map((e) => {
25
+ }), G = ["AGENTS.md", "CLAUDE.md"], ge = "voltro:agents-md:keep", _e = 2048, ve = "<!-- VOLTRO:INDEX -->", K = (e, t) => e.exists(t).pipe(b.orElseSucceed(() => !1)), q = (e, t) => e.readFileString(t).pipe(b.orElseSucceed(() => "")), ye = (e, t) => e.readFileString(t).pipe(b.map((e) => {
26
26
  try {
27
27
  return JSON.parse(e).workspaces !== void 0;
28
28
  } catch {
@@ -174,7 +174,7 @@ boundary, naming, anti-patterns) before editing.
174
174
  `, Ae = (e, t, n, r) => b.gen(function* () {
175
175
  let i = yield* K(e, t);
176
176
  if (i) {
177
- if ((yield* q(e, t)).slice(0, ve).includes("voltro:agents-md:keep")) return {
177
+ if ((yield* q(e, t)).slice(0, _e).includes("voltro:agents-md:keep")) return {
178
178
  path: t,
179
179
  action: "protected"
180
180
  };
@@ -189,23 +189,23 @@ boundary, naming, anti-patterns) before editing.
189
189
  };
190
190
  }), je = (e, t = {}) => b.gen(function* () {
191
191
  let n = yield* v.FileSystem, r = yield* J(e), i = null;
192
- for (let e of U) if (yield* K(n, p(e, "AGENTS.core.md"))) {
192
+ for (let e of W) if (yield* K(n, p(e, "AGENTS.core.md"))) {
193
193
  i = e;
194
194
  break;
195
195
  }
196
196
  if (i === null) {
197
- for (let e of U) if (yield* K(n, p(e, "AGENTS.md"))) {
197
+ for (let e of W) if (yield* K(n, p(e, "AGENTS.md"))) {
198
198
  let i = yield* q(n, p(e, "AGENTS.md")), a = [];
199
- for (let e of W) a.push(yield* Ae(n, p(r, e), i, t.force ?? !1));
199
+ for (let e of G) a.push(yield* Ae(n, p(r, e), i, t.force ?? !1));
200
200
  return { files: a };
201
201
  }
202
- return yield* b.fail(ge(U.map((e) => p(e, "AGENTS.core.md"))));
202
+ return yield* b.fail(he(W.map((e) => p(e, "AGENTS.core.md"))));
203
203
  }
204
204
  let a = yield* q(n, p(i, "AGENTS.core.md")), o = yield* q(n, p(i, "agent-docs", "_manifest.json")), s = o ? JSON.parse(o) : {
205
205
  modules: [],
206
206
  plugins: []
207
- }, c = (t.preferPointer ?? !1) || (yield* K(n, p(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = W.map((e) => p(r, e));
208
- if ((yield* b.forEach(d, (e) => q(n, e).pipe(b.map((e) => e.slice(0, ve))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
207
+ }, c = (t.preferPointer ?? !1) || (yield* K(n, p(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = G.map((e) => p(r, e));
208
+ if ((yield* b.forEach(d, (e) => q(n, e).pipe(b.map((e) => e.slice(0, _e))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
209
209
  path: e,
210
210
  action: "protected"
211
211
  })) };
@@ -217,13 +217,13 @@ boundary, naming, anti-patterns) before editing.
217
217
  for (let e of t) _.add(e);
218
218
  }
219
219
  }
220
- let x = t.plugins ? t.plugins.map(xe).filter((e) => e !== null) : y ? [..._] : null, S = a.includes(G) ? a.replace(G, Te(s, x, l)) : a, C = [];
220
+ let x = t.plugins ? t.plugins.map(xe).filter((e) => e !== null) : y ? [..._] : null, S = a.includes(ve) ? a.replace(ve, Te(s, x, l)) : a, C = [];
221
221
  for (let e of d) C.push(yield* Ae(n, e, S, u));
222
222
  c || (yield* be(n, p(i, "agent-docs"), p(r, "agent-docs")));
223
223
  let w = new Map((t.appTemplates ?? []).map((e) => [h(e.dir), e.template])), T = (e) => {
224
224
  let t = w.get(h(e));
225
225
  return t ? Ee(t, s, l) : "";
226
- }, E = (e, t) => b.forEach(W, (r) => Ae(n, p(e, r), t, u));
226
+ }, E = (e, t) => b.forEach(G, (r) => Ae(n, p(e, r), t, u));
227
227
  for (let e of f) C.push(...yield* E(e, De.api(l, g.get(e) ?? null, T(e)))), (yield* K(n, p(e, "database"))) && C.push(...yield* E(p(e, "database"), De.database(l)));
228
228
  for (let e of m) C.push(...yield* E(e, De.web(l, T(e))));
229
229
  for (let e of Oe) C.push(yield* Ae(n, p(r, ".claude", "skills", e.name, "SKILL.md"), ke(e, l), u));
@@ -233,14 +233,14 @@ boundary, naming, anti-patterns) before editing.
233
233
  return e(b.gen(function* () {
234
234
  let e = yield* je(r, { force: n });
235
235
  for (let t of e.files) {
236
- let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${_e}")` : "present (use --force to overwrite)";
236
+ let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${ge}")` : "present (use --force to overwrite)";
237
237
  yield* b.logInfo(`${t.path.split("/").slice(-2).join("/")} ${e}`, { action: t.action });
238
238
  }
239
239
  return 0;
240
240
  }).pipe(b.catchTag("TemplateNotFoundError", (e) => b.gen(function* () {
241
241
  return yield* b.logError("AGENTS.md template not found", { searched: e.searched }), 1;
242
242
  }))), { scope: "voltro:agents-md" });
243
- }, Pe = p(P(), ".voltro"), Fe = p(Pe, "runtime-registry.json"), Ie = 3e4, Le = () => {
243
+ }, Pe = p(F(), ".voltro"), Fe = p(Pe, "runtime-registry.json"), Ie = 3e4, Le = () => {
244
244
  let e = Math.random().toString(36).slice(2, 10);
245
245
  return `${Fe}.${process.pid}.${Date.now()}.${e}.tmp`;
246
246
  }, Re = async () => {
@@ -357,7 +357,7 @@ ${n.length > 0 ? n : " // (no variables declared)"}
357
357
  }
358
358
  }
359
359
  `;
360
- await de(p(e, "env.generated.d.ts"), r, "utf8");
360
+ await ue(p(e, "env.generated.d.ts"), r, "utf8");
361
361
  }, tt = async (e, t) => {
362
362
  let n = $e(t, (e) => e === "public"), r = `${Ze}
363
363
  import '@voltro/env/public'
@@ -368,7 +368,7 @@ ${n.length > 0 ? n : " // (no public variables declared)"}
368
368
  }
369
369
  }
370
370
  `, i = p(e, "src");
371
- await V(i, { recursive: !0 }), await de(p(i, "voltro-env.d.ts"), r, "utf8");
371
+ await H(i, { recursive: !0 }), await ue(p(i, "voltro-env.d.ts"), r, "utf8");
372
372
  }, nt = async (e, t) => {
373
373
  let n = `${Ze}
374
374
  import { __installPublicEnv } from '@voltro/env/public'
@@ -378,14 +378,14 @@ export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
378
378
  // Set the browser/SSR-shared global the \`publicEnv\` accessor reads.
379
379
  __installPublicEnv(publicEnvValues)
380
380
  `;
381
- await V(e, { recursive: !0 }), await de(p(e, "env.public.ts"), n, "utf8");
381
+ await H(e, { recursive: !0 }), await ue(p(e, "env.public.ts"), n, "utf8");
382
382
  }, rt = async (e) => {
383
- let t = z(e.rawEnv) ? e.rawEnv : void 0, n = await ce({
383
+ let t = B(e.rawEnv) ? e.rawEnv : void 0, n = await se({
384
384
  contract: t,
385
- resolveSecret: N
386
- }), r = [...n.errors, ...L(t, e.appType)];
387
- if (r.length > 0) throw Error(R(r));
388
- oe(n.values), e.appType === "web" && le(n.publicValues);
385
+ resolveSecret: P
386
+ }), r = [...n.errors, ...R(t, e.appType)];
387
+ if (r.length > 0) throw Error(z(r));
388
+ ae(n.values), e.appType === "web" && ce(n.publicValues);
389
389
  let i = t ? Object.keys(t.vars).length : 0;
390
390
  if (i > 0) {
391
391
  let r = Object.keys(n.publicValues).length;
@@ -402,7 +402,7 @@ __installPublicEnv(publicEnvValues)
402
402
  contract: t
403
403
  };
404
404
  }, it = (e) => {
405
- let t = I(e.contract), n = (e.plugins ?? []).flatMap((e) => se(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : ae, i = /* @__PURE__ */ new Set(), a = [];
405
+ let t = L(e.contract), n = (e.plugins ?? []).flatMap((e) => oe(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : ie, i = /* @__PURE__ */ new Set(), a = [];
406
406
  for (let e of [
407
407
  ...t,
408
408
  ...n,
@@ -427,7 +427,7 @@ __installPublicEnv(publicEnvValues)
427
427
  missingRequired: r.filter((e) => e.required && !e.isSet && e.default === void 0).length
428
428
  }
429
429
  };
430
- }, ot = (e, t) => B(it({
430
+ }, ot = (e, t) => V(it({
431
431
  ...e,
432
432
  includeFramework: !1
433
433
  }), {
@@ -476,7 +476,7 @@ __installPublicEnv(publicEnvValues)
476
476
  if (t?.code !== "EACCES") return "";
477
477
  if (typeof process.getuid != "function") return " — permission denied";
478
478
  try {
479
- let t = k(e);
479
+ let t = A(e);
480
480
  return ` — permission denied: the file is owned by uid ${t.uid} (mode ${(t.mode & 511).toString(8)}) and this process is uid ${process.getuid()}. A container running as root with the workspace bind-mounted writes files the host user cannot read; run it as \`--user <your-uid>:<your-gid>\`, or delete the file and let the owning user recreate it.`;
481
481
  } catch {
482
482
  return " — permission denied (and the file could not be stat-ed either)";
@@ -513,7 +513,7 @@ __installPublicEnv(publicEnvValues)
513
513
  if (e.length === 0) return () => {};
514
514
  let r = (e) => n.root ? m(n.root, e) : e, i = !1, a = (e) => {
515
515
  i || (i = !0, t.warn(`.env changed (${r(e)}) — hard-restarting: process.env is read once at boot, a reload would keep stale values`, { file: r(e) }), Promise.resolve().then(() => n.onBeforeRestart?.()).catch((e) => t.warn(".env restart: onBeforeRestart failed (continuing)", {}, e)).finally(() => {
516
- let e = pe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
516
+ let e = fe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
517
517
  stdio: "inherit",
518
518
  env: process.env,
519
519
  cwd: n.cwd ?? process.cwd()
@@ -527,14 +527,14 @@ __installPublicEnv(publicEnvValues)
527
527
  });
528
528
  }));
529
529
  };
530
- for (let t of e) re(t, { interval: gt }, (e, n) => {
530
+ for (let t of e) ne(t, { interval: gt }, (e, n) => {
531
531
  e.mtimeMs !== n.mtimeMs && a(t);
532
532
  });
533
533
  return t.info("watching .env files for changes", {
534
534
  files: e.map(r),
535
535
  intervalMs: gt
536
536
  }), () => {
537
- for (let t of e) ne(t);
537
+ for (let t of e) te(t);
538
538
  };
539
539
  }, vt = S({ scope: "vite" }), yt = /\x1b\[[0-9;]*m/g, bt = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, xt = (e) => e.replace(yt, "").replace(bt, "").trim(), St = /proxy error/i, Ct = [
540
540
  "ECONNREFUSED",
@@ -871,7 +871,7 @@ __installPublicEnv(publicEnvValues)
871
871
  if (dn(t[i], a), !r) {
872
872
  r = !0;
873
873
  try {
874
- let t = a.length > 0 ? cn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = M();
874
+ let t = a.length > 0 ? cn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = N();
875
875
  e.emit("log", {
876
876
  level: i,
877
877
  message: r,
@@ -909,7 +909,7 @@ __installPublicEnv(publicEnvValues)
909
909
  argsCount: 1,
910
910
  ...t.scope === void 0 ? {} : { scope: t.scope }
911
911
  });
912
- let a = M(), o = a !== void 0 && t.fields.traceId === void 0 ? {
912
+ let a = N(), o = a !== void 0 && t.fields.traceId === void 0 ? {
913
913
  ...t.fields,
914
914
  traceId: a.traceId
915
915
  } : t.fields;
@@ -1309,7 +1309,7 @@ import {
1309
1309
  let n = (await Promise.all(t.map(async (t) => {
1310
1310
  let n;
1311
1311
  try {
1312
- n = await ue(p(e, t.file), "utf8");
1312
+ n = await le(p(e, t.file), "utf8");
1313
1313
  } catch {
1314
1314
  return null;
1315
1315
  }
@@ -1317,7 +1317,7 @@ import {
1317
1317
  return r !== null && !Jn(r) ? Xn(p("src", "pages", t.file), r) : ar(n) ? null : `${p("src", "pages", t.file)} is a route (a \`page.tsx\` under src/pages/) 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 re-export another page's component\n (\`export { default } from '../page'\`). If this file is NOT a route, rename it —\n only the reserved names route, and anything else under src/pages/ is ordinary code\n that may live beside the page that uses it.`;
1318
1318
  }))).filter((e) => e !== null);
1319
1319
  if (n.length !== 0) throw Error(n.join("\n\n"));
1320
- }, X = p(P(), ".voltro", "logs"), sr = () => {
1320
+ }, X = p(F(), ".voltro", "logs"), sr = () => {
1321
1321
  let e = Number(process.env.VOLTRO_LOG_FILE_TTL_MS);
1322
1322
  return Number.isFinite(e) && e > 0 ? e : 3600 * 1e3;
1323
1323
  }, cr = !1, lr = () => {
@@ -1325,7 +1325,7 @@ import {
1325
1325
  cr = !0;
1326
1326
  let e = Date.now() - sr(), t = [];
1327
1327
  try {
1328
- t = te(X);
1328
+ t = k(X);
1329
1329
  } catch {
1330
1330
  return;
1331
1331
  }
@@ -1333,13 +1333,13 @@ import {
1333
1333
  if (!n.endsWith(".log")) continue;
1334
1334
  let t = p(X, n);
1335
1335
  try {
1336
- k(t).mtimeMs < e && A(t);
1336
+ A(t).mtimeMs < e && j(t);
1337
1337
  } catch {}
1338
1338
  }
1339
1339
  }, ur = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), dr = (e, t) => p(X, `${ur(e)}-${t}.log`), fr = (e) => {
1340
1340
  let t = ur(e), n = [];
1341
1341
  try {
1342
- n = te(X);
1342
+ n = k(X);
1343
1343
  } catch {
1344
1344
  return;
1345
1345
  }
@@ -1349,7 +1349,7 @@ import {
1349
1349
  for (let e of r) {
1350
1350
  let t = p(X, e);
1351
1351
  try {
1352
- let e = k(t);
1352
+ let e = A(t);
1353
1353
  e.mtimeMs > a && (a = e.mtimeMs, i = t);
1354
1354
  } catch {}
1355
1355
  }
@@ -1382,7 +1382,7 @@ import {
1382
1382
  }
1383
1383
  }, i = !1, a = x((e) => {
1384
1384
  if (!i) try {
1385
- j(n, r(e));
1385
+ M(n, r(e));
1386
1386
  } catch {}
1387
1387
  }), o = () => {
1388
1388
  if (!i) {
@@ -1414,7 +1414,7 @@ import {
1414
1414
  i.push(t);
1415
1415
  } catch {}
1416
1416
  return t?.max !== void 0 && i.length > t.max ? i.slice(i.length - t.max) : i;
1417
- }, hr = S({ scope: "voltro:dashboard" }), gr = F(import.meta.url), _r = 5179, vr = (e) => {
1417
+ }, hr = S({ scope: "voltro:dashboard" }), gr = I(import.meta.url), _r = 5179, vr = (e) => {
1418
1418
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1419
1419
  if (t && T(p(h(t), "app.config.ts"))) return h(t);
1420
1420
  try {
@@ -1431,14 +1431,14 @@ import {
1431
1431
  }
1432
1432
  return null;
1433
1433
  }, yr = "VOLTRO_IS_DASHBOARD", br = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1434
- let i = me({
1434
+ let i = pe({
1435
1435
  port: e,
1436
1436
  host: t
1437
1437
  }), a = !1, o = (e) => {
1438
1438
  a || (a = !0, i.destroy(), r(e));
1439
1439
  };
1440
1440
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
1441
- }), xr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Sr = () => process.env[yr] === "1", Cr = () => process.stdout.isTTY === !0, wr = p(P(), ".voltro", "dashboard-launch.lock"), Tr = 1e4, Er = async () => {
1441
+ }), xr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Sr = () => process.env[yr] === "1", Cr = () => process.stdout.isTTY === !0, wr = p(F(), ".voltro", "dashboard-launch.lock"), Tr = 1e4, Er = async () => {
1442
1442
  try {
1443
1443
  await O.mkdir(d(wr), { recursive: !0 });
1444
1444
  let e = await O.open(wr, "wx");
@@ -1485,7 +1485,7 @@ import {
1485
1485
  let e = process.argv[1];
1486
1486
  n = e && e.endsWith("/src/bin.ts") ? p(d(e), "..", "bin", "voltro.mjs") : e ?? "voltro";
1487
1487
  }
1488
- let r = T(p(e.dashboardAppPath, ".framework", "dist", "index.html")), i = r ? "start" : "dev", a = pe(process.execPath, [
1488
+ let r = T(p(e.dashboardAppPath, ".framework", "dist", "index.html")), i = r ? "start" : "dev", a = fe(process.execPath, [
1489
1489
  n,
1490
1490
  i,
1491
1491
  e.dashboardAppPath
@@ -1653,17 +1653,17 @@ import {
1653
1653
  tail: `${Hr}${r.slice(i + 21)}`,
1654
1654
  bootstrapModules: n
1655
1655
  };
1656
- }, qr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Jr = (e) => {
1656
+ }, qr = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), Jr = (e) => qr(e.head, e.headInjection).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Yr = (e) => {
1657
1657
  let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1658
1658
  if (s || !o || a === null) return;
1659
1659
  s = !0, t.statusCode = e.statusCode ?? 200;
1660
1660
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1661
- t.flushHeaders?.(), t.write(qr({
1661
+ t.flushHeaders?.(), t.write(Jr({
1662
1662
  head: n.head,
1663
1663
  headInjection: i(a.meta),
1664
1664
  htmlLang: r
1665
1665
  }));
1666
- let c = new he();
1666
+ let c = new me();
1667
1667
  c.pipe(t, { end: !1 }), c.on("end", () => {
1668
1668
  t.end(n.tail);
1669
1669
  }), a.stream.pipe(c);
@@ -1688,16 +1688,16 @@ import {
1688
1688
  return;
1689
1689
  }
1690
1690
  c();
1691
- }, Yr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Xr = (e, t) => typeof e == "string" ? {
1691
+ }, Xr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Zr = (e, t) => typeof e == "string" ? {
1692
1692
  tag: e,
1693
1693
  input: {}
1694
1694
  } : {
1695
1695
  tag: e.tag,
1696
1696
  input: e.input?.(t) ?? {}
1697
- }, Zr = async (e) => {
1697
+ }, Qr = async (e) => {
1698
1698
  let { pageMod: t, params: n, query: r, apiName: i, seed: a, onError: o } = e;
1699
- if (Yr(t) && !(r === void 0 || i === void 0)) for (let e of t.preload) {
1700
- let { tag: t, input: s } = Xr(e, n);
1699
+ if (Xr(t) && !(r === void 0 || i === void 0)) for (let e of t.preload) {
1700
+ let { tag: t, input: s } = Zr(e, n);
1701
1701
  try {
1702
1702
  a(i, t, s, await r(t, s));
1703
1703
  } catch (e) {
@@ -1707,14 +1707,14 @@ import {
1707
1707
  }, e);
1708
1708
  }
1709
1709
  }
1710
- }, Z = S({ scope: "voltro:dev:web" }), Qr = S({ scope: "vite" }), $r = await (async () => {
1710
+ }, Z = S({ scope: "voltro:dev:web" }), $r = S({ scope: "vite" }), ei = await (async () => {
1711
1711
  try {
1712
1712
  let e = p(d(g(import.meta.url)), "..", "package.json"), t = await O.readFile(e, "utf8");
1713
1713
  return JSON.parse(t).version ?? "0.0.0";
1714
1714
  } catch {
1715
1715
  return "0.0.0";
1716
1716
  }
1717
- })(), ei = async () => {
1717
+ })(), ti = async () => {
1718
1718
  try {
1719
1719
  let e = d(g(import.meta.url)), t = h(e, "..", "..", "devtools");
1720
1720
  if (T(p(t, "package.json"))) return t;
@@ -1723,7 +1723,7 @@ import {
1723
1723
  } catch {
1724
1724
  return null;
1725
1725
  }
1726
- }, ti = (e, t) => e.disableDevtools || !t ? [] : [
1726
+ }, ni = (e, t) => e.disableDevtools || !t ? [] : [
1727
1727
  "",
1728
1728
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1729
1729
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1733,12 +1733,12 @@ import {
1733
1733
  " await import('@voltro/devtools/styles.css')",
1734
1734
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1735
1735
  "}"
1736
- ], ni = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ri = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], ii = (e) => e.sentry ? [
1736
+ ], ri = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ii = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], ai = (e) => e.sentry ? [
1737
1737
  "",
1738
1738
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1739
1739
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1740
1740
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1741
- ] : [], ai = (e) => e.env ? ["import './env.public'"] : [], oi = (e) => {
1741
+ ] : [], oi = (e) => e.env ? ["import './env.public'"] : [], si = (e) => {
1742
1742
  let t = [], n = h(e);
1743
1743
  for (;;) {
1744
1744
  T(p(n, "pnpm-workspace.yaml")) && t.push(n);
@@ -1747,14 +1747,14 @@ import {
1747
1747
  n = e;
1748
1748
  }
1749
1749
  return t;
1750
- }, si = In, ci = (e) => {
1750
+ }, ci = In, li = (e) => {
1751
1751
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1752
1752
  let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1753
1753
  if (t) return `island-${t[1]}`;
1754
- }, li = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, ui = (e) => e.startsWith("(") && e.endsWith(")"), di = (e) => e.filter((e) => !ui(e)), fi = (e) => {
1755
- let t = e.replace(r, "").split("/").filter(Boolean).filter((e) => !ui(e));
1754
+ }, ui = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, di = (e) => e.startsWith("(") && e.endsWith(")"), fi = (e) => e.filter((e) => !di(e)), pi = (e) => {
1755
+ let t = e.replace(r, "").split("/").filter(Boolean).filter((e) => !di(e));
1756
1756
  return t.length === 0 ? "/" : "/" + t.join("/");
1757
- }, pi = (e) => `${e.replace(r, "").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 (e) => {
1757
+ }, mi = (e) => `${e.replace(r, "").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 (e) => {
1758
1758
  let t = [], i = [], a = async (e, o) => {
1759
1759
  let s = [];
1760
1760
  try {
@@ -1762,17 +1762,17 @@ import {
1762
1762
  } catch {
1763
1763
  return;
1764
1764
  }
1765
- let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !si(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1765
+ let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !ci(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1766
1766
  if (l.some((e) => n.has(e))) {
1767
1767
  let t = u.has("layout.tsx"), r = !1;
1768
1768
  if (t) try {
1769
1769
  let t = await O.readFile(p(e, "layout.tsx"), "utf8");
1770
- r = li.test(t);
1770
+ r = ui.test(t);
1771
1771
  } catch {}
1772
1772
  i.push({
1773
1773
  dir: d,
1774
1774
  chain: o,
1775
- contributesToUrl: o.length === 0 || !ui(o[o.length - 1]),
1775
+ contributesToUrl: o.length === 0 || !di(o[o.length - 1]),
1776
1776
  hasLayout: t,
1777
1777
  hasLayoutLoader: r,
1778
1778
  hasError: u.has("error.tsx"),
@@ -1786,8 +1786,8 @@ import {
1786
1786
  let n = d ? `${d}/${e}` : e;
1787
1787
  t.push({
1788
1788
  file: n,
1789
- pattern: fi(n),
1790
- ident: pi(n),
1789
+ pattern: pi(n),
1790
+ ident: mi(n),
1791
1791
  dirChain: o
1792
1792
  });
1793
1793
  }
@@ -1806,14 +1806,14 @@ import {
1806
1806
  dirs: s,
1807
1807
  orphanedSpecials: c
1808
1808
  };
1809
- }, mi = (e, t) => {
1809
+ }, hi = (e, t) => {
1810
1810
  let n = [];
1811
1811
  for (let r = 0; r <= t.length; r++) {
1812
1812
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1813
1813
  a && n.push(a);
1814
1814
  }
1815
1815
  return n;
1816
- }, hi = async (e) => {
1816
+ }, gi = async (e) => {
1817
1817
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1818
1818
  return {
1819
1819
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1836,10 +1836,10 @@ import {
1836
1836
  })),
1837
1837
  segmentLoaderData: o
1838
1838
  };
1839
- }, gi = (e) => {
1840
- let t = di(e);
1839
+ }, _i = (e) => {
1840
+ let t = fi(e);
1841
1841
  return t.length === 0 ? "" : "/" + t.join("/");
1842
- }, _i = [
1842
+ }, vi = [
1843
1843
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1844
1844
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1845
1845
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1932,7 +1932,7 @@ import {
1932
1932
  " _vdtErrorStart('Build error')",
1933
1933
  " })",
1934
1934
  "}"
1935
- ].join("\n"), vi = (e) => {
1935
+ ].join("\n"), yi = (e) => {
1936
1936
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1937
1937
  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, "\\$&"));
1938
1938
  let a = i.join("/");
@@ -1941,8 +1941,8 @@ import {
1941
1941
  paramNames: t,
1942
1942
  priority: n
1943
1943
  };
1944
- }, yi = (e) => e.map((e) => {
1945
- let { regex: t, paramNames: n, priority: r } = vi(e.pattern);
1944
+ }, bi = (e) => e.map((e) => {
1945
+ let { regex: t, paramNames: n, priority: r } = yi(e.pattern);
1946
1946
  return {
1947
1947
  pattern: e.pattern,
1948
1948
  file: e.file,
@@ -1951,7 +1951,7 @@ import {
1951
1951
  paramNames: n,
1952
1952
  priority: r
1953
1953
  };
1954
- }).slice().sort((e, t) => e.priority - t.priority), bi = (e, t) => {
1954
+ }).slice().sort((e, t) => e.priority - t.priority), xi = (e, t) => {
1955
1955
  for (let n of t) {
1956
1956
  let t = n.regex.exec(e);
1957
1957
  if (!t) continue;
@@ -1963,7 +1963,7 @@ import {
1963
1963
  };
1964
1964
  }
1965
1965
  return null;
1966
- }, xi = async (e, t) => {
1966
+ }, Si = async (e, t) => {
1967
1967
  let n = e;
1968
1968
  for (;;) {
1969
1969
  let e = p(n, "node_modules", t);
@@ -1977,7 +1977,7 @@ import {
1977
1977
  if (r === n) return null;
1978
1978
  n = r;
1979
1979
  }
1980
- }, Si = async (e) => {
1980
+ }, Ci = async (e) => {
1981
1981
  try {
1982
1982
  let t = await import(_(p(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;
1983
1983
  return a ? {
@@ -1986,7 +1986,7 @@ import {
1986
1986
  } : { port: r };
1987
1987
  } catch {}
1988
1988
  return { port: 4e3 };
1989
- }, Ci = (e, t) => ({
1989
+ }, wi = (e, t) => ({
1990
1990
  name: e,
1991
1991
  pkg: t.package,
1992
1992
  browserWsUrl: t.url,
@@ -1994,7 +1994,7 @@ import {
1994
1994
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1995
1995
  ...t.headers ? { headers: t.headers } : {},
1996
1996
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1997
- }), wi = (e, t, n) => {
1997
+ }), Ti = (e, t, n) => {
1998
1998
  let r = t.transport?.wsPath ?? n.wsPath;
1999
1999
  return {
2000
2000
  name: e,
@@ -2006,7 +2006,7 @@ import {
2006
2006
  ...t.headers ? { headers: t.headers } : {},
2007
2007
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
2008
2008
  };
2009
- }, Ti = (e) => {
2009
+ }, Ei = (e) => {
2010
2010
  let t = /* @__PURE__ */ new Map();
2011
2011
  for (let n of e) {
2012
2012
  if (n.proxyTarget === void 0) continue;
@@ -2014,43 +2014,43 @@ import {
2014
2014
  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>.`);
2015
2015
  t.set(n.browserWsUrl, n.name);
2016
2016
  }
2017
- }, Ei = async (e, t) => {
2017
+ }, Di = async (e, t) => {
2018
2018
  let n = Object.entries(t.apis ?? {}), r = [];
2019
2019
  for (let [t, i] of n) {
2020
2020
  if (i.url) {
2021
- r.push(Ci(t, i));
2021
+ r.push(wi(t, i));
2022
2022
  continue;
2023
2023
  }
2024
- let n = await xi(e, i.package);
2024
+ let n = await Si(e, i.package);
2025
2025
  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.`);
2026
- r.push(wi(t, i, await Si(n)));
2026
+ r.push(Ti(t, i, await Ci(n)));
2027
2027
  }
2028
- return Ti(r), r;
2029
- }, Di = (e) => {
2028
+ return Ei(r), r;
2029
+ }, Oi = (e) => {
2030
2030
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
2031
2031
  let t = new URL(e);
2032
2032
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
2033
2033
  } catch {
2034
2034
  return;
2035
2035
  }
2036
- }, Oi = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, ki = (e) => process.env[Oi(e)] ?? process.env.VOLTRO_API_ORIGIN, Ai = (e, t) => {
2036
+ }, ki = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, Ai = (e) => process.env[ki(e)] ?? process.env.VOLTRO_API_ORIGIN, ji = (e, t) => {
2037
2037
  if (!e) return;
2038
- let n = ki(e.name) ?? e.serverOrigin;
2038
+ let n = Ai(e.name) ?? e.serverOrigin;
2039
2039
  if (n) {
2040
- let e = Di(n);
2040
+ let e = Oi(n);
2041
2041
  if (e) return e;
2042
2042
  }
2043
2043
  if (t?.allowDevProxy && e.proxyTarget) {
2044
- let t = Di(e.proxyTarget);
2044
+ let t = Oi(e.proxyTarget);
2045
2045
  if (t) return t;
2046
2046
  }
2047
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Di(e.browserWsUrl);
2048
- }, ji = (e, t, n) => {
2047
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Oi(e.browserWsUrl);
2048
+ }, Mi = (e, t, n) => {
2049
2049
  if (!e) {
2050
2050
  if (n?.apiName === void 0) return;
2051
2051
  let e = n.apiName;
2052
2052
  return async () => {
2053
- 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 ${Oi(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.`);
2053
+ 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 ${ki(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.`);
2054
2054
  };
2055
2055
  }
2056
2056
  return async (r, i) => {
@@ -2072,7 +2072,7 @@ import {
2072
2072
  });
2073
2073
  } catch (t) {
2074
2074
  let i = t?.cause?.code ?? String(t?.message ?? t);
2075
- throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${Oi(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 });
2075
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${ki(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 });
2076
2076
  }
2077
2077
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2078
2078
  let s = await o.json();
@@ -2090,8 +2090,8 @@ import {
2090
2090
  }
2091
2091
  if (u) return l;
2092
2092
  };
2093
- }, Mi = async (e, t, n, r = {}) => {
2094
- let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = T(p(e, "node_modules", "@voltro", "devtools", "package.json")) || await ei() !== null, s = t.theme === "system" ? [
2093
+ }, Ni = async (e, t, n, r = {}) => {
2094
+ let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = T(p(e, "node_modules", "@voltro", "devtools", "package.json")) || await ti() !== null, s = t.theme === "system" ? [
2095
2095
  " <script>",
2096
2096
  " (function () {",
2097
2097
  " var root = document.documentElement",
@@ -2139,63 +2139,63 @@ import {
2139
2139
  return t.push(`descriptors: ${h(e.name)}`), t.push(`wsUrl: ${JSON.stringify(e.browserWsUrl)}`), e.hasAuthHeaders ? t.push(`headers: __voltroAuthHeaders?.[${JSON.stringify(e.name)}]?.authHeaders`) : e.headers && t.push(`headers: ${JSON.stringify(e.headers)}`), ` ${JSON.stringify(e.name)}: { ${t.join(", ")} },`;
2140
2140
  }), v, y, b;
2141
2141
  if (u.length > 0) {
2142
- let e = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), n = [];
2142
+ let n = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2143
2143
  for (let e of d) {
2144
2144
  let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`;
2145
- 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'`);
2145
+ e.hasLayout && e.hasLayoutLoader ? r.push(`import * as ${Q(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && r.push(`import ${Q(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && r.push(`import ${Q(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && r.push(`import ${Q(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && r.push(`import ${Q(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2146
2146
  }
2147
- let r = u.map((e) => {
2148
- let t = mi(d, e.dirChain).map((e) => {
2147
+ let i = u.map((e) => {
2148
+ let t = hi(d, e.dirChain).map((e) => {
2149
2149
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2150
2150
  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(", ")} }`;
2151
2151
  }).join(",\n");
2152
2152
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2153
- }), i = d.filter((e) => e.hasNotFound).map((e) => {
2154
- let t = gi(e.chain), n = mi(d, e.chain).map((e) => {
2153
+ }), a = d.filter((e) => e.hasNotFound).map((e) => {
2154
+ let t = _i(e.chain), n = hi(d, e.chain).map((e) => {
2155
2155
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2156
2156
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2157
2157
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
2158
2158
  return ` {\n prefix: ${JSON.stringify(t)},\n Component: refs.notFounds[${JSON.stringify(e.dir)}],${r}\n },`;
2159
- }), a = [], s = [], c = [], l = [], f = [], p = [];
2159
+ }), s = [], c = [], l = [], f = [], m = [], h = [];
2160
2160
  for (let e of d) {
2161
- let t = e.dir === "" ? "../src/pages/layout.tsx" : `../src/pages/${e.dir}/layout.tsx`, n = e.dir === "" ? "../src/pages/error.tsx" : `../src/pages/${e.dir}/error.tsx`, r = e.dir === "" ? "../src/pages/loading.tsx" : `../src/pages/${e.dir}/loading.tsx`, i = e.dir === "" ? "../src/pages/not-found.tsx" : `../src/pages/${e.dir}/not-found.tsx`, o = JSON.stringify(e.dir);
2162
- e.hasLayout && e.hasLayoutLoader ? (s.push(` ${o}: ${Q(e.dir, "Layout")}Mod.default,`), c.push(` ${o}: ${Q(e.dir, "Layout")}Mod.loader,`), a.push({
2161
+ let t = e.dir === "" ? "../src/pages/layout.tsx" : `../src/pages/${e.dir}/layout.tsx`, n = e.dir === "" ? "../src/pages/error.tsx" : `../src/pages/${e.dir}/error.tsx`, r = e.dir === "" ? "../src/pages/loading.tsx" : `../src/pages/${e.dir}/loading.tsx`, i = e.dir === "" ? "../src/pages/not-found.tsx" : `../src/pages/${e.dir}/not-found.tsx`, a = JSON.stringify(e.dir);
2162
+ e.hasLayout && e.hasLayoutLoader ? (c.push(` ${a}: ${Q(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${Q(e.dir, "Layout")}Mod.loader,`), s.push({
2163
2163
  relPath: t,
2164
2164
  kind: "layout",
2165
2165
  slotKey: e.dir
2166
- })) : e.hasLayout && (s.push(` ${o}: ${Q(e.dir, "Layout")},`), a.push({
2166
+ })) : e.hasLayout && (c.push(` ${a}: ${Q(e.dir, "Layout")},`), s.push({
2167
2167
  relPath: t,
2168
2168
  kind: "layout",
2169
2169
  slotKey: e.dir
2170
- })), e.hasError && (l.push(` ${o}: ${Q(e.dir, "Error")},`), a.push({
2170
+ })), e.hasError && (f.push(` ${a}: ${Q(e.dir, "Error")},`), s.push({
2171
2171
  relPath: n,
2172
2172
  kind: "error",
2173
2173
  slotKey: e.dir
2174
- })), e.hasPending && (f.push(` ${o}: ${Q(e.dir, "Pending")},`), a.push({
2174
+ })), e.hasPending && (m.push(` ${a}: ${Q(e.dir, "Pending")},`), s.push({
2175
2175
  relPath: r,
2176
2176
  kind: "pending",
2177
2177
  slotKey: e.dir
2178
- })), e.hasNotFound && (p.push(` ${o}: ${Q(e.dir, "NotFound")},`), a.push({
2178
+ })), e.hasNotFound && (h.push(` ${a}: ${Q(e.dir, "NotFound")},`), s.push({
2179
2179
  relPath: i,
2180
2180
  kind: "notFound",
2181
2181
  slotKey: e.dir
2182
2182
  }));
2183
2183
  }
2184
- for (let e of u) a.push({
2184
+ for (let e of u) s.push({
2185
2185
  relPath: `../src/pages/${e.file}`,
2186
2186
  kind: "page",
2187
2187
  slotKey: e.pattern
2188
2188
  });
2189
- let m = a.map((e) => ` ${JSON.stringify(e.relPath)},`), h = a.map((e, t) => {
2189
+ let x = s.map((e) => ` ${JSON.stringify(e.relPath)},`), S = s.map((e, t) => {
2190
2190
  let n = JSON.stringify(e.slotKey);
2191
2191
  return e.kind === "page" ? ` if (newMods[${t}] && refs.pages[${n}] !== undefined) { refs.pages[${n}] = newMods[${t}]; changed = true }` : ` if (newMods[${t}]?.default) { refs.${e.kind === "layout" ? "layouts" : e.kind === "error" ? "errors" : e.kind === "pending" ? "pendings" : "notFounds"}[${n}] = newMods[${t}].default;${e.kind === "layout" ? ` refs.layoutLoaders[${n}] = newMods[${t}].loader;` : ""} changed = true }`;
2192
- }), x = t.locales ?? [], S = x.length > 0, C = t.defaultLocale ?? x[0] ?? "en";
2193
- if (S && !x.includes(C)) throw Error(`[voltro dev] app.config.ts: defaultLocale '${C}' must be one of locales [${x.join(", ")}]`);
2194
- let w = S ? [
2192
+ }), C = t.locales ?? [], w = C.length > 0 && C.every((t) => T(p(e, "src", "locales", `${t}.ts`)) || T(p(e, "src", "locales", `${t}.tsx`))), E = w, D = t.defaultLocale ?? C[0] ?? "en";
2193
+ if (C.length > 0 && !w && Z.info(`i18n: locales [${C.join(", ")}] declared with no src/locales/<code>.ts — using them for <html lang> and the resolved locale only. Add the catalogs to get <I18nProvider> wired, or keep your own i18n stack.`), C.length > 0 && !C.includes(D)) throw Error(`[voltro dev] app.config.ts: defaultLocale '${D}' must be one of locales [${C.join(", ")}]`);
2194
+ let O = E ? [
2195
2195
  "import { I18nProvider } from '@voltro/i18n'",
2196
2196
  "import { resolveLocale } from '@voltro/i18n/server'",
2197
2197
  "import { useServerRequest } from '@voltro/web'",
2198
- ...x.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2198
+ ...C.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2199
2199
  ] : [];
2200
2200
  y = [
2201
2201
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2218,7 +2218,7 @@ import {
2218
2218
  "// without unmounting the surrounding tree.",
2219
2219
  "",
2220
2220
  "import { pageRoute, lazyPageRoute, preloadRouteModule, type PageDescriptor, type NotFoundDescriptor } from '@voltro/web'",
2221
- ...n,
2221
+ ...r,
2222
2222
  "",
2223
2223
  "// Mutable module registry. Initial values come from the static",
2224
2224
  "// imports above; HMR patches the slot, never the import.",
@@ -2231,19 +2231,19 @@ import {
2231
2231
  " pages: Record<string, unknown>",
2232
2232
  "} = {",
2233
2233
  " layouts: {",
2234
- ...s,
2234
+ ...c,
2235
2235
  " },",
2236
2236
  " layoutLoaders: {",
2237
- ...c,
2237
+ ...l,
2238
2238
  " },",
2239
2239
  " errors: {",
2240
- ...l,
2240
+ ...f,
2241
2241
  " },",
2242
2242
  " pendings: {",
2243
- ...f,
2243
+ ...m,
2244
2244
  " },",
2245
2245
  " notFounds: {",
2246
- ...p,
2246
+ ...h,
2247
2247
  " },",
2248
2248
  " pages: {},",
2249
2249
  "}",
@@ -2251,7 +2251,7 @@ import {
2251
2251
  "// Per-pattern dynamic-import thunks. Each is a literal `import()` so vite",
2252
2252
  "// code-splits the page into its own chunk and only fetches it on match.",
2253
2253
  "const pageLoaders: Record<string, () => Promise<Record<string, unknown>>> = {",
2254
- ...e,
2254
+ ...n,
2255
2255
  "}",
2256
2256
  "",
2257
2257
  "let version = 0",
@@ -2285,7 +2285,7 @@ import {
2285
2285
  " }, { chain })",
2286
2286
  "",
2287
2287
  "export const buildRoutes = (): PageDescriptor[] => [",
2288
- ...r,
2288
+ ...i,
2289
2289
  "]",
2290
2290
  "",
2291
2291
  "// Preload the CURRENT url's page chunk before hydration. main.tsx awaits",
@@ -2302,17 +2302,17 @@ import {
2302
2302
  "}",
2303
2303
  "",
2304
2304
  "export const buildNotFounds = (): NotFoundDescriptor[] => [",
2305
- ...i,
2305
+ ...a,
2306
2306
  "]",
2307
2307
  "",
2308
2308
  "if (import.meta.hot) {",
2309
2309
  " import.meta.hot.accept(",
2310
2310
  " [",
2311
- ...m,
2311
+ ...x,
2312
2312
  " ],",
2313
2313
  " (newMods: Array<Record<string, unknown> | undefined>) => {",
2314
2314
  " let changed = false",
2315
- ...h,
2315
+ ...S,
2316
2316
  " if (changed) bump()",
2317
2317
  " },",
2318
2318
  " )",
@@ -2329,16 +2329,16 @@ import {
2329
2329
  "",
2330
2330
  "import { useMemo, useSyncExternalStore } from 'react'",
2331
2331
  "import { Router } from '@voltro/web'",
2332
- ...w,
2332
+ ...O,
2333
2333
  "import { subscribe, getVersion, buildRoutes, buildNotFounds } from './routeTable'",
2334
2334
  "",
2335
- ...S ? [
2336
- `// i18n auto-wiring (config.locales = [${x.map((e) => JSON.stringify(e)).join(", ")}]).`,
2335
+ ...E ? [
2336
+ `// i18n auto-wiring (config.locales = [${C.map((e) => JSON.stringify(e)).join(", ")}]).`,
2337
2337
  "const I18N_CATALOGS: Record<string, import('@voltro/i18n').MessageCatalog> = {",
2338
- ...x.map((e) => ` ${JSON.stringify(e)}: i18nCatalog_${e},`),
2338
+ ...C.map((e) => ` ${JSON.stringify(e)}: i18nCatalog_${e},`),
2339
2339
  "}",
2340
- `const I18N_SUPPORTED: ReadonlyArray<string> = [${x.map((e) => JSON.stringify(e)).join(", ")}]`,
2341
- `const I18N_DEFAULT = ${JSON.stringify(C)}`,
2340
+ `const I18N_SUPPORTED: ReadonlyArray<string> = [${C.map((e) => JSON.stringify(e)).join(", ")}]`,
2341
+ `const I18N_DEFAULT = ${JSON.stringify(D)}`,
2342
2342
  "",
2343
2343
  "const pickI18nLocale = (ssr: ReturnType<typeof useServerRequest>): string => {",
2344
2344
  " if (ssr) {",
@@ -2389,7 +2389,7 @@ import {
2389
2389
  " const v = useSyncExternalStore(subscribe, getVersion, getVersion)",
2390
2390
  " const routes = useMemo(() => buildRoutes(), [v])",
2391
2391
  " const notFounds = useMemo(() => buildNotFounds(), [v])",
2392
- ...S ? [
2392
+ ...E ? [
2393
2393
  " const ssr = useServerRequest()",
2394
2394
  " const locale = pickI18nLocale(ssr)",
2395
2395
  " const messages = I18N_CATALOGS[locale] ?? I18N_CATALOGS[I18N_DEFAULT]!",
@@ -2407,14 +2407,14 @@ import {
2407
2407
  "// resolved apis map. Side-effect only — no local component definitions —",
2408
2408
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2409
2409
  "",
2410
- ...ai(t),
2410
+ ...oi(t),
2411
2411
  "import { mount } from '@voltro/web'",
2412
2412
  ...g,
2413
2413
  "import { App } from './app'",
2414
2414
  "import { preloadCurrentRoute } from './routeTable'",
2415
- ...ri(t),
2416
- ...ti(t, o),
2417
2415
  ...ii(t),
2416
+ ...ni(t, o),
2417
+ ...ai(t),
2418
2418
  "",
2419
2419
  "// Preload the current route's page chunk BEFORE hydration so the first",
2420
2420
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2431,10 +2431,10 @@ import {
2431
2431
  " apis: {",
2432
2432
  ..._,
2433
2433
  " },",
2434
- ...ni(t, o),
2434
+ ...ri(t, o),
2435
2435
  "})",
2436
2436
  "",
2437
- _i
2437
+ vi
2438
2438
  ].join("\n");
2439
2439
  } else v = "", y = "", b = [
2440
2440
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2442,22 +2442,22 @@ import {
2442
2442
  "// and calls mount(). Side-effect only, no component definitions, so the",
2443
2443
  "// user's component file remains the Fast Refresh boundary.",
2444
2444
  "",
2445
- ...ai(t),
2445
+ ...oi(t),
2446
2446
  "import { mount } from '@voltro/web'",
2447
2447
  ...g,
2448
2448
  "import App from '../src/App'",
2449
- ...ri(t),
2450
- ...ti(t, o),
2451
2449
  ...ii(t),
2450
+ ...ni(t, o),
2451
+ ...ai(t),
2452
2452
  "",
2453
2453
  "mount(App, {",
2454
2454
  " apis: {",
2455
2455
  ..._,
2456
2456
  " },",
2457
- ...ni(t, o),
2457
+ ...ri(t, o),
2458
2458
  "})",
2459
2459
  "",
2460
- _i
2460
+ vi
2461
2461
  ].join("\n");
2462
2462
  let x = p(e, ".framework");
2463
2463
  await O.mkdir(x, { recursive: !0 }), t.env ? await nt(x, r) : await O.rm(p(x, "env.public.ts"), { force: !0 }), await O.writeFile(p(x, "index.html"), c, "utf8"), await O.writeFile(p(x, "main.tsx"), b, "utf8"), v ? (await O.writeFile(p(x, "app.tsx"), v, "utf8"), await O.writeFile(p(x, "routeTable.ts"), y, "utf8")) : (await O.rm(p(x, "app.tsx"), { force: !0 }), await O.rm(p(x, "routeTable.ts"), { force: !0 }));
@@ -2474,7 +2474,7 @@ import {
2474
2474
  Z.warn(`could not add ${D.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2475
2475
  }
2476
2476
  }
2477
- }, Ni = async (e, t) => {
2477
+ }, Pi = async (e, t) => {
2478
2478
  try {
2479
2479
  let n = p(d(e), "project.json");
2480
2480
  if (!T(n)) return;
@@ -2487,16 +2487,16 @@ import {
2487
2487
  projectJson: n
2488
2488
  });
2489
2489
  } catch {}
2490
- }, Pi = (e) => p(e, ".framework", "dist", "server", "appConfig.js"), Fi = async (e) => {
2491
- let t = Pi(e), n = T(t) ? t : p(e, "app.config.ts");
2490
+ }, Fi = (e) => p(e, ".framework", "dist", "server", "appConfig.js"), Ii = async (e) => {
2491
+ let t = Fi(e), n = T(t) ? t : p(e, "app.config.ts");
2492
2492
  try {
2493
2493
  let e = (await import(_(n).href)).default;
2494
2494
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2495
2495
  } catch {
2496
2496
  return null;
2497
2497
  }
2498
- }, Ii = async (e) => {
2499
- let t = await Fi(e);
2498
+ }, Li = async (e) => {
2499
+ let t = await Ii(e);
2500
2500
  if (!t) return {
2501
2501
  ran: !1,
2502
2502
  exitCode: 0
@@ -2504,7 +2504,7 @@ import {
2504
2504
  Nn();
2505
2505
  let n = qt();
2506
2506
  fn(n), Z.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2507
- let r = await Ei(e, t);
2507
+ let r = await Di(e, t);
2508
2508
  for (let e of r) Z.info("api wired", {
2509
2509
  name: e.name,
2510
2510
  pkg: e.pkg,
@@ -2523,7 +2523,7 @@ import {
2523
2523
  log: Z,
2524
2524
  generateTypes: !0
2525
2525
  }), f = d.publicValues;
2526
- await Mi(e, t, r, f), Z.debug("generated framework entry files", { files: [
2526
+ await Ni(e, t, r, f), Z.debug("generated framework entry files", { files: [
2527
2527
  "index.html",
2528
2528
  ".framework/main.tsx",
2529
2529
  ...t.env ? [".framework/env.public.ts"] : []
@@ -2537,10 +2537,10 @@ import {
2537
2537
  pid: process.pid,
2538
2538
  status: "booting",
2539
2539
  logFile: y.path
2540
- }).catch(() => {}), await Ni(e, g);
2540
+ }).catch(() => {}), await Pi(e, g);
2541
2541
  let { pages: b, dirs: x } = await $(p(e, "src", "pages")), S = {
2542
2542
  dirs: x,
2543
- ssrRoutes: yi(b)
2543
+ ssrRoutes: bi(b)
2544
2544
  }, w = x.map((e) => ({
2545
2545
  dir: e.dir,
2546
2546
  hasLayout: e.hasLayout,
@@ -2552,7 +2552,7 @@ import {
2552
2552
  pages: b
2553
2553
  });
2554
2554
  E.wrote && Z.debug("routes codegen wrote", { path: m(e, E.path) });
2555
- let D = await Xe("vite", () => import("vite")), ee = (await import("@vitejs/plugin-react")).default, te = (await import("@tailwindcss/vite")).default, k = p(e, ".framework"), A = p(e, "src"), ne = /* @__PURE__ */ new Set([
2555
+ let D = await Xe("vite", () => import("vite")), ee = (await import("@vitejs/plugin-react")).default, k = (await import("@tailwindcss/vite")).default, A = p(e, ".framework"), j = p(e, "src"), te = /* @__PURE__ */ new Set([
2556
2556
  ".framework",
2557
2557
  "node_modules",
2558
2558
  "dist",
@@ -2560,15 +2560,15 @@ import {
2560
2560
  ".vite",
2561
2561
  ".turbo",
2562
2562
  ".cache"
2563
- ]), re = {
2563
+ ]), ne = {
2564
2564
  name: "framework:watch-app-sources",
2565
2565
  async configureServer(t) {
2566
2566
  try {
2567
- let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !ne.has(e.name));
2567
+ let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !te.has(e.name));
2568
2568
  for (let r of n) t.watcher.add(p(e, r.name));
2569
- n.length === 0 && t.watcher.add(A);
2569
+ n.length === 0 && t.watcher.add(j);
2570
2570
  } catch {
2571
- t.watcher.add(A);
2571
+ t.watcher.add(j);
2572
2572
  }
2573
2573
  try {
2574
2574
  let n = await O.readFile(p(e, "package.json"), "utf8"), r = JSON.parse(n), i = Object.keys({
@@ -2576,7 +2576,7 @@ import {
2576
2576
  ...r.devDependencies
2577
2577
  });
2578
2578
  await Promise.all(i.map(async (n) => {
2579
- let r = await xi(e, n);
2579
+ let r = await Si(e, n);
2580
2580
  if (!r) return;
2581
2581
  let i = p(r, "src");
2582
2582
  try {
@@ -2585,15 +2585,15 @@ import {
2585
2585
  }));
2586
2586
  } catch {}
2587
2587
  }
2588
- }, j = p(e, "src", "pages"), M = (e) => e.endsWith(".tsx") && (e === j || e.startsWith(j + "/")), ie = (e) => e === j || e.startsWith(j + "/"), N = async (n) => {
2588
+ }, M = p(e, "src", "pages"), N = (e) => e.endsWith(".tsx") && (e === M || e.startsWith(M + "/")), re = (e) => e === M || e.startsWith(M + "/"), P = async (n) => {
2589
2589
  try {
2590
2590
  let i = Date.now();
2591
- await Mi(e, t, r, f);
2592
- let { pages: a, dirs: o } = await $(j);
2591
+ await Ni(e, t, r, f);
2592
+ let { pages: a, dirs: o } = await $(M);
2593
2593
  await zt({
2594
2594
  appRoot: e,
2595
2595
  pages: a
2596
- }), S.dirs = o, S.ssrRoutes = yi(a), Z.info("page tree regenerated", {
2596
+ }), S.dirs = o, S.ssrRoutes = bi(a), Z.info("page tree regenerated", {
2597
2597
  reason: n,
2598
2598
  ms: Date.now() - i,
2599
2599
  routes: S.ssrRoutes.length
@@ -2601,44 +2601,44 @@ import {
2601
2601
  } catch (e) {
2602
2602
  Z.error("page tree regen failed", { reason: n }, e);
2603
2603
  }
2604
- }, P = {
2604
+ }, F = {
2605
2605
  name: "framework:regenerate-on-page-tree-change",
2606
2606
  configureServer(t) {
2607
2607
  let n = null, r = [], i = (e) => {
2608
2608
  r.push(e), n && clearTimeout(n), n = setTimeout(() => {
2609
2609
  n = null;
2610
2610
  let e = r.length === 1 ? r[0] : `${r.length} events (${r[0]}, …)`;
2611
- r.length = 0, N(e);
2611
+ r.length = 0, P(e);
2612
2612
  }, 50);
2613
2613
  };
2614
2614
  t.watcher.on("add", (t) => {
2615
- M(t) && i(`add ${m(e, t)}`);
2615
+ N(t) && i(`add ${m(e, t)}`);
2616
2616
  }), t.watcher.on("unlink", (t) => {
2617
- M(t) && i(`unlink ${m(e, t)}`);
2617
+ N(t) && i(`unlink ${m(e, t)}`);
2618
2618
  }), t.watcher.on("addDir", (t) => {
2619
- ie(t) && i(`addDir ${m(e, t)}`);
2619
+ re(t) && i(`addDir ${m(e, t)}`);
2620
2620
  }), t.watcher.on("unlinkDir", (t) => {
2621
- ie(t) && i(`unlinkDir ${m(e, t)}`);
2621
+ re(t) && i(`unlinkDir ${m(e, t)}`);
2622
2622
  });
2623
2623
  }
2624
- }, F = p(e, "app.config.ts"), ae = (e) => {
2625
- if (!z(e.env)) return "";
2624
+ }, I = p(e, "app.config.ts"), ie = (e) => {
2625
+ if (!B(e.env)) return "";
2626
2626
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2627
2627
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2628
- }, I = (e, t) => {
2628
+ }, L = (e, t) => {
2629
2629
  let n = [];
2630
- return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), ae(e) !== ae(t) && n.push("env"), n;
2631
- }, L = t, R = h(F), oe = {
2630
+ return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), ie(e) !== ie(t) && n.push("env"), n;
2631
+ }, R = t, z = h(I), ae = {
2632
2632
  name: "framework:watch-app-config",
2633
2633
  async configureServer(t) {
2634
- t.watcher.add(F), Z.info("watching app.config.ts for changes", { path: m(e, F) });
2634
+ t.watcher.add(I), Z.info("watching app.config.ts for changes", { path: m(e, I) });
2635
2635
  let n = async () => {
2636
2636
  try {
2637
2637
  try {
2638
- let e = t.moduleGraph.getModuleById(F);
2638
+ let e = t.moduleGraph.getModuleById(I);
2639
2639
  e && t.moduleGraph.invalidateModule(e);
2640
2640
  } catch {}
2641
- let e = (await t.ssrLoadModule(F, { fixStacktrace: !0 })).default;
2641
+ let e = (await t.ssrLoadModule(I, { fixStacktrace: !0 })).default;
2642
2642
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : (Z.warn("app.config.ts re-load returned wrong shape", { hasDefault: e !== void 0 }), null);
2643
2643
  } catch (e) {
2644
2644
  return Z.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
@@ -2657,17 +2657,17 @@ import {
2657
2657
  theme: r.theme,
2658
2658
  port: r.port,
2659
2659
  name: r.name
2660
- }), JSON.stringify(r) === JSON.stringify(L)) {
2660
+ }), JSON.stringify(r) === JSON.stringify(R)) {
2661
2661
  Z.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2662
2662
  return;
2663
2663
  }
2664
- let i = I(L, r);
2664
+ let i = L(R, r);
2665
2665
  if (i.length > 0) {
2666
2666
  Z.warn("app.config.ts changed — hard restart required", { fields: i });
2667
2667
  try {
2668
2668
  await t.close();
2669
2669
  } catch {}
2670
- let e = pe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2670
+ let e = fe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2671
2671
  stdio: "inherit",
2672
2672
  env: process.env,
2673
2673
  cwd: process.cwd()
@@ -2683,7 +2683,7 @@ import {
2683
2683
  }
2684
2684
  try {
2685
2685
  let n = Date.now();
2686
- await Mi(e, r, await Ei(e, r)), L = r, t.ws && t.ws.send({
2686
+ await Ni(e, r, await Di(e, r)), R = r, t.ws && t.ws.send({
2687
2687
  type: "full-reload",
2688
2688
  path: "*"
2689
2689
  }), Z.info("app.config.ts soft-regen", {
@@ -2693,7 +2693,7 @@ import {
2693
2693
  } catch (e) {
2694
2694
  Z.error("app.config.ts soft-regen failed", {}, e);
2695
2695
  }
2696
- }, o = (e) => u(e) === "app.config.ts" ? e === F || h(e) === R : !1;
2696
+ }, o = (e) => u(e) === "app.config.ts" ? e === I || h(e) === z : !1;
2697
2697
  t.watcher.on("change", (e) => {
2698
2698
  o(e) && (Z.info("app.config.ts change event (chokidar)", { file: e }), i());
2699
2699
  }), t.watcher.on("add", (e) => {
@@ -2701,7 +2701,7 @@ import {
2701
2701
  });
2702
2702
  try {
2703
2703
  let { watchFile: e } = await import("node:fs");
2704
- e(F, { interval: 500 }, (e, t) => {
2704
+ e(I, { interval: 500 }, (e, t) => {
2705
2705
  e.mtimeMs !== t.mtimeMs && (Z.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), i());
2706
2706
  }), Z.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2707
2707
  } catch (e) {
@@ -2712,18 +2712,18 @@ import {
2712
2712
  onBeforeRestart: () => t.close()
2713
2713
  });
2714
2714
  }
2715
- }, se = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, B = 0, ce = {
2715
+ }, oe = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, V = 0, se = {
2716
2716
  name: "framework:suppress-api-hmr",
2717
2717
  handleHotUpdate(e) {
2718
- if (B += 1, se.test(e.file)) return [];
2718
+ if (V += 1, oe.test(e.file)) return [];
2719
2719
  }
2720
- }, le = {
2720
+ }, ce = {
2721
2721
  name: "framework:reoptimize-on-rpcgroup-change",
2722
2722
  async configureServer(t) {
2723
2723
  let n = /* @__PURE__ */ new Map();
2724
2724
  for (let i of r) {
2725
2725
  if (!i.proxyTarget) continue;
2726
- let r = await xi(e, i.pkg);
2726
+ let r = await Si(e, i.pkg);
2727
2727
  if (!r) continue;
2728
2728
  let a = p(r, "rpcGroup.generated.ts");
2729
2729
  try {
@@ -2751,7 +2751,7 @@ import {
2751
2751
  if (r !== null) {
2752
2752
  a = !0, Z.info(`rpcGroup changed (${m(e, r)}) — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)`);
2753
2753
  try {
2754
- await O.rm(p(k, ".vite", "deps"), {
2754
+ await O.rm(p(A, ".vite", "deps"), {
2755
2755
  recursive: !0,
2756
2756
  force: !0
2757
2757
  }), await t.restart(!0);
@@ -2766,7 +2766,7 @@ import {
2766
2766
  };
2767
2767
  t.watcher.on("change", s), t.watcher.on("add", s);
2768
2768
  }
2769
- }, V = {}, ue = (e) => (t) => {
2769
+ }, H = {}, le = (e) => (t) => {
2770
2770
  t.on("proxyReq", (t, n) => {
2771
2771
  jn(t, n, {
2772
2772
  target: e,
@@ -2778,26 +2778,26 @@ import {
2778
2778
  };
2779
2779
  for (let e of r) {
2780
2780
  if (!e.proxyTarget) continue;
2781
- V[e.browserWsUrl] = {
2781
+ H[e.browserWsUrl] = {
2782
2782
  target: e.proxyTarget,
2783
2783
  ws: !0,
2784
2784
  changeOrigin: !0,
2785
2785
  ...e.wsPath ? {} : { rewrite: () => "/ws" }
2786
2786
  };
2787
2787
  let t = e.proxyTarget.replace(/^ws/, "http");
2788
- V[`/_voltro/api/${e.name}`] = {
2788
+ H[`/_voltro/api/${e.name}`] = {
2789
2789
  target: t,
2790
2790
  changeOrigin: !0,
2791
2791
  rewrite: (t) => t.replace(RegExp(`^/_voltro/api/${e.name}`), ""),
2792
- configure: ue(t)
2792
+ configure: le(t)
2793
2793
  };
2794
2794
  }
2795
2795
  for (let [e, n] of Object.entries(t.proxies ?? {})) {
2796
- if (V[e]) {
2796
+ if (H[e]) {
2797
2797
  Z.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
2798
2798
  continue;
2799
2799
  }
2800
- V[e] = {
2800
+ H[e] = {
2801
2801
  target: n.target,
2802
2802
  changeOrigin: n.changeOrigin ?? !0,
2803
2803
  ...n.rewrite === void 0 ? {} : { rewrite: (t) => t.replace(RegExp(`^${e}`), n.rewrite) }
@@ -2807,7 +2807,7 @@ import {
2807
2807
  ...n.rewrite === void 0 ? {} : { rewrite: n.rewrite }
2808
2808
  });
2809
2809
  }
2810
- let de = {
2810
+ let ue = {
2811
2811
  name: "framework:inspect",
2812
2812
  configureServer(r) {
2813
2813
  let u = null, d = async () => {
@@ -3012,7 +3012,7 @@ import {
3012
3012
  kind: "web",
3013
3013
  meta: {
3014
3014
  name: t.name ?? "(unnamed)",
3015
- voltroVersion: $r,
3015
+ voltroVersion: ei,
3016
3016
  port: g,
3017
3017
  mode: "dev",
3018
3018
  apis: Object.entries(t.apis ?? {}).map(([e, t]) => {
@@ -3030,7 +3030,7 @@ import {
3030
3030
  size: 0,
3031
3031
  entries: []
3032
3032
  }),
3033
- env: () => at(t.name ?? "app", { contract: z(t.env) ? t.env : void 0 })
3033
+ env: () => at(t.name ?? "app", { contract: B(t.env) ? t.env : void 0 })
3034
3034
  }, u, { method: e.method ?? "GET" });
3035
3035
  if (n === null) return i();
3036
3036
  r.statusCode = n.status, r.setHeader("content-type", n.contentType);
@@ -3041,7 +3041,7 @@ import {
3041
3041
  }
3042
3042
  });
3043
3043
  }
3044
- }, me = t.name === "voltroDashboard" ? {
3044
+ }, pe = t.name === "voltroDashboard" ? {
3045
3045
  name: "framework:dashboard-registry",
3046
3046
  configureServer(e) {
3047
3047
  e.middlewares.use(async (e, t, n) => {
@@ -3054,7 +3054,7 @@ import {
3054
3054
  }
3055
3055
  });
3056
3056
  }
3057
- } : null, he = /* @__PURE__ */ new Set(), H = (e, t, n, r, i, a = !1) => {
3057
+ } : null, me = /* @__PURE__ */ new Set(), U = (e, t, n, r, i, a = !1) => {
3058
3058
  let o = zr(i, a, t) ?? "";
3059
3059
  if (Z.error(`${t} render failed`, {
3060
3060
  pathname: n,
@@ -3067,12 +3067,12 @@ import {
3067
3067
  e.writeHead(500, {
3068
3068
  "content-type": "text/plain; charset=utf-8",
3069
3069
  "x-voltro-rendered-by": `${t}-failed`,
3070
- "x-voltro-ssr-generation": String(B)
3070
+ "x-voltro-ssr-generation": String(V)
3071
3071
  });
3072
- let s = B === 0 ? "" : `\n[voltro] this process has absorbed ${B} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3072
+ let s = V === 0 ? "" : `\n[voltro] this process has absorbed ${V} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3073
3073
  e.end(`${t} render failed for ${n}\n\n${Zt(i)}\n${o}\n${s}`);
3074
- }, U = Dt(), ge = kt({
3075
- limit: U,
3074
+ }, W = Dt(), he = kt({
3075
+ limit: W,
3076
3076
  onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
3077
3077
  onColdEnd: (e, { durationMs: t, failed: n }) => Z.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3078
3078
  id: e,
@@ -3080,11 +3080,11 @@ import {
3080
3080
  ...n ? { failed: !0 } : {}
3081
3081
  })
3082
3082
  });
3083
- Z.debug(`ssr cold-compile concurrency ${U}`, { concurrency: U });
3084
- let W = null, _e = async () => (W === null && (W = await O.readFile(p(e, ".framework", "index.html"), "utf8")), W), ve = {
3083
+ Z.debug(`ssr cold-compile concurrency ${W}`, { concurrency: W });
3084
+ let G = null, ge = async () => (G === null && (G = await O.readFile(p(e, ".framework", "index.html"), "utf8")), G), _e = {
3085
3085
  name: "framework:ssr",
3086
3086
  configureServer(n) {
3087
- let i = (e) => ge.load(e, async () => await n.ssrLoadModule(e)), a, o = () => {
3087
+ let i = (e) => he.load(e, async () => await n.ssrLoadModule(e)), a, o = () => {
3088
3088
  if (a !== void 0) return a;
3089
3089
  let n = t.locales ?? [], r = t.defaultLocale ?? n[0] ?? "en";
3090
3090
  return n.length === 0 ? (a = Promise.resolve(() => void 0), a) : (a = (async () => {
@@ -3108,9 +3108,9 @@ import {
3108
3108
  l.indexOf("?");
3109
3109
  let { pathname: u, search: d } = Ir(l);
3110
3110
  if (u.startsWith("/@") || u.startsWith("/node_modules/") || u.startsWith("/.framework/") || u.startsWith("/_voltro/") || u === "/main.tsx" || u === "/index.html" || u === "/sw.js" || u === "/favicon.ico" || u === "/robots.txt" || /\.[a-z0-9]+$/i.test(u)) return c();
3111
- let f = bi(u, S.ssrRoutes);
3111
+ let f = xi(u, S.ssrRoutes);
3112
3112
  if (!f) return c();
3113
- let m = !he.has(f.route.pattern), h = Date.now();
3113
+ let m = !me.has(f.route.pattern), h = Date.now();
3114
3114
  m && Z.info(`ssr compiling ${f.route.pattern}`, {
3115
3115
  pattern: f.route.pattern,
3116
3116
  pathname: u
@@ -3130,15 +3130,15 @@ import {
3130
3130
  }
3131
3131
  }, y = !1;
3132
3132
  try {
3133
- let b = await _("loadPage", async () => await i(p(e, "src", "pages", f.route.file))), x = Qn(b, p("src", "pages", f.route.file)), C = mi(S.dirs, f.route.dirChain), w = x === "spa" && C.some((e) => e.hasLayout);
3133
+ let b = await _("loadPage", async () => await i(p(e, "src", "pages", f.route.file))), x = Qn(b, p("src", "pages", f.route.file)), C = hi(S.dirs, f.route.dirChain), w = x === "spa" && C.some((e) => e.hasLayout);
3134
3134
  if (x !== "ssr" && x !== "isr" && !w) return c();
3135
3135
  let T = {};
3136
3136
  for (let [e, t] of Object.entries(a.headers ?? {})) typeof t == "string" ? T[e] = t : Array.isArray(t) && (T[e] = t.join(", "));
3137
- let E = ji(Ai(r[0], { allowDevProxy: !0 }), T.cookie, { apiName: r[0]?.name }), D = new AbortController(), O = () => D.abort();
3137
+ let E = Mi(ji(r[0], { allowDevProxy: !0 }), T.cookie, { apiName: r[0]?.name }), D = new AbortController(), O = () => D.abort();
3138
3138
  s.once("close", O);
3139
- let ee = null, te = [], k = {};
3139
+ let ee = null, k = [], A = {};
3140
3140
  try {
3141
- (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: te, segmentLoaderData: k} = await _("loadChain", () => hi({
3141
+ (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: k, segmentLoaderData: A} = await _("loadChain", () => gi({
3142
3142
  entries: C,
3143
3143
  loadLayout: (t) => i(p(e, "src", "pages", t.dir, "layout.tsx")),
3144
3144
  loadError: (t) => i(p(e, "src", "pages", t.dir, "error.tsx")),
@@ -3164,20 +3164,20 @@ import {
3164
3164
  } finally {
3165
3165
  s.off("close", O);
3166
3166
  }
3167
- let A = await _("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3168
- w || await Zr({
3167
+ let j = await _("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3168
+ w || await Qr({
3169
3169
  pageMod: b,
3170
3170
  params: f.params,
3171
3171
  query: E,
3172
3172
  apiName: r[0]?.name,
3173
- seed: A.seedPreloadedSubscription,
3173
+ seed: j.seedPreloadedSubscription,
3174
3174
  onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
3175
3175
  tag: e,
3176
3176
  apiName: t,
3177
3177
  pathname: u
3178
3178
  }, n)
3179
3179
  });
3180
- let ne = {
3180
+ let te = {
3181
3181
  pattern: f.route.pattern,
3182
3182
  Component: b.default,
3183
3183
  meta: b.meta,
@@ -3185,40 +3185,40 @@ import {
3185
3185
  ErrorBoundary: b.ErrorBoundary,
3186
3186
  Pending: b.Pending,
3187
3187
  renderMode: x,
3188
- chain: te
3189
- }, re = {
3190
- cookies: A.parseCookieHeader(T.cookie),
3188
+ chain: k
3189
+ }, ne = {
3190
+ cookies: j.parseCookieHeader(T.cookie),
3191
3191
  headers: T,
3192
3192
  url: l
3193
- }, j = b.interactive ?? "full", M = (await o())(T.cookie, T["accept-language"]);
3194
- y = M !== void 0;
3195
- let ie = M ? {
3196
- outerWrap: M.outerWrap,
3197
- locale: M.locale
3198
- } : {}, N = w ? Nr({
3199
- helpers: A,
3193
+ }, M = b.interactive ?? "full", N = (await o())(T.cookie, T["accept-language"]);
3194
+ y = N !== void 0;
3195
+ let re = N ? {
3196
+ outerWrap: N.outerWrap,
3197
+ locale: N.locale
3198
+ } : {}, P = w ? Nr({
3199
+ helpers: j,
3200
3200
  page: `src/pages/${f.route.file}`,
3201
- interactive: j,
3201
+ interactive: M,
3202
3202
  delivery: "stream",
3203
3203
  renderInput: {
3204
- descriptor: ne,
3204
+ descriptor: te,
3205
3205
  params: f.params,
3206
3206
  pathname: u,
3207
3207
  search: d,
3208
- segmentLoaderData: k,
3209
- requestContext: re,
3210
- ...ie
3208
+ segmentLoaderData: A,
3209
+ requestContext: ne,
3210
+ ...re
3211
3211
  }
3212
- }) : null, P = w ? null : Mr({
3213
- helpers: A,
3212
+ }) : null, F = w ? null : Mr({
3213
+ helpers: j,
3214
3214
  page: `src/pages/${f.route.file}`,
3215
3215
  pathname: u,
3216
3216
  renderMode: x,
3217
- interactive: j,
3217
+ interactive: M,
3218
3218
  loaderData: ee,
3219
- segmentLoaderData: k,
3219
+ segmentLoaderData: A,
3220
3220
  pageLoaderRan: typeof b.loader == "function"
3221
- }), F = [];
3221
+ }), I = [];
3222
3222
  await _("collectCss", async () => {
3223
3223
  let t = /* @__PURE__ */ new Set(), n = [
3224
3224
  p(e, "src", "pages", f.route.file),
@@ -3229,98 +3229,98 @@ import {
3229
3229
  ]),
3230
3230
  p(e, ".framework", "main.tsx")
3231
3231
  ];
3232
- for (let e of n) await v(e, t, F);
3232
+ for (let e of n) await v(e, t, I);
3233
3233
  });
3234
- let ae = await _("readShell", _e), I = await _("transformShell", () => n.transformIndexHtml(l, ae)), L = F.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), R = M?.locale ?? re.cookies["voltro:locale"] ?? t.defaultLocale ?? (t.locales ?? [])[0] ?? "en", oe = Date.now();
3235
- if (N) {
3234
+ let ie = await _("readShell", ge), L = await _("transformShell", () => n.transformIndexHtml(l, ie)), R = I.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), z = N?.locale ?? ne.cookies["voltro:locale"] ?? t.defaultLocale ?? (t.locales ?? [])[0] ?? "en", ae = Date.now();
3235
+ if (P) {
3236
3236
  let e = (e) => Fr({
3237
- helpers: A,
3238
- prepared: N,
3237
+ helpers: j,
3238
+ prepared: P,
3239
3239
  meta: e,
3240
- interactive: j,
3241
- extra: [L]
3240
+ interactive: M,
3241
+ extra: [R]
3242
3242
  });
3243
- if (N.hasDeferred) Jr({
3243
+ if (P.hasDeferred) Yr({
3244
3244
  res: s,
3245
3245
  shell: Kr({
3246
- shell: I,
3246
+ shell: L,
3247
3247
  inlineModuleScriptsAsync: !0
3248
3248
  }),
3249
- htmlLang: R,
3249
+ htmlLang: z,
3250
3250
  headers: {
3251
3251
  "content-type": "text/html; charset=utf-8",
3252
3252
  "x-voltro-rendered-by": "spa-shell-dev"
3253
3253
  },
3254
3254
  headInjection: e,
3255
- render: (e) => A.renderPageToStream({
3256
- ...N.renderInput,
3255
+ render: (e) => j.renderPageToStream({
3256
+ ...P.renderInput,
3257
3257
  ...e
3258
3258
  }),
3259
3259
  onShellError: (e) => {
3260
- H(s, "spa-shell-dev", u, f.route.pattern, e, y);
3260
+ U(s, "spa-shell-dev", u, f.route.pattern, e, y);
3261
3261
  }
3262
3262
  });
3263
3263
  else {
3264
3264
  let t = Pr({
3265
- helpers: A,
3266
- prepared: N
3267
- }), n = I.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="${R}"`);
3265
+ helpers: j,
3266
+ prepared: P
3267
+ }), n = L.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="${z}"`);
3268
3268
  s.statusCode = 200, s.setHeader("content-type", "text/html; charset=utf-8"), s.setHeader("x-voltro-rendered-by", "spa-shell-dev"), s.end(n);
3269
3269
  }
3270
- } else if (P) {
3270
+ } else if (F) {
3271
3271
  let e = (e) => [
3272
- L,
3273
- A.renderMetaToHtml(e),
3274
- `<meta name="voltro-interactive" content="${j}" />`,
3275
- ...P.hasDeferred ? [A.renderDeferredRegistryScript()] : [],
3276
- A.renderRouterStateScript(P.stateInput)
3272
+ R,
3273
+ j.renderMetaToHtml(e),
3274
+ `<meta name="voltro-interactive" content="${M}" />`,
3275
+ ...F.hasDeferred ? [j.renderDeferredRegistryScript()] : [],
3276
+ j.renderRouterStateScript(F.stateInput)
3277
3277
  ].filter((e) => e.length > 0).join("\n "), t = {
3278
- descriptor: ne,
3278
+ descriptor: te,
3279
3279
  params: f.params,
3280
3280
  pathname: u,
3281
3281
  search: d,
3282
- loaderData: P.loaderData,
3283
- segmentLoaderData: P.segmentLoaderData,
3284
- requestContext: re,
3285
- ...ie
3282
+ loaderData: F.loaderData,
3283
+ segmentLoaderData: F.segmentLoaderData,
3284
+ requestContext: ne,
3285
+ ...re
3286
3286
  };
3287
- if (x === "ssr" && j === "full") Jr({
3287
+ if (x === "ssr" && M === "full") Yr({
3288
3288
  res: s,
3289
3289
  shell: Kr({
3290
- shell: I,
3290
+ shell: L,
3291
3291
  inlineModuleScriptsAsync: !0
3292
3292
  }),
3293
- htmlLang: R,
3293
+ htmlLang: z,
3294
3294
  headers: {
3295
3295
  "content-type": "text/html; charset=utf-8",
3296
3296
  "x-voltro-rendered-by": "ssr-dev"
3297
3297
  },
3298
3298
  headInjection: e,
3299
- render: (e) => A.renderPageToStream({
3299
+ render: (e) => j.renderPageToStream({
3300
3300
  ...t,
3301
3301
  ...e
3302
3302
  }),
3303
3303
  onShellError: (e) => {
3304
- H(s, "ssr-dev", u, f.route.pattern, e, y);
3304
+ U(s, "ssr-dev", u, f.route.pattern, e, y);
3305
3305
  }
3306
3306
  });
3307
3307
  else {
3308
- let { html: n, meta: r } = A.renderPageToHtml(t), i = I.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${R}"`);
3308
+ let { html: n, meta: r } = j.renderPageToHtml(t), i = L.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${z}"`);
3309
3309
  s.statusCode = 200, s.setHeader("content-type", "text/html; charset=utf-8"), s.setHeader("x-voltro-rendered-by", "ssr-dev"), s.end(i);
3310
3310
  }
3311
3311
  }
3312
- g.render = Date.now() - oe;
3313
- let z = Date.now() - h;
3314
- m ? (he.add(f.route.pattern), Z.info(`ssr compiled ${f.route.pattern} in ${z}ms`, {
3312
+ g.render = Date.now() - ae;
3313
+ let B = Date.now() - h;
3314
+ m ? (me.add(f.route.pattern), Z.info(`ssr compiled ${f.route.pattern} in ${B}ms`, {
3315
3315
  pattern: f.route.pattern,
3316
3316
  pathname: u,
3317
- elapsedMs: z,
3317
+ elapsedMs: B,
3318
3318
  cold: !0,
3319
3319
  phases: g
3320
- })) : z > 200 && Z.info(`ssr rendered ${u} in ${z}ms`, {
3320
+ })) : B > 200 && Z.info(`ssr rendered ${u} in ${B}ms`, {
3321
3321
  pattern: f.route.pattern,
3322
3322
  pathname: u,
3323
- elapsedMs: z,
3323
+ elapsedMs: B,
3324
3324
  cold: !1,
3325
3325
  phases: g
3326
3326
  });
@@ -3339,21 +3339,21 @@ import {
3339
3339
  s.end(t.body);
3340
3340
  return;
3341
3341
  }
3342
- H(s, "ssr-dev", u, f.route.pattern, e, y);
3342
+ U(s, "ssr-dev", u, f.route.pattern, e, y);
3343
3343
  }
3344
3344
  });
3345
3345
  }
3346
- }, G = Date.now(), K = D.version ?? "?", q = await ei(), ye = p(e, "node_modules", "@voltro", "ui-shadcn"), J = T(p(ye, "package.json")) ? ye : null, be = [], xe = await (async () => {
3346
+ }, ve = Date.now(), K = D.version ?? "?", q = await ti(), ye = p(e, "node_modules", "@voltro", "ui-shadcn"), J = T(p(ye, "package.json")) ? ye : null, be = [], xe = await (async () => {
3347
3347
  let t = [];
3348
3348
  for (let n of r) {
3349
3349
  if (!n.proxyTarget) continue;
3350
- let r = await xi(e, n.pkg);
3350
+ let r = await Si(e, n.pkg);
3351
3351
  if (r) try {
3352
3352
  t.push(await O.readFile(p(r, "rpcGroup.generated.ts"), "utf8"));
3353
3353
  } catch {}
3354
3354
  }
3355
3355
  if (t.length === 0) return !1;
3356
- let n = fe("sha1").update(t.join("\0")).digest("hex"), i = p(k, ".voltro-rpcgroup-optimize"), a = "";
3356
+ let n = de("sha1").update(t.join("\0")).digest("hex"), i = p(A, ".voltro-rpcgroup-optimize"), a = "";
3357
3357
  try {
3358
3358
  a = (await O.readFile(i, "utf8")).trim();
3359
3359
  } catch {}
@@ -3364,7 +3364,7 @@ import {
3364
3364
  return !0;
3365
3365
  })();
3366
3366
  xe && Z.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client"), await (await D.createServer({
3367
- root: k,
3367
+ root: A,
3368
3368
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3369
3369
  ssr: { noExternal: ["react-intl"] },
3370
3370
  resolve: {
@@ -3410,30 +3410,30 @@ import {
3410
3410
  plugins: [
3411
3411
  Kn(p(e, "src", "pages")),
3412
3412
  ee(),
3413
- te(),
3414
- re,
3415
- P,
3416
- oe,
3413
+ k(),
3414
+ ne,
3415
+ F,
3416
+ ae,
3417
+ se,
3417
3418
  ce,
3418
- le,
3419
- de,
3420
- ve,
3421
- ...me ? [me] : []
3419
+ ue,
3420
+ _e,
3421
+ ...pe ? [pe] : []
3422
3422
  ],
3423
3423
  server: {
3424
3424
  port: g,
3425
3425
  strictPort: !0,
3426
3426
  host: !0,
3427
3427
  allowedHosts: t.allowedHosts === !0 || [...t.allowedHosts ?? []],
3428
- proxy: V,
3429
- fs: { allow: [e, ...oi(e)] }
3428
+ proxy: H,
3429
+ fs: { allow: [e, ...si(e)] }
3430
3430
  },
3431
3431
  appType: "spa",
3432
- cacheDir: p(k, ".vite"),
3432
+ cacheDir: p(A, ".vite"),
3433
3433
  publicDir: p(e, "public")
3434
- })).listen(), Qr.info(`v${K} ready in ${Date.now() - G}ms`, {
3434
+ })).listen(), $r.info(`v${K} ready in ${Date.now() - ve}ms`, {
3435
3435
  version: K,
3436
- bootMs: Date.now() - G
3436
+ bootMs: Date.now() - ve
3437
3437
  }), Z.info(`listening on http://localhost:${g}`, {
3438
3438
  port: g,
3439
3439
  app: t.name ?? "(unnamed)"
@@ -3479,23 +3479,23 @@ import {
3479
3479
  app: t.name ?? "unnamed",
3480
3480
  kind: "web",
3481
3481
  url: `http://localhost:${g}`,
3482
- bootMs: Date.now() - G
3482
+ bootMs: Date.now() - ve
3483
3483
  }), new Promise(() => {});
3484
- }, Li = async (e) => {
3484
+ }, Ri = async (e) => {
3485
3485
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
3486
- let t = await Fi(e);
3486
+ let t = await Ii(e);
3487
3487
  if (!t) return {
3488
3488
  ran: !1,
3489
3489
  exitCode: 0
3490
3490
  };
3491
3491
  let n = Date.now(), r = Z.child("serve");
3492
3492
  r.info("booting voltro serve (preview)", { app: t.name ?? "(unnamed)" });
3493
- let i = await Ei(e, t);
3493
+ let i = await Di(e, t);
3494
3494
  for (let e of i) r.info("api wired", {
3495
3495
  name: e.name,
3496
3496
  pkg: e.pkg
3497
3497
  });
3498
- await Mi(e, t, i);
3498
+ await Ni(e, t, i);
3499
3499
  {
3500
3500
  let { pages: t } = await $(p(e, "src", "pages"));
3501
3501
  await zt({
@@ -3516,7 +3516,7 @@ import {
3516
3516
  ] },
3517
3517
  build: {
3518
3518
  outDir: "dist",
3519
- rollupOptions: { output: { manualChunks: ci } }
3519
+ rollupOptions: { output: { manualChunks: li } }
3520
3520
  },
3521
3521
  publicDir: p(e, "public")
3522
3522
  });
@@ -3536,14 +3536,14 @@ import {
3536
3536
  extras: d,
3537
3537
  bootMs: Date.now() - n
3538
3538
  }), new Promise(() => {});
3539
- }, Ri = 5e3, zi = 6e4, Bi = (e, t) => {
3539
+ }, zi = 5e3, Bi = 6e4, Vi = (e, t) => {
3540
3540
  if (e.length === 0) return 0;
3541
3541
  if (e.length === 1) return e[0];
3542
3542
  let n = t * (e.length - 1), r = Math.floor(n), i = Math.ceil(n);
3543
3543
  if (r === i) return e[r];
3544
3544
  let a = n - r;
3545
3545
  return e[r] * (1 - a) + e[i] * a;
3546
- }, Vi = (e) => {
3546
+ }, Hi = (e) => {
3547
3547
  if (e.length === 0) return {
3548
3548
  p50: 0,
3549
3549
  p95: 0,
@@ -3555,18 +3555,18 @@ import {
3555
3555
  let t = e.slice().sort((e, t) => e - t), n = 0;
3556
3556
  for (let e of t) n += e;
3557
3557
  return {
3558
- p50: Bi(t, .5),
3559
- p95: Bi(t, .95),
3560
- p99: Bi(t, .99),
3558
+ p50: Vi(t, .5),
3559
+ p95: Vi(t, .95),
3560
+ p99: Vi(t, .99),
3561
3561
  mean: n / t.length,
3562
3562
  min: t[0],
3563
3563
  max: t[t.length - 1]
3564
3564
  };
3565
- }, Hi = (e = {}) => {
3566
- let t = e.maxSamples ?? Ri, n = e.defaultWindowMs ?? zi, r = [];
3565
+ }, Ui = (e = {}) => {
3566
+ let t = e.maxSamples ?? zi, n = e.defaultWindowMs ?? Bi, r = [];
3567
3567
  return {
3568
3568
  record(e) {
3569
- ie(e), r.push({
3569
+ re(e), r.push({
3570
3570
  ...e,
3571
3571
  ts: Date.now()
3572
3572
  }), r.length > t && r.shift();
@@ -3592,7 +3592,7 @@ import {
3592
3592
  tag: e.tag,
3593
3593
  count: e.samples.length,
3594
3594
  errorCount: n,
3595
- latencyMs: Vi(t)
3595
+ latencyMs: Hi(t)
3596
3596
  });
3597
3597
  }
3598
3598
  return c.sort((e, t) => t.count - e.count), {
@@ -3605,4 +3605,4 @@ import {
3605
3605
  };
3606
3606
  };
3607
3607
  //#endregion
3608
- export { _t as $, tr as A, Tn as B, yr as C, fr as D, vr as E, Xn as F, Jt as G, yn as H, Qn as I, Gt as J, qt as K, In as L, qn as M, $n as N, pr as O, Jn as P, Dt as Q, Ln as R, Ir as S, Or as T, fn as U, xn as V, sn as W, zt as X, Wt as Y, kt as Z, Ar as _, We as _t, hi as a, st as at, Pr as b, Ei as c, ot as ct, ci as d, et as dt, ht as et, $ as f, Xe as ft, Jr as g, Ge as gt, Kr as h, Ue as ht, ji as i, dt as it, rr as j, mr as k, Ii as l, rt as lt, Zr as m, Ke as mt, li as n, lt as nt, mi as o, ct as ot, Mi as p, Je as pt, Yt as q, Ai as r, ut as rt, Fi as s, at as st, Hi as t, mt as tt, Li as u, tt as ut, Mr as v, Me as vt, _r as w, Fr as x, Nr as y, Ne as yt, An as z };
3608
+ export { Dt as $, mr as A, An as B, Ir as C, vr as D, Or as E, Jn as F, sn as G, xn as H, Xn as I, Yt as J, Jt as K, Qn as L, rr as M, qn as N, fr as O, $n as P, kt as Q, In as R, Fr as S, _r as T, yn as U, Tn as V, fn as W, Wt as X, Gt as Y, zt as Z, Yr as _, Ge as _t, gi as a, dt as at, Nr as b, Ne as bt, Di as c, at as ct, li as d, tt as dt, _t as et, $ as f, et as ft, Kr as g, Ue as gt, qr as h, Ke as ht, Mi as i, ut as it, tr as j, pr as k, Li as l, ot as lt, Qr as m, Je as mt, ui as n, mt as nt, hi as o, st as ot, Ni as p, Xe as pt, qt as q, ji as r, lt as rt, Ii as s, ct as st, Ui as t, ht as tt, Ri as u, rt as ut, Ar as v, We as vt, yr as w, Pr as x, Mr as y, Me as yt, Ln as z };