@voltro/cli 0.30.1 → 0.31.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 (124) hide show
  1. package/CHANGELOG.md +163 -0
  2. package/dist/apiBuild-BOqL1dlg.js +2 -0
  3. package/dist/{apiBuild-DmkzRyv7.js → apiBuild-CLPt-pX6.js} +2 -2
  4. package/dist/appGraph-CvQCte0z.js +2 -0
  5. package/dist/appGraph-gQ_6GkQQ.js +110 -0
  6. package/dist/bin.js +3 -3
  7. package/dist/checkCommand-ClRvH_SN.js +2 -0
  8. package/dist/{checkCommand-C4konUy9.js → checkCommand-D7r6_pk7.js} +439 -530
  9. package/dist/{commands-BkJft9K2.js → commands-CNVVv03h.js} +1941 -1880
  10. package/dist/{dbCommand-qn__kLEt.js → dbCommand-BH8GAYuf.js} +76 -19
  11. package/dist/dbCommand-BwQ_Jl98.js +2 -0
  12. package/dist/{dev-DXhhZ7-f.js → dev-DOZVMVfi.js} +1 -1
  13. package/dist/{dev-C_NPcLDp.js → dev-DdQEn2Ia.js} +1986 -1967
  14. package/dist/{frameworkTableAssembly-Cpgn2e88.js → frameworkTableAssembly-BwIrO5nv.js} +122 -103
  15. package/dist/frameworkTableAssembly-D-EebUQX.js +2 -0
  16. package/dist/index.js +1 -1
  17. package/dist/{inspectMetrics-CkB2J0Zn.js → inspectMetrics-BeEAnjqw.js} +774 -527
  18. package/dist/{sdkgen-wsWLrq4l.js → sdkgen-v9WV8zRi.js} +1 -1
  19. package/dist/{serveCommand-HtI4X5kj.js → serveCommand-KsKXXWn4.js} +294 -293
  20. package/dist/serveEntry.js +2 -2
  21. package/dist/{start-egkbpugc.js → start-CI2QdKy9.js} +351 -346
  22. package/dist/startEntry.js +2 -2
  23. package/package.json +17 -17
  24. package/templates/AGENTS.md +43 -43
  25. package/templates/agent-docs/_index.md +43 -43
  26. package/templates/agent-docs/_manifest.json +84 -42
  27. package/templates/agent-docs/cli.md +4 -2
  28. package/templates/agent-docs/database/migrations.md +14 -1
  29. package/templates/agent-docs/internationalization.md +54 -3
  30. package/templates/agent-docs/plugins/ai-flows.md +148 -0
  31. package/templates/agent-docs/plugins/analytics-postgres.md +90 -0
  32. package/templates/agent-docs/plugins/atlassian.md +378 -0
  33. package/templates/agent-docs/plugins/audit.md +324 -0
  34. package/templates/agent-docs/plugins/auth-auth0.md +92 -0
  35. package/templates/agent-docs/plugins/auth-clerk.md +90 -0
  36. package/templates/agent-docs/plugins/auth-kinde.md +88 -0
  37. package/templates/agent-docs/plugins/auth-oidc.md +95 -0
  38. package/templates/agent-docs/plugins/auth-supabase.md +103 -0
  39. package/templates/agent-docs/plugins/auth-workos.md +105 -0
  40. package/templates/agent-docs/plugins/auth.md +227 -0
  41. package/templates/agent-docs/plugins/billing.md +324 -0
  42. package/templates/agent-docs/plugins/broadcast.md +144 -0
  43. package/templates/agent-docs/plugins/cdc-out.md +116 -0
  44. package/templates/agent-docs/plugins/clickhouse.md +91 -0
  45. package/templates/agent-docs/plugins/datadog.md +105 -0
  46. package/templates/agent-docs/plugins/deactivation.md +114 -0
  47. package/templates/agent-docs/plugins/duckdb.md +82 -0
  48. package/templates/agent-docs/plugins/flags.md +146 -0
  49. package/templates/agent-docs/plugins/governance.md +143 -0
  50. package/templates/agent-docs/plugins/licensing.md +74 -0
  51. package/templates/agent-docs/plugins/logship.md +56 -0
  52. package/templates/agent-docs/plugins/mail.md +334 -0
  53. package/templates/agent-docs/plugins/moderation.md +65 -0
  54. package/templates/agent-docs/plugins/multitenancy.md +99 -0
  55. package/templates/agent-docs/plugins/notifications.md +252 -0
  56. package/templates/agent-docs/plugins/openapi.md +94 -0
  57. package/templates/agent-docs/plugins/postgis.md +140 -0
  58. package/templates/agent-docs/plugins/posthog.md +91 -0
  59. package/templates/agent-docs/plugins/presence.md +115 -0
  60. package/templates/agent-docs/plugins/prometheus.md +124 -0
  61. package/templates/agent-docs/plugins/ratelimit.md +274 -0
  62. package/templates/agent-docs/plugins/rbac.md +270 -0
  63. package/templates/agent-docs/plugins/scim.md +63 -0
  64. package/templates/agent-docs/plugins/search.md +116 -0
  65. package/templates/agent-docs/plugins/sentry.md +192 -0
  66. package/templates/agent-docs/plugins/soft-delete.md +72 -0
  67. package/templates/agent-docs/plugins/sso-saml.md +132 -0
  68. package/templates/agent-docs/plugins/storage.md +709 -0
  69. package/templates/agent-docs/plugins/tinybird.md +92 -0
  70. package/templates/agent-docs/plugins/versioning.md +226 -0
  71. package/templates/agent-docs/plugins/webhooks.md +585 -0
  72. package/templates/agent-docs/security.md +12 -1
  73. package/templates/agent-docs/whats-new.md +81 -37
  74. package/templates/apps/api-ai/package.json +7 -7
  75. package/templates/apps/api-auth/package.json +8 -8
  76. package/templates/apps/api-backend/package.json +7 -7
  77. package/templates/apps/api-backend-deactivation/package.json +7 -7
  78. package/templates/apps/api-backend-mail/package.json +8 -8
  79. package/templates/apps/api-backend-mariadb/package.json +9 -9
  80. package/templates/apps/api-backend-sqlite/package.json +8 -8
  81. package/templates/apps/api-backend-storage/package.json +8 -8
  82. package/templates/apps/api-cms/package.json +10 -10
  83. package/templates/apps/api-collab/package.json +8 -8
  84. package/templates/apps/api-data-advanced/package.json +8 -8
  85. package/templates/apps/api-durable/package.json +8 -8
  86. package/templates/apps/api-feature-flags/package.json +9 -9
  87. package/templates/apps/api-governance/package.json +8 -8
  88. package/templates/apps/api-kv/package.json +8 -8
  89. package/templates/apps/api-moderation/package.json +8 -8
  90. package/templates/apps/api-observability/package.json +8 -8
  91. package/templates/apps/api-ratelimit/package.json +8 -8
  92. package/templates/apps/api-rbac/package.json +8 -8
  93. package/templates/apps/api-rest/package.json +7 -7
  94. package/templates/apps/api-saas/package.json +11 -11
  95. package/templates/apps/api-saas-starter/package.json +10 -10
  96. package/templates/apps/api-search/package.json +8 -8
  97. package/templates/apps/api-status/package.json +8 -8
  98. package/templates/apps/api-versioning/package.json +8 -8
  99. package/templates/apps/api-webhooks/package.json +9 -9
  100. package/templates/apps/changelog/package.json +6 -6
  101. package/templates/apps/edge-functions/package.json +2 -2
  102. package/templates/apps/frontend-admin/package.json +8 -8
  103. package/templates/apps/frontend-app/package.json +8 -8
  104. package/templates/apps/frontend-auth/package.json +8 -8
  105. package/templates/apps/frontend-blank/package.json +7 -7
  106. package/templates/apps/frontend-cms/package.json +9 -9
  107. package/templates/apps/frontend-collab/package.json +9 -9
  108. package/templates/apps/frontend-contact/package.json +7 -7
  109. package/templates/apps/frontend-dashboard/package.json +7 -7
  110. package/templates/apps/frontend-docs/package.json +7 -7
  111. package/templates/apps/frontend-i18n/package.json +6 -6
  112. package/templates/apps/frontend-landing/package.json +7 -7
  113. package/templates/apps/frontend-portal/package.json +8 -8
  114. package/templates/apps/frontend-saas/package.json +8 -8
  115. package/templates/apps/frontend-spa/package.json +7 -7
  116. package/templates/apps/frontend-ssr/package.json +7 -7
  117. package/templates/apps/frontend-ssr-api/package.json +8 -8
  118. package/templates/apps/frontend-static-blog/package.json +6 -6
  119. package/templates/apps/frontend-status/package.json +8 -8
  120. package/templates/apps/mobile-app/package.json +2 -2
  121. package/dist/apiBuild-Ca6Sq5jy.js +0 -2
  122. package/dist/checkCommand-DHD0aBeR.js +0 -2
  123. package/dist/dbCommand-wfGi3FgG.js +0 -2
  124. package/dist/frameworkTableAssembly-Bn_c4Mnl.js +0 -2
@@ -7,19 +7,19 @@ 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 k, readdirSync as A, statSync as j, unlinkSync as M, unwatchFile as ee, watchFile as te, writeSync as N } from "node:fs";
11
+ import { currentTraceContext as P, recordSample as ne, resolveSecret as F } from "@voltro/runtime";
12
+ import { homedir as I } from "node:os";
13
+ import { createRequire as L } from "node:module";
14
+ import { FRAMEWORK_ENV_CATALOG as re, appEnvEntries as R, checkEnvNaming as z, formatEnvErrors as B, installEnvSnapshot as ie, isEnvContract as V, pluginEnvEntries as ae, renderDotEnvExample as oe, 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 he = d(g(import.meta.url)), U = [h(he, "..", "templates"), h(he, "..", "..", "templates")], ge = (e) => ({
23
23
  _tag: "TemplateNotFoundError",
24
24
  searched: e
25
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) => {
@@ -81,11 +81,11 @@ var H = d(g(import.meta.url)), U = [h(H, "..", "templates"), h(H, "..", "..", "t
81
81
  "|---|---|---|",
82
82
  ...e.modules.map((e) => `| ${e.title} | \`${n}${e.path}\` | ${we(e.description)} |`),
83
83
  ""
84
- ], i = new Map(e.plugins.map((e) => [e.pkg, e])), a = t === null ? e.plugins.map((e) => `| ${e.slug} | \`node_modules/${e.pkg}/README.md\` | ${we(e.description)} |`) : t.map((e) => {
84
+ ], i = new Map(e.plugins.map((e) => [e.pkg, e])), a = (e, t) => e.module === void 0 ? `\`node_modules/${t}/README.md\`` : `\`${n}${e.module}\` (or \`node_modules/${t}/README.md\`)`, o = t === null ? e.plugins.map((e) => `| ${e.slug} | ${a(e, e.pkg)} | ${we(e.description)} |`) : t.map((e) => {
85
85
  let t = i.get(e);
86
- return t ? `| ${t.slug} | \`node_modules/${e}/README.md\` | ${we(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
86
+ return t ? `| ${t.slug} | ${a(t, e)} | ${we(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
87
87
  });
88
- return r.push(`### Plugins${t === null ? "" : " (installed)"}`, "", "| Plugin | Open | Summary |", "|---|---|---|"), r.push(a.length ? a.join("\n") : "| _(none installed)_ | | |", ""), r.join("\n");
88
+ return r.push(`### Plugins${t === null ? "" : " (installed)"}`, "", "| Plugin | Open | Summary |", "|---|---|---|"), r.push(o.length ? o.join("\n") : "| _(none installed)_ | | |", ""), r.join("\n");
89
89
  }, Ee = (e, t, n) => {
90
90
  let r = t.templates?.[e] ?? t.templates?.[e.replace(/^frontend-/, "")];
91
91
  return `\nScaffolded from the \`${e}\` template — see \`${r ? `${n}${r}` : `${n}agent-docs/templates/overview.md`}\`.\n`;
@@ -240,7 +240,7 @@ boundary, naming, anti-patterns) before editing.
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(I(), ".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 () => {
@@ -318,7 +318,7 @@ boundary, naming, anti-patterns) before editing.
318
318
  try {
319
319
  let t = p(e, "tsconfig.json");
320
320
  if (!T(t)) return [];
321
- let n = JSON.parse(qe(ee(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = h(e, n.baseUrl ?? "."), a = [];
321
+ let n = JSON.parse(qe(k(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = h(e, n.baseUrl ?? "."), a = [];
322
322
  for (let [e, t] of Object.entries(r)) {
323
323
  let n = t[0];
324
324
  if (!n) continue;
@@ -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 = V(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: F
386
+ }), r = [...n.errors, ...z(t, e.appType)];
387
+ if (r.length > 0) throw Error(B(r));
388
+ ie(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 = R(e.contract), n = (e.plugins ?? []).flatMap((e) => ae(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : re, 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) => oe(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 = j(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)";
@@ -495,7 +495,7 @@ __installPublicEnv(publicEnvValues)
495
495
  if (T(n)) {
496
496
  mt.push(n);
497
497
  try {
498
- let e = ee(n, "utf8");
498
+ let e = k(n, "utf8");
499
499
  for (let t of e.split(/\r?\n/)) {
500
500
  let e = t.trim();
501
501
  if (e === "" || e.startsWith("#")) continue;
@@ -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,62 +527,264 @@ __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) te(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) ee(t);
538
538
  };
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 = [
539
+ }, vt = "VoltroBootRefusal", yt = (e) => {
540
+ let t = Error(e);
541
+ return t.name = vt, t;
542
+ }, bt = [{
543
+ host: "127.0.0.1",
544
+ family: "IPv4"
545
+ }, {
546
+ host: "::1",
547
+ family: "IPv6"
548
+ }], xt = (e, t, n) => new Promise((r) => {
549
+ let i = !1, a = (e) => {
550
+ if (!i) {
551
+ i = !0;
552
+ try {
553
+ o.destroy();
554
+ } catch {}
555
+ r(e);
556
+ }
557
+ }, o = pe({
558
+ host: e,
559
+ port: t
560
+ });
561
+ o.once("connect", () => a(!0)), o.once("error", () => a(!1)), o.setTimeout(n, () => a(!1));
562
+ }), St = async (e, t = 400) => ({ families: (await Promise.all(bt.map(async (n) => ({
563
+ family: n.family,
564
+ taken: await xt(n.host, e, t)
565
+ })))).filter((e) => e.taken).map((e) => e.family) }), Ct = (e, t, n) => [
566
+ `${t}: port ${e} is already being served (${n.join(" + ")}).`,
567
+ "",
568
+ " Refusing to start. This is NOT a spurious check — a second listener can",
569
+ " bind the SAME port on the other IP stack, so the boot would report",
570
+ ` "listening on http://localhost:${e}" and "ready", while every request`,
571
+ " went to the process that is already there. Your edits would have no",
572
+ " effect and nothing would say so.",
573
+ "",
574
+ " Find it and stop it:",
575
+ "",
576
+ ` lsof -nP -iTCP:${e} -sTCP:LISTEN`,
577
+ "",
578
+ " Then re-run. To use a different port instead, change `port` in",
579
+ " app.config.ts."
580
+ ].join("\n"), wt = async (e, t) => {
581
+ let { families: n } = await St(e);
582
+ if (n.length !== 0) throw yt(Ct(e, t, n));
583
+ }, Tt = (e) => e === "effect" || e.startsWith("@effect/") || e.startsWith("@voltro/") || e === "react" || e === "react-dom", Et = /(^|\/)(\.bin|\.cache|\.pnpm-store|dist|build)(\/|$)/, Dt = (e) => {
584
+ let t = [], n = [], r = e;
585
+ for (let e = 0; e < 12; e++) {
586
+ let e = p(r, "node_modules");
587
+ if (T(e)) {
588
+ t.push(e);
589
+ let r = p(e, ".pnpm");
590
+ T(r) && n.push(r);
591
+ }
592
+ let i = d(r);
593
+ if (i === r) break;
594
+ r = i;
595
+ }
596
+ return Ot.push(...n), t;
597
+ }, Ot = [], kt = () => {
598
+ let e = [];
599
+ for (let t of Ot) {
600
+ let n;
601
+ try {
602
+ n = A(t);
603
+ } catch {
604
+ continue;
605
+ }
606
+ for (let r of n) {
607
+ let n = r.lastIndexOf("@");
608
+ if (n <= 0) continue;
609
+ let i = r.slice(0, n).replace("+", "/"), a = (r.slice(n + 1).split("_")[0] ?? "").trim();
610
+ a === "" || !/^\d/.test(a) || e.push({
611
+ pkg: i,
612
+ version: a,
613
+ dir: p(t, r)
614
+ });
615
+ }
616
+ }
617
+ return e;
618
+ }, At = (e) => {
619
+ try {
620
+ let t = JSON.parse(k(p(e, "package.json"), "utf8"));
621
+ return typeof t.version == "string" ? t.version : void 0;
622
+ } catch {
623
+ return;
624
+ }
625
+ }, jt = (e) => {
626
+ let t = [], n;
627
+ try {
628
+ n = A(e);
629
+ } catch {
630
+ return t;
631
+ }
632
+ for (let r of n) {
633
+ if (r.startsWith(".") || Et.test(r)) continue;
634
+ let n = p(e, r);
635
+ if (r.startsWith("@")) {
636
+ let e;
637
+ try {
638
+ e = A(n);
639
+ } catch {
640
+ continue;
641
+ }
642
+ for (let i of e) t.push({
643
+ pkg: `${r}/${i}`,
644
+ dir: p(n, i)
645
+ });
646
+ continue;
647
+ }
648
+ try {
649
+ if (!j(n).isDirectory()) continue;
650
+ } catch {
651
+ continue;
652
+ }
653
+ t.push({
654
+ pkg: r,
655
+ dir: n
656
+ });
657
+ }
658
+ return t;
659
+ }, Mt = (e) => {
660
+ let t = /* @__PURE__ */ new Map(), n = (e, n, r) => {
661
+ if (!Tt(e)) return;
662
+ let i = t.get(e) ?? /* @__PURE__ */ new Map();
663
+ i.has(n) || i.set(n, r), t.set(e, i);
664
+ };
665
+ Ot.length = 0;
666
+ for (let t of Dt(e)) for (let { pkg: e, dir: r } of jt(t)) {
667
+ let t = At(r);
668
+ t !== void 0 && n(e, t, r);
669
+ }
670
+ for (let { pkg: e, version: t, dir: r } of kt()) n(e, t, r);
671
+ let r = [];
672
+ for (let [n, i] of t) i.size < 2 || r.push({
673
+ pkg: n,
674
+ versions: [...i.keys()].sort(),
675
+ paths: [...i.values()].map((t) => m(e, t)).sort()
676
+ });
677
+ return r.sort((e, t) => e.pkg.localeCompare(t.pkg));
678
+ }, Nt = (e) => {
679
+ if (e.length !== 0) return [
680
+ `• ${e.length} package(s) resolved at more than one version:`,
681
+ ...e.flatMap((e) => [` ${e.pkg} — ${e.versions.join(", ")}`, ...e.paths.map((e) => ` ${e}`)]),
682
+ "",
683
+ " Two copies of `effect` (or `@effect/*`) is the usual cause of type errors",
684
+ " inside the GENERATED rpcGroup.generated.ts that look like framework bugs:",
685
+ " \"Property '[TypeId]' is missing\", \"typeof Never is not assignable to All\",",
686
+ " or an `Rpc<…, Stream<…>, …>` that will not go where `Any` is expected.",
687
+ " Effect types are nominal, so a Schema built by one copy is not the same",
688
+ " type as a Schema expected by the other — and the RUNTIME often still works,",
689
+ " which is why this shows up as a red tsc against a green server.",
690
+ "",
691
+ " Fix it in the install, not the code: align the version across the workspace",
692
+ " (a root `pnpm.overrides` / `resolutions` entry for `effect` is the blunt",
693
+ " instrument), then reinstall. Do not silence the generated file — it is where",
694
+ " a genuine mistake in your own descriptors surfaces."
695
+ ].join("\n");
696
+ }, Pt = (e) => {
697
+ let t = /* @__PURE__ */ new Map();
698
+ Ot.length = 0;
699
+ for (let n of Dt(e)) for (let { pkg: e, dir: r } of jt(n)) {
700
+ if (!e.startsWith("@voltro/")) continue;
701
+ let n = At(r);
702
+ n !== void 0 && !t.has(e) && t.set(e, n);
703
+ }
704
+ if (t.size < 2) return;
705
+ let n = /* @__PURE__ */ new Map();
706
+ for (let e of t.values()) n.set(e, (n.get(e) ?? 0) + 1);
707
+ if (n.size < 2) return;
708
+ let r = [...n.entries()].sort((e, t) => t[1] - e[1] || e[0].localeCompare(t[0]) * -1)[0][0];
709
+ return {
710
+ majority: r,
711
+ behind: [...t.entries()].filter(([, e]) => e !== r).map(([e, t]) => ({
712
+ pkg: e,
713
+ version: t
714
+ })).sort((e, t) => e.pkg.localeCompare(t.pkg))
715
+ };
716
+ }, Ft = (e) => {
717
+ if (e !== void 0) return [
718
+ `• ${e.behind.length} @voltro/* package(s) are not on ${e.majority}:`,
719
+ ...e.behind.map((e) => ` ${e.pkg} ${e.version}`),
720
+ "",
721
+ " The framework ships in LOCKSTEP — every @voltro/* package carries the",
722
+ " same version at release — so this combination was never built or tested",
723
+ " as a set. It is not a judgement about whether they are compatible.",
724
+ "",
725
+ " Nothing else will tell you. A consumer carried a package two releases",
726
+ " behind through `tsc`, 19 317 tests, `voltro doctor` exit 0 in four apps",
727
+ " and three production builds, all green. None of those checks is ABOUT",
728
+ " version agreement.",
729
+ "",
730
+ " Bump the listed packages and reinstall. If you bump with a script, check",
731
+ " its pattern: the one that produced this report was `@voltro/[a-z-]+`,",
732
+ " which silently skips `@voltro/i18n` because the name contains digits."
733
+ ].join("\n");
734
+ }, It = (e, t) => {
735
+ let n = Pt(e);
736
+ n !== void 0 && t.warn?.(`@voltro/* version skew: ${n.behind.length} package(s) are not on ${n.majority}`, {
737
+ majority: n.majority,
738
+ behind: n.behind.map((e) => `${e.pkg}@${e.version}`),
739
+ fix: "the framework ships in lockstep; bump the listed packages and reinstall"
740
+ });
741
+ }, Lt = S({ scope: "vite" }), Rt = /\x1b\[[0-9;]*m/g, zt = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, Bt = (e) => e.replace(Rt, "").replace(zt, "").trim(), Vt = /proxy error/i, Ht = [
540
742
  "ECONNREFUSED",
541
743
  "ECONNRESET",
542
744
  "ECONNABORTED",
543
745
  "EPIPE",
544
746
  "ETIMEDOUT"
545
- ], wt = (e, t = 0) => {
747
+ ], Ut = (e, t = 0) => {
546
748
  if (e == null || t > 5) return !1;
547
749
  let n = e;
548
- return typeof n.code == "string" && Ct.includes(n.code) || typeof n.message == "string" && Ct.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => wt(e, t + 1)) ? !0 : wt(n.cause, t + 1);
549
- }, Tt = 4e3, Et = () => {
750
+ return typeof n.code == "string" && Ht.includes(n.code) || typeof n.message == "string" && Ht.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => Ut(e, t + 1)) ? !0 : Ut(n.cause, t + 1);
751
+ }, Wt = 4e3, Gt = () => {
550
752
  let e = /* @__PURE__ */ new Set(), t = 0, n = {
551
753
  hasWarned: !1,
552
754
  info: (e) => {
553
- let t = xt(e);
554
- t.length !== 0 && vt.info(t);
755
+ let t = Bt(e);
756
+ t.length !== 0 && Lt.info(t);
555
757
  },
556
758
  warn: (e) => {
557
759
  n.hasWarned = !0;
558
- let t = xt(e);
559
- t.length !== 0 && vt.warn(t);
760
+ let t = Bt(e);
761
+ t.length !== 0 && Lt.warn(t);
560
762
  },
561
763
  warnOnce: (t) => {
562
- let r = xt(t);
563
- e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && vt.warn(r));
764
+ let r = Bt(t);
765
+ e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && Lt.warn(r));
564
766
  },
565
767
  error: (e, n) => {
566
- let r = xt(e), i = n?.error;
768
+ let r = Bt(e), i = n?.error;
567
769
  if (r.length !== 0) {
568
- if (St.test(r) && wt(i)) {
770
+ if (Vt.test(r) && Ut(i)) {
569
771
  let e = Date.now();
570
- e - t > Tt && (t = e, vt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
772
+ e - t > Wt && (t = e, Lt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
571
773
  return;
572
774
  }
573
- vt.error(r, {}, i);
775
+ Lt.error(r, {}, i);
574
776
  }
575
777
  },
576
778
  clearScreen: () => {},
577
779
  hasErrorLogged: (e) => !1
578
780
  };
579
781
  return n;
580
- }, Dt = (e = process.env) => {
782
+ }, Kt = (e = process.env) => {
581
783
  let t = e.VOLTRO_DEV_SSR_COMPILE_CONCURRENCY;
582
784
  if (t === void 0 || t.trim() === "") return 4;
583
785
  let n = Number(t);
584
786
  return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
585
- }, Ot = (e) => {
787
+ }, qt = (e) => {
586
788
  let t = Math.max(1, Math.floor(e)), n = 0, r = [], i = () => n < t ? (n++, Promise.resolve()) : new Promise((e) => r.push(e)), a = () => {
587
789
  let e = r.shift();
588
790
  e ? e() : n--;
@@ -600,8 +802,8 @@ __installPublicEnv(publicEnvValues)
600
802
  return n;
601
803
  }
602
804
  };
603
- }, kt = (e) => {
604
- let t = Ot(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
805
+ }, Jt = (e) => {
806
+ let t = qt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
605
807
  return {
606
808
  load: (i, a) => {
607
809
  if (r.has(i)) return a();
@@ -631,7 +833,7 @@ __installPublicEnv(publicEnvValues)
631
833
  return r.size;
632
834
  }
633
835
  };
634
- }, At = (e) => {
836
+ }, Yt = (e) => {
635
837
  let t = [];
636
838
  for (let n of e.split("/").filter(Boolean)) n.startsWith("[[...") && n.endsWith("]]") ? t.push({
637
839
  name: n.slice(5, -2),
@@ -647,7 +849,7 @@ __installPublicEnv(publicEnvValues)
647
849
  optional: !1
648
850
  });
649
851
  return t;
650
- }, jt = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), Mt = async (e) => {
852
+ }, Xt = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), Zt = async (e) => {
651
853
  let t = h(e);
652
854
  for (let e = 0; e < 4; e++) {
653
855
  let e = p(t, "project.json");
@@ -665,8 +867,8 @@ __installPublicEnv(publicEnvValues)
665
867
  t = n;
666
868
  }
667
869
  return null;
668
- }, Nt = async (e) => {
669
- let t = await Mt(e);
870
+ }, Qt = async (e) => {
871
+ let t = await Zt(e);
670
872
  if (!t) return [];
671
873
  let { projectDir: n, manifest: r } = t, i = u(e), a = r.apps ?? {}, o = [];
672
874
  for (let [e, t] of Object.entries(a)) {
@@ -678,20 +880,20 @@ __installPublicEnv(publicEnvValues)
678
880
  let { pages: e } = await $(r);
679
881
  a = e.map((e) => ({
680
882
  pattern: e.pattern,
681
- params: At(e.pattern)
883
+ params: Yt(e.pattern)
682
884
  }));
683
885
  } catch {
684
886
  continue;
685
887
  }
686
888
  o.push({
687
- key: jt(e),
889
+ key: Xt(e),
688
890
  origin: `http://localhost:${t.port}`,
689
891
  ...typeof t.origin == "string" && t.origin.length > 0 ? { prodOrigin: t.origin } : {},
690
892
  routes: a
691
893
  });
692
894
  }
693
895
  return o;
694
- }, Pt = (e) => {
896
+ }, $t = (e) => {
695
897
  if (e.params.length === 0) return `'${e.pattern}'`;
696
898
  let t = e.pattern;
697
899
  for (let n of e.params) {
@@ -699,21 +901,21 @@ __installPublicEnv(publicEnvValues)
699
901
  t = t.replace(e, r);
700
902
  }
701
903
  return "`" + t + "`";
702
- }, Ft = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
904
+ }, en = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
703
905
  let t = "string";
704
906
  return e.optional ? `readonly ${e.name}?: ${t}` : `readonly ${e.name}: ${t}`;
705
- }).join("; ")} }`, It = (e, t, n) => {
706
- let r = Ft(e), i = Pt(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
907
+ }).join("; ")} }`, tn = (e, t, n) => {
908
+ let r = en(e), i = $t(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
707
909
  return e.params.length === 0 ? `() => (${o}${i}) as ${a}` : `({ ${e.params.map((e) => e.name).join(", ")} }: ${r}) => (${o}${i}) as ${a}`;
708
- }, Lt = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${It(e, !1)},`).join("\n")}\n}`, Rt = (e, t) => {
910
+ }, nn = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${tn(e, !1)},`).join("\n")}\n}`, rn = (e, t) => {
709
911
  if (e.routes.length === 0) return ` ${e.key}: {} as Record<string, never>,`;
710
- let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${It(e, !0, i)},`);
912
+ let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${tn(e, !0, i)},`);
711
913
  return ` ${e.key}: {\n${a.join("\n")}\n },`;
712
- }, zt = async (e) => {
914
+ }, an = async (e) => {
713
915
  let t = e.pages.map((e) => ({
714
916
  pattern: e.pattern,
715
- params: At(e.pattern)
716
- })), n = await Nt(e.appRoot), r = [
917
+ params: Yt(e.pattern)
918
+ })), n = await Qt(e.appRoot), r = [
717
919
  "// THIS FILE IS GENERATED — DO NOT EDIT BY HAND.",
718
920
  "// Re-emitted by `voltro dev` whenever `src/pages/**` changes.",
719
921
  "// Type-safe route builders consumed by <Link to={...}>.",
@@ -722,7 +924,7 @@ __installPublicEnv(publicEnvValues)
722
924
  "",
723
925
  "type EmptyParams = Record<string, never>",
724
926
  ""
725
- ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${Lt(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => Rt(e, i)).join("\n")}\n} as const\n`}`, o = p(e.appRoot, ".framework", "routes.generated.ts");
927
+ ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${nn(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => rn(e, i)).join("\n")}\n} as const\n`}`, o = p(e.appRoot, ".framework", "routes.generated.ts");
726
928
  await O.mkdir(d(o), { recursive: !0 });
727
929
  let s = null;
728
930
  try {
@@ -735,37 +937,37 @@ __installPublicEnv(publicEnvValues)
735
937
  path: o,
736
938
  wrote: !0
737
939
  });
738
- }, Bt = (e) => {
940
+ }, on = (e) => {
739
941
  if (e === "" || e === "/") return "/";
740
942
  let t = e.startsWith("/") ? e : `/${e}`;
741
943
  return t.endsWith("/") ? t.slice(0, -1) : t;
742
- }, Vt = (e, t) => {
743
- let n = e.endsWith("/") ? e.slice(0, -1) : e, r = Bt(t);
944
+ }, sn = (e, t) => {
945
+ let n = e.endsWith("/") ? e.slice(0, -1) : e, r = on(t);
744
946
  return r === "/" ? `${n}/` : `${n}${r}`;
745
- }, Ht = (e, t, n) => {
746
- let r = Bt(e);
947
+ }, cn = (e, t, n) => {
948
+ let r = on(e);
747
949
  return t === n ? r : r === "/" ? `/${t}` : `/${t}${r}`;
748
- }, Ut = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), Wt = (e) => {
950
+ }, ln = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), un = (e) => {
749
951
  let { siteUrl: t, entries: n } = e, r = e.locales && e.locales.length > 1 ? e.locales : void 0, i = e.defaultLocale ?? r?.[0] ?? "en", a = r !== void 0, o = /* @__PURE__ */ new Map(), s = (e) => {
750
952
  if (!r) return "";
751
- let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${Ut(n)}" href="${Ut(Vt(t, Ht(e, n, i)))}" />`);
752
- return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${Ut(Vt(t, Ht(e, i, i)))}" />`), `\n${n.join("\n")}`;
953
+ let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${ln(n)}" href="${ln(sn(t, cn(e, n, i)))}" />`);
954
+ return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${ln(sn(t, cn(e, i, i)))}" />`), `\n${n.join("\n")}`;
753
955
  };
754
956
  for (let e of n) {
755
957
  let n = r ?? [i];
756
958
  for (let r of n) {
757
- let n = Vt(t, Ht(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${Ut(e.lastmod)}</lastmod>` : "";
758
- o.set(n, ` <url>\n <loc>${Ut(n)}</loc>${a}${s(e.path)}\n </url>`);
959
+ let n = sn(t, cn(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${ln(e.lastmod)}</lastmod>` : "";
960
+ o.set(n, ` <url>\n <loc>${ln(n)}</loc>${a}${s(e.path)}\n </url>`);
759
961
  }
760
962
  }
761
963
  let c = [...o.keys()].sort().map((e) => o.get(e)).join("\n");
762
964
  return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset${a ? " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" : " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\""}>\n${c}\n</urlset>\n`;
763
- }, Gt = (e) => {
965
+ }, dn = (e) => {
764
966
  if (!e.indexable) return "User-agent: *\nDisallow: /\n";
765
967
  let t = ["User-agent: *", "Allow: /"];
766
- for (let n of e.disallow ?? []) t.push(`Disallow: ${Bt(n)}`);
968
+ for (let n of e.disallow ?? []) t.push(`Disallow: ${on(n)}`);
767
969
  return e.sitemapUrl && t.push("", `Sitemap: ${e.sitemapUrl}`), `${t.join("\n")}\n`;
768
- }, Kt = 256, qt = (e = Kt) => {
970
+ }, fn = 256, pn = (e = fn) => {
769
971
  let t = [], n = /* @__PURE__ */ new Set();
770
972
  return {
771
973
  emit(r, i) {
@@ -788,17 +990,17 @@ __installPublicEnv(publicEnvValues)
788
990
  return t.slice();
789
991
  }
790
992
  };
791
- }, Jt = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, Yt = () => `: keep-alive ${Date.now()}\n\n`, Xt = 8e3, Zt = (e, t = Xt) => {
792
- let n = $t(e);
993
+ }, mn = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, hn = () => `: keep-alive ${Date.now()}\n\n`, gn = 8e3, _n = (e, t = gn) => {
994
+ let n = yn(e);
793
995
  return n.length <= t ? n : `${n.slice(0, t)}\n… [voltro] truncated at ${t} chars (${n.length} total)`;
794
- }, Qt = 4, $t = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
996
+ }, vn = 4, yn = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
795
997
  if (e instanceof Error) {
796
998
  let r = e.stack ?? `${e.name}: ${e.message}`;
797
999
  if (n.has(e)) return `${r}\n [cycle]`;
798
1000
  n.add(e);
799
1001
  let i = [];
800
- if (t < Qt) if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${en($t(a, t + 1, n))}`);
801
- else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${en($t(e.cause, t + 1, n))}`);
1002
+ if (t < vn) if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${bn(yn(a, t + 1, n))}`);
1003
+ else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${bn(yn(e.cause, t + 1, n))}`);
802
1004
  return r + i.join("");
803
1005
  }
804
1006
  try {
@@ -806,30 +1008,30 @@ __installPublicEnv(publicEnvValues)
806
1008
  } catch {
807
1009
  return "[unstringifiable thrown value]";
808
1010
  }
809
- }, en = (e) => {
1011
+ }, bn = (e) => {
810
1012
  let t = e.split("\n");
811
1013
  return t.length <= 3 ? e : `${t.slice(0, 3).join("\n")}\n …`;
812
- }, tn = {
1014
+ }, xn = {
813
1015
  trace: 0,
814
1016
  debug: 1,
815
1017
  info: 2,
816
1018
  warn: 3,
817
1019
  error: 4,
818
1020
  fatal: 5
819
- }, nn = 2e3, rn = 200, an = class {
1021
+ }, Sn = 2e3, Cn = 200, wn = class {
820
1022
  capacity;
821
1023
  buffer = [];
822
- constructor(e = nn) {
1024
+ constructor(e = Sn) {
823
1025
  this.capacity = e;
824
1026
  }
825
1027
  append(e) {
826
1028
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
827
1029
  }
828
1030
  query(e = {}) {
829
- let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? rn, this.capacity), i = e.minLevel === void 0 ? tn.trace : tn[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
1031
+ let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? Cn, this.capacity), i = e.minLevel === void 0 ? xn.trace : xn[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
830
1032
  for (let e = this.buffer.length - 1; e >= 0 && l.length < r; e--) {
831
1033
  let r = this.buffer[e];
832
- r.ts < t || r.ts > n || tn[r.level] < i || o !== void 0 && r.source !== o || a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || c !== void 0 && r.fields.traceId !== c || l.push(r);
1034
+ r.ts < t || r.ts > n || xn[r.level] < i || o !== void 0 && r.source !== o || a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || c !== void 0 && r.fields.traceId !== c || l.push(r);
833
1035
  }
834
1036
  return l.reverse();
835
1037
  }
@@ -842,7 +1044,7 @@ __installPublicEnv(publicEnvValues)
842
1044
  clear() {
843
1045
  this.buffer = [];
844
1046
  }
845
- }, on = null, sn = () => (on === null && (on = new an()), on), cn = (e) => {
1047
+ }, Tn = null, En = () => (Tn === null && (Tn = new wn()), Tn), Dn = (e) => {
846
1048
  if (typeof e == "string") return e;
847
1049
  if (e instanceof Error) return e.message;
848
1050
  try {
@@ -850,28 +1052,28 @@ __installPublicEnv(publicEnvValues)
850
1052
  } catch {
851
1053
  return String(e);
852
1054
  }
853
- }, ln = 8e3, un = (e) => typeof e == "string" ? e.length <= ln ? e : `${e.slice(0, ln)}… [voltro: truncated]` : typeof e != "object" || !e ? e : Zt(e, ln), dn = (e, t) => {
1055
+ }, On = 8e3, kn = (e) => typeof e == "string" ? e.length <= On ? e : `${e.slice(0, On)}… [voltro: truncated]` : typeof e != "object" || !e ? e : _n(e, On), An = (e, t) => {
854
1056
  try {
855
1057
  e(...t);
856
1058
  } catch (n) {
857
1059
  try {
858
- e(...t.map(un)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${ln} chars per argument.`);
1060
+ e(...t.map(kn)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${On} chars per argument.`);
859
1061
  } catch {
860
1062
  e(`[voltro] a console.error argument could not be formatted at all (${t.length} arg(s)).`);
861
1063
  }
862
1064
  }
863
- }, fn = (e) => {
1065
+ }, jn = (e) => {
864
1066
  let t = {
865
1067
  log: console.log.bind(console),
866
1068
  info: console.info.bind(console),
867
1069
  warn: console.warn.bind(console),
868
1070
  error: console.error.bind(console),
869
1071
  debug: console.debug.bind(console)
870
- }, n = sn(), r = !1, i = (i) => (...a) => {
871
- if (dn(t[i], a), !r) {
1072
+ }, n = En(), r = !1, i = (i) => (...a) => {
1073
+ if (An(t[i], a), !r) {
872
1074
  r = !0;
873
1075
  try {
874
- let t = a.length > 0 ? cn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = M();
1076
+ let t = a.length > 0 ? Dn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = P();
875
1077
  e.emit("log", {
876
1078
  level: i,
877
1079
  message: r,
@@ -909,7 +1111,7 @@ __installPublicEnv(publicEnvValues)
909
1111
  argsCount: 1,
910
1112
  ...t.scope === void 0 ? {} : { scope: t.scope }
911
1113
  });
912
- let a = M(), o = a !== void 0 && t.fields.traceId === void 0 ? {
1114
+ let a = P(), o = a !== void 0 && t.fields.traceId === void 0 ? {
913
1115
  ...t.fields,
914
1116
  traceId: a.traceId
915
1117
  } : t.fields;
@@ -929,24 +1131,24 @@ __installPublicEnv(publicEnvValues)
929
1131
  return () => {
930
1132
  console.log = t.log, console.info = t.info, console.warn = t.warn, console.error = t.error, console.debug = t.debug, a();
931
1133
  };
932
- }, pn = 2e3, mn = 8, hn = 1e3, gn = 200, Y = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, _n = (e) => {
1134
+ }, Mn = 2e3, Nn = 8, Pn = 1e3, Fn = 200, Y = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, In = (e) => {
933
1135
  switch (e) {
934
1136
  case "error": return "error";
935
1137
  case "warn": return "warn";
936
1138
  case "debug": return "debug";
937
1139
  default: return "info";
938
1140
  }
939
- }, vn = S({ scope: "client" }), yn = (e, t) => {
1141
+ }, Ln = S({ scope: "client" }), Rn = (e, t) => {
940
1142
  let n;
941
1143
  try {
942
1144
  n = JSON.parse(e);
943
1145
  } catch {
944
- return bn(400, { error: "invalid JSON body" });
1146
+ return zn(400, { error: "invalid JSON body" });
945
1147
  }
946
- if (typeof n != "object" || !n) return bn(400, { error: "body must be a JSON object" });
1148
+ if (typeof n != "object" || !n) return zn(400, { error: "body must be a JSON object" });
947
1149
  let r = n;
948
- if (!Array.isArray(r.entries)) return bn(400, { error: "entries must be an array" });
949
- let i = typeof r.app == "string" ? Y(r.app, 120) : void 0, a = typeof r.page == "string" ? Y(r.page, 200) : void 0, o = typeof r.ua == "string" ? Y(r.ua, 200) : void 0, s = r.entries.slice(0, gn), c = 0;
1150
+ if (!Array.isArray(r.entries)) return zn(400, { error: "entries must be an array" });
1151
+ let i = typeof r.app == "string" ? Y(r.app, 120) : void 0, a = typeof r.page == "string" ? Y(r.page, 200) : void 0, o = typeof r.ua == "string" ? Y(r.ua, 200) : void 0, s = r.entries.slice(0, Fn), c = 0;
950
1152
  for (let e of s) {
951
1153
  if (typeof e != "object" || !e) continue;
952
1154
  let n = e;
@@ -957,7 +1159,7 @@ __installPublicEnv(publicEnvValues)
957
1159
  "warn",
958
1160
  "error",
959
1161
  "debug"
960
- ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Y(n.message, pn), u = Array.isArray(n.args) ? n.args.slice(0, mn).filter((e) => typeof e == "string").map((e) => Y(e, hn)) : void 0, d = typeof n.stack == "string" ? Y(n.stack, pn) : void 0;
1162
+ ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Y(n.message, Mn), u = Array.isArray(n.args) ? n.args.slice(0, Nn).filter((e) => typeof e == "string").map((e) => Y(e, Pn)) : void 0, d = typeof n.stack == "string" ? Y(n.stack, Mn) : void 0;
961
1163
  t.emit("clientLog", {
962
1164
  ts: s,
963
1165
  level: r,
@@ -972,35 +1174,35 @@ __installPublicEnv(publicEnvValues)
972
1174
  ...i === void 0 ? {} : { app: i },
973
1175
  ...a === void 0 ? {} : { page: a },
974
1176
  ...u !== void 0 && u.length > 0 ? { args: u } : {}
975
- }, p = _n(r);
976
- (p === "error" || p === "warn") && d !== void 0 ? vn[p](l, f, { stack: d }) : vn[p](l, {
1177
+ }, p = In(r);
1178
+ (p === "error" || p === "warn") && d !== void 0 ? Ln[p](l, f, { stack: d }) : Ln[p](l, {
977
1179
  ...f,
978
1180
  ...d === void 0 ? {} : { stack: d }
979
1181
  }), c++;
980
1182
  }
981
- return bn(202, {
1183
+ return zn(202, {
982
1184
  accepted: c,
983
1185
  dropped: r.entries.length - c
984
1186
  });
985
- }, bn = (e, t) => ({
1187
+ }, zn = (e, t) => ({
986
1188
  status: e,
987
1189
  contentType: "application/json; charset=utf-8",
988
1190
  body: JSON.stringify(t)
989
- }), xn = "/_voltro/inspect/clientLog", Sn = [
1191
+ }), Bn = "/_voltro/inspect/clientLog", Vn = [
990
1192
  "trace",
991
1193
  "debug",
992
1194
  "info",
993
1195
  "warn",
994
1196
  "error",
995
1197
  "fatal"
996
- ], Cn = {
1198
+ ], Hn = {
997
1199
  trace: "TRACE",
998
1200
  debug: "DEBUG",
999
1201
  info: "INFO ",
1000
1202
  warn: "WARN ",
1001
1203
  error: "ERROR",
1002
1204
  fatal: "FATAL"
1003
- }, wn = (e) => Sn.includes(e), Tn = (e, t, n = {}) => {
1205
+ }, Un = (e) => Vn.includes(e), Wn = (e, t, n = {}) => {
1004
1206
  if (c()) return {
1005
1207
  status: 503,
1006
1208
  contentType: "application/json",
@@ -1031,7 +1233,7 @@ __installPublicEnv(publicEnvValues)
1031
1233
  Number.isFinite(e) && e > 0 && (o.max = Math.floor(e));
1032
1234
  }
1033
1235
  let f = a.get("level");
1034
- f !== null && wn(f) && (o.minLevel = f);
1236
+ f !== null && Un(f) && (o.minLevel = f);
1035
1237
  let p = a.get("source");
1036
1238
  (p === "server" || p === "client") && (o.source = p);
1037
1239
  let m = a.get("scope");
@@ -1044,7 +1246,7 @@ __installPublicEnv(publicEnvValues)
1044
1246
  if ((a.get("format") ?? "json") === "text") return {
1045
1247
  status: 200,
1046
1248
  contentType: "text/plain; charset=utf-8",
1047
- body: _.map(En).join("\n") + (_.length > 0 ? "\n" : "")
1249
+ body: _.map(Gn).join("\n") + (_.length > 0 ? "\n" : "")
1048
1250
  };
1049
1251
  let v = {
1050
1252
  capturedAt: Date.now(),
@@ -1058,40 +1260,40 @@ __installPublicEnv(publicEnvValues)
1058
1260
  contentType: "application/json; charset=utf-8",
1059
1261
  body: JSON.stringify(v)
1060
1262
  };
1061
- }, En = (e) => {
1062
- let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = On(e.fields);
1063
- return `${n}:${r}:${i}.${a} ${Cn[e.level]} ${o} ${e.message}${s}`;
1064
- }, Dn = 80, On = (e) => {
1263
+ }, Gn = (e) => {
1264
+ let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = qn(e.fields);
1265
+ return `${n}:${r}:${i}.${a} ${Hn[e.level]} ${o} ${e.message}${s}`;
1266
+ }, Kn = 80, qn = (e) => {
1065
1267
  let t = Object.entries(e);
1066
1268
  if (t.length === 0) return "";
1067
1269
  let n = [];
1068
1270
  for (let [e, r] of t) {
1069
1271
  if (r === void 0) continue;
1070
- let t = kn(r);
1272
+ let t = Jn(r);
1071
1273
  n.push(`${e}=${t}`);
1072
1274
  }
1073
1275
  return n.length > 0 ? " " + n.join(" ") : "";
1074
- }, kn = (e) => {
1276
+ }, Jn = (e) => {
1075
1277
  if (typeof e == "string") {
1076
- let t = e.length > Dn ? e.slice(0, Dn) + "…" : e;
1278
+ let t = e.length > Kn ? e.slice(0, Kn) + "…" : e;
1077
1279
  return /[\s=]/.test(t) ? `"${t.replace(/"/g, "\\\"")}"` : t;
1078
1280
  }
1079
1281
  if (e === null) return "null";
1080
1282
  if (typeof e == "number" || typeof e == "boolean") return String(e);
1081
1283
  try {
1082
1284
  let t = JSON.stringify(e);
1083
- return t.length > Dn ? t.slice(0, Dn) + "…" : t;
1285
+ return t.length > Kn ? t.slice(0, Kn) + "…" : t;
1084
1286
  } catch {
1085
1287
  return "[unserialisable]";
1086
1288
  }
1087
- }, An = "/_voltro/inspect/logs", jn = (e, t, n) => {
1289
+ }, Yn = "/_voltro/inspect/logs", Xn = (e, t, n) => {
1088
1290
  if (t.headers.authorization !== void 0) return !1;
1089
1291
  let { token: r } = n;
1090
1292
  if (r === void 0 || r === "" || !n.isLoopback(n.target)) return !1;
1091
1293
  e.setHeader("authorization", `Bearer ${r}`);
1092
1294
  let i = n.writeToken;
1093
1295
  return i !== void 0 && i !== "" && t.headers["x-voltro-inspect-write"] === void 0 && e.setHeader("x-voltro-inspect-write", i), !0;
1094
- }, Mn = [{
1296
+ }, Zn = [{
1095
1297
  match: (e) => typeof e == "string" && e.startsWith("[BABEL] Note: The code generator has deoptimised"),
1096
1298
  handle: (e, t) => {
1097
1299
  let n = e[0], r = n.match(/deoptimised the styling of (.+?) as it exceeds the max of (\d+\w*B)\.?/);
@@ -1103,13 +1305,13 @@ __installPublicEnv(publicEnvValues)
1103
1305
  });
1104
1306
  } else t.info(n);
1105
1307
  }
1106
- }], Nn = () => {
1308
+ }], Qn = () => {
1107
1309
  let e = {
1108
1310
  warn: console.warn.bind(console),
1109
1311
  error: console.error.bind(console)
1110
1312
  }, t = S({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1111
1313
  if (!n) {
1112
- for (let e of Mn) if (e.match(i[0])) {
1314
+ for (let e of Zn) if (e.match(i[0])) {
1113
1315
  n = !0;
1114
1316
  try {
1115
1317
  e.handle(i, t);
@@ -1124,7 +1326,7 @@ __installPublicEnv(publicEnvValues)
1124
1326
  return console.warn = r("warn"), console.error = r("error"), () => {
1125
1327
  console.warn = e.warn, console.error = e.error;
1126
1328
  };
1127
- }, Pn = {
1329
+ }, $n = {
1128
1330
  loader: "it runs on the server, and the router caches its result per route + params",
1129
1331
  renderMode: "it picks the server render strategy",
1130
1332
  dynamic: "it picks the server render strategy",
@@ -1135,7 +1337,7 @@ __installPublicEnv(publicEnvValues)
1135
1337
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1136
1338
  interactive: "it decides how much client JS the server ships",
1137
1339
  tenantAware: "it is part of the server-side cache key"
1138
- }, Fn = Object.keys(Pn), In = (e) => t.test(e), Ln = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), Rn = "virtual:voltro-route-refresh", zn = `\0${Rn}`, Bn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, Vn = () => `
1340
+ }, er = Object.keys($n), tr = (e) => t.test(e), nr = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), rr = "virtual:voltro-route-refresh", ir = `\0${rr}`, ar = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, or = () => `
1139
1341
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1140
1342
 
1141
1343
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1164,11 +1366,11 @@ const stableForm = (value) => {
1164
1366
  * readers (\`build.ts\` prerender, \`webDev.ts\` dev SSR, \`start.ts\`). A change to
1165
1367
  * one of THESE cannot be hot-applied: the server already ran with the old
1166
1368
  * value. Everything else a page exports is plain client-side data. */
1167
- const serverRelevantExports = ${JSON.stringify(Fn)}
1369
+ const serverRelevantExports = ${JSON.stringify(er)}
1168
1370
 
1169
1371
  /** Name → the server step that already consumed it, so the reload message can
1170
1372
  * say WHY rather than just WHAT. Injected from the same single source. */
1171
- const serverExportEffect = ${JSON.stringify(Pn)}
1373
+ const serverExportEffect = ${JSON.stringify($n)}
1172
1374
 
1173
1375
  /** The reason \`name\` forces a reload, for the console line. */
1174
1376
  export const serverEffectOf = (name) =>
@@ -1211,7 +1413,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1211
1413
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1212
1414
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1213
1415
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1214
- `, Hn = (e) => `
1416
+ `, sr = (e) => `
1215
1417
  if (import.meta.hot) {
1216
1418
  // Self-import to read our OWN exports, the same technique the react plugin
1217
1419
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1238,45 +1440,45 @@ import {
1238
1440
  registerRouteModule as __voltro_registerRouteModule,
1239
1441
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1240
1442
  serverEffectOf as __voltro_serverEffect,
1241
- } from '${Rn}'
1242
- `, Un = (e) => e.replace(/\\/g, "/"), Wn = (e, t) => {
1243
- let [i = "", a] = Un(e).split("?");
1244
- if (!i.endsWith(".tsx") || a !== void 0 && Bn.test(a)) return !1;
1245
- let o = Un(t).replace(/\/$/, "");
1443
+ } from '${rr}'
1444
+ `, cr = (e) => e.replace(/\\/g, "/"), lr = (e, t) => {
1445
+ let [i = "", a] = cr(e).split("?");
1446
+ if (!i.endsWith(".tsx") || a !== void 0 && ar.test(a)) return !1;
1447
+ let o = cr(t).replace(/\/$/, "");
1246
1448
  return i.startsWith(`${o}/`) ? r.test(i) || n.has(i.slice(i.lastIndexOf("/") + 1)) : !1;
1247
- }, Gn = (e, t, n) => Wn(t, n) ? `${e}${Hn(Un(t).split("?")[0] ?? t)}` : null, Kn = (e) => ({
1449
+ }, ur = (e, t, n) => lr(t, n) ? `${e}${sr(cr(t).split("?")[0] ?? t)}` : null, dr = (e) => ({
1248
1450
  name: "voltro:route-fast-refresh",
1249
1451
  enforce: "pre",
1250
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? zn : void 0,
1251
- load: (e) => e === zn ? Vn() : void 0,
1452
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? ir : void 0,
1453
+ load: (e) => e === ir ? or() : void 0,
1252
1454
  transform: (t, n, r) => {
1253
1455
  if (r?.ssr === !0) return null;
1254
- let i = Gn(t, n, e);
1456
+ let i = ur(t, n, e);
1255
1457
  return i === null ? null : {
1256
1458
  code: i,
1257
1459
  map: null
1258
1460
  };
1259
1461
  }
1260
- }), qn = [
1462
+ }), fr = [
1261
1463
  "static",
1262
1464
  "spa",
1263
1465
  "ssr",
1264
1466
  "isr"
1265
- ], Jn = (e) => typeof e == "string" && qn.includes(e), Yn = qn.map((e) => `'${e}'`).join(" | "), Xn = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${Yn}.${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)." : ""}`, Zn = class extends Error {
1467
+ ], pr = (e) => typeof e == "string" && fr.includes(e), mr = fr.map((e) => `'${e}'`).join(" | "), hr = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${mr}.${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)." : ""}`, gr = class extends Error {
1266
1468
  page;
1267
1469
  value;
1268
1470
  name = "InvalidRenderModeError";
1269
1471
  constructor(e, t) {
1270
- super(Xn(e, t)), this.page = e, this.value = t;
1472
+ super(hr(e, t)), this.page = e, this.value = t;
1271
1473
  }
1272
- }, Qn = (e, t = "<page>") => {
1474
+ }, _r = (e, t = "<page>") => {
1273
1475
  if (e.renderMode !== void 0 && e.renderMode !== null) {
1274
- if (!Jn(e.renderMode)) throw new Zn(t, String(e.renderMode));
1476
+ if (!pr(e.renderMode)) throw new gr(t, String(e.renderMode));
1275
1477
  return e.renderMode;
1276
1478
  }
1277
1479
  return e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static");
1278
- }, $n = (e, t = "<page>") => ({
1279
- renderMode: Qn(e, t),
1480
+ }, vr = (e, t = "<page>") => ({
1481
+ renderMode: _r(e, t),
1280
1482
  tenantAware: e.tenantAware === !0,
1281
1483
  revalidateMs: ct(e.revalidate),
1282
1484
  staleWhileRevalidateMs: ct(e.staleWhileRevalidate) ?? 0,
@@ -1285,10 +1487,10 @@ import {
1285
1487
  hasLoader: typeof e.loader == "function",
1286
1488
  hasMeta: e.meta != null,
1287
1489
  hasGetStaticPaths: typeof e.getStaticPaths == "function"
1288
- }), er = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, tr = (e) => er.exec(e)?.[1] ?? null, nr = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, rr = (e) => {
1289
- nr.lastIndex = 0;
1490
+ }), yr = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, br = (e) => yr.exec(e)?.[1] ?? null, xr = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, Sr = (e) => {
1491
+ xr.lastIndex = 0;
1290
1492
  let t;
1291
- for (; (t = nr.exec(e)) !== null;) {
1493
+ for (; (t = xr.exec(e)) !== null;) {
1292
1494
  let e = t[2];
1293
1495
  if (e.startsWith(".")) for (let n of t[1].split(",")) {
1294
1496
  let t = n.lastIndexOf(" as ");
@@ -1296,36 +1498,36 @@ import {
1296
1498
  }
1297
1499
  }
1298
1500
  return null;
1299
- }, ir = /export\s*\{([^}]*)\}/g, ar = (e) => {
1501
+ }, Cr = /export\s*\{([^}]*)\}/g, wr = (e) => {
1300
1502
  if (/export\s+default\b/.test(e)) return !0;
1301
- ir.lastIndex = 0;
1503
+ Cr.lastIndex = 0;
1302
1504
  let t;
1303
- for (; (t = ir.exec(e)) !== null;) for (let e of t[1].split(",")) {
1505
+ for (; (t = Cr.exec(e)) !== null;) for (let e of t[1].split(",")) {
1304
1506
  let t = e.lastIndexOf(" as ");
1305
1507
  if ((t === -1 ? e : e.slice(t + 4)).trim() === "default") return !0;
1306
1508
  }
1307
1509
  return !1;
1308
- }, or = async (e, t) => {
1510
+ }, Tr = async (e, t) => {
1309
1511
  let n = (await Promise.all(t.map(async (t) => {
1310
1512
  let n;
1311
1513
  try {
1312
- n = await ue(p(e, t.file), "utf8");
1514
+ n = await le(p(e, t.file), "utf8");
1313
1515
  } catch {
1314
1516
  return null;
1315
1517
  }
1316
- let r = tr(n);
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.`;
1518
+ let r = br(n);
1519
+ return r !== null && !pr(r) ? hr(p("src", "pages", t.file), r) : wr(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
1520
  }))).filter((e) => e !== null);
1319
1521
  if (n.length !== 0) throw Error(n.join("\n\n"));
1320
- }, X = p(P(), ".voltro", "logs"), sr = () => {
1522
+ }, X = p(I(), ".voltro", "logs"), Er = () => {
1321
1523
  let e = Number(process.env.VOLTRO_LOG_FILE_TTL_MS);
1322
1524
  return Number.isFinite(e) && e > 0 ? e : 3600 * 1e3;
1323
- }, cr = !1, lr = () => {
1324
- if (cr) return;
1325
- cr = !0;
1326
- let e = Date.now() - sr(), t = [];
1525
+ }, Dr = !1, Or = () => {
1526
+ if (Dr) return;
1527
+ Dr = !0;
1528
+ let e = Date.now() - Er(), t = [];
1327
1529
  try {
1328
- t = te(X);
1530
+ t = A(X);
1329
1531
  } catch {
1330
1532
  return;
1331
1533
  }
@@ -1333,13 +1535,13 @@ import {
1333
1535
  if (!n.endsWith(".log")) continue;
1334
1536
  let t = p(X, n);
1335
1537
  try {
1336
- k(t).mtimeMs < e && A(t);
1538
+ j(t).mtimeMs < e && M(t);
1337
1539
  } catch {}
1338
1540
  }
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
- let t = ur(e), n = [];
1541
+ }, kr = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), Ar = (e, t) => p(X, `${kr(e)}-${t}.log`), jr = (e) => {
1542
+ let t = kr(e), n = [];
1341
1543
  try {
1342
- n = te(X);
1544
+ n = A(X);
1343
1545
  } catch {
1344
1546
  return;
1345
1547
  }
@@ -1349,17 +1551,17 @@ import {
1349
1551
  for (let e of r) {
1350
1552
  let t = p(X, e);
1351
1553
  try {
1352
- let e = k(t);
1554
+ let e = j(t);
1353
1555
  e.mtimeMs > a && (a = e.mtimeMs, i = t);
1354
1556
  } catch {}
1355
1557
  }
1356
1558
  return i;
1357
- }, pr = (e) => {
1559
+ }, Mr = (e) => {
1358
1560
  try {
1359
1561
  E(X, { recursive: !0 });
1360
1562
  } catch {}
1361
- lr();
1362
- let t = dr(e, process.pid), n = D(t, "w"), r = (e) => {
1563
+ Or();
1564
+ let t = Ar(e, process.pid), n = D(t, "w"), r = (e) => {
1363
1565
  let t = {
1364
1566
  ts: e.ts.getTime(),
1365
1567
  level: e.level,
@@ -1382,7 +1584,7 @@ import {
1382
1584
  }
1383
1585
  }, i = !1, a = x((e) => {
1384
1586
  if (!i) try {
1385
- j(n, r(e));
1587
+ N(n, r(e));
1386
1588
  } catch {}
1387
1589
  }), o = () => {
1388
1590
  if (!i) {
@@ -1400,7 +1602,7 @@ import {
1400
1602
  a(), o(), process.off("exit", o), process.off("uncaughtException", s), process.off("unhandledRejection", s);
1401
1603
  }
1402
1604
  };
1403
- }, mr = async (e, t) => {
1605
+ }, Nr = async (e, t) => {
1404
1606
  let n;
1405
1607
  try {
1406
1608
  n = await O.readFile(e, "utf8");
@@ -1414,11 +1616,11 @@ import {
1414
1616
  i.push(t);
1415
1617
  } catch {}
1416
1618
  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) => {
1619
+ }, Pr = S({ scope: "voltro:dashboard" }), Fr = L(import.meta.url), Ir = 5179, Lr = (e) => {
1418
1620
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1419
1621
  if (t && T(p(h(t), "app.config.ts"))) return h(t);
1420
1622
  try {
1421
- let e = d(gr.resolve("@voltro/dashboard/package.json"));
1623
+ let e = d(Fr.resolve("@voltro/dashboard/package.json"));
1422
1624
  if (T(p(e, "app.config.ts"))) return e;
1423
1625
  } catch {}
1424
1626
  let n = p("voltro-devtools", "apps", "dashboard"), r = h(e);
@@ -1430,53 +1632,53 @@ import {
1430
1632
  r = t;
1431
1633
  }
1432
1634
  return null;
1433
- }, yr = "VOLTRO_IS_DASHBOARD", br = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1434
- let i = me({
1635
+ }, Rr = "VOLTRO_IS_DASHBOARD", zr = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1636
+ let i = pe({
1435
1637
  port: e,
1436
1638
  host: t
1437
1639
  }), a = !1, o = (e) => {
1438
1640
  a || (a = !0, i.destroy(), r(e));
1439
1641
  };
1440
1642
  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 () => {
1643
+ }), Br = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Vr = () => process.env[Rr] === "1", Hr = () => process.stdout.isTTY === !0, Ur = p(I(), ".voltro", "dashboard-launch.lock"), Wr = 1e4, Gr = async () => {
1442
1644
  try {
1443
- await O.mkdir(d(wr), { recursive: !0 });
1444
- let e = await O.open(wr, "wx");
1645
+ await O.mkdir(d(Ur), { recursive: !0 });
1646
+ let e = await O.open(Ur, "wx");
1445
1647
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1446
1648
  } catch {
1447
1649
  try {
1448
- let e = await O.stat(wr);
1449
- if (Date.now() - e.mtimeMs > Tr) return await O.unlink(wr).catch(() => void 0), Er();
1650
+ let e = await O.stat(Ur);
1651
+ if (Date.now() - e.mtimeMs > Wr) return await O.unlink(Ur).catch(() => void 0), Gr();
1450
1652
  } catch {}
1451
1653
  return !1;
1452
1654
  }
1453
- }, Dr = async () => {
1655
+ }, Kr = async () => {
1454
1656
  try {
1455
- await O.unlink(wr);
1657
+ await O.unlink(Ur);
1456
1658
  } catch {}
1457
- }, Or = async (e) => {
1659
+ }, qr = async (e) => {
1458
1660
  let t = e.port ?? 5179;
1459
- if (xr()) return {
1661
+ if (Br()) return {
1460
1662
  status: "skipped",
1461
1663
  reason: "disabled by flag/env",
1462
1664
  port: t
1463
1665
  };
1464
- if (Sr()) return {
1666
+ if (Vr()) return {
1465
1667
  status: "skipped",
1466
1668
  reason: "this process IS the dashboard",
1467
1669
  port: t
1468
1670
  };
1469
- if (!Cr()) return {
1671
+ if (!Hr()) return {
1470
1672
  status: "skipped",
1471
1673
  reason: "stdout is not a TTY (CI/smoke)",
1472
1674
  port: t
1473
1675
  };
1474
- if (!await Er()) return {
1676
+ if (!await Gr()) return {
1475
1677
  status: "skipped",
1476
1678
  reason: "another voltro process is currently launching the dashboard",
1477
1679
  port: t
1478
1680
  };
1479
- if (await br(t)) return await Dr(), {
1681
+ if (await zr(t)) return await Kr(), {
1480
1682
  status: "already-running",
1481
1683
  port: t
1482
1684
  };
@@ -1485,7 +1687,7 @@ import {
1485
1687
  let e = process.argv[1];
1486
1688
  n = e && e.endsWith("/src/bin.ts") ? p(d(e), "..", "bin", "voltro.mjs") : e ?? "voltro";
1487
1689
  }
1488
- let r = T(p(e.dashboardAppPath, ".framework", "dist", "index.html")), i = r ? "start" : "dev", a = pe(process.execPath, [
1690
+ let r = T(p(e.dashboardAppPath, ".framework", "dist", "index.html")), i = r ? "start" : "dev", a = fe(process.execPath, [
1489
1691
  n,
1490
1692
  i,
1491
1693
  e.dashboardAppPath
@@ -1493,7 +1695,7 @@ import {
1493
1695
  stdio: "ignore",
1494
1696
  env: {
1495
1697
  ...process.env,
1496
- [yr]: "1",
1698
+ [Rr]: "1",
1497
1699
  VOLTRO_DASHBOARD_PORT: String(t)
1498
1700
  }
1499
1701
  });
@@ -1501,22 +1703,22 @@ import {
1501
1703
  if (a.exitCode === null && a.signalCode === null) try {
1502
1704
  a.kill("SIGTERM");
1503
1705
  } catch {}
1504
- }), hr.info(`auto-launching dashboard at http://localhost:${t}`, {
1706
+ }), Pr.info(`auto-launching dashboard at http://localhost:${t}`, {
1505
1707
  port: t,
1506
1708
  mode: i,
1507
1709
  prebuilt: r
1508
- }), r || hr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), hr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1509
- Dr();
1710
+ }), r || Pr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), Pr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1711
+ Kr();
1510
1712
  }, 4e3).unref(), {
1511
1713
  status: "launched",
1512
1714
  port: t
1513
1715
  };
1514
- }, kr = class extends Error {
1716
+ }, Jr = class extends Error {
1515
1717
  _voltroDeferral = !0;
1516
1718
  constructor(e) {
1517
1719
  super(e), this.name = "DeferralNotSupportedError";
1518
1720
  }
1519
- }, Ar = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, jr = (e) => {
1721
+ }, Yr = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Xr = (e) => {
1520
1722
  if (!(e instanceof Error)) return;
1521
1723
  let t = e._voltroControl;
1522
1724
  if (t === "redirect") {
@@ -1538,7 +1740,7 @@ import {
1538
1740
  },
1539
1741
  body: "not found"
1540
1742
  };
1541
- }, Mr = (e) => {
1743
+ }, Zr = (e) => {
1542
1744
  let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1543
1745
  for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1544
1746
  let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
@@ -1553,7 +1755,7 @@ import {
1553
1755
  ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
1554
1756
  });
1555
1757
  } catch (e) {
1556
- throw new kr(e instanceof Error ? e.message : String(e));
1758
+ throw new Jr(e instanceof Error ? e.message : String(e));
1557
1759
  }
1558
1760
  return {
1559
1761
  loaderData: n.renderData,
@@ -1569,8 +1771,8 @@ import {
1569
1771
  ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1570
1772
  }
1571
1773
  };
1572
- }, Nr = (e) => {
1573
- let { helpers: t, renderInput: n } = e, r = Mr({
1774
+ }, Qr = (e) => {
1775
+ let { helpers: t, renderInput: n } = e, r = Zr({
1574
1776
  helpers: t,
1575
1777
  page: e.page,
1576
1778
  pathname: n.pathname,
@@ -1591,19 +1793,19 @@ import {
1591
1793
  stateScript: t.renderRouterStateScript(r.stateInput),
1592
1794
  hasDeferred: r.hasDeferred
1593
1795
  };
1594
- }, Pr = (e) => {
1796
+ }, $r = (e) => {
1595
1797
  let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
1596
1798
  return {
1597
1799
  body: t,
1598
1800
  meta: n
1599
1801
  };
1600
- }, Fr = (e) => [
1802
+ }, ei = (e) => [
1601
1803
  ...e.extra ?? [],
1602
1804
  e.helpers.renderMetaToHtml(e.meta),
1603
1805
  `<meta name="voltro-interactive" content="${e.interactive}" />`,
1604
1806
  ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
1605
1807
  e.prepared.stateScript
1606
- ].filter((e) => e.length > 0).join("\n "), Ir = (e) => {
1808
+ ].filter((e) => e.length > 0).join("\n "), ti = (e) => {
1607
1809
  let t = e.indexOf("?");
1608
1810
  return t === -1 ? {
1609
1811
  pathname: e || "/",
@@ -1612,58 +1814,95 @@ import {
1612
1814
  pathname: e.slice(0, t) || "/",
1613
1815
  search: e.slice(t)
1614
1816
  };
1615
- }, Lr = /Could not find required `intl` object/, Rr = (e) => [
1817
+ }, ni = /Could not find required `intl` object/, ri = "__voltro_i18n_instances__", ii = (e = globalThis) => {
1818
+ try {
1819
+ let t = e[ri]?.records;
1820
+ return t === void 0 || t.length === 0 ? void 0 : {
1821
+ instances: t.length,
1822
+ reactIntlCopies: new Set(t.map((e) => e.intlProvider)).size,
1823
+ files: [...new Set(t.map((e) => e.file))]
1824
+ };
1825
+ } catch {
1826
+ return;
1827
+ }
1828
+ }, ai = (e, t) => [
1616
1829
  "",
1617
1830
  "── voltro diagnosis ───────────────────────────────────────────────────",
1618
- `${e} DID wrap this render in <I18nProvider> the framework`,
1619
- "resolved a locale for this request and supplied the provider. You are",
1620
- "seeing this error anyway, which leaves one cause:",
1831
+ `${e} DID wrap this render in <I18nProvider>, and this process`,
1832
+ `holds ${t.instances} live copies of @voltro/i18n bound to`,
1833
+ `${t.reactIntlCopies} distinct react-intl instances.`,
1621
1834
  "",
1622
- " TWO PHYSICAL COPIES OF react-intl (or of @voltro/i18n, which owns it).",
1835
+ " THAT is the cause. A React context is identified by object identity,",
1836
+ " so the provider built from one copy is invisible to a `useT()` from the",
1837
+ " other, and the error is identical to having no provider at all.",
1623
1838
  "",
1624
- "A React context is identified by object identity. The provider built from",
1625
- "one copy is invisible to a `useT()` / `useIntl()` from the other, and the",
1626
- "error is identical to having no provider at all.",
1839
+ " Loaded from:",
1840
+ ...t.files.map((e) => ` - ${e}`),
1627
1841
  "",
1628
- "Check it:",
1842
+ " NOTE: `pnpm ls` will very likely show ONE version. It enumerates",
1843
+ " versions on disk; this counts instances in the running process, and one",
1844
+ " file loaded down two paths is two instances.",
1845
+ "───────────────────────────────────────────────────────────────────────"
1846
+ ].join("\n"), oi = (e, t) => [
1629
1847
  "",
1630
- " pnpm ls -r --depth 10 @voltro/i18n react-intl",
1848
+ "── voltro diagnosis ───────────────────────────────────────────────────",
1849
+ `${e} DID wrap this render in <I18nProvider>, and this process`,
1850
+ `holds exactly ONE @voltro/i18n bound to ONE react-intl (${t.instances}/${t.reactIntlCopies}, from ${t.files[0] ?? "unknown"}).`,
1631
1851
  "",
1632
- "More than one version of either, anywhere in the workspace, is the cause.",
1633
- "It usually means one package.json was left behind on an upgrade — the app",
1634
- "still builds and every other test still passes.",
1852
+ " So neither of the two known causes applies, and this IS a framework",
1853
+ " bug report it with this block attached.",
1635
1854
  "",
1636
- "If both resolve to exactly one version, this diagnosis is wrong and the",
1637
- "framework is at fault. Report it with that output attached.",
1855
+ " One thing to check first, because it is the remaining non-framework",
1856
+ " cause and it is in YOUR code: a provider built from react-intl",
1857
+ " DIRECTLY (`import { IntlProvider } from \"react-intl\"`) rather than from",
1858
+ " @voltro/i18n. Vite bundles react-intl for modules it transforms, so a",
1859
+ " direct import can land on a second copy that this count does not see —",
1860
+ " it counts what @voltro/i18n is bound to.",
1638
1861
  "───────────────────────────────────────────────────────────────────────"
1639
- ].join("\n"), zr = (e, t, n) => {
1862
+ ].join("\n"), si = (e) => [
1863
+ "",
1864
+ "── voltro diagnosis ───────────────────────────────────────────────────",
1865
+ `${e} DID wrap this render in <I18nProvider> — the framework`,
1866
+ "resolved a locale for this request and supplied the provider, so \"no",
1867
+ "provider\" is excluded.",
1868
+ "",
1869
+ " The instance count is unavailable (@voltro/i18n did not register), so",
1870
+ " the remaining cause cannot be confirmed from here. It is almost always",
1871
+ " TWO LIVE COPIES of react-intl or @voltro/i18n — a React context is an",
1872
+ " object identity, and a provider from one copy is invisible to a hook",
1873
+ " from the other.",
1874
+ "",
1875
+ " Do NOT use `pnpm ls` to rule that out: it lists versions on disk, and",
1876
+ " the duplication here is of module instances in one process.",
1877
+ "───────────────────────────────────────────────────────────────────────"
1878
+ ].join("\n"), ci = (e, t, n, r = ii()) => {
1640
1879
  if (!t) return;
1641
- let r = String(e?.message ?? e);
1642
- return Lr.test(r) ? Rr(n) : void 0;
1643
- }, Br = "<div id=\"root\"></div>", Vr = "<div id=\"root\">", Hr = "</div>", Ur = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Wr = /\bsrc=["']([^"']+)["']/i, Gr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Kr = (e) => {
1644
- let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Ur, (e) => {
1645
- let r = Wr.exec(e)?.[1];
1880
+ let i = String(e?.message ?? e);
1881
+ if (ni.test(i)) return r === void 0 ? si(n) : r.reactIntlCopies > 1 || r.instances > 1 ? ai(n, r) : oi(n, r);
1882
+ }, li = "<div id=\"root\"></div>", ui = "<div id=\"root\">", di = "</div>", fi = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, pi = /\bsrc=["']([^"']+)["']/i, mi = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, hi = (e) => {
1883
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(fi, (e) => {
1884
+ let r = pi.exec(e)?.[1];
1646
1885
  return r === void 0 || t(r) ? e : (n.push(r), "");
1647
1886
  });
1648
- e.inlineModuleScriptsAsync && (r = r.replace(Gr, "<script async$1>"));
1649
- let i = r.indexOf(Br);
1650
- if (i === -1) throw Error(`[voltro] the generated shell has no \`${Br}\` 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.`);
1887
+ e.inlineModuleScriptsAsync && (r = r.replace(mi, "<script async$1>"));
1888
+ let i = r.indexOf(li);
1889
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${li}\` 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.`);
1651
1890
  return {
1652
- head: `${r.slice(0, i)}${Vr}`,
1653
- tail: `${Hr}${r.slice(i + 21)}`,
1891
+ head: `${r.slice(0, i)}${ui}`,
1892
+ tail: `${di}${r.slice(i + 21)}`,
1654
1893
  bootstrapModules: n
1655
1894
  };
1656
- }, qr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Jr = (e) => {
1895
+ }, gi = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), _i = (e) => gi(e.head, e.headInjection).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), vi = (e) => {
1657
1896
  let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1658
1897
  if (s || !o || a === null) return;
1659
1898
  s = !0, t.statusCode = e.statusCode ?? 200;
1660
1899
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1661
- t.flushHeaders?.(), t.write(qr({
1900
+ t.flushHeaders?.(), t.write(_i({
1662
1901
  head: n.head,
1663
1902
  headInjection: i(a.meta),
1664
1903
  htmlLang: r
1665
1904
  }));
1666
- let c = new he();
1905
+ let c = new me();
1667
1906
  c.pipe(t, { end: !1 }), c.on("end", () => {
1668
1907
  t.end(n.tail);
1669
1908
  }), a.stream.pipe(c);
@@ -1688,16 +1927,16 @@ import {
1688
1927
  return;
1689
1928
  }
1690
1929
  c();
1691
- }, Yr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Xr = (e, t) => typeof e == "string" ? {
1930
+ }, yi = (e) => Array.isArray(e.preload) && e.preload.length > 0, bi = (e, t) => typeof e == "string" ? {
1692
1931
  tag: e,
1693
1932
  input: {}
1694
1933
  } : {
1695
1934
  tag: e.tag,
1696
1935
  input: e.input?.(t) ?? {}
1697
- }, Zr = async (e) => {
1936
+ }, xi = async (e) => {
1698
1937
  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);
1938
+ if (yi(t) && !(r === void 0 || i === void 0)) for (let e of t.preload) {
1939
+ let { tag: t, input: s } = bi(e, n);
1701
1940
  try {
1702
1941
  a(i, t, s, await r(t, s));
1703
1942
  } catch (e) {
@@ -1707,14 +1946,14 @@ import {
1707
1946
  }, e);
1708
1947
  }
1709
1948
  }
1710
- }, Z = S({ scope: "voltro:dev:web" }), Qr = S({ scope: "vite" }), $r = await (async () => {
1949
+ }, Z = S({ scope: "voltro:dev:web" }), Si = S({ scope: "vite" }), Ci = await (async () => {
1711
1950
  try {
1712
1951
  let e = p(d(g(import.meta.url)), "..", "package.json"), t = await O.readFile(e, "utf8");
1713
1952
  return JSON.parse(t).version ?? "0.0.0";
1714
1953
  } catch {
1715
1954
  return "0.0.0";
1716
1955
  }
1717
- })(), ei = async () => {
1956
+ })(), wi = async () => {
1718
1957
  try {
1719
1958
  let e = d(g(import.meta.url)), t = h(e, "..", "..", "devtools");
1720
1959
  if (T(p(t, "package.json"))) return t;
@@ -1723,7 +1962,7 @@ import {
1723
1962
  } catch {
1724
1963
  return null;
1725
1964
  }
1726
- }, ti = (e, t) => e.disableDevtools || !t ? [] : [
1965
+ }, Ti = (e, t) => e.disableDevtools || !t ? [] : [
1727
1966
  "",
1728
1967
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1729
1968
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1733,12 +1972,12 @@ import {
1733
1972
  " await import('@voltro/devtools/styles.css')",
1734
1973
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1735
1974
  "}"
1736
- ], ni = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ri = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], ii = (e) => e.sentry ? [
1975
+ ], Ei = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Di = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Oi = (e) => e.sentry ? [
1737
1976
  "",
1738
1977
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1739
1978
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1740
1979
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1741
- ] : [], ai = (e) => e.env ? ["import './env.public'"] : [], oi = (e) => {
1980
+ ] : [], ki = (e) => e.env ? ["import './env.public'"] : [], Ai = (e) => {
1742
1981
  let t = [], n = h(e);
1743
1982
  for (;;) {
1744
1983
  T(p(n, "pnpm-workspace.yaml")) && t.push(n);
@@ -1747,14 +1986,14 @@ import {
1747
1986
  n = e;
1748
1987
  }
1749
1988
  return t;
1750
- }, si = In, ci = (e) => {
1989
+ }, ji = tr, Mi = (e) => {
1751
1990
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1752
1991
  let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1753
1992
  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));
1993
+ }, Ni = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Pi = (e) => e.startsWith("(") && e.endsWith(")"), Fi = (e) => e.filter((e) => !Pi(e)), Ii = (e) => {
1994
+ let t = e.replace(r, "").split("/").filter(Boolean).filter((e) => !Pi(e));
1756
1995
  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) => {
1996
+ }, Li = (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
1997
  let t = [], i = [], a = async (e, o) => {
1759
1998
  let s = [];
1760
1999
  try {
@@ -1762,17 +2001,17 @@ import {
1762
2001
  } catch {
1763
2002
  return;
1764
2003
  }
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("/");
2004
+ let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !ji(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1766
2005
  if (l.some((e) => n.has(e))) {
1767
2006
  let t = u.has("layout.tsx"), r = !1;
1768
2007
  if (t) try {
1769
2008
  let t = await O.readFile(p(e, "layout.tsx"), "utf8");
1770
- r = li.test(t);
2009
+ r = Ni.test(t);
1771
2010
  } catch {}
1772
2011
  i.push({
1773
2012
  dir: d,
1774
2013
  chain: o,
1775
- contributesToUrl: o.length === 0 || !ui(o[o.length - 1]),
2014
+ contributesToUrl: o.length === 0 || !Pi(o[o.length - 1]),
1776
2015
  hasLayout: t,
1777
2016
  hasLayoutLoader: r,
1778
2017
  hasError: u.has("error.tsx"),
@@ -1786,8 +2025,8 @@ import {
1786
2025
  let n = d ? `${d}/${e}` : e;
1787
2026
  t.push({
1788
2027
  file: n,
1789
- pattern: fi(n),
1790
- ident: pi(n),
2028
+ pattern: Ii(n),
2029
+ ident: Li(n),
1791
2030
  dirChain: o
1792
2031
  });
1793
2032
  }
@@ -1806,14 +2045,14 @@ import {
1806
2045
  dirs: s,
1807
2046
  orphanedSpecials: c
1808
2047
  };
1809
- }, mi = (e, t) => {
2048
+ }, Ri = (e, t) => {
1810
2049
  let n = [];
1811
2050
  for (let r = 0; r <= t.length; r++) {
1812
2051
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1813
2052
  a && n.push(a);
1814
2053
  }
1815
2054
  return n;
1816
- }, hi = async (e) => {
2055
+ }, zi = async (e) => {
1817
2056
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1818
2057
  return {
1819
2058
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1836,10 +2075,10 @@ import {
1836
2075
  })),
1837
2076
  segmentLoaderData: o
1838
2077
  };
1839
- }, gi = (e) => {
1840
- let t = di(e);
2078
+ }, Bi = (e) => {
2079
+ let t = Fi(e);
1841
2080
  return t.length === 0 ? "" : "/" + t.join("/");
1842
- }, _i = [
2081
+ }, Vi = [
1843
2082
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1844
2083
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1845
2084
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1932,7 +2171,7 @@ import {
1932
2171
  " _vdtErrorStart('Build error')",
1933
2172
  " })",
1934
2173
  "}"
1935
- ].join("\n"), vi = (e) => {
2174
+ ].join("\n"), Hi = (e) => {
1936
2175
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1937
2176
  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
2177
  let a = i.join("/");
@@ -1941,8 +2180,8 @@ import {
1941
2180
  paramNames: t,
1942
2181
  priority: n
1943
2182
  };
1944
- }, yi = (e) => e.map((e) => {
1945
- let { regex: t, paramNames: n, priority: r } = vi(e.pattern);
2183
+ }, Ui = (e) => e.map((e) => {
2184
+ let { regex: t, paramNames: n, priority: r } = Hi(e.pattern);
1946
2185
  return {
1947
2186
  pattern: e.pattern,
1948
2187
  file: e.file,
@@ -1951,7 +2190,7 @@ import {
1951
2190
  paramNames: n,
1952
2191
  priority: r
1953
2192
  };
1954
- }).slice().sort((e, t) => e.priority - t.priority), bi = (e, t) => {
2193
+ }).slice().sort((e, t) => e.priority - t.priority), Wi = (e, t) => {
1955
2194
  for (let n of t) {
1956
2195
  let t = n.regex.exec(e);
1957
2196
  if (!t) continue;
@@ -1963,7 +2202,7 @@ import {
1963
2202
  };
1964
2203
  }
1965
2204
  return null;
1966
- }, xi = async (e, t) => {
2205
+ }, Gi = async (e, t) => {
1967
2206
  let n = e;
1968
2207
  for (;;) {
1969
2208
  let e = p(n, "node_modules", t);
@@ -1977,7 +2216,7 @@ import {
1977
2216
  if (r === n) return null;
1978
2217
  n = r;
1979
2218
  }
1980
- }, Si = async (e) => {
2219
+ }, Ki = async (e) => {
1981
2220
  try {
1982
2221
  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
2222
  return a ? {
@@ -1986,7 +2225,7 @@ import {
1986
2225
  } : { port: r };
1987
2226
  } catch {}
1988
2227
  return { port: 4e3 };
1989
- }, Ci = (e, t) => ({
2228
+ }, qi = (e, t) => ({
1990
2229
  name: e,
1991
2230
  pkg: t.package,
1992
2231
  browserWsUrl: t.url,
@@ -1994,7 +2233,7 @@ import {
1994
2233
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1995
2234
  ...t.headers ? { headers: t.headers } : {},
1996
2235
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1997
- }), wi = (e, t, n) => {
2236
+ }), Ji = (e, t, n) => {
1998
2237
  let r = t.transport?.wsPath ?? n.wsPath;
1999
2238
  return {
2000
2239
  name: e,
@@ -2006,7 +2245,7 @@ import {
2006
2245
  ...t.headers ? { headers: t.headers } : {},
2007
2246
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
2008
2247
  };
2009
- }, Ti = (e) => {
2248
+ }, Yi = (e) => {
2010
2249
  let t = /* @__PURE__ */ new Map();
2011
2250
  for (let n of e) {
2012
2251
  if (n.proxyTarget === void 0) continue;
@@ -2014,43 +2253,43 @@ import {
2014
2253
  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
2254
  t.set(n.browserWsUrl, n.name);
2016
2255
  }
2017
- }, Ei = async (e, t) => {
2256
+ }, Xi = async (e, t) => {
2018
2257
  let n = Object.entries(t.apis ?? {}), r = [];
2019
2258
  for (let [t, i] of n) {
2020
2259
  if (i.url) {
2021
- r.push(Ci(t, i));
2260
+ r.push(qi(t, i));
2022
2261
  continue;
2023
2262
  }
2024
- let n = await xi(e, i.package);
2263
+ let n = await Gi(e, i.package);
2025
2264
  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)));
2265
+ r.push(Ji(t, i, await Ki(n)));
2027
2266
  }
2028
- return Ti(r), r;
2029
- }, Di = (e) => {
2267
+ return Yi(r), r;
2268
+ }, Zi = (e) => {
2030
2269
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
2031
2270
  let t = new URL(e);
2032
2271
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
2033
2272
  } catch {
2034
2273
  return;
2035
2274
  }
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) => {
2275
+ }, Qi = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, $i = (e) => process.env[Qi(e)] ?? process.env.VOLTRO_API_ORIGIN, ea = (e, t) => {
2037
2276
  if (!e) return;
2038
- let n = ki(e.name) ?? e.serverOrigin;
2277
+ let n = $i(e.name) ?? e.serverOrigin;
2039
2278
  if (n) {
2040
- let e = Di(n);
2279
+ let e = Zi(n);
2041
2280
  if (e) return e;
2042
2281
  }
2043
2282
  if (t?.allowDevProxy && e.proxyTarget) {
2044
- let t = Di(e.proxyTarget);
2283
+ let t = Zi(e.proxyTarget);
2045
2284
  if (t) return t;
2046
2285
  }
2047
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Di(e.browserWsUrl);
2048
- }, ji = (e, t, n) => {
2286
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Zi(e.browserWsUrl);
2287
+ }, ta = (e, t, n) => {
2049
2288
  if (!e) {
2050
2289
  if (n?.apiName === void 0) return;
2051
2290
  let e = n.apiName;
2052
2291
  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.`);
2292
+ 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 ${Qi(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
2293
  };
2055
2294
  }
2056
2295
  return async (r, i) => {
@@ -2072,7 +2311,7 @@ import {
2072
2311
  });
2073
2312
  } catch (t) {
2074
2313
  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 });
2314
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${Qi(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
2315
  }
2077
2316
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2078
2317
  let s = await o.json();
@@ -2090,8 +2329,8 @@ import {
2090
2329
  }
2091
2330
  if (u) return l;
2092
2331
  };
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" ? [
2332
+ }, na = async (e, t, n, r = {}) => {
2333
+ 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 wi() !== null, s = t.theme === "system" ? [
2095
2334
  " <script>",
2096
2335
  " (function () {",
2097
2336
  " var root = document.documentElement",
@@ -2130,7 +2369,7 @@ import {
2130
2369
  "</html>",
2131
2370
  ""
2132
2371
  ].join("\n"), l = p(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: f } = await $(l);
2133
- await or(l, u);
2372
+ await Tr(l, u);
2134
2373
  for (let e of f) 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.`);
2135
2374
  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'`);
2136
2375
  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"));
@@ -2139,63 +2378,63 @@ import {
2139
2378
  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
2379
  }), v, y, b;
2141
2380
  if (u.length > 0) {
2142
- let e = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), n = [];
2381
+ let n = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2143
2382
  for (let e of d) {
2144
2383
  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'`);
2384
+ 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
2385
  }
2147
- let r = u.map((e) => {
2148
- let t = mi(d, e.dirChain).map((e) => {
2386
+ let i = u.map((e) => {
2387
+ let t = Ri(d, e.dirChain).map((e) => {
2149
2388
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2150
2389
  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
2390
  }).join(",\n");
2152
2391
  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) => {
2392
+ }), a = d.filter((e) => e.hasNotFound).map((e) => {
2393
+ let t = Bi(e.chain), n = Ri(d, e.chain).map((e) => {
2155
2394
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2156
2395
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2157
2396
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
2158
2397
  return ` {\n prefix: ${JSON.stringify(t)},\n Component: refs.notFounds[${JSON.stringify(e.dir)}],${r}\n },`;
2159
- }), a = [], s = [], c = [], l = [], f = [], p = [];
2398
+ }), s = [], c = [], l = [], f = [], m = [], h = [];
2160
2399
  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({
2400
+ 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);
2401
+ 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
2402
  relPath: t,
2164
2403
  kind: "layout",
2165
2404
  slotKey: e.dir
2166
- })) : e.hasLayout && (s.push(` ${o}: ${Q(e.dir, "Layout")},`), a.push({
2405
+ })) : e.hasLayout && (c.push(` ${a}: ${Q(e.dir, "Layout")},`), s.push({
2167
2406
  relPath: t,
2168
2407
  kind: "layout",
2169
2408
  slotKey: e.dir
2170
- })), e.hasError && (l.push(` ${o}: ${Q(e.dir, "Error")},`), a.push({
2409
+ })), e.hasError && (f.push(` ${a}: ${Q(e.dir, "Error")},`), s.push({
2171
2410
  relPath: n,
2172
2411
  kind: "error",
2173
2412
  slotKey: e.dir
2174
- })), e.hasPending && (f.push(` ${o}: ${Q(e.dir, "Pending")},`), a.push({
2413
+ })), e.hasPending && (m.push(` ${a}: ${Q(e.dir, "Pending")},`), s.push({
2175
2414
  relPath: r,
2176
2415
  kind: "pending",
2177
2416
  slotKey: e.dir
2178
- })), e.hasNotFound && (p.push(` ${o}: ${Q(e.dir, "NotFound")},`), a.push({
2417
+ })), e.hasNotFound && (h.push(` ${a}: ${Q(e.dir, "NotFound")},`), s.push({
2179
2418
  relPath: i,
2180
2419
  kind: "notFound",
2181
2420
  slotKey: e.dir
2182
2421
  }));
2183
2422
  }
2184
- for (let e of u) a.push({
2423
+ for (let e of u) s.push({
2185
2424
  relPath: `../src/pages/${e.file}`,
2186
2425
  kind: "page",
2187
2426
  slotKey: e.pattern
2188
2427
  });
2189
- let m = a.map((e) => ` ${JSON.stringify(e.relPath)},`), h = a.map((e, t) => {
2428
+ let x = s.map((e) => ` ${JSON.stringify(e.relPath)},`), S = s.map((e, t) => {
2190
2429
  let n = JSON.stringify(e.slotKey);
2191
2430
  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 ? [
2431
+ }), 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";
2432
+ 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(", ")}]`);
2433
+ let O = E ? [
2195
2434
  "import { I18nProvider } from '@voltro/i18n'",
2196
2435
  "import { resolveLocale } from '@voltro/i18n/server'",
2197
2436
  "import { useServerRequest } from '@voltro/web'",
2198
- ...x.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2437
+ ...C.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2199
2438
  ] : [];
2200
2439
  y = [
2201
2440
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2218,7 +2457,7 @@ import {
2218
2457
  "// without unmounting the surrounding tree.",
2219
2458
  "",
2220
2459
  "import { pageRoute, lazyPageRoute, preloadRouteModule, type PageDescriptor, type NotFoundDescriptor } from '@voltro/web'",
2221
- ...n,
2460
+ ...r,
2222
2461
  "",
2223
2462
  "// Mutable module registry. Initial values come from the static",
2224
2463
  "// imports above; HMR patches the slot, never the import.",
@@ -2231,19 +2470,19 @@ import {
2231
2470
  " pages: Record<string, unknown>",
2232
2471
  "} = {",
2233
2472
  " layouts: {",
2234
- ...s,
2473
+ ...c,
2235
2474
  " },",
2236
2475
  " layoutLoaders: {",
2237
- ...c,
2476
+ ...l,
2238
2477
  " },",
2239
2478
  " errors: {",
2240
- ...l,
2479
+ ...f,
2241
2480
  " },",
2242
2481
  " pendings: {",
2243
- ...f,
2482
+ ...m,
2244
2483
  " },",
2245
2484
  " notFounds: {",
2246
- ...p,
2485
+ ...h,
2247
2486
  " },",
2248
2487
  " pages: {},",
2249
2488
  "}",
@@ -2251,7 +2490,7 @@ import {
2251
2490
  "// Per-pattern dynamic-import thunks. Each is a literal `import()` so vite",
2252
2491
  "// code-splits the page into its own chunk and only fetches it on match.",
2253
2492
  "const pageLoaders: Record<string, () => Promise<Record<string, unknown>>> = {",
2254
- ...e,
2493
+ ...n,
2255
2494
  "}",
2256
2495
  "",
2257
2496
  "let version = 0",
@@ -2285,7 +2524,7 @@ import {
2285
2524
  " }, { chain })",
2286
2525
  "",
2287
2526
  "export const buildRoutes = (): PageDescriptor[] => [",
2288
- ...r,
2527
+ ...i,
2289
2528
  "]",
2290
2529
  "",
2291
2530
  "// Preload the CURRENT url's page chunk before hydration. main.tsx awaits",
@@ -2302,17 +2541,17 @@ import {
2302
2541
  "}",
2303
2542
  "",
2304
2543
  "export const buildNotFounds = (): NotFoundDescriptor[] => [",
2305
- ...i,
2544
+ ...a,
2306
2545
  "]",
2307
2546
  "",
2308
2547
  "if (import.meta.hot) {",
2309
2548
  " import.meta.hot.accept(",
2310
2549
  " [",
2311
- ...m,
2550
+ ...x,
2312
2551
  " ],",
2313
2552
  " (newMods: Array<Record<string, unknown> | undefined>) => {",
2314
2553
  " let changed = false",
2315
- ...h,
2554
+ ...S,
2316
2555
  " if (changed) bump()",
2317
2556
  " },",
2318
2557
  " )",
@@ -2329,16 +2568,16 @@ import {
2329
2568
  "",
2330
2569
  "import { useMemo, useSyncExternalStore } from 'react'",
2331
2570
  "import { Router } from '@voltro/web'",
2332
- ...w,
2571
+ ...O,
2333
2572
  "import { subscribe, getVersion, buildRoutes, buildNotFounds } from './routeTable'",
2334
2573
  "",
2335
- ...S ? [
2336
- `// i18n auto-wiring (config.locales = [${x.map((e) => JSON.stringify(e)).join(", ")}]).`,
2574
+ ...E ? [
2575
+ `// i18n auto-wiring (config.locales = [${C.map((e) => JSON.stringify(e)).join(", ")}]).`,
2337
2576
  "const I18N_CATALOGS: Record<string, import('@voltro/i18n').MessageCatalog> = {",
2338
- ...x.map((e) => ` ${JSON.stringify(e)}: i18nCatalog_${e},`),
2577
+ ...C.map((e) => ` ${JSON.stringify(e)}: i18nCatalog_${e},`),
2339
2578
  "}",
2340
- `const I18N_SUPPORTED: ReadonlyArray<string> = [${x.map((e) => JSON.stringify(e)).join(", ")}]`,
2341
- `const I18N_DEFAULT = ${JSON.stringify(C)}`,
2579
+ `const I18N_SUPPORTED: ReadonlyArray<string> = [${C.map((e) => JSON.stringify(e)).join(", ")}]`,
2580
+ `const I18N_DEFAULT = ${JSON.stringify(D)}`,
2342
2581
  "",
2343
2582
  "const pickI18nLocale = (ssr: ReturnType<typeof useServerRequest>): string => {",
2344
2583
  " if (ssr) {",
@@ -2389,7 +2628,7 @@ import {
2389
2628
  " const v = useSyncExternalStore(subscribe, getVersion, getVersion)",
2390
2629
  " const routes = useMemo(() => buildRoutes(), [v])",
2391
2630
  " const notFounds = useMemo(() => buildNotFounds(), [v])",
2392
- ...S ? [
2631
+ ...E ? [
2393
2632
  " const ssr = useServerRequest()",
2394
2633
  " const locale = pickI18nLocale(ssr)",
2395
2634
  " const messages = I18N_CATALOGS[locale] ?? I18N_CATALOGS[I18N_DEFAULT]!",
@@ -2407,14 +2646,14 @@ import {
2407
2646
  "// resolved apis map. Side-effect only — no local component definitions —",
2408
2647
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2409
2648
  "",
2410
- ...ai(t),
2649
+ ...ki(t),
2411
2650
  "import { mount } from '@voltro/web'",
2412
2651
  ...g,
2413
2652
  "import { App } from './app'",
2414
2653
  "import { preloadCurrentRoute } from './routeTable'",
2415
- ...ri(t),
2416
- ...ti(t, o),
2417
- ...ii(t),
2654
+ ...Di(t),
2655
+ ...Ti(t, o),
2656
+ ...Oi(t),
2418
2657
  "",
2419
2658
  "// Preload the current route's page chunk BEFORE hydration so the first",
2420
2659
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2431,10 +2670,10 @@ import {
2431
2670
  " apis: {",
2432
2671
  ..._,
2433
2672
  " },",
2434
- ...ni(t, o),
2673
+ ...Ei(t, o),
2435
2674
  "})",
2436
2675
  "",
2437
- _i
2676
+ Vi
2438
2677
  ].join("\n");
2439
2678
  } else v = "", y = "", b = [
2440
2679
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2442,22 +2681,22 @@ import {
2442
2681
  "// and calls mount(). Side-effect only, no component definitions, so the",
2443
2682
  "// user's component file remains the Fast Refresh boundary.",
2444
2683
  "",
2445
- ...ai(t),
2684
+ ...ki(t),
2446
2685
  "import { mount } from '@voltro/web'",
2447
2686
  ...g,
2448
2687
  "import App from '../src/App'",
2449
- ...ri(t),
2450
- ...ti(t, o),
2451
- ...ii(t),
2688
+ ...Di(t),
2689
+ ...Ti(t, o),
2690
+ ...Oi(t),
2452
2691
  "",
2453
2692
  "mount(App, {",
2454
2693
  " apis: {",
2455
2694
  ..._,
2456
2695
  " },",
2457
- ...ni(t, o),
2696
+ ...Ei(t, o),
2458
2697
  "})",
2459
2698
  "",
2460
- _i
2699
+ Vi
2461
2700
  ].join("\n");
2462
2701
  let x = p(e, ".framework");
2463
2702
  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 +2713,7 @@ import {
2474
2713
  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
2714
  }
2476
2715
  }
2477
- }, Ni = async (e, t) => {
2716
+ }, ra = async (e, t) => {
2478
2717
  try {
2479
2718
  let n = p(d(e), "project.json");
2480
2719
  if (!T(n)) return;
@@ -2487,24 +2726,24 @@ import {
2487
2726
  projectJson: n
2488
2727
  });
2489
2728
  } 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");
2729
+ }, ia = (e) => p(e, ".framework", "dist", "server", "appConfig.js"), aa = async (e) => {
2730
+ let t = ia(e), n = T(t) ? t : p(e, "app.config.ts");
2492
2731
  try {
2493
2732
  let e = (await import(_(n).href)).default;
2494
2733
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2495
2734
  } catch {
2496
2735
  return null;
2497
2736
  }
2498
- }, Ii = async (e) => {
2499
- let t = await Fi(e);
2737
+ }, oa = async (e) => {
2738
+ let t = await aa(e);
2500
2739
  if (!t) return {
2501
2740
  ran: !1,
2502
2741
  exitCode: 0
2503
2742
  };
2504
- Nn();
2505
- let n = qt();
2506
- fn(n), Z.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2507
- let r = await Ei(e, t);
2743
+ Qn();
2744
+ let n = pn();
2745
+ jn(n), Z.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" }), It(e, Z);
2746
+ let r = await Xi(e, t);
2508
2747
  for (let e of r) Z.info("api wired", {
2509
2748
  name: e.name,
2510
2749
  pkg: e.pkg,
@@ -2523,12 +2762,12 @@ import {
2523
2762
  log: Z,
2524
2763
  generateTypes: !0
2525
2764
  }), f = d.publicValues;
2526
- await Mi(e, t, r, f), Z.debug("generated framework entry files", { files: [
2765
+ await na(e, t, r, f), Z.debug("generated framework entry files", { files: [
2527
2766
  "index.html",
2528
2767
  ".framework/main.tsx",
2529
2768
  ...t.env ? [".framework/env.public.ts"] : []
2530
2769
  ] });
2531
- 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 = Ke("web", _, g), y = pr(_);
2770
+ 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 = Ke("web", _, g), y = Mr(_);
2532
2771
  await We({
2533
2772
  id: v,
2534
2773
  name: _,
@@ -2537,22 +2776,22 @@ import {
2537
2776
  pid: process.pid,
2538
2777
  status: "booting",
2539
2778
  logFile: y.path
2540
- }).catch(() => {}), await Ni(e, g);
2779
+ }).catch(() => {}), await ra(e, g);
2541
2780
  let { pages: b, dirs: x } = await $(p(e, "src", "pages")), S = {
2542
2781
  dirs: x,
2543
- ssrRoutes: yi(b)
2782
+ ssrRoutes: Ui(b)
2544
2783
  }, w = x.map((e) => ({
2545
2784
  dir: e.dir,
2546
2785
  hasLayout: e.hasLayout,
2547
2786
  hasError: e.hasError,
2548
2787
  hasPending: e.hasPending,
2549
2788
  hasNotFound: e.hasNotFound
2550
- })), E = await zt({
2789
+ })), E = await an({
2551
2790
  appRoot: e,
2552
2791
  pages: b
2553
2792
  });
2554
2793
  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([
2794
+ let D = await Xe("vite", () => import("vite")), k = (await import("@vitejs/plugin-react")).default, A = (await import("@tailwindcss/vite")).default, j = p(e, ".framework"), M = p(e, "src"), ee = /* @__PURE__ */ new Set([
2556
2795
  ".framework",
2557
2796
  "node_modules",
2558
2797
  "dist",
@@ -2560,15 +2799,15 @@ import {
2560
2799
  ".vite",
2561
2800
  ".turbo",
2562
2801
  ".cache"
2563
- ]), re = {
2802
+ ]), te = {
2564
2803
  name: "framework:watch-app-sources",
2565
2804
  async configureServer(t) {
2566
2805
  try {
2567
- let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !ne.has(e.name));
2806
+ let n = (await O.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !ee.has(e.name));
2568
2807
  for (let r of n) t.watcher.add(p(e, r.name));
2569
- n.length === 0 && t.watcher.add(A);
2808
+ n.length === 0 && t.watcher.add(M);
2570
2809
  } catch {
2571
- t.watcher.add(A);
2810
+ t.watcher.add(M);
2572
2811
  }
2573
2812
  try {
2574
2813
  let n = await O.readFile(p(e, "package.json"), "utf8"), r = JSON.parse(n), i = Object.keys({
@@ -2576,7 +2815,7 @@ import {
2576
2815
  ...r.devDependencies
2577
2816
  });
2578
2817
  await Promise.all(i.map(async (n) => {
2579
- let r = await xi(e, n);
2818
+ let r = await Gi(e, n);
2580
2819
  if (!r) return;
2581
2820
  let i = p(r, "src");
2582
2821
  try {
@@ -2585,15 +2824,15 @@ import {
2585
2824
  }));
2586
2825
  } catch {}
2587
2826
  }
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) => {
2827
+ }, N = p(e, "src", "pages"), P = (e) => e.endsWith(".tsx") && (e === N || e.startsWith(N + "/")), ne = (e) => e === N || e.startsWith(N + "/"), F = async (n) => {
2589
2828
  try {
2590
2829
  let i = Date.now();
2591
- await Mi(e, t, r, f);
2592
- let { pages: a, dirs: o } = await $(j);
2593
- await zt({
2830
+ await na(e, t, r, f);
2831
+ let { pages: a, dirs: o } = await $(N);
2832
+ await an({
2594
2833
  appRoot: e,
2595
2834
  pages: a
2596
- }), S.dirs = o, S.ssrRoutes = yi(a), Z.info("page tree regenerated", {
2835
+ }), S.dirs = o, S.ssrRoutes = Ui(a), Z.info("page tree regenerated", {
2597
2836
  reason: n,
2598
2837
  ms: Date.now() - i,
2599
2838
  routes: S.ssrRoutes.length
@@ -2601,44 +2840,44 @@ import {
2601
2840
  } catch (e) {
2602
2841
  Z.error("page tree regen failed", { reason: n }, e);
2603
2842
  }
2604
- }, P = {
2843
+ }, I = {
2605
2844
  name: "framework:regenerate-on-page-tree-change",
2606
2845
  configureServer(t) {
2607
2846
  let n = null, r = [], i = (e) => {
2608
2847
  r.push(e), n && clearTimeout(n), n = setTimeout(() => {
2609
2848
  n = null;
2610
2849
  let e = r.length === 1 ? r[0] : `${r.length} events (${r[0]}, …)`;
2611
- r.length = 0, N(e);
2850
+ r.length = 0, F(e);
2612
2851
  }, 50);
2613
2852
  };
2614
2853
  t.watcher.on("add", (t) => {
2615
- M(t) && i(`add ${m(e, t)}`);
2854
+ P(t) && i(`add ${m(e, t)}`);
2616
2855
  }), t.watcher.on("unlink", (t) => {
2617
- M(t) && i(`unlink ${m(e, t)}`);
2856
+ P(t) && i(`unlink ${m(e, t)}`);
2618
2857
  }), t.watcher.on("addDir", (t) => {
2619
- ie(t) && i(`addDir ${m(e, t)}`);
2858
+ ne(t) && i(`addDir ${m(e, t)}`);
2620
2859
  }), t.watcher.on("unlinkDir", (t) => {
2621
- ie(t) && i(`unlinkDir ${m(e, t)}`);
2860
+ ne(t) && i(`unlinkDir ${m(e, t)}`);
2622
2861
  });
2623
2862
  }
2624
- }, F = p(e, "app.config.ts"), ae = (e) => {
2625
- if (!z(e.env)) return "";
2863
+ }, L = p(e, "app.config.ts"), re = (e) => {
2864
+ if (!V(e.env)) return "";
2626
2865
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2627
2866
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2628
- }, I = (e, t) => {
2867
+ }, R = (e, t) => {
2629
2868
  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 = {
2869
+ 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"), re(e) !== re(t) && n.push("env"), n;
2870
+ }, z = t, B = h(L), ie = {
2632
2871
  name: "framework:watch-app-config",
2633
2872
  async configureServer(t) {
2634
- t.watcher.add(F), Z.info("watching app.config.ts for changes", { path: m(e, F) });
2873
+ t.watcher.add(L), Z.info("watching app.config.ts for changes", { path: m(e, L) });
2635
2874
  let n = async () => {
2636
2875
  try {
2637
2876
  try {
2638
- let e = t.moduleGraph.getModuleById(F);
2877
+ let e = t.moduleGraph.getModuleById(L);
2639
2878
  e && t.moduleGraph.invalidateModule(e);
2640
2879
  } catch {}
2641
- let e = (await t.ssrLoadModule(F, { fixStacktrace: !0 })).default;
2880
+ let e = (await t.ssrLoadModule(L, { fixStacktrace: !0 })).default;
2642
2881
  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
2882
  } catch (e) {
2644
2883
  return Z.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
@@ -2657,17 +2896,17 @@ import {
2657
2896
  theme: r.theme,
2658
2897
  port: r.port,
2659
2898
  name: r.name
2660
- }), JSON.stringify(r) === JSON.stringify(L)) {
2899
+ }), JSON.stringify(r) === JSON.stringify(z)) {
2661
2900
  Z.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2662
2901
  return;
2663
2902
  }
2664
- let i = I(L, r);
2903
+ let i = R(z, r);
2665
2904
  if (i.length > 0) {
2666
2905
  Z.warn("app.config.ts changed — hard restart required", { fields: i });
2667
2906
  try {
2668
2907
  await t.close();
2669
2908
  } catch {}
2670
- let e = pe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2909
+ let e = fe(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2671
2910
  stdio: "inherit",
2672
2911
  env: process.env,
2673
2912
  cwd: process.cwd()
@@ -2683,7 +2922,7 @@ import {
2683
2922
  }
2684
2923
  try {
2685
2924
  let n = Date.now();
2686
- await Mi(e, r, await Ei(e, r)), L = r, t.ws && t.ws.send({
2925
+ await na(e, r, await Xi(e, r)), z = r, t.ws && t.ws.send({
2687
2926
  type: "full-reload",
2688
2927
  path: "*"
2689
2928
  }), Z.info("app.config.ts soft-regen", {
@@ -2693,7 +2932,7 @@ import {
2693
2932
  } catch (e) {
2694
2933
  Z.error("app.config.ts soft-regen failed", {}, e);
2695
2934
  }
2696
- }, o = (e) => u(e) === "app.config.ts" ? e === F || h(e) === R : !1;
2935
+ }, o = (e) => u(e) === "app.config.ts" ? e === L || h(e) === B : !1;
2697
2936
  t.watcher.on("change", (e) => {
2698
2937
  o(e) && (Z.info("app.config.ts change event (chokidar)", { file: e }), i());
2699
2938
  }), t.watcher.on("add", (e) => {
@@ -2701,7 +2940,7 @@ import {
2701
2940
  });
2702
2941
  try {
2703
2942
  let { watchFile: e } = await import("node:fs");
2704
- e(F, { interval: 500 }, (e, t) => {
2943
+ e(L, { interval: 500 }, (e, t) => {
2705
2944
  e.mtimeMs !== t.mtimeMs && (Z.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), i());
2706
2945
  }), Z.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2707
2946
  } catch (e) {
@@ -2712,18 +2951,18 @@ import {
2712
2951
  onBeforeRestart: () => t.close()
2713
2952
  });
2714
2953
  }
2715
- }, se = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, B = 0, ce = {
2954
+ }, ae = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, oe = 0, se = {
2716
2955
  name: "framework:suppress-api-hmr",
2717
2956
  handleHotUpdate(e) {
2718
- if (B += 1, se.test(e.file)) return [];
2957
+ if (oe += 1, ae.test(e.file)) return [];
2719
2958
  }
2720
- }, le = {
2959
+ }, ce = {
2721
2960
  name: "framework:reoptimize-on-rpcgroup-change",
2722
2961
  async configureServer(t) {
2723
2962
  let n = /* @__PURE__ */ new Map();
2724
2963
  for (let i of r) {
2725
2964
  if (!i.proxyTarget) continue;
2726
- let r = await xi(e, i.pkg);
2965
+ let r = await Gi(e, i.pkg);
2727
2966
  if (!r) continue;
2728
2967
  let a = p(r, "rpcGroup.generated.ts");
2729
2968
  try {
@@ -2751,7 +2990,7 @@ import {
2751
2990
  if (r !== null) {
2752
2991
  a = !0, Z.info(`rpcGroup changed (${m(e, r)}) — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)`);
2753
2992
  try {
2754
- await O.rm(p(k, ".vite", "deps"), {
2993
+ await O.rm(p(j, ".vite", "deps"), {
2755
2994
  recursive: !0,
2756
2995
  force: !0
2757
2996
  }), await t.restart(!0);
@@ -2766,9 +3005,9 @@ import {
2766
3005
  };
2767
3006
  t.watcher.on("change", s), t.watcher.on("add", s);
2768
3007
  }
2769
- }, V = {}, ue = (e) => (t) => {
3008
+ }, H = {}, le = (e) => (t) => {
2770
3009
  t.on("proxyReq", (t, n) => {
2771
- jn(t, n, {
3010
+ Xn(t, n, {
2772
3011
  target: e,
2773
3012
  token: process.env.VOLTRO_INSPECT_TOKEN,
2774
3013
  writeToken: process.env.VOLTRO_INSPECT_WRITE_TOKEN,
@@ -2778,26 +3017,26 @@ import {
2778
3017
  };
2779
3018
  for (let e of r) {
2780
3019
  if (!e.proxyTarget) continue;
2781
- V[e.browserWsUrl] = {
3020
+ H[e.browserWsUrl] = {
2782
3021
  target: e.proxyTarget,
2783
3022
  ws: !0,
2784
3023
  changeOrigin: !0,
2785
3024
  ...e.wsPath ? {} : { rewrite: () => "/ws" }
2786
3025
  };
2787
3026
  let t = e.proxyTarget.replace(/^ws/, "http");
2788
- V[`/_voltro/api/${e.name}`] = {
3027
+ H[`/_voltro/api/${e.name}`] = {
2789
3028
  target: t,
2790
3029
  changeOrigin: !0,
2791
3030
  rewrite: (t) => t.replace(RegExp(`^/_voltro/api/${e.name}`), ""),
2792
- configure: ue(t)
3031
+ configure: le(t)
2793
3032
  };
2794
3033
  }
2795
3034
  for (let [e, n] of Object.entries(t.proxies ?? {})) {
2796
- if (V[e]) {
3035
+ if (H[e]) {
2797
3036
  Z.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
2798
3037
  continue;
2799
3038
  }
2800
- V[e] = {
3039
+ H[e] = {
2801
3040
  target: n.target,
2802
3041
  changeOrigin: n.changeOrigin ?? !0,
2803
3042
  ...n.rewrite === void 0 ? {} : { rewrite: (t) => t.replace(RegExp(`^${e}`), n.rewrite) }
@@ -2807,7 +3046,7 @@ import {
2807
3046
  ...n.rewrite === void 0 ? {} : { rewrite: n.rewrite }
2808
3047
  });
2809
3048
  }
2810
- let de = {
3049
+ let ue = {
2811
3050
  name: "framework:inspect",
2812
3051
  configureServer(r) {
2813
3052
  let u = null, d = async () => {
@@ -2819,7 +3058,7 @@ import {
2819
3058
  pattern: n.pattern,
2820
3059
  file: n.file,
2821
3060
  dirChain: n.dirChain,
2822
- renderMode: Qn(i, p("src", "pages", n.file)),
3061
+ renderMode: _r(i, p("src", "pages", n.file)),
2823
3062
  interactive: i.interactive ?? "full",
2824
3063
  tenantAware: i.tenantAware === !0,
2825
3064
  revalidateMs: ct(i.revalidate),
@@ -2850,9 +3089,9 @@ import {
2850
3089
  }), r();
2851
3090
  }), r.middlewares.use((t, n, r) => {
2852
3091
  if (t.method !== "GET" && t.method !== "HEAD") return r();
2853
- let { pathname: i } = Ir(t.url ?? "/");
3092
+ let { pathname: i } = ti(t.url ?? "/");
2854
3093
  if (i !== "/robots.txt" || T(p(e, "public", "robots.txt"))) return r();
2855
- n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(Gt({ indexable: !1 }));
3094
+ n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(dn({ indexable: !1 }));
2856
3095
  }), t.name === "voltroDashboard" && r.middlewares.use(async (e, t, n) => {
2857
3096
  let r = e.url ?? "", a = r.split("?")[0];
2858
3097
  if (a === "/api/dashboard/proxy") {
@@ -2943,7 +3182,7 @@ import {
2943
3182
  for (let [t, n] of Object.entries(e.headers ?? {})) n !== void 0 && (u[String(t).toLowerCase()] = Array.isArray(n) ? n.join(", ") : String(n));
2944
3183
  let f = o.split("?")[0];
2945
3184
  if (e.method === "GET" && (f === "/_voltro/inspect/logs" || o.startsWith("/_voltro/inspect/logs?"))) {
2946
- let e = a(u.origin), t = Tn(o, sn(), u);
3185
+ let e = a(u.origin), t = Wn(o, En(), u);
2947
3186
  r.statusCode = t.status, r.setHeader("content-type", t.contentType);
2948
3187
  for (let [t, n] of Object.entries(e)) r.setHeader(t, n);
2949
3188
  r.end(t.body);
@@ -2961,7 +3200,7 @@ import {
2961
3200
  e.setEncoding("utf-8"), e.on("data", (e) => {
2962
3201
  i += e;
2963
3202
  }), e.on("end", () => {
2964
- let e = yn(i, n);
3203
+ let e = Rn(i, n);
2965
3204
  r.statusCode = e.status, r.setHeader("content-type", e.contentType);
2966
3205
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2967
3206
  r.end(e.body);
@@ -2992,14 +3231,14 @@ import {
2992
3231
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2993
3232
  r.flushHeaders?.(), r.write("retry: 5000\n\n");
2994
3233
  let l = o.indexOf("?");
2995
- if (!(l !== -1 && new URLSearchParams(o.slice(l + 1)).get("live") === "1")) for (let e of n.buffered()) r.write(Jt(e));
3234
+ if (!(l !== -1 && new URLSearchParams(o.slice(l + 1)).get("live") === "1")) for (let e of n.buffered()) r.write(mn(e));
2996
3235
  let d = n.subscribe((e) => {
2997
3236
  try {
2998
- r.write(Jt(e));
3237
+ r.write(mn(e));
2999
3238
  } catch {}
3000
3239
  }), f = setInterval(() => {
3001
3240
  try {
3002
- r.write(Yt());
3241
+ r.write(hn());
3003
3242
  } catch {}
3004
3243
  }, 15e3), p = () => {
3005
3244
  clearInterval(f), d();
@@ -3012,7 +3251,7 @@ import {
3012
3251
  kind: "web",
3013
3252
  meta: {
3014
3253
  name: t.name ?? "(unnamed)",
3015
- voltroVersion: $r,
3254
+ voltroVersion: Ci,
3016
3255
  port: g,
3017
3256
  mode: "dev",
3018
3257
  apis: Object.entries(t.apis ?? {}).map(([e, t]) => {
@@ -3030,7 +3269,7 @@ import {
3030
3269
  size: 0,
3031
3270
  entries: []
3032
3271
  }),
3033
- env: () => at(t.name ?? "app", { contract: z(t.env) ? t.env : void 0 })
3272
+ env: () => at(t.name ?? "app", { contract: V(t.env) ? t.env : void 0 })
3034
3273
  }, u, { method: e.method ?? "GET" });
3035
3274
  if (n === null) return i();
3036
3275
  r.statusCode = n.status, r.setHeader("content-type", n.contentType);
@@ -3041,7 +3280,7 @@ import {
3041
3280
  }
3042
3281
  });
3043
3282
  }
3044
- }, me = t.name === "voltroDashboard" ? {
3283
+ }, pe = t.name === "voltroDashboard" ? {
3045
3284
  name: "framework:dashboard-registry",
3046
3285
  configureServer(e) {
3047
3286
  e.middlewares.use(async (e, t, n) => {
@@ -3054,12 +3293,12 @@ import {
3054
3293
  }
3055
3294
  });
3056
3295
  }
3057
- } : null, he = /* @__PURE__ */ new Set(), H = (e, t, n, r, i, a = !1) => {
3058
- let o = zr(i, a, t) ?? "";
3296
+ } : null, me = /* @__PURE__ */ new Set(), he = (e, t, n, r, i, a = !1) => {
3297
+ let o = ci(i, a, t) ?? "";
3059
3298
  if (Z.error(`${t} render failed`, {
3060
3299
  pathname: n,
3061
3300
  pattern: r,
3062
- cause: Zt(i) + o
3301
+ cause: _n(i) + o
3063
3302
  }), e.headersSent) {
3064
3303
  e.end();
3065
3304
  return;
@@ -3067,11 +3306,11 @@ import {
3067
3306
  e.writeHead(500, {
3068
3307
  "content-type": "text/plain; charset=utf-8",
3069
3308
  "x-voltro-rendered-by": `${t}-failed`,
3070
- "x-voltro-ssr-generation": String(B)
3309
+ "x-voltro-ssr-generation": String(oe)
3071
3310
  });
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`;
3073
- e.end(`${t} render failed for ${n}\n\n${Zt(i)}\n${o}\n${s}`);
3074
- }, U = Dt(), ge = kt({
3311
+ let s = oe === 0 ? "" : `\n[voltro] this process has absorbed ${oe} 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`;
3312
+ e.end(`${t} render failed for ${n}\n\n${_n(i)}\n${o}\n${s}`);
3313
+ }, U = Kt(), ge = Jt({
3075
3314
  limit: U,
3076
3315
  onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
3077
3316
  onColdEnd: (e, { durationMs: t, failed: n }) => Z.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
@@ -3106,11 +3345,11 @@ import {
3106
3345
  if (a.method !== "GET" && a.method !== "HEAD") return c();
3107
3346
  let l = a.url ?? "/";
3108
3347
  l.indexOf("?");
3109
- let { pathname: u, search: d } = Ir(l);
3348
+ let { pathname: u, search: d } = ti(l);
3110
3349
  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);
3350
+ let f = Wi(u, S.ssrRoutes);
3112
3351
  if (!f) return c();
3113
- let m = !he.has(f.route.pattern), h = Date.now();
3352
+ let m = !me.has(f.route.pattern), h = Date.now();
3114
3353
  m && Z.info(`ssr compiling ${f.route.pattern}`, {
3115
3354
  pattern: f.route.pattern,
3116
3355
  pathname: u
@@ -3130,15 +3369,15 @@ import {
3130
3369
  }
3131
3370
  }, y = !1;
3132
3371
  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);
3372
+ let b = await _("loadPage", async () => await i(p(e, "src", "pages", f.route.file))), x = _r(b, p("src", "pages", f.route.file)), C = Ri(S.dirs, f.route.dirChain), w = x === "spa" && C.some((e) => e.hasLayout);
3134
3373
  if (x !== "ssr" && x !== "isr" && !w) return c();
3135
3374
  let T = {};
3136
3375
  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();
3376
+ let E = ta(ea(r[0], { allowDevProxy: !0 }), T.cookie, { apiName: r[0]?.name }), D = new AbortController(), O = () => D.abort();
3138
3377
  s.once("close", O);
3139
- let ee = null, te = [], k = {};
3378
+ let k = null, A = [], j = {};
3140
3379
  try {
3141
- (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: te, segmentLoaderData: k} = await _("loadChain", () => hi({
3380
+ (await i("@voltro/web/ssr")).beginStoreSeeds(), {chain: A, segmentLoaderData: j} = await _("loadChain", () => zi({
3142
3381
  entries: C,
3143
3382
  loadLayout: (t) => i(p(e, "src", "pages", t.dir, "layout.tsx")),
3144
3383
  loadError: (t) => i(p(e, "src", "pages", t.dir, "error.tsx")),
@@ -3153,7 +3392,7 @@ import {
3153
3392
  }
3154
3393
  }));
3155
3394
  let t = b.loader;
3156
- typeof t == "function" && !w && (ee = await _("loader", () => t({
3395
+ typeof t == "function" && !w && (k = await _("loader", () => t({
3157
3396
  params: f.params,
3158
3397
  pathname: u,
3159
3398
  search: d,
@@ -3164,20 +3403,20 @@ import {
3164
3403
  } finally {
3165
3404
  s.off("close", O);
3166
3405
  }
3167
- let A = await _("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3168
- w || await Zr({
3406
+ let M = await _("loadSsrHelpers", async () => await i("@voltro/web/ssr"));
3407
+ w || await xi({
3169
3408
  pageMod: b,
3170
3409
  params: f.params,
3171
3410
  query: E,
3172
3411
  apiName: r[0]?.name,
3173
- seed: A.seedPreloadedSubscription,
3412
+ seed: M.seedPreloadedSubscription,
3174
3413
  onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
3175
3414
  tag: e,
3176
3415
  apiName: t,
3177
3416
  pathname: u
3178
3417
  }, n)
3179
3418
  });
3180
- let ne = {
3419
+ let ee = {
3181
3420
  pattern: f.route.pattern,
3182
3421
  Component: b.default,
3183
3422
  meta: b.meta,
@@ -3185,40 +3424,40 @@ import {
3185
3424
  ErrorBoundary: b.ErrorBoundary,
3186
3425
  Pending: b.Pending,
3187
3426
  renderMode: x,
3188
- chain: te
3189
- }, re = {
3190
- cookies: A.parseCookieHeader(T.cookie),
3427
+ chain: A
3428
+ }, te = {
3429
+ cookies: M.parseCookieHeader(T.cookie),
3191
3430
  headers: T,
3192
3431
  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,
3432
+ }, N = b.interactive ?? "full", P = (await o())(T.cookie, T["accept-language"]);
3433
+ y = P !== void 0;
3434
+ let ne = P ? {
3435
+ outerWrap: P.outerWrap,
3436
+ locale: P.locale
3437
+ } : {}, F = w ? Qr({
3438
+ helpers: M,
3200
3439
  page: `src/pages/${f.route.file}`,
3201
- interactive: j,
3440
+ interactive: N,
3202
3441
  delivery: "stream",
3203
3442
  renderInput: {
3204
- descriptor: ne,
3443
+ descriptor: ee,
3205
3444
  params: f.params,
3206
3445
  pathname: u,
3207
3446
  search: d,
3208
- segmentLoaderData: k,
3209
- requestContext: re,
3210
- ...ie
3447
+ segmentLoaderData: j,
3448
+ requestContext: te,
3449
+ ...ne
3211
3450
  }
3212
- }) : null, P = w ? null : Mr({
3213
- helpers: A,
3451
+ }) : null, I = w ? null : Zr({
3452
+ helpers: M,
3214
3453
  page: `src/pages/${f.route.file}`,
3215
3454
  pathname: u,
3216
3455
  renderMode: x,
3217
- interactive: j,
3218
- loaderData: ee,
3219
- segmentLoaderData: k,
3456
+ interactive: N,
3457
+ loaderData: k,
3458
+ segmentLoaderData: j,
3220
3459
  pageLoaderRan: typeof b.loader == "function"
3221
- }), F = [];
3460
+ }), L = [];
3222
3461
  await _("collectCss", async () => {
3223
3462
  let t = /* @__PURE__ */ new Set(), n = [
3224
3463
  p(e, "src", "pages", f.route.file),
@@ -3229,131 +3468,131 @@ import {
3229
3468
  ]),
3230
3469
  p(e, ".framework", "main.tsx")
3231
3470
  ];
3232
- for (let e of n) await v(e, t, F);
3471
+ for (let e of n) await v(e, t, L);
3233
3472
  });
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) {
3236
- let e = (e) => Fr({
3237
- helpers: A,
3238
- prepared: N,
3473
+ let re = await _("readShell", _e), R = await _("transformShell", () => n.transformIndexHtml(l, re)), z = L.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), B = P?.locale ?? te.cookies["voltro:locale"] ?? t.defaultLocale ?? (t.locales ?? [])[0] ?? "en", ie = Date.now();
3474
+ if (F) {
3475
+ let e = (e) => ei({
3476
+ helpers: M,
3477
+ prepared: F,
3239
3478
  meta: e,
3240
- interactive: j,
3241
- extra: [L]
3479
+ interactive: N,
3480
+ extra: [z]
3242
3481
  });
3243
- if (N.hasDeferred) Jr({
3482
+ if (F.hasDeferred) vi({
3244
3483
  res: s,
3245
- shell: Kr({
3246
- shell: I,
3484
+ shell: hi({
3485
+ shell: R,
3247
3486
  inlineModuleScriptsAsync: !0
3248
3487
  }),
3249
- htmlLang: R,
3488
+ htmlLang: B,
3250
3489
  headers: {
3251
3490
  "content-type": "text/html; charset=utf-8",
3252
3491
  "x-voltro-rendered-by": "spa-shell-dev"
3253
3492
  },
3254
3493
  headInjection: e,
3255
- render: (e) => A.renderPageToStream({
3256
- ...N.renderInput,
3494
+ render: (e) => M.renderPageToStream({
3495
+ ...F.renderInput,
3257
3496
  ...e
3258
3497
  }),
3259
3498
  onShellError: (e) => {
3260
- H(s, "spa-shell-dev", u, f.route.pattern, e, y);
3499
+ he(s, "spa-shell-dev", u, f.route.pattern, e, y);
3261
3500
  }
3262
3501
  });
3263
3502
  else {
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}"`);
3503
+ let t = $r({
3504
+ helpers: M,
3505
+ prepared: F
3506
+ }), n = R.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="${B}"`);
3268
3507
  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
3508
  }
3270
- } else if (P) {
3509
+ } else if (I) {
3271
3510
  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)
3511
+ z,
3512
+ M.renderMetaToHtml(e),
3513
+ `<meta name="voltro-interactive" content="${N}" />`,
3514
+ ...I.hasDeferred ? [M.renderDeferredRegistryScript()] : [],
3515
+ M.renderRouterStateScript(I.stateInput)
3277
3516
  ].filter((e) => e.length > 0).join("\n "), t = {
3278
- descriptor: ne,
3517
+ descriptor: ee,
3279
3518
  params: f.params,
3280
3519
  pathname: u,
3281
3520
  search: d,
3282
- loaderData: P.loaderData,
3283
- segmentLoaderData: P.segmentLoaderData,
3284
- requestContext: re,
3285
- ...ie
3521
+ loaderData: I.loaderData,
3522
+ segmentLoaderData: I.segmentLoaderData,
3523
+ requestContext: te,
3524
+ ...ne
3286
3525
  };
3287
- if (x === "ssr" && j === "full") Jr({
3526
+ if (x === "ssr" && N === "full") vi({
3288
3527
  res: s,
3289
- shell: Kr({
3290
- shell: I,
3528
+ shell: hi({
3529
+ shell: R,
3291
3530
  inlineModuleScriptsAsync: !0
3292
3531
  }),
3293
- htmlLang: R,
3532
+ htmlLang: B,
3294
3533
  headers: {
3295
3534
  "content-type": "text/html; charset=utf-8",
3296
3535
  "x-voltro-rendered-by": "ssr-dev"
3297
3536
  },
3298
3537
  headInjection: e,
3299
- render: (e) => A.renderPageToStream({
3538
+ render: (e) => M.renderPageToStream({
3300
3539
  ...t,
3301
3540
  ...e
3302
3541
  }),
3303
3542
  onShellError: (e) => {
3304
- H(s, "ssr-dev", u, f.route.pattern, e, y);
3543
+ he(s, "ssr-dev", u, f.route.pattern, e, y);
3305
3544
  }
3306
3545
  });
3307
3546
  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}"`);
3547
+ let { html: n, meta: r } = M.renderPageToHtml(t), i = R.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${B}"`);
3309
3548
  s.statusCode = 200, s.setHeader("content-type", "text/html; charset=utf-8"), s.setHeader("x-voltro-rendered-by", "ssr-dev"), s.end(i);
3310
3549
  }
3311
3550
  }
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`, {
3551
+ g.render = Date.now() - ie;
3552
+ let V = Date.now() - h;
3553
+ m ? (me.add(f.route.pattern), Z.info(`ssr compiled ${f.route.pattern} in ${V}ms`, {
3315
3554
  pattern: f.route.pattern,
3316
3555
  pathname: u,
3317
- elapsedMs: z,
3556
+ elapsedMs: V,
3318
3557
  cold: !0,
3319
3558
  phases: g
3320
- })) : z > 200 && Z.info(`ssr rendered ${u} in ${z}ms`, {
3559
+ })) : V > 200 && Z.info(`ssr rendered ${u} in ${V}ms`, {
3321
3560
  pattern: f.route.pattern,
3322
3561
  pathname: u,
3323
- elapsedMs: z,
3562
+ elapsedMs: V,
3324
3563
  cold: !1,
3325
3564
  phases: g
3326
3565
  });
3327
3566
  } catch (e) {
3328
- if (Ar(e)) {
3567
+ if (Yr(e)) {
3329
3568
  Z.error("ssr-dev render refused", {
3330
3569
  pathname: u,
3331
3570
  pattern: f.route.pattern
3332
3571
  }, e), s.statusCode = 500, s.setHeader("content-type", "text/plain; charset=utf-8"), s.end(e.message);
3333
3572
  return;
3334
3573
  }
3335
- let t = jr(e);
3574
+ let t = Xr(e);
3336
3575
  if (t) {
3337
3576
  s.statusCode = t.status;
3338
3577
  for (let [e, n] of Object.entries(t.headers)) s.setHeader(e, String(n));
3339
3578
  s.end(t.body);
3340
3579
  return;
3341
3580
  }
3342
- H(s, "ssr-dev", u, f.route.pattern, e, y);
3581
+ he(s, "ssr-dev", u, f.route.pattern, e, y);
3343
3582
  }
3344
3583
  });
3345
3584
  }
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 () => {
3585
+ }, G = Date.now(), K = D.version ?? "?", q = await wi(), ye = p(e, "node_modules", "@voltro", "ui-shadcn"), J = T(p(ye, "package.json")) ? ye : null, be = [], xe = await (async () => {
3347
3586
  let t = [];
3348
3587
  for (let n of r) {
3349
3588
  if (!n.proxyTarget) continue;
3350
- let r = await xi(e, n.pkg);
3589
+ let r = await Gi(e, n.pkg);
3351
3590
  if (r) try {
3352
3591
  t.push(await O.readFile(p(r, "rpcGroup.generated.ts"), "utf8"));
3353
3592
  } catch {}
3354
3593
  }
3355
3594
  if (t.length === 0) return !1;
3356
- let n = fe("sha1").update(t.join("\0")).digest("hex"), i = p(k, ".voltro-rpcgroup-optimize"), a = "";
3595
+ let n = de("sha1").update(t.join("\0")).digest("hex"), i = p(j, ".voltro-rpcgroup-optimize"), a = "";
3357
3596
  try {
3358
3597
  a = (await O.readFile(i, "utf8")).trim();
3359
3598
  } catch {}
@@ -3363,15 +3602,22 @@ import {
3363
3602
  } catch {}
3364
3603
  return !0;
3365
3604
  })();
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,
3605
+ xe && Z.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client");
3606
+ try {
3607
+ await wt(g, "voltro dev (web)");
3608
+ } catch (e) {
3609
+ Z.error(String(e.message ?? e)), process.exit(1);
3610
+ }
3611
+ await (await D.createServer({
3612
+ root: j,
3368
3613
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3369
- ssr: { noExternal: ["react-intl"] },
3614
+ ssr: { noExternal: ["react-intl", "@voltro/i18n"] },
3370
3615
  resolve: {
3371
3616
  dedupe: [
3372
3617
  "react",
3373
3618
  "react-dom",
3374
- "react-intl"
3619
+ "react-intl",
3620
+ "@voltro/i18n"
3375
3621
  ],
3376
3622
  alias: [
3377
3623
  ...q ? [{
@@ -3406,32 +3652,32 @@ import {
3406
3652
  include: [...r.map((e) => `${e.pkg}/rpcGroup`), ...be],
3407
3653
  force: xe
3408
3654
  },
3409
- customLogger: Et(),
3655
+ customLogger: Gt(),
3410
3656
  plugins: [
3411
- Kn(p(e, "src", "pages")),
3412
- ee(),
3413
- te(),
3414
- re,
3415
- P,
3416
- oe,
3657
+ dr(p(e, "src", "pages")),
3658
+ k(),
3659
+ A(),
3660
+ te,
3661
+ I,
3662
+ ie,
3663
+ se,
3417
3664
  ce,
3418
- le,
3419
- de,
3665
+ ue,
3420
3666
  ve,
3421
- ...me ? [me] : []
3667
+ ...pe ? [pe] : []
3422
3668
  ],
3423
3669
  server: {
3424
3670
  port: g,
3425
3671
  strictPort: !0,
3426
3672
  host: !0,
3427
3673
  allowedHosts: t.allowedHosts === !0 || [...t.allowedHosts ?? []],
3428
- proxy: V,
3429
- fs: { allow: [e, ...oi(e)] }
3674
+ proxy: H,
3675
+ fs: { allow: [e, ...Ai(e)] }
3430
3676
  },
3431
3677
  appType: "spa",
3432
- cacheDir: p(k, ".vite"),
3678
+ cacheDir: p(j, ".vite"),
3433
3679
  publicDir: p(e, "public")
3434
- })).listen(), Qr.info(`v${K} ready in ${Date.now() - G}ms`, {
3680
+ })).listen(), Si.info(`v${K} ready in ${Date.now() - G}ms`, {
3435
3681
  version: K,
3436
3682
  bootMs: Date.now() - G
3437
3683
  }), Z.info(`listening on http://localhost:${g}`, {
@@ -3452,9 +3698,9 @@ import {
3452
3698
  status: "live",
3453
3699
  logFile: y.path
3454
3700
  });
3455
- let t = vr(e);
3701
+ let t = Lr(e);
3456
3702
  if (t) {
3457
- let e = await Or({ dashboardAppPath: t });
3703
+ let e = await qr({ dashboardAppPath: t });
3458
3704
  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 });
3459
3705
  }
3460
3706
  setInterval(() => {
@@ -3481,24 +3727,24 @@ import {
3481
3727
  url: `http://localhost:${g}`,
3482
3728
  bootMs: Date.now() - G
3483
3729
  }), new Promise(() => {});
3484
- }, Li = async (e) => {
3730
+ }, sa = async (e) => {
3485
3731
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
3486
- let t = await Fi(e);
3732
+ let t = await aa(e);
3487
3733
  if (!t) return {
3488
3734
  ran: !1,
3489
3735
  exitCode: 0
3490
3736
  };
3491
3737
  let n = Date.now(), r = Z.child("serve");
3492
3738
  r.info("booting voltro serve (preview)", { app: t.name ?? "(unnamed)" });
3493
- let i = await Ei(e, t);
3739
+ let i = await Xi(e, t);
3494
3740
  for (let e of i) r.info("api wired", {
3495
3741
  name: e.name,
3496
3742
  pkg: e.pkg
3497
3743
  });
3498
- await Mi(e, t, i);
3744
+ await na(e, t, i);
3499
3745
  {
3500
3746
  let { pages: t } = await $(p(e, "src", "pages"));
3501
- await zt({
3747
+ await an({
3502
3748
  appRoot: e,
3503
3749
  pages: t
3504
3750
  });
@@ -3508,15 +3754,16 @@ import {
3508
3754
  root: c,
3509
3755
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3510
3756
  plugins: [s()],
3511
- customLogger: Et(),
3757
+ customLogger: Gt(),
3512
3758
  resolve: { dedupe: [
3513
3759
  "react",
3514
3760
  "react-dom",
3515
- "react-intl"
3761
+ "react-intl",
3762
+ "@voltro/i18n"
3516
3763
  ] },
3517
3764
  build: {
3518
3765
  outDir: "dist",
3519
- rollupOptions: { output: { manualChunks: ci } }
3766
+ rollupOptions: { output: { manualChunks: Mi } }
3520
3767
  },
3521
3768
  publicDir: p(e, "public")
3522
3769
  });
@@ -3536,14 +3783,14 @@ import {
3536
3783
  extras: d,
3537
3784
  bootMs: Date.now() - n
3538
3785
  }), new Promise(() => {});
3539
- }, Ri = 5e3, zi = 6e4, Bi = (e, t) => {
3786
+ }, ca = 5e3, la = 6e4, ua = (e, t) => {
3540
3787
  if (e.length === 0) return 0;
3541
3788
  if (e.length === 1) return e[0];
3542
3789
  let n = t * (e.length - 1), r = Math.floor(n), i = Math.ceil(n);
3543
3790
  if (r === i) return e[r];
3544
3791
  let a = n - r;
3545
3792
  return e[r] * (1 - a) + e[i] * a;
3546
- }, Vi = (e) => {
3793
+ }, da = (e) => {
3547
3794
  if (e.length === 0) return {
3548
3795
  p50: 0,
3549
3796
  p95: 0,
@@ -3555,18 +3802,18 @@ import {
3555
3802
  let t = e.slice().sort((e, t) => e - t), n = 0;
3556
3803
  for (let e of t) n += e;
3557
3804
  return {
3558
- p50: Bi(t, .5),
3559
- p95: Bi(t, .95),
3560
- p99: Bi(t, .99),
3805
+ p50: ua(t, .5),
3806
+ p95: ua(t, .95),
3807
+ p99: ua(t, .99),
3561
3808
  mean: n / t.length,
3562
3809
  min: t[0],
3563
3810
  max: t[t.length - 1]
3564
3811
  };
3565
- }, Hi = (e = {}) => {
3566
- let t = e.maxSamples ?? Ri, n = e.defaultWindowMs ?? zi, r = [];
3812
+ }, fa = (e = {}) => {
3813
+ let t = e.maxSamples ?? ca, n = e.defaultWindowMs ?? la, r = [];
3567
3814
  return {
3568
3815
  record(e) {
3569
- ie(e), r.push({
3816
+ ne(e), r.push({
3570
3817
  ...e,
3571
3818
  ts: Date.now()
3572
3819
  }), r.length > t && r.shift();
@@ -3592,7 +3839,7 @@ import {
3592
3839
  tag: e.tag,
3593
3840
  count: e.samples.length,
3594
3841
  errorCount: n,
3595
- latencyMs: Vi(t)
3842
+ latencyMs: da(t)
3596
3843
  });
3597
3844
  }
3598
3845
  return c.sort((e, t) => t.count - e.count), {
@@ -3605,4 +3852,4 @@ import {
3605
3852
  };
3606
3853
  };
3607
3854
  //#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 };
3855
+ export { Kt as $, Nr as A, Yn as B, ti as C, Ue as Ct, Lr as D, Ne as Dt, qr as E, Me as Et, pr as F, En as G, Bn as H, hr as I, hn as J, mn as K, _r as L, Sr as M, fr as N, jr as O, vr as P, Jt as Q, tr as R, ei as S, Ke as St, Ir as T, We as Tt, Rn as U, Wn as V, jn as W, un as X, dn as Y, an as Z, vi as _, rt as _t, zi as a, wt as at, Qr as b, Xe as bt, Xi as c, ht as ct, Mi as d, ut as dt, Mt as et, $ as f, dt as ft, hi as g, ot as gt, gi as h, at as ht, ta as i, It as it, br as j, Mr as k, oa as l, mt as lt, xi as m, ct as mt, Ni as n, Nt as nt, Ri as o, yt as ot, na as p, st as pt, pn as q, ea as r, Ft as rt, aa as s, _t as st, fa as t, Pt as tt, sa as u, lt as ut, Yr as v, tt as vt, Rr as w, Ge as wt, $r as x, Je as xt, Zr as y, et as yt, nr as z };