@voltro/cli 0.20.2 → 0.21.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 (64) hide show
  1. package/CHANGELOG.md +149 -0
  2. package/THIRD-PARTY-NOTICES.md +61 -61
  3. package/dist/{apiBuild-qZBEu59d.js → apiBuild-BHOtsQkp.js} +93 -80
  4. package/dist/apiBuild-K7M6Rt0U.js +2 -0
  5. package/dist/bin.js +41 -20
  6. package/dist/{commands-kYbfVoPO.js → commands-BZoimvvS.js} +2752 -2633
  7. package/dist/{dbCommand-BPp9R0Wc.js → dbCommand-CDBbZ-Ac.js} +27 -13
  8. package/dist/dbCommand-oADAj6ez.js +2 -0
  9. package/dist/dev-CZQ73Yoh.js +3 -0
  10. package/dist/{dev-OHLsAq4K.js → dev-DKb92NYX.js} +1537 -1527
  11. package/dist/index.js +1 -1
  12. package/dist/{inspectMetrics-DvPNXmGA.js → inspectMetrics-DMjWBQif.js} +576 -567
  13. package/dist/serveCommand-qHJCs0cX.js +1162 -0
  14. package/dist/serveEntry.js +2 -2
  15. package/dist/{start-CXQ7WL1W.js → start-B1x6Z60h.js} +389 -389
  16. package/dist/startEntry.js +2 -2
  17. package/package.json +27 -27
  18. package/templates/AGENTS.md +1 -1
  19. package/templates/agent-docs/_index.md +1 -1
  20. package/templates/agent-docs/cli.md +63 -0
  21. package/templates/agent-docs/database/migrations.md +33 -11
  22. package/templates/agent-docs/database/schema.md +7 -0
  23. package/templates/agent-docs/database/seedsdialects.md +3 -3
  24. package/templates/agent-docs/whats-new.md +136 -9
  25. package/templates/apps/api-ai/package.json +12 -12
  26. package/templates/apps/api-auth/package.json +13 -13
  27. package/templates/apps/api-backend/package.json +12 -12
  28. package/templates/apps/api-backend-deactivation/package.json +12 -12
  29. package/templates/apps/api-backend-mail/package.json +11 -11
  30. package/templates/apps/api-backend-mariadb/package.json +14 -14
  31. package/templates/apps/api-backend-storage/package.json +11 -11
  32. package/templates/apps/api-data-advanced/package.json +13 -13
  33. package/templates/apps/api-durable/package.json +13 -13
  34. package/templates/apps/api-feature-flags/package.json +14 -14
  35. package/templates/apps/api-governance/package.json +13 -13
  36. package/templates/apps/api-kv/package.json +13 -13
  37. package/templates/apps/api-moderation/package.json +13 -13
  38. package/templates/apps/api-observability/package.json +13 -13
  39. package/templates/apps/api-ratelimit/package.json +13 -13
  40. package/templates/apps/api-rbac/package.json +13 -13
  41. package/templates/apps/api-rest/package.json +12 -12
  42. package/templates/apps/api-saas/package.json +16 -16
  43. package/templates/apps/api-search/package.json +13 -13
  44. package/templates/apps/api-versioning/package.json +13 -13
  45. package/templates/apps/api-webhooks/package.json +14 -14
  46. package/templates/apps/changelog/package.json +8 -8
  47. package/templates/apps/edge-functions/package.json +5 -5
  48. package/templates/apps/frontend-admin/package.json +10 -10
  49. package/templates/apps/frontend-app/package.json +10 -10
  50. package/templates/apps/frontend-blank/package.json +9 -9
  51. package/templates/apps/frontend-contact/package.json +11 -11
  52. package/templates/apps/frontend-dashboard/package.json +9 -9
  53. package/templates/apps/frontend-docs/package.json +9 -9
  54. package/templates/apps/frontend-i18n/package.json +8 -8
  55. package/templates/apps/frontend-landing/package.json +9 -9
  56. package/templates/apps/frontend-spa/package.json +9 -9
  57. package/templates/apps/frontend-ssr/package.json +9 -9
  58. package/templates/apps/frontend-ssr-api/package.json +10 -10
  59. package/templates/apps/frontend-static-blog/package.json +8 -8
  60. package/dist/apiBuild-C9aHz4Yh.js +0 -2
  61. package/dist/dbCommand-DtUe-0dM.js +0 -2
  62. package/dist/dev-2AvdzDg2.js +0 -3
  63. package/dist/serveCommand-BKqTKWTX.js +0 -1136
  64. /package/templates/patches/{@effect__cluster@0.59.0.patch → @effect__cluster@0.60.0.patch} +0 -0
@@ -6,13 +6,13 @@ import { FileSystem as _ } from "@effect/platform";
6
6
  import { NodeContext as v, NodeRuntime as y } from "@effect/platform-node";
7
7
  import { Cause as b, Effect as x, Layer as S } from "effect";
8
8
  import { LoggerLayer as C, addSink as w, createLogger as T, printReadyBlock as E } from "@voltro/logger";
9
- import { closeSync as D, existsSync as O, mkdirSync as k, openSync as A, promises as j, readFileSync as M, readdirSync as N, statSync as P, unlinkSync as ee, unwatchFile as F, watchFile as te, writeSync as I } from "node:fs";
10
- import { currentTraceContext as L, recordSample as R, resolveSecret as ne } from "@voltro/runtime";
11
- import { createRequire as re } from "node:module";
9
+ import { closeSync as D, existsSync as O, mkdirSync as ee, openSync as k, promises as A, readFileSync as j, readdirSync as M, statSync as N, unlinkSync as P, unwatchFile as F, watchFile as te, writeSync as I } from "node:fs";
10
+ import { currentTraceContext as ne, recordSample as L, resolveSecret as re } from "@voltro/runtime";
12
11
  import { homedir as ie } from "node:os";
13
- import { FRAMEWORK_ENV_CATALOG as ae, appEnvEntries as oe, checkEnvNaming as se, formatEnvErrors as ce, installEnvSnapshot as z, isEnvContract as le, pluginEnvEntries as ue, renderDotEnvExample as de, resolveEnv as fe } from "@voltro/env";
14
- import { __installPublicEnv as pe } from "@voltro/env/public";
15
- import { mkdir as me, readFile as he, writeFile as ge } from "node:fs/promises";
12
+ import { createRequire as ae } from "node:module";
13
+ import { FRAMEWORK_ENV_CATALOG as oe, appEnvEntries as se, checkEnvNaming as ce, formatEnvErrors as le, installEnvSnapshot as ue, isEnvContract as de, pluginEnvEntries as R, renderDotEnvExample as fe, resolveEnv as pe } from "@voltro/env";
14
+ import { __installPublicEnv as me } from "@voltro/env/public";
15
+ import { mkdir as he, readFile as ge, writeFile as z } from "node:fs/promises";
16
16
  import { createHash as _e } from "node:crypto";
17
17
  import { spawn as ve } from "node:child_process";
18
18
  import { createConnection as ye } from "node:net";
@@ -35,7 +35,7 @@ var xe = [
35
35
  "file",
36
36
  "line",
37
37
  "routine"
38
- ], B = (e, t = 0, n = /* @__PURE__ */ new WeakSet()) => {
38
+ ], Se = (e, t = 0, n = /* @__PURE__ */ new WeakSet()) => {
39
39
  if (t > 10 || typeof e != "object" || !e || n.has(e)) return null;
40
40
  n.add(e);
41
41
  let r = e, i = r.message;
@@ -55,20 +55,20 @@ var xe = [
55
55
  ]) {
56
56
  let i = r[e];
57
57
  if (i !== void 0) {
58
- let e = B(i, t + 1, n);
58
+ let e = Se(i, t + 1, n);
59
59
  if (e) return e;
60
60
  }
61
61
  }
62
62
  if (Array.isArray(r.failures)) for (let e of r.failures) {
63
- let r = B(e, t + 1, n);
63
+ let r = Se(e, t + 1, n);
64
64
  if (r) return r;
65
65
  }
66
66
  return null;
67
- }, Se = (e = {}) => S.merge(v.layer, C({
67
+ }, B = (e) => ({
68
68
  ...e.scope ? { defaultScope: e.scope } : {},
69
69
  ...e.logger
70
- })), V = async (e, t = {}) => {
71
- let n = e.pipe(x.provide(Se(t)));
70
+ }), Ce = (e = {}) => S.merge(v.layer, C(B(e))), V = async (e, t = {}) => {
71
+ let n = e.pipe(x.provide(v.layer));
72
72
  return await x.runPromise(x.matchCauseEffect(n, {
73
73
  onSuccess: (e) => x.succeed(e),
74
74
  onFailure: (e) => {
@@ -84,7 +84,7 @@ var xe = [
84
84
  }
85
85
  let n = null;
86
86
  for (let e of t) {
87
- let t = B(e);
87
+ let t = Se(e);
88
88
  if (t) {
89
89
  n = t;
90
90
  break;
@@ -103,40 +103,40 @@ var xe = [
103
103
  } : { causePretty: b.pretty(e) };
104
104
  return x.zipRight(x.logError("cli command failed", r), x.succeed(1));
105
105
  }
106
- }).pipe(x.provide(C(t.logger ?? {}))));
107
- }, Ce = (e, t = {}) => {
108
- let n = e.pipe(x.provide(Se(t)));
106
+ }).pipe(x.provide(C(B(t)))));
107
+ }, we = (e, t = {}) => {
108
+ let n = e.pipe(x.provide(Ce(t)));
109
109
  y.runMain(n, { disableErrorReporting: !1 });
110
- }, H = u(h(import.meta.url)), we = [m(H, "..", "templates"), m(H, "..", "..", "templates")], Te = (e) => ({
110
+ }, H = u(h(import.meta.url)), Te = [m(H, "..", "templates"), m(H, "..", "..", "templates")], Ee = (e) => ({
111
111
  _tag: "TemplateNotFoundError",
112
112
  searched: e
113
- }), Ee = ["AGENTS.md", "CLAUDE.md"], De = "voltro:agents-md:keep", Oe = 2048, ke = "<!-- VOLTRO:INDEX -->", U = (e, t) => e.exists(t).pipe(x.orElseSucceed(() => !1)), W = (e, t) => e.readFileString(t).pipe(x.orElseSucceed(() => "")), Ae = (e, t) => e.readFileString(t).pipe(x.map((e) => {
113
+ }), De = ["AGENTS.md", "CLAUDE.md"], Oe = "voltro:agents-md:keep", ke = 2048, Ae = "<!-- VOLTRO:INDEX -->", U = (e, t) => e.exists(t).pipe(x.orElseSucceed(() => !1)), W = (e, t) => e.readFileString(t).pipe(x.orElseSucceed(() => "")), je = (e, t) => e.readFileString(t).pipe(x.map((e) => {
114
114
  try {
115
115
  return JSON.parse(e).workspaces !== void 0;
116
116
  } catch {
117
117
  return !1;
118
118
  }
119
- }), x.orElseSucceed(() => !1)), je = (e) => x.gen(function* () {
119
+ }), x.orElseSucceed(() => !1)), Me = (e) => x.gen(function* () {
120
120
  let t = yield* _.FileSystem, n = m(e);
121
121
  for (;;) {
122
- if ((yield* U(t, f(n, ".git"))) || (yield* U(t, f(n, "pnpm-workspace.yaml"))) || (yield* Ae(t, f(n, "package.json")))) return n;
122
+ if ((yield* U(t, f(n, ".git"))) || (yield* U(t, f(n, "pnpm-workspace.yaml"))) || (yield* je(t, f(n, "package.json")))) return n;
123
123
  let r = u(n);
124
124
  if (r === n) return m(e);
125
125
  n = r;
126
126
  }
127
- }), Me = (e, t, n) => x.gen(function* () {
127
+ }), Ne = (e, t, n) => x.gen(function* () {
128
128
  yield* e.makeDirectory(n, { recursive: !0 }).pipe(x.orElseSucceed(() => void 0));
129
129
  let r = yield* e.readDirectory(t).pipe(x.orElseSucceed(() => []));
130
130
  for (let i of r) {
131
131
  let r = f(t, i), a = f(n, i);
132
- (yield* e.stat(r).pipe(x.orElseSucceed(() => null)))?.type === "Directory" ? yield* Me(e, r, a) : yield* e.copyFile(r, a).pipe(x.orElseSucceed(() => void 0));
132
+ (yield* e.stat(r).pipe(x.orElseSucceed(() => null)))?.type === "Directory" ? yield* Ne(e, r, a) : yield* e.copyFile(r, a).pipe(x.orElseSucceed(() => void 0));
133
133
  }
134
- }), Ne = (e) => typeof e?.name == "string" && e.name.length > 0 ? e.name.split("#")[0] : null, Pe = (e, t) => x.gen(function* () {
134
+ }), Pe = (e) => typeof e?.name == "string" && e.name.length > 0 ? e.name.split("#")[0] : null, Fe = (e, t) => x.gen(function* () {
135
135
  let n = f(t, "app.config.ts");
136
136
  if (!(yield* U(e, n))) return null;
137
137
  let r = (yield* x.tryPromise(() => import(g(n).href)).pipe(x.orElseSucceed(() => null)))?.default;
138
- return !r || r.type && r.type !== "api" ? r?.type === "web" ? [] : null : (r.plugins ?? []).map(Ne).filter((e) => e !== null);
139
- }), Fe = (e, t) => x.gen(function* () {
138
+ return !r || r.type && r.type !== "api" ? r?.type === "web" ? [] : null : (r.plugins ?? []).map(Pe).filter((e) => e !== null);
139
+ }), Ie = (e, t) => x.gen(function* () {
140
140
  let n = [], r = [], i = f(t, "apps");
141
141
  if (!(yield* U(e, i))) return {
142
142
  apis: n,
@@ -155,7 +155,7 @@ var xe = [
155
155
  apis: n,
156
156
  webs: r
157
157
  };
158
- }), Ie = (e) => e.replace(/\|/g, "\\|").replace(/\n/g, " ").trim(), Le = (e, t, n) => {
158
+ }), Le = (e) => e.replace(/\|/g, "\\|").replace(/\n/g, " ").trim(), Re = (e, t, n) => {
159
159
  let r = [
160
160
  "<!-- voltro agent-docs index — regenerated at seed time -->",
161
161
  "## Deep reference (read on demand)",
@@ -167,17 +167,17 @@ var xe = [
167
167
  "",
168
168
  "| Topic | Open | Summary |",
169
169
  "|---|---|---|",
170
- ...e.modules.map((e) => `| ${e.title} | \`${n}${e.path}\` | ${Ie(e.description)} |`),
170
+ ...e.modules.map((e) => `| ${e.title} | \`${n}${e.path}\` | ${Le(e.description)} |`),
171
171
  ""
172
- ], 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\` | ${Ie(e.description)} |`) : t.map((e) => {
172
+ ], 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\` | ${Le(e.description)} |`) : t.map((e) => {
173
173
  let t = i.get(e);
174
- return t ? `| ${t.slug} | \`node_modules/${e}/README.md\` | ${Ie(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
174
+ return t ? `| ${t.slug} | \`node_modules/${e}/README.md\` | ${Le(t.description)} |` : `| ${e.replace(/^@[^/]+\//, "")} | \`node_modules/${e}/README.md\` | (see plugin README) |`;
175
175
  });
176
176
  return r.push(`### Plugins${t === null ? "" : " (installed)"}`, "", "| Plugin | Open | Summary |", "|---|---|---|"), r.push(a.length ? a.join("\n") : "| _(none installed)_ | | |", ""), r.join("\n");
177
- }, Re = (e, t, n) => {
177
+ }, ze = (e, t, n) => {
178
178
  let r = t.templates?.[e] ?? t.templates?.[e.replace(/^frontend-/, "")];
179
179
  return `\nScaffolded from the \`${e}\` template — see \`${r ? `${n}${r}` : `${n}agent-docs/templates/overview.md`}\`.\n`;
180
- }, ze = {
180
+ }, Be = {
181
181
  api: (e, t, n = "") => `# api — agent notes
182
182
 
183
183
  You are in a Voltro **api** app. Server primitives live here: \`queries/\`,
@@ -217,7 +217,7 @@ You are in a Voltro **web** app. File-based routing under \`src/pages/**\`.
217
217
  Deep reference (paths from the repo root): \`${e}agent-docs/routing.md\`,
218
218
  \`${e}agent-docs/schema-driven-ui.md\`, \`${e}agent-docs/internationalization.md\`.
219
219
  ${t}`
220
- }, Be = [
220
+ }, Ve = [
221
221
  {
222
222
  name: "voltro-schema",
223
223
  description: "Define or change a Voltro database table/schema (columns, mixins, indexes, relations).",
@@ -248,7 +248,7 @@ ${t}`
248
248
  description: "Export/import + backup/restore Voltro data & assets, and copy prod→dev/stage SAFELY with fail-closed masking/anonymization (.sensitive()/.safe()) + referential subsetting. Use for data takeout, seeding lower envs, backups, or cross-dialect moves.",
249
249
  module: "cli.md"
250
250
  }
251
- ], Ve = (e, t) => `---
251
+ ], He = (e, t) => `---
252
252
  name: ${e.name}
253
253
  description: ${e.description}
254
254
  ---
@@ -259,10 +259,10 @@ Open the full reference and follow the patterns there:
259
259
 
260
260
  Also read the repo-root \`AGENTS.md\` for the always-true rules (browser/server
261
261
  boundary, naming, anti-patterns) before editing.
262
- `, He = (e, t, n, r) => x.gen(function* () {
262
+ `, Ue = (e, t, n, r) => x.gen(function* () {
263
263
  let i = yield* U(e, t);
264
264
  if (i) {
265
- if ((yield* W(e, t)).slice(0, Oe).includes("voltro:agents-md:keep")) return {
265
+ if ((yield* W(e, t)).slice(0, ke).includes("voltro:agents-md:keep")) return {
266
266
  path: t,
267
267
  action: "protected"
268
268
  };
@@ -275,64 +275,138 @@ boundary, naming, anti-patterns) before editing.
275
275
  path: t,
276
276
  action: i ? "overwritten" : "created"
277
277
  };
278
- }), Ue = (e, t = {}) => x.gen(function* () {
279
- let n = yield* _.FileSystem, r = yield* je(e), i = null;
280
- for (let e of we) if (yield* U(n, f(e, "AGENTS.core.md"))) {
278
+ }), We = (e, t = {}) => x.gen(function* () {
279
+ let n = yield* _.FileSystem, r = yield* Me(e), i = null;
280
+ for (let e of Te) if (yield* U(n, f(e, "AGENTS.core.md"))) {
281
281
  i = e;
282
282
  break;
283
283
  }
284
284
  if (i === null) {
285
- for (let e of we) if (yield* U(n, f(e, "AGENTS.md"))) {
285
+ for (let e of Te) if (yield* U(n, f(e, "AGENTS.md"))) {
286
286
  let i = yield* W(n, f(e, "AGENTS.md")), a = [];
287
- for (let e of Ee) a.push(yield* He(n, f(r, e), i, t.force ?? !1));
287
+ for (let e of De) a.push(yield* Ue(n, f(r, e), i, t.force ?? !1));
288
288
  return { files: a };
289
289
  }
290
- return yield* x.fail(Te(we.map((e) => f(e, "AGENTS.core.md"))));
290
+ return yield* x.fail(Ee(Te.map((e) => f(e, "AGENTS.core.md"))));
291
291
  }
292
292
  let a = yield* W(n, f(i, "AGENTS.core.md")), o = yield* W(n, f(i, "agent-docs", "_manifest.json")), s = o ? JSON.parse(o) : {
293
293
  modules: [],
294
294
  plugins: []
295
- }, c = (t.preferPointer ?? !1) || (yield* U(n, f(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = Ee.map((e) => f(r, e));
296
- if ((yield* x.forEach(d, (e) => W(n, e).pipe(x.map((e) => e.slice(0, Oe))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
295
+ }, c = (t.preferPointer ?? !1) || (yield* U(n, f(r, "node_modules/@voltro/cli/templates/agent-docs", "_manifest.json"))), l = c ? "node_modules/@voltro/cli/templates/" : "", u = t.force ?? !1, d = De.map((e) => f(r, e));
296
+ if ((yield* x.forEach(d, (e) => W(n, e).pipe(x.map((e) => e.slice(0, ke))))).every((e) => e.includes("voltro:agents-md:keep"))) return { files: d.map((e) => ({
297
297
  path: e,
298
298
  action: "protected"
299
299
  })) };
300
- let { apis: p, webs: h } = yield* Fe(n, r), g = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Set(), y = !1;
300
+ let { apis: p, webs: h } = yield* Ie(n, r), g = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Set(), y = !1;
301
301
  for (let e of p) {
302
- let t = yield* Pe(n, e);
302
+ let t = yield* Fe(n, e);
303
303
  if (g.set(e, t), t !== null) {
304
304
  y = !0;
305
305
  for (let e of t) v.add(e);
306
306
  }
307
307
  }
308
- let b = t.plugins ? t.plugins.map(Ne).filter((e) => e !== null) : y ? [...v] : null, S = a.includes(ke) ? a.replace(ke, Le(s, b, l)) : a, C = [];
309
- for (let e of d) C.push(yield* He(n, e, S, u));
310
- c || (yield* Me(n, f(i, "agent-docs"), f(r, "agent-docs")));
308
+ let b = t.plugins ? t.plugins.map(Pe).filter((e) => e !== null) : y ? [...v] : null, S = a.includes(Ae) ? a.replace(Ae, Re(s, b, l)) : a, C = [];
309
+ for (let e of d) C.push(yield* Ue(n, e, S, u));
310
+ c || (yield* Ne(n, f(i, "agent-docs"), f(r, "agent-docs")));
311
311
  let w = new Map((t.appTemplates ?? []).map((e) => [m(e.dir), e.template])), T = (e) => {
312
312
  let t = w.get(m(e));
313
- return t ? Re(t, s, l) : "";
314
- }, E = (e, t) => x.forEach(Ee, (r) => He(n, f(e, r), t, u));
315
- for (let e of p) C.push(...yield* E(e, ze.api(l, g.get(e) ?? null, T(e)))), (yield* U(n, f(e, "database"))) && C.push(...yield* E(f(e, "database"), ze.database(l)));
316
- for (let e of h) C.push(...yield* E(e, ze.web(l, T(e))));
317
- for (let e of Be) C.push(yield* He(n, f(r, ".claude", "skills", e.name, "SKILL.md"), Ve(e, l), u));
313
+ return t ? ze(t, s, l) : "";
314
+ }, E = (e, t) => x.forEach(De, (r) => Ue(n, f(e, r), t, u));
315
+ for (let e of p) C.push(...yield* E(e, Be.api(l, g.get(e) ?? null, T(e)))), (yield* U(n, f(e, "database"))) && C.push(...yield* E(f(e, "database"), Be.database(l)));
316
+ for (let e of h) C.push(...yield* E(e, Be.web(l, T(e))));
317
+ for (let e of Ve) C.push(yield* Ue(n, f(r, ".claude", "skills", e.name, "SKILL.md"), He(e, l), u));
318
318
  return { files: C };
319
- }), We = (e, t = {}) => x.runPromise(Ue(e, t).pipe(x.provide(v.layer))), Ge = async (e) => {
319
+ }), Ge = (e, t = {}) => x.runPromise(We(e, t).pipe(x.provide(v.layer))), Ke = async (e) => {
320
320
  let t = e.includes("--force"), n = e.find((e) => !e.startsWith("-")) ?? process.cwd();
321
321
  return V(x.gen(function* () {
322
- let e = yield* Ue(n, { force: t });
322
+ let e = yield* We(n, { force: t });
323
323
  for (let t of e.files) {
324
- let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${De}")` : "present (use --force to overwrite)";
324
+ let e = t.action === "created" ? "wrote" : t.action === "overwritten" ? "overwrote" : t.action === "protected" ? `protected (hand-maintained — has "${Oe}")` : "present (use --force to overwrite)";
325
325
  yield* x.logInfo(`${t.path.split("/").slice(-2).join("/")} ${e}`, { action: t.action });
326
326
  }
327
327
  return 0;
328
328
  }).pipe(x.catchTag("TemplateNotFoundError", (e) => x.gen(function* () {
329
329
  return yield* x.logError("AGENTS.md template not found", { searched: e.searched }), 1;
330
330
  }))), { scope: "voltro:agents-md" });
331
- }, Ke = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), qe = (e) => {
331
+ }, qe = f(ie(), ".voltro"), Je = f(qe, "runtime-registry.json"), Ye = 3e4, Xe = () => {
332
+ let e = Math.random().toString(36).slice(2, 10);
333
+ return `${Je}.${process.pid}.${Date.now()}.${e}.tmp`;
334
+ }, Ze = async () => {
335
+ await A.mkdir(qe, { recursive: !0 });
336
+ }, Qe = async () => {
337
+ try {
338
+ let e = await A.readFile(Je, "utf8"), t = JSON.parse(e);
339
+ return t.version !== 1 || !Array.isArray(t.apps) ? {
340
+ version: 1,
341
+ apps: []
342
+ } : t;
343
+ } catch {
344
+ return {
345
+ version: 1,
346
+ apps: []
347
+ };
348
+ }
349
+ }, $e = async (e) => {
350
+ await Ze();
351
+ let t = Xe();
352
+ try {
353
+ await A.writeFile(t, JSON.stringify(e, null, 2), {
354
+ encoding: "utf8",
355
+ mode: 384
356
+ }), await A.rename(t, Je), await A.chmod(Je, 384).catch(() => {});
357
+ } catch (e) {
358
+ try {
359
+ await A.unlink(t);
360
+ } catch {}
361
+ throw e;
362
+ }
363
+ }, et = (e) => {
364
+ try {
365
+ return process.kill(e, 0), !0;
366
+ } catch {
367
+ return !1;
368
+ }
369
+ }, tt = (e) => {
370
+ let t = Date.now();
371
+ return e.filter((e) => et(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Ye : !1);
372
+ }, nt = async () => {
373
+ let e = await Qe(), t = tt(e.apps);
374
+ if (t.length === e.apps.length) return e;
375
+ try {
376
+ await $e({
377
+ version: 1,
378
+ apps: t
379
+ });
380
+ } catch {}
381
+ return {
382
+ version: 1,
383
+ apps: t
384
+ };
385
+ }, rt = async (e) => {
386
+ let t = await Qe(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
387
+ ...e,
388
+ ...i !== void 0 && i !== "" ? { inspectToken: i } : {},
389
+ registeredAt: r >= 0 ? t.apps[r].registeredAt : n,
390
+ heartbeatAt: n
391
+ };
392
+ await $e({
393
+ version: 1,
394
+ apps: r >= 0 ? t.apps.map((e, t) => t === r ? a : e) : [...t.apps, a]
395
+ });
396
+ }, it = async (e) => {
397
+ try {
398
+ let t = await Qe(), n = t.apps.filter((t) => t.id !== e);
399
+ if (n.length === t.apps.length) return;
400
+ await $e({
401
+ version: 1,
402
+ apps: n
403
+ });
404
+ } catch {}
405
+ }, at = (e, t, n) => `${e}:${t}:${n}`, ot = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), st = (e) => {
332
406
  try {
333
407
  let t = f(e, "tsconfig.json");
334
408
  if (!O(t)) return [];
335
- let n = JSON.parse(Ke(M(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = m(e, n.baseUrl ?? "."), a = [];
409
+ let n = JSON.parse(ot(j(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = m(e, n.baseUrl ?? "."), a = [];
336
410
  for (let [e, t] of Object.entries(r)) {
337
411
  let n = t[0];
338
412
  if (!n) continue;
@@ -352,17 +426,17 @@ boundary, naming, anti-patterns) before editing.
352
426
  } catch {
353
427
  return [];
354
428
  }
355
- }, Je = (e) => {
429
+ }, ct = (e) => {
356
430
  let t = e;
357
431
  return t?.code === "ERR_MODULE_NOT_FOUND" || /Cannot find (package|module)/.test(String(t?.message ?? ""));
358
- }, Ye = async (e, t) => {
432
+ }, lt = async (e, t) => {
359
433
  try {
360
434
  return await t();
361
435
  } catch (t) {
362
- throw Je(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
436
+ throw ct(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
363
437
  }
364
- }, Xe = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", Ze = (e, t) => t ? `${e} | undefined` : e, Qe = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${Ze(t.tsType, t.optional)}`).join("\n"), $e = async (e, t) => {
365
- let n = Qe(t, () => !0), r = `${Xe}
438
+ }, ut = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", dt = (e, t) => t ? `${e} | undefined` : e, ft = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${dt(t.tsType, t.optional)}`).join("\n"), pt = async (e, t) => {
439
+ let n = ft(t, () => !0), r = `${ut}
366
440
  import '@voltro/env/server'
367
441
 
368
442
  declare module '@voltro/env/server' {
@@ -371,9 +445,9 @@ ${n.length > 0 ? n : " // (no variables declared)"}
371
445
  }
372
446
  }
373
447
  `;
374
- await ge(f(e, "env.generated.d.ts"), r, "utf8");
375
- }, et = async (e, t) => {
376
- let n = Qe(t, (e) => e === "public"), r = `${Xe}
448
+ await z(f(e, "env.generated.d.ts"), r, "utf8");
449
+ }, mt = async (e, t) => {
450
+ let n = ft(t, (e) => e === "public"), r = `${ut}
377
451
  import '@voltro/env/public'
378
452
 
379
453
  declare module '@voltro/env/public' {
@@ -382,9 +456,9 @@ ${n.length > 0 ? n : " // (no public variables declared)"}
382
456
  }
383
457
  }
384
458
  `, i = f(e, "src");
385
- await me(i, { recursive: !0 }), await ge(f(i, "voltro-env.d.ts"), r, "utf8");
386
- }, tt = async (e, t) => {
387
- let n = `${Xe}
459
+ await he(i, { recursive: !0 }), await z(f(i, "voltro-env.d.ts"), r, "utf8");
460
+ }, ht = async (e, t) => {
461
+ let n = `${ut}
388
462
  import { __installPublicEnv } from '@voltro/env/public'
389
463
 
390
464
  export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
@@ -392,14 +466,14 @@ export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
392
466
  // Set the browser/SSR-shared global the \`publicEnv\` accessor reads.
393
467
  __installPublicEnv(publicEnvValues)
394
468
  `;
395
- await me(e, { recursive: !0 }), await ge(f(e, "env.public.ts"), n, "utf8");
396
- }, nt = async (e) => {
397
- let t = le(e.rawEnv) ? e.rawEnv : void 0, n = await fe({
469
+ await he(e, { recursive: !0 }), await z(f(e, "env.public.ts"), n, "utf8");
470
+ }, gt = async (e) => {
471
+ let t = de(e.rawEnv) ? e.rawEnv : void 0, n = await pe({
398
472
  contract: t,
399
- resolveSecret: ne
400
- }), r = [...n.errors, ...se(t, e.appType)];
401
- if (r.length > 0) throw Error(ce(r));
402
- z(n.values), e.appType === "web" && pe(n.publicValues);
473
+ resolveSecret: re
474
+ }), r = [...n.errors, ...ce(t, e.appType)];
475
+ if (r.length > 0) throw Error(le(r));
476
+ ue(n.values), e.appType === "web" && me(n.publicValues);
403
477
  let i = t ? Object.keys(t.vars).length : 0;
404
478
  if (i > 0) {
405
479
  let r = Object.keys(n.publicValues).length;
@@ -411,20 +485,20 @@ __installPublicEnv(publicEnvValues)
411
485
  n.length > 0 && e.log.warn(`env: ${n.length} secret var(s) declared on a web app — secrets are reachable only from server-side render code and are NEVER bundled. Prefer declaring secrets on the api.`, { keys: n });
412
486
  }
413
487
  }
414
- return e.generateTypes && t && (e.appType === "api" ? await $e(e.root, t) : await et(e.root, t)), {
488
+ return e.generateTypes && t && (e.appType === "api" ? await pt(e.root, t) : await mt(e.root, t)), {
415
489
  resolved: n,
416
490
  contract: t
417
491
  };
418
- }, rt = (e) => {
419
- let t = oe(e.contract), n = (e.plugins ?? []).flatMap((e) => ue(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : ae, i = /* @__PURE__ */ new Set(), a = [];
492
+ }, _t = (e) => {
493
+ let t = se(e.contract), n = (e.plugins ?? []).flatMap((e) => R(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : oe, i = /* @__PURE__ */ new Set(), a = [];
420
494
  for (let e of [
421
495
  ...t,
422
496
  ...n,
423
497
  ...r
424
498
  ]) i.has(e.key) || (i.add(e.key), a.push(e));
425
499
  return a;
426
- }, it = (e, t, n = (e) => process.env[e]) => {
427
- let r = rt(t).map((e) => {
500
+ }, vt = (e, t, n = (e) => process.env[e]) => {
501
+ let r = _t(t).map((e) => {
428
502
  let t = n(e.key) !== void 0;
429
503
  return {
430
504
  ...e,
@@ -441,13 +515,13 @@ __installPublicEnv(publicEnvValues)
441
515
  missingRequired: r.filter((e) => e.required && !e.isSet && e.default === void 0).length
442
516
  }
443
517
  };
444
- }, at = (e, t) => de(rt({
518
+ }, yt = (e, t) => fe(_t({
445
519
  ...e,
446
520
  includeFramework: !1
447
521
  }), {
448
522
  includeFramework: e.includeFramework !== !1,
449
523
  ...t ? { header: t } : {}
450
- }), ot = () => {
524
+ }), bt = () => {
451
525
  let e = /* @__PURE__ */ new Map();
452
526
  return {
453
527
  get(t) {
@@ -483,20 +557,20 @@ __installPublicEnv(publicEnvValues)
483
557
  if (!Number.isFinite(n) || n <= 0) return null;
484
558
  let r = t[2].toLowerCase();
485
559
  return r === "s" || r.startsWith("second") ? n * 1e3 : r === "m" || r.startsWith("minute") ? n * 6e4 : r === "h" || r.startsWith("hour") ? n * 36e5 : r === "d" || r.startsWith("day") ? n * 864e5 : null;
486
- }, st = (e, t = {}) => {
560
+ }, xt = (e, t = {}) => {
487
561
  let n = [e];
488
562
  return t.tenant !== void 0 && t.tenant !== "" && n.push(`tenant=${t.tenant}`), t.locale !== void 0 && t.locale !== "" && n.push(`lang=${t.locale}`), n.join("|");
489
- }, ct = (e, t) => e.expiresAt > t, lt = (e, t) => e.expiresAt <= t && e.servableUntil > t, ut = T({ scope: "voltro:cli" }), dt = (e, t) => {
563
+ }, St = (e, t) => e.expiresAt > t, Ct = (e, t) => e.expiresAt <= t && e.servableUntil > t, wt = T({ scope: "voltro:cli" }), Tt = (e, t) => {
490
564
  if (t?.code !== "EACCES") return "";
491
565
  if (typeof process.getuid != "function") return " — permission denied";
492
566
  try {
493
- let t = P(e);
567
+ let t = N(e);
494
568
  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.`;
495
569
  } catch {
496
570
  return " — permission denied (and the file could not be stat-ed either)";
497
571
  }
498
- }, ft = [], pt = (e) => {
499
- ft.length = 0;
572
+ }, Et = [], Dt = (e) => {
573
+ Et.length = 0;
500
574
  let t = e[1] && !e[1].startsWith("-") ? e[1] : void 0, n = t ? d(t) ? t : m(process.cwd(), t) : process.cwd(), r = [], i = n;
501
575
  for (;;) {
502
576
  r.push(i);
@@ -507,9 +581,9 @@ __installPublicEnv(publicEnvValues)
507
581
  for (let e of r) for (let t of [".env.local", ".env"]) {
508
582
  let n = m(e, t);
509
583
  if (O(n)) {
510
- ft.push(n);
584
+ Et.push(n);
511
585
  try {
512
- let e = M(n, "utf8");
586
+ let e = j(n, "utf8");
513
587
  for (let t of e.split(/\r?\n/)) {
514
588
  let e = t.trim();
515
589
  if (e === "" || e.startsWith("#")) continue;
@@ -519,11 +593,11 @@ __installPublicEnv(publicEnvValues)
519
593
  (i.startsWith("\"") && i.endsWith("\"") || i.startsWith("'") && i.endsWith("'")) && (i = i.slice(1, -1)), process.env[r] === void 0 && (process.env[r] = i);
520
594
  }
521
595
  } catch (e) {
522
- ut.warn(`failed to load env file (continuing)${dt(n, e)}`, { path: n }, e);
596
+ wt.warn(`failed to load env file (continuing)${Tt(n, e)}`, { path: n }, e);
523
597
  }
524
598
  }
525
599
  }
526
- }, mt = 500, ht = (e, t, n = {}) => {
600
+ }, Ot = 500, kt = (e, t, n = {}) => {
527
601
  if (e.length === 0) return () => {};
528
602
  let r = (e) => n.root ? p(n.root, e) : e, i = !1, a = (e) => {
529
603
  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(() => {
@@ -541,47 +615,47 @@ __installPublicEnv(publicEnvValues)
541
615
  });
542
616
  }));
543
617
  };
544
- for (let t of e) te(t, { interval: mt }, (e, n) => {
618
+ for (let t of e) te(t, { interval: Ot }, (e, n) => {
545
619
  e.mtimeMs !== n.mtimeMs && a(t);
546
620
  });
547
621
  return t.info("watching .env files for changes", {
548
622
  files: e.map(r),
549
- intervalMs: mt
623
+ intervalMs: Ot
550
624
  }), () => {
551
625
  for (let t of e) F(t);
552
626
  };
553
- }, K = T({ scope: "vite" }), gt = /\x1b\[[0-9;]*m/g, _t = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, vt = (e) => e.replace(gt, "").replace(_t, "").trim(), yt = /proxy error/i, bt = [
627
+ }, K = T({ scope: "vite" }), At = /\x1b\[[0-9;]*m/g, jt = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, Mt = (e) => e.replace(At, "").replace(jt, "").trim(), Nt = /proxy error/i, Pt = [
554
628
  "ECONNREFUSED",
555
629
  "ECONNRESET",
556
630
  "ECONNABORTED",
557
631
  "EPIPE",
558
632
  "ETIMEDOUT"
559
- ], xt = (e, t = 0) => {
633
+ ], Ft = (e, t = 0) => {
560
634
  if (e == null || t > 5) return !1;
561
635
  let n = e;
562
- return typeof n.code == "string" && bt.includes(n.code) || typeof n.message == "string" && bt.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => xt(e, t + 1)) ? !0 : xt(n.cause, t + 1);
563
- }, St = 4e3, Ct = () => {
636
+ return typeof n.code == "string" && Pt.includes(n.code) || typeof n.message == "string" && Pt.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => Ft(e, t + 1)) ? !0 : Ft(n.cause, t + 1);
637
+ }, It = 4e3, Lt = () => {
564
638
  let e = /* @__PURE__ */ new Set(), t = 0, n = {
565
639
  hasWarned: !1,
566
640
  info: (e) => {
567
- let t = vt(e);
641
+ let t = Mt(e);
568
642
  t.length !== 0 && K.info(t);
569
643
  },
570
644
  warn: (e) => {
571
645
  n.hasWarned = !0;
572
- let t = vt(e);
646
+ let t = Mt(e);
573
647
  t.length !== 0 && K.warn(t);
574
648
  },
575
649
  warnOnce: (t) => {
576
- let r = vt(t);
650
+ let r = Mt(t);
577
651
  e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && K.warn(r));
578
652
  },
579
653
  error: (e, n) => {
580
- let r = vt(e), i = n?.error;
654
+ let r = Mt(e), i = n?.error;
581
655
  if (r.length !== 0) {
582
- if (yt.test(r) && xt(i)) {
656
+ if (Nt.test(r) && Ft(i)) {
583
657
  let e = Date.now();
584
- e - t > St && (t = e, K.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
658
+ e - t > It && (t = e, K.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
585
659
  return;
586
660
  }
587
661
  K.error(r, {}, i);
@@ -591,12 +665,12 @@ __installPublicEnv(publicEnvValues)
591
665
  hasErrorLogged: (e) => !1
592
666
  };
593
667
  return n;
594
- }, wt = (e = process.env) => {
668
+ }, Rt = (e = process.env) => {
595
669
  let t = e.VOLTRO_DEV_SSR_COMPILE_CONCURRENCY;
596
670
  if (t === void 0 || t.trim() === "") return 4;
597
671
  let n = Number(t);
598
672
  return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
599
- }, Tt = (e) => {
673
+ }, zt = (e) => {
600
674
  let t = Math.max(1, Math.floor(e)), n = 0, r = [], i = () => n < t ? (n++, Promise.resolve()) : new Promise((e) => r.push(e)), a = () => {
601
675
  let e = r.shift();
602
676
  e ? e() : n--;
@@ -614,8 +688,8 @@ __installPublicEnv(publicEnvValues)
614
688
  return n;
615
689
  }
616
690
  };
617
- }, Et = (e) => {
618
- let t = Tt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
691
+ }, Bt = (e) => {
692
+ let t = zt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
619
693
  return {
620
694
  load: (i, a) => {
621
695
  if (r.has(i)) return a();
@@ -645,7 +719,7 @@ __installPublicEnv(publicEnvValues)
645
719
  return r.size;
646
720
  }
647
721
  };
648
- }, Dt = (e) => {
722
+ }, Vt = (e) => {
649
723
  let t = [];
650
724
  for (let n of e.split("/").filter(Boolean)) n.startsWith("[[...") && n.endsWith("]]") ? t.push({
651
725
  name: n.slice(5, -2),
@@ -661,12 +735,12 @@ __installPublicEnv(publicEnvValues)
661
735
  optional: !1
662
736
  });
663
737
  return t;
664
- }, Ot = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), kt = async (e) => {
738
+ }, Ht = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), Ut = async (e) => {
665
739
  let t = m(e);
666
740
  for (let e = 0; e < 4; e++) {
667
741
  let e = f(t, "project.json");
668
742
  if (O(e)) try {
669
- let n = await j.readFile(e, "utf8");
743
+ let n = await A.readFile(e, "utf8");
670
744
  return {
671
745
  projectDir: t,
672
746
  manifest: JSON.parse(n)
@@ -679,8 +753,8 @@ __installPublicEnv(publicEnvValues)
679
753
  t = n;
680
754
  }
681
755
  return null;
682
- }, At = async (e) => {
683
- let t = await kt(e);
756
+ }, Wt = async (e) => {
757
+ let t = await Ut(e);
684
758
  if (!t) return [];
685
759
  let { projectDir: n, manifest: r } = t, i = l(e), a = r.apps ?? {}, o = [];
686
760
  for (let [e, t] of Object.entries(a)) {
@@ -692,20 +766,20 @@ __installPublicEnv(publicEnvValues)
692
766
  let { pages: e } = await Q(r);
693
767
  a = e.map((e) => ({
694
768
  pattern: e.pattern,
695
- params: Dt(e.pattern)
769
+ params: Vt(e.pattern)
696
770
  }));
697
771
  } catch {
698
772
  continue;
699
773
  }
700
774
  o.push({
701
- key: Ot(e),
775
+ key: Ht(e),
702
776
  origin: `http://localhost:${t.port}`,
703
777
  ...typeof t.origin == "string" && t.origin.length > 0 ? { prodOrigin: t.origin } : {},
704
778
  routes: a
705
779
  });
706
780
  }
707
781
  return o;
708
- }, jt = (e) => {
782
+ }, Gt = (e) => {
709
783
  if (e.params.length === 0) return `'${e.pattern}'`;
710
784
  let t = e.pattern;
711
785
  for (let n of e.params) {
@@ -713,21 +787,21 @@ __installPublicEnv(publicEnvValues)
713
787
  t = t.replace(e, r);
714
788
  }
715
789
  return "`" + t + "`";
716
- }, Mt = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
790
+ }, Kt = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
717
791
  let t = "string";
718
792
  return e.optional ? `readonly ${e.name}?: ${t}` : `readonly ${e.name}: ${t}`;
719
- }).join("; ")} }`, Nt = (e, t, n) => {
720
- let r = Mt(e), i = jt(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
793
+ }).join("; ")} }`, qt = (e, t, n) => {
794
+ let r = Kt(e), i = Gt(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
721
795
  return e.params.length === 0 ? `() => (${o}${i}) as ${a}` : `({ ${e.params.map((e) => e.name).join(", ")} }: ${r}) => (${o}${i}) as ${a}`;
722
- }, Pt = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${Nt(e, !1)},`).join("\n")}\n}`, Ft = (e, t) => {
796
+ }, Jt = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${qt(e, !1)},`).join("\n")}\n}`, Yt = (e, t) => {
723
797
  if (e.routes.length === 0) return ` ${e.key}: {} as Record<string, never>,`;
724
- 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)}: ${Nt(e, !0, i)},`);
798
+ 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)}: ${qt(e, !0, i)},`);
725
799
  return ` ${e.key}: {\n${a.join("\n")}\n },`;
726
- }, It = async (e) => {
800
+ }, Xt = async (e) => {
727
801
  let t = e.pages.map((e) => ({
728
802
  pattern: e.pattern,
729
- params: Dt(e.pattern)
730
- })), n = await At(e.appRoot), r = [
803
+ params: Vt(e.pattern)
804
+ })), n = await Wt(e.appRoot), r = [
731
805
  "// THIS FILE IS GENERATED — DO NOT EDIT BY HAND.",
732
806
  "// Re-emitted by `voltro dev` whenever `src/pages/**` changes.",
733
807
  "// Type-safe route builders consumed by <Link to={...}>.",
@@ -736,20 +810,20 @@ __installPublicEnv(publicEnvValues)
736
810
  "",
737
811
  "type EmptyParams = Record<string, never>",
738
812
  ""
739
- ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${Pt(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => Ft(e, i)).join("\n")}\n} as const\n`}`, o = f(e.appRoot, ".framework", "routes.generated.ts");
740
- await j.mkdir(u(o), { recursive: !0 });
813
+ ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${Jt(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => Yt(e, i)).join("\n")}\n} as const\n`}`, o = f(e.appRoot, ".framework", "routes.generated.ts");
814
+ await A.mkdir(u(o), { recursive: !0 });
741
815
  let s = null;
742
816
  try {
743
- s = await j.readFile(o, "utf8");
817
+ s = await A.readFile(o, "utf8");
744
818
  } catch {}
745
819
  return s === a ? {
746
820
  path: o,
747
821
  wrote: !1
748
- } : (await j.writeFile(o, a, "utf8"), {
822
+ } : (await A.writeFile(o, a, "utf8"), {
749
823
  path: o,
750
824
  wrote: !0
751
825
  });
752
- }, Lt = 256, Rt = (e = Lt) => {
826
+ }, Zt = 256, Qt = (e = Zt) => {
753
827
  let t = [], n = /* @__PURE__ */ new Set();
754
828
  return {
755
829
  emit(r, i) {
@@ -772,27 +846,27 @@ __installPublicEnv(publicEnvValues)
772
846
  return t.slice();
773
847
  }
774
848
  };
775
- }, zt = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, Bt = () => `: keep-alive ${Date.now()}\n\n`, Vt = {
849
+ }, $t = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, en = () => `: keep-alive ${Date.now()}\n\n`, tn = {
776
850
  trace: 0,
777
851
  debug: 1,
778
852
  info: 2,
779
853
  warn: 3,
780
854
  error: 4,
781
855
  fatal: 5
782
- }, Ht = 2e3, Ut = 200, Wt = class {
856
+ }, nn = 2e3, rn = 200, an = class {
783
857
  capacity;
784
858
  buffer = [];
785
- constructor(e = Ht) {
859
+ constructor(e = nn) {
786
860
  this.capacity = e;
787
861
  }
788
862
  append(e) {
789
863
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
790
864
  }
791
865
  query(e = {}) {
792
- let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? Ut, this.capacity), i = e.minLevel === void 0 ? Vt.trace : Vt[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
866
+ 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 = [];
793
867
  for (let e = this.buffer.length - 1; e >= 0 && l.length < r; e--) {
794
868
  let r = this.buffer[e];
795
- r.ts < t || r.ts > n || Vt[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);
869
+ 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);
796
870
  }
797
871
  return l.reverse();
798
872
  }
@@ -805,7 +879,7 @@ __installPublicEnv(publicEnvValues)
805
879
  clear() {
806
880
  this.buffer = [];
807
881
  }
808
- }, Gt = null, Kt = () => (Gt === null && (Gt = new Wt()), Gt), qt = (e) => {
882
+ }, on = null, sn = () => (on === null && (on = new an()), on), cn = (e) => {
809
883
  if (typeof e == "string") return e;
810
884
  if (e instanceof Error) return e.message;
811
885
  try {
@@ -813,18 +887,18 @@ __installPublicEnv(publicEnvValues)
813
887
  } catch {
814
888
  return String(e);
815
889
  }
816
- }, Jt = (e) => {
890
+ }, ln = (e) => {
817
891
  let t = {
818
892
  log: console.log.bind(console),
819
893
  info: console.info.bind(console),
820
894
  warn: console.warn.bind(console),
821
895
  error: console.error.bind(console),
822
896
  debug: console.debug.bind(console)
823
- }, n = Kt(), r = !1, i = (i) => (...a) => {
897
+ }, n = sn(), r = !1, i = (i) => (...a) => {
824
898
  if (t[i](...a), !r) {
825
899
  r = !0;
826
900
  try {
827
- let t = a.length > 0 ? qt(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = L();
901
+ let t = a.length > 0 ? cn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = ne();
828
902
  e.emit("log", {
829
903
  level: i,
830
904
  message: r,
@@ -862,7 +936,7 @@ __installPublicEnv(publicEnvValues)
862
936
  argsCount: 1,
863
937
  ...t.scope === void 0 ? {} : { scope: t.scope }
864
938
  });
865
- let a = L(), o = a !== void 0 && t.fields.traceId === void 0 ? {
939
+ let a = ne(), o = a !== void 0 && t.fields.traceId === void 0 ? {
866
940
  ...t.fields,
867
941
  traceId: a.traceId
868
942
  } : t.fields;
@@ -882,24 +956,24 @@ __installPublicEnv(publicEnvValues)
882
956
  return () => {
883
957
  console.log = t.log, console.info = t.info, console.warn = t.warn, console.error = t.error, console.debug = t.debug, a();
884
958
  };
885
- }, Yt = 2e3, Xt = 8, Zt = 1e3, Qt = 200, q = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, $t = (e) => {
959
+ }, un = 2e3, dn = 8, fn = 1e3, pn = 200, q = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, mn = (e) => {
886
960
  switch (e) {
887
961
  case "error": return "error";
888
962
  case "warn": return "warn";
889
963
  case "debug": return "debug";
890
964
  default: return "info";
891
965
  }
892
- }, en = T({ scope: "client" }), tn = (e, t) => {
966
+ }, hn = T({ scope: "client" }), gn = (e, t) => {
893
967
  let n;
894
968
  try {
895
969
  n = JSON.parse(e);
896
970
  } catch {
897
- return nn(400, { error: "invalid JSON body" });
971
+ return _n(400, { error: "invalid JSON body" });
898
972
  }
899
- if (typeof n != "object" || !n) return nn(400, { error: "body must be a JSON object" });
973
+ if (typeof n != "object" || !n) return _n(400, { error: "body must be a JSON object" });
900
974
  let r = n;
901
- if (!Array.isArray(r.entries)) return nn(400, { error: "entries must be an array" });
902
- let i = typeof r.app == "string" ? q(r.app, 120) : void 0, a = typeof r.page == "string" ? q(r.page, 200) : void 0, o = typeof r.ua == "string" ? q(r.ua, 200) : void 0, s = r.entries.slice(0, Qt), c = 0;
975
+ if (!Array.isArray(r.entries)) return _n(400, { error: "entries must be an array" });
976
+ let i = typeof r.app == "string" ? q(r.app, 120) : void 0, a = typeof r.page == "string" ? q(r.page, 200) : void 0, o = typeof r.ua == "string" ? q(r.ua, 200) : void 0, s = r.entries.slice(0, pn), c = 0;
903
977
  for (let e of s) {
904
978
  if (typeof e != "object" || !e) continue;
905
979
  let n = e;
@@ -910,7 +984,7 @@ __installPublicEnv(publicEnvValues)
910
984
  "warn",
911
985
  "error",
912
986
  "debug"
913
- ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = q(n.message, Yt), u = Array.isArray(n.args) ? n.args.slice(0, Xt).filter((e) => typeof e == "string").map((e) => q(e, Zt)) : void 0, d = typeof n.stack == "string" ? q(n.stack, Yt) : void 0;
987
+ ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = q(n.message, un), u = Array.isArray(n.args) ? n.args.slice(0, dn).filter((e) => typeof e == "string").map((e) => q(e, fn)) : void 0, d = typeof n.stack == "string" ? q(n.stack, un) : void 0;
914
988
  t.emit("clientLog", {
915
989
  ts: s,
916
990
  level: r,
@@ -925,35 +999,35 @@ __installPublicEnv(publicEnvValues)
925
999
  ...i === void 0 ? {} : { app: i },
926
1000
  ...a === void 0 ? {} : { page: a },
927
1001
  ...u !== void 0 && u.length > 0 ? { args: u } : {}
928
- }, p = $t(r);
929
- (p === "error" || p === "warn") && d !== void 0 ? en[p](l, f, { stack: d }) : en[p](l, {
1002
+ }, p = mn(r);
1003
+ (p === "error" || p === "warn") && d !== void 0 ? hn[p](l, f, { stack: d }) : hn[p](l, {
930
1004
  ...f,
931
1005
  ...d === void 0 ? {} : { stack: d }
932
1006
  }), c++;
933
1007
  }
934
- return nn(202, {
1008
+ return _n(202, {
935
1009
  accepted: c,
936
1010
  dropped: r.entries.length - c
937
1011
  });
938
- }, nn = (e, t) => ({
1012
+ }, _n = (e, t) => ({
939
1013
  status: e,
940
1014
  contentType: "application/json; charset=utf-8",
941
1015
  body: JSON.stringify(t)
942
- }), rn = "/_voltro/inspect/clientLog", an = [
1016
+ }), vn = "/_voltro/inspect/clientLog", yn = [
943
1017
  "trace",
944
1018
  "debug",
945
1019
  "info",
946
1020
  "warn",
947
1021
  "error",
948
1022
  "fatal"
949
- ], on = {
1023
+ ], bn = {
950
1024
  trace: "TRACE",
951
1025
  debug: "DEBUG",
952
1026
  info: "INFO ",
953
1027
  warn: "WARN ",
954
1028
  error: "ERROR",
955
1029
  fatal: "FATAL"
956
- }, sn = (e) => an.includes(e), cn = (e, t, n = {}) => {
1030
+ }, xn = (e) => yn.includes(e), Sn = (e, t, n = {}) => {
957
1031
  if (i()) return {
958
1032
  status: 503,
959
1033
  contentType: "application/json",
@@ -984,7 +1058,7 @@ __installPublicEnv(publicEnvValues)
984
1058
  Number.isFinite(e) && e > 0 && (c.max = Math.floor(e));
985
1059
  }
986
1060
  let f = s.get("level");
987
- f !== null && sn(f) && (c.minLevel = f);
1061
+ f !== null && xn(f) && (c.minLevel = f);
988
1062
  let p = s.get("source");
989
1063
  (p === "server" || p === "client") && (c.source = p);
990
1064
  let m = s.get("scope");
@@ -997,7 +1071,7 @@ __installPublicEnv(publicEnvValues)
997
1071
  if ((s.get("format") ?? "json") === "text") return {
998
1072
  status: 200,
999
1073
  contentType: "text/plain; charset=utf-8",
1000
- body: _.map(ln).join("\n") + (_.length > 0 ? "\n" : "")
1074
+ body: _.map(Cn).join("\n") + (_.length > 0 ? "\n" : "")
1001
1075
  };
1002
1076
  let v = {
1003
1077
  capturedAt: Date.now(),
@@ -1011,37 +1085,37 @@ __installPublicEnv(publicEnvValues)
1011
1085
  contentType: "application/json; charset=utf-8",
1012
1086
  body: JSON.stringify(v)
1013
1087
  };
1014
- }, ln = (e) => {
1015
- 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 = dn(e.fields);
1016
- return `${n}:${r}:${i}.${a} ${on[e.level]} ${o} ${e.message}${s}`;
1017
- }, un = 80, dn = (e) => {
1088
+ }, Cn = (e) => {
1089
+ 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 = Tn(e.fields);
1090
+ return `${n}:${r}:${i}.${a} ${bn[e.level]} ${o} ${e.message}${s}`;
1091
+ }, wn = 80, Tn = (e) => {
1018
1092
  let t = Object.entries(e);
1019
1093
  if (t.length === 0) return "";
1020
1094
  let n = [];
1021
1095
  for (let [e, r] of t) {
1022
1096
  if (r === void 0) continue;
1023
- let t = fn(r);
1097
+ let t = En(r);
1024
1098
  n.push(`${e}=${t}`);
1025
1099
  }
1026
1100
  return n.length > 0 ? " " + n.join(" ") : "";
1027
- }, fn = (e) => {
1101
+ }, En = (e) => {
1028
1102
  if (typeof e == "string") {
1029
- let t = e.length > un ? e.slice(0, un) + "…" : e;
1103
+ let t = e.length > wn ? e.slice(0, wn) + "…" : e;
1030
1104
  return /[\s=]/.test(t) ? `"${t.replace(/"/g, "\\\"")}"` : t;
1031
1105
  }
1032
1106
  if (e === null) return "null";
1033
1107
  if (typeof e == "number" || typeof e == "boolean") return String(e);
1034
1108
  try {
1035
1109
  let t = JSON.stringify(e);
1036
- return t.length > un ? t.slice(0, un) + "…" : t;
1110
+ return t.length > wn ? t.slice(0, wn) + "…" : t;
1037
1111
  } catch {
1038
1112
  return "[unserialisable]";
1039
1113
  }
1040
- }, pn = "/_voltro/inspect/logs", mn = (e, t, n) => {
1114
+ }, Dn = "/_voltro/inspect/logs", On = (e, t, n) => {
1041
1115
  if (t.headers.authorization !== void 0) return !1;
1042
1116
  let { token: r } = n;
1043
1117
  return r === void 0 || r === "" || !n.isLoopback(n.target) ? !1 : (e.setHeader("authorization", `Bearer ${r}`), !0);
1044
- }, hn = [{
1118
+ }, kn = [{
1045
1119
  match: (e) => typeof e == "string" && e.startsWith("[BABEL] Note: The code generator has deoptimised"),
1046
1120
  handle: (e, t) => {
1047
1121
  let n = e[0], r = n.match(/deoptimised the styling of (.+?) as it exceeds the max of (\d+\w*B)\.?/);
@@ -1053,13 +1127,13 @@ __installPublicEnv(publicEnvValues)
1053
1127
  });
1054
1128
  } else t.info(n);
1055
1129
  }
1056
- }], gn = () => {
1130
+ }], An = () => {
1057
1131
  let e = {
1058
1132
  warn: console.warn.bind(console),
1059
1133
  error: console.error.bind(console)
1060
1134
  }, t = T({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1061
1135
  if (!n) {
1062
- for (let e of hn) if (e.match(i[0])) {
1136
+ for (let e of kn) if (e.match(i[0])) {
1063
1137
  n = !0;
1064
1138
  try {
1065
1139
  e.handle(i, t);
@@ -1074,7 +1148,7 @@ __installPublicEnv(publicEnvValues)
1074
1148
  return console.warn = r("warn"), console.error = r("error"), () => {
1075
1149
  console.warn = e.warn, console.error = e.error;
1076
1150
  };
1077
- }, _n = {
1151
+ }, jn = {
1078
1152
  loader: "it runs on the server, and the router caches its result per route + params",
1079
1153
  renderMode: "it picks the server render strategy",
1080
1154
  dynamic: "it picks the server render strategy",
@@ -1085,7 +1159,7 @@ __installPublicEnv(publicEnvValues)
1085
1159
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1086
1160
  interactive: "it decides how much client JS the server ships",
1087
1161
  tenantAware: "it is part of the server-side cache key"
1088
- }, vn = Object.keys(_n), yn = (e) => n.test(e), bn = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), xn = "virtual:voltro-route-refresh", Sn = `\0${xn}`, Cn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, wn = () => `
1162
+ }, Mn = Object.keys(jn), Nn = (e) => n.test(e), Pn = (e) => e.replace(/page\.tsx$/, "page.test.tsx"), Fn = "virtual:voltro-route-refresh", In = `\0${Fn}`, Ln = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, Rn = () => `
1089
1163
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1090
1164
 
1091
1165
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1114,11 +1188,11 @@ const stableForm = (value) => {
1114
1188
  * readers (\`build.ts\` prerender, \`webDev.ts\` dev SSR, \`start.ts\`). A change to
1115
1189
  * one of THESE cannot be hot-applied: the server already ran with the old
1116
1190
  * value. Everything else a page exports is plain client-side data. */
1117
- const serverRelevantExports = ${JSON.stringify(vn)}
1191
+ const serverRelevantExports = ${JSON.stringify(Mn)}
1118
1192
 
1119
1193
  /** Name → the server step that already consumed it, so the reload message can
1120
1194
  * say WHY rather than just WHAT. Injected from the same single source. */
1121
- const serverExportEffect = ${JSON.stringify(_n)}
1195
+ const serverExportEffect = ${JSON.stringify(jn)}
1122
1196
 
1123
1197
  /** The reason \`name\` forces a reload, for the console line. */
1124
1198
  export const serverEffectOf = (name) =>
@@ -1161,7 +1235,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1161
1235
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1162
1236
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1163
1237
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1164
- `, Tn = (e) => `
1238
+ `, zn = (e) => `
1165
1239
  if (import.meta.hot) {
1166
1240
  // Self-import to read our OWN exports, the same technique the react plugin
1167
1241
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1188,45 +1262,45 @@ import {
1188
1262
  registerRouteModule as __voltro_registerRouteModule,
1189
1263
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1190
1264
  serverEffectOf as __voltro_serverEffect,
1191
- } from '${xn}'
1192
- `, En = (e) => e.replace(/\\/g, "/"), Dn = (n, r) => {
1193
- let [i = "", a] = En(n).split("?");
1194
- if (!i.endsWith(".tsx") || a !== void 0 && Cn.test(a)) return !1;
1195
- let o = En(r).replace(/\/$/, "");
1265
+ } from '${Fn}'
1266
+ `, Bn = (e) => e.replace(/\\/g, "/"), Vn = (n, r) => {
1267
+ let [i = "", a] = Bn(n).split("?");
1268
+ if (!i.endsWith(".tsx") || a !== void 0 && Ln.test(a)) return !1;
1269
+ let o = Bn(r).replace(/\/$/, "");
1196
1270
  return i.startsWith(`${o}/`) ? t.test(i) || e.has(i.slice(i.lastIndexOf("/") + 1)) : !1;
1197
- }, On = (e, t, n) => Dn(t, n) ? `${e}${Tn(En(t).split("?")[0] ?? t)}` : null, kn = (e) => ({
1271
+ }, Hn = (e, t, n) => Vn(t, n) ? `${e}${zn(Bn(t).split("?")[0] ?? t)}` : null, Un = (e) => ({
1198
1272
  name: "voltro:route-fast-refresh",
1199
1273
  enforce: "pre",
1200
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? Sn : void 0,
1201
- load: (e) => e === Sn ? wn() : void 0,
1274
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? In : void 0,
1275
+ load: (e) => e === In ? Rn() : void 0,
1202
1276
  transform: (t, n, r) => {
1203
1277
  if (r?.ssr === !0) return null;
1204
- let i = On(t, n, e);
1278
+ let i = Hn(t, n, e);
1205
1279
  return i === null ? null : {
1206
1280
  code: i,
1207
1281
  map: null
1208
1282
  };
1209
1283
  }
1210
- }), An = [
1284
+ }), Wn = [
1211
1285
  "static",
1212
1286
  "spa",
1213
1287
  "ssr",
1214
1288
  "isr"
1215
- ], jn = (e) => typeof e == "string" && An.includes(e), Mn = An.map((e) => `'${e}'`).join(" | "), Nn = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${Mn}.${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)." : ""}`, Pn = class extends Error {
1289
+ ], Gn = (e) => typeof e == "string" && Wn.includes(e), Kn = Wn.map((e) => `'${e}'`).join(" | "), qn = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${Kn}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, Jn = class extends Error {
1216
1290
  page;
1217
1291
  value;
1218
1292
  name = "InvalidRenderModeError";
1219
1293
  constructor(e, t) {
1220
- super(Nn(e, t)), this.page = e, this.value = t;
1294
+ super(qn(e, t)), this.page = e, this.value = t;
1221
1295
  }
1222
- }, Fn = (e, t = "<page>") => {
1296
+ }, Yn = (e, t = "<page>") => {
1223
1297
  if (e.renderMode !== void 0 && e.renderMode !== null) {
1224
- if (!jn(e.renderMode)) throw new Pn(t, String(e.renderMode));
1298
+ if (!Gn(e.renderMode)) throw new Jn(t, String(e.renderMode));
1225
1299
  return e.renderMode;
1226
1300
  }
1227
1301
  return e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static");
1228
- }, In = (e, t = "<page>") => ({
1229
- renderMode: Fn(e, t),
1302
+ }, Xn = (e, t = "<page>") => ({
1303
+ renderMode: Yn(e, t),
1230
1304
  tenantAware: e.tenantAware === !0,
1231
1305
  revalidateMs: G(e.revalidate),
1232
1306
  staleWhileRevalidateMs: G(e.staleWhileRevalidate) ?? 0,
@@ -1235,10 +1309,10 @@ import {
1235
1309
  hasLoader: typeof e.loader == "function",
1236
1310
  hasMeta: e.meta != null,
1237
1311
  hasGetStaticPaths: typeof e.getStaticPaths == "function"
1238
- }), Ln = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, Rn = (e) => Ln.exec(e)?.[1] ?? null, zn = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, Bn = (e) => {
1239
- zn.lastIndex = 0;
1312
+ }), Zn = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, Qn = (e) => Zn.exec(e)?.[1] ?? null, $n = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, er = (e) => {
1313
+ $n.lastIndex = 0;
1240
1314
  let t;
1241
- for (; (t = zn.exec(e)) !== null;) {
1315
+ for (; (t = $n.exec(e)) !== null;) {
1242
1316
  let e = t[2];
1243
1317
  if (e.startsWith(".")) for (let n of t[1].split(",")) {
1244
1318
  let t = n.lastIndexOf(" as ");
@@ -1246,110 +1320,36 @@ import {
1246
1320
  }
1247
1321
  }
1248
1322
  return null;
1249
- }, Vn = /export\s*\{([^}]*)\}/g, Hn = (e) => {
1323
+ }, tr = /export\s*\{([^}]*)\}/g, nr = (e) => {
1250
1324
  if (/export\s+default\b/.test(e)) return !0;
1251
- Vn.lastIndex = 0;
1325
+ tr.lastIndex = 0;
1252
1326
  let t;
1253
- for (; (t = Vn.exec(e)) !== null;) for (let e of t[1].split(",")) {
1327
+ for (; (t = tr.exec(e)) !== null;) for (let e of t[1].split(",")) {
1254
1328
  let t = e.lastIndexOf(" as ");
1255
1329
  if ((t === -1 ? e : e.slice(t + 4)).trim() === "default") return !0;
1256
1330
  }
1257
1331
  return !1;
1258
- }, Un = async (e, t) => {
1332
+ }, rr = async (e, t) => {
1259
1333
  let n = (await Promise.all(t.map(async (t) => {
1260
1334
  let n;
1261
1335
  try {
1262
- n = await he(f(e, t.file), "utf8");
1336
+ n = await ge(f(e, t.file), "utf8");
1263
1337
  } catch {
1264
1338
  return null;
1265
1339
  }
1266
- let r = Rn(n);
1267
- return r !== null && !jn(r) ? Nn(f("src", "pages", t.file), r) : Hn(n) ? null : `${f("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.`;
1340
+ let r = Qn(n);
1341
+ return r !== null && !Gn(r) ? qn(f("src", "pages", t.file), r) : nr(n) ? null : `${f("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.`;
1268
1342
  }))).filter((e) => e !== null);
1269
1343
  if (n.length !== 0) throw Error(n.join("\n\n"));
1270
- }, Wn = f(ie(), ".voltro"), Gn = f(Wn, "runtime-registry.json"), Kn = 3e4, qn = () => {
1271
- let e = Math.random().toString(36).slice(2, 10);
1272
- return `${Gn}.${process.pid}.${Date.now()}.${e}.tmp`;
1273
- }, Jn = async () => {
1274
- await j.mkdir(Wn, { recursive: !0 });
1275
- }, Yn = async () => {
1276
- try {
1277
- let e = await j.readFile(Gn, "utf8"), t = JSON.parse(e);
1278
- return t.version !== 1 || !Array.isArray(t.apps) ? {
1279
- version: 1,
1280
- apps: []
1281
- } : t;
1282
- } catch {
1283
- return {
1284
- version: 1,
1285
- apps: []
1286
- };
1287
- }
1288
- }, Xn = async (e) => {
1289
- await Jn();
1290
- let t = qn();
1291
- try {
1292
- await j.writeFile(t, JSON.stringify(e, null, 2), {
1293
- encoding: "utf8",
1294
- mode: 384
1295
- }), await j.rename(t, Gn), await j.chmod(Gn, 384).catch(() => {});
1296
- } catch (e) {
1297
- try {
1298
- await j.unlink(t);
1299
- } catch {}
1300
- throw e;
1301
- }
1302
- }, Zn = (e) => {
1303
- try {
1304
- return process.kill(e, 0), !0;
1305
- } catch {
1306
- return !1;
1307
- }
1308
- }, Qn = (e) => {
1309
- let t = Date.now();
1310
- return e.filter((e) => Zn(e.pid) ? t - new Date(e.heartbeatAt).getTime() < Kn : !1);
1311
- }, $n = async () => {
1312
- let e = await Yn(), t = Qn(e.apps);
1313
- if (t.length === e.apps.length) return e;
1314
- try {
1315
- await Xn({
1316
- version: 1,
1317
- apps: t
1318
- });
1319
- } catch {}
1320
- return {
1321
- version: 1,
1322
- apps: t
1323
- };
1324
- }, er = async (e) => {
1325
- let t = await Yn(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
1326
- ...e,
1327
- ...i !== void 0 && i !== "" ? { inspectToken: i } : {},
1328
- registeredAt: r >= 0 ? t.apps[r].registeredAt : n,
1329
- heartbeatAt: n
1330
- };
1331
- await Xn({
1332
- version: 1,
1333
- apps: r >= 0 ? t.apps.map((e, t) => t === r ? a : e) : [...t.apps, a]
1334
- });
1335
- }, tr = async (e) => {
1336
- try {
1337
- let t = await Yn(), n = t.apps.filter((t) => t.id !== e);
1338
- if (n.length === t.apps.length) return;
1339
- await Xn({
1340
- version: 1,
1341
- apps: n
1342
- });
1343
- } catch {}
1344
- }, nr = (e, t, n) => `${e}:${t}:${n}`, J = f(ie(), ".voltro", "logs"), rr = () => {
1344
+ }, J = f(ie(), ".voltro", "logs"), ir = () => {
1345
1345
  let e = Number(process.env.VOLTRO_LOG_FILE_TTL_MS);
1346
1346
  return Number.isFinite(e) && e > 0 ? e : 3600 * 1e3;
1347
- }, ir = !1, ar = () => {
1348
- if (ir) return;
1349
- ir = !0;
1350
- let e = Date.now() - rr(), t = [];
1347
+ }, ar = !1, or = () => {
1348
+ if (ar) return;
1349
+ ar = !0;
1350
+ let e = Date.now() - ir(), t = [];
1351
1351
  try {
1352
- t = N(J);
1352
+ t = M(J);
1353
1353
  } catch {
1354
1354
  return;
1355
1355
  }
@@ -1357,13 +1357,13 @@ import {
1357
1357
  if (!n.endsWith(".log")) continue;
1358
1358
  let t = f(J, n);
1359
1359
  try {
1360
- P(t).mtimeMs < e && ee(t);
1360
+ N(t).mtimeMs < e && P(t);
1361
1361
  } catch {}
1362
1362
  }
1363
- }, or = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), sr = (e, t) => f(J, `${or(e)}-${t}.log`), cr = (e) => {
1364
- let t = or(e), n = [];
1363
+ }, sr = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80), cr = (e, t) => f(J, `${sr(e)}-${t}.log`), lr = (e) => {
1364
+ let t = sr(e), n = [];
1365
1365
  try {
1366
- n = N(J);
1366
+ n = M(J);
1367
1367
  } catch {
1368
1368
  return;
1369
1369
  }
@@ -1373,17 +1373,17 @@ import {
1373
1373
  for (let e of r) {
1374
1374
  let t = f(J, e);
1375
1375
  try {
1376
- let e = P(t);
1376
+ let e = N(t);
1377
1377
  e.mtimeMs > a && (a = e.mtimeMs, i = t);
1378
1378
  } catch {}
1379
1379
  }
1380
1380
  return i;
1381
- }, lr = (e) => {
1381
+ }, ur = (e) => {
1382
1382
  try {
1383
- k(J, { recursive: !0 });
1383
+ ee(J, { recursive: !0 });
1384
1384
  } catch {}
1385
- ar();
1386
- let t = sr(e, process.pid), n = A(t, "w"), r = (e) => {
1385
+ or();
1386
+ let t = cr(e, process.pid), n = k(t, "w"), r = (e) => {
1387
1387
  let t = {
1388
1388
  ts: e.ts.getTime(),
1389
1389
  level: e.level,
@@ -1424,10 +1424,10 @@ import {
1424
1424
  a(), o(), process.off("exit", o), process.off("uncaughtException", s), process.off("unhandledRejection", s);
1425
1425
  }
1426
1426
  };
1427
- }, ur = async (e, t) => {
1427
+ }, dr = async (e, t) => {
1428
1428
  let n;
1429
1429
  try {
1430
- n = await j.readFile(e, "utf8");
1430
+ n = await A.readFile(e, "utf8");
1431
1431
  } catch {
1432
1432
  return [];
1433
1433
  }
@@ -1438,11 +1438,11 @@ import {
1438
1438
  i.push(t);
1439
1439
  } catch {}
1440
1440
  return t?.max !== void 0 && i.length > t.max ? i.slice(i.length - t.max) : i;
1441
- }, dr = T({ scope: "voltro:dashboard" }), fr = re(import.meta.url), pr = 5179, mr = (e) => {
1441
+ }, fr = T({ scope: "voltro:dashboard" }), pr = ae(import.meta.url), mr = 5179, hr = (e) => {
1442
1442
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1443
1443
  if (t && O(f(m(t), "app.config.ts"))) return m(t);
1444
1444
  try {
1445
- let e = u(fr.resolve("@voltro/dashboard/package.json"));
1445
+ let e = u(pr.resolve("@voltro/dashboard/package.json"));
1446
1446
  if (O(f(e, "app.config.ts"))) return e;
1447
1447
  } catch {}
1448
1448
  let n = f("voltro-devtools", "apps", "dashboard"), r = m(e);
@@ -1454,7 +1454,7 @@ import {
1454
1454
  r = t;
1455
1455
  }
1456
1456
  return null;
1457
- }, hr = "VOLTRO_IS_DASHBOARD", gr = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1457
+ }, gr = "VOLTRO_IS_DASHBOARD", _r = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1458
1458
  let i = ye({
1459
1459
  port: e,
1460
1460
  host: t
@@ -1462,45 +1462,45 @@ import {
1462
1462
  a || (a = !0, i.destroy(), r(e));
1463
1463
  };
1464
1464
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
1465
- }), _r = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), vr = () => process.env[hr] === "1", yr = () => process.stdout.isTTY === !0, Y = f(ie(), ".voltro", "dashboard-launch.lock"), br = 1e4, xr = async () => {
1465
+ }), vr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), yr = () => process.env[gr] === "1", br = () => process.stdout.isTTY === !0, Y = f(ie(), ".voltro", "dashboard-launch.lock"), xr = 1e4, Sr = async () => {
1466
1466
  try {
1467
- await j.mkdir(u(Y), { recursive: !0 });
1468
- let e = await j.open(Y, "wx");
1467
+ await A.mkdir(u(Y), { recursive: !0 });
1468
+ let e = await A.open(Y, "wx");
1469
1469
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1470
1470
  } catch {
1471
1471
  try {
1472
- let e = await j.stat(Y);
1473
- if (Date.now() - e.mtimeMs > br) return await j.unlink(Y).catch(() => void 0), xr();
1472
+ let e = await A.stat(Y);
1473
+ if (Date.now() - e.mtimeMs > xr) return await A.unlink(Y).catch(() => void 0), Sr();
1474
1474
  } catch {}
1475
1475
  return !1;
1476
1476
  }
1477
- }, Sr = async () => {
1477
+ }, Cr = async () => {
1478
1478
  try {
1479
- await j.unlink(Y);
1479
+ await A.unlink(Y);
1480
1480
  } catch {}
1481
- }, Cr = async (e) => {
1481
+ }, wr = async (e) => {
1482
1482
  let t = e.port ?? 5179;
1483
- if (_r()) return {
1483
+ if (vr()) return {
1484
1484
  status: "skipped",
1485
1485
  reason: "disabled by flag/env",
1486
1486
  port: t
1487
1487
  };
1488
- if (vr()) return {
1488
+ if (yr()) return {
1489
1489
  status: "skipped",
1490
1490
  reason: "this process IS the dashboard",
1491
1491
  port: t
1492
1492
  };
1493
- if (!yr()) return {
1493
+ if (!br()) return {
1494
1494
  status: "skipped",
1495
1495
  reason: "stdout is not a TTY (CI/smoke)",
1496
1496
  port: t
1497
1497
  };
1498
- if (!await xr()) return {
1498
+ if (!await Sr()) return {
1499
1499
  status: "skipped",
1500
1500
  reason: "another voltro process is currently launching the dashboard",
1501
1501
  port: t
1502
1502
  };
1503
- if (await gr(t)) return await Sr(), {
1503
+ if (await _r(t)) return await Cr(), {
1504
1504
  status: "already-running",
1505
1505
  port: t
1506
1506
  };
@@ -1517,7 +1517,7 @@ import {
1517
1517
  stdio: "ignore",
1518
1518
  env: {
1519
1519
  ...process.env,
1520
- [hr]: "1",
1520
+ [gr]: "1",
1521
1521
  VOLTRO_DASHBOARD_PORT: String(t)
1522
1522
  }
1523
1523
  });
@@ -1525,22 +1525,22 @@ import {
1525
1525
  if (a.exitCode === null && a.signalCode === null) try {
1526
1526
  a.kill("SIGTERM");
1527
1527
  } catch {}
1528
- }), dr.info(`auto-launching dashboard at http://localhost:${t}`, {
1528
+ }), fr.info(`auto-launching dashboard at http://localhost:${t}`, {
1529
1529
  port: t,
1530
1530
  mode: i,
1531
1531
  prebuilt: r
1532
- }), r || dr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), dr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1533
- Sr();
1532
+ }), r || fr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), fr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1533
+ Cr();
1534
1534
  }, 4e3).unref(), {
1535
1535
  status: "launched",
1536
1536
  port: t
1537
1537
  };
1538
- }, wr = class extends Error {
1538
+ }, Tr = class extends Error {
1539
1539
  _voltroDeferral = !0;
1540
1540
  constructor(e) {
1541
1541
  super(e), this.name = "DeferralNotSupportedError";
1542
1542
  }
1543
- }, Tr = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Er = (e) => {
1543
+ }, Er = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Dr = (e) => {
1544
1544
  let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1545
1545
  for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1546
1546
  let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
@@ -1555,7 +1555,7 @@ import {
1555
1555
  ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
1556
1556
  });
1557
1557
  } catch (e) {
1558
- throw new wr(e instanceof Error ? e.message : String(e));
1558
+ throw new Tr(e instanceof Error ? e.message : String(e));
1559
1559
  }
1560
1560
  return {
1561
1561
  loaderData: n.renderData,
@@ -1571,8 +1571,8 @@ import {
1571
1571
  ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1572
1572
  }
1573
1573
  };
1574
- }, Dr = (e) => {
1575
- let { helpers: t, renderInput: n } = e, r = Er({
1574
+ }, Or = (e) => {
1575
+ let { helpers: t, renderInput: n } = e, r = Dr({
1576
1576
  helpers: t,
1577
1577
  page: e.page,
1578
1578
  pathname: n.pathname,
@@ -1593,37 +1593,37 @@ import {
1593
1593
  stateScript: t.renderRouterStateScript(r.stateInput),
1594
1594
  hasDeferred: r.hasDeferred
1595
1595
  };
1596
- }, Or = (e) => {
1596
+ }, kr = (e) => {
1597
1597
  let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
1598
1598
  return {
1599
1599
  body: t,
1600
1600
  meta: n
1601
1601
  };
1602
- }, kr = (e) => [
1602
+ }, Ar = (e) => [
1603
1603
  ...e.extra ?? [],
1604
1604
  e.helpers.renderMetaToHtml(e.meta),
1605
1605
  `<meta name="voltro-interactive" content="${e.interactive}" />`,
1606
1606
  ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
1607
1607
  e.prepared.stateScript
1608
- ].filter((e) => e.length > 0).join("\n "), Ar = "<div id=\"root\"></div>", jr = "<div id=\"root\">", Mr = "</div>", Nr = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Pr = /\bsrc=["']([^"']+)["']/i, Fr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Ir = (e) => {
1609
- let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Nr, (e) => {
1610
- let r = Pr.exec(e)?.[1];
1608
+ ].filter((e) => e.length > 0).join("\n "), jr = "<div id=\"root\"></div>", Mr = "<div id=\"root\">", Nr = "</div>", Pr = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Fr = /\bsrc=["']([^"']+)["']/i, Ir = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Lr = (e) => {
1609
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Pr, (e) => {
1610
+ let r = Fr.exec(e)?.[1];
1611
1611
  return r === void 0 || t(r) ? e : (n.push(r), "");
1612
1612
  });
1613
- e.inlineModuleScriptsAsync && (r = r.replace(Fr, "<script async$1>"));
1614
- let i = r.indexOf(Ar);
1615
- if (i === -1) throw Error(`[voltro] the generated shell has no \`${Ar}\` 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.`);
1613
+ e.inlineModuleScriptsAsync && (r = r.replace(Ir, "<script async$1>"));
1614
+ let i = r.indexOf(jr);
1615
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${jr}\` 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.`);
1616
1616
  return {
1617
- head: `${r.slice(0, i)}${jr}`,
1618
- tail: `${Mr}${r.slice(i + 21)}`,
1617
+ head: `${r.slice(0, i)}${Mr}`,
1618
+ tail: `${Nr}${r.slice(i + 21)}`,
1619
1619
  bootstrapModules: n
1620
1620
  };
1621
- }, Lr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), Rr = (e) => {
1621
+ }, Rr = (e) => e.head.replace("</head>", ` ${e.headInjection}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), zr = (e) => {
1622
1622
  let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1623
1623
  if (s || !o || a === null) return;
1624
1624
  s = !0, t.statusCode = e.statusCode ?? 200;
1625
1625
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1626
- t.flushHeaders?.(), t.write(Lr({
1626
+ t.flushHeaders?.(), t.write(Rr({
1627
1627
  head: n.head,
1628
1628
  headInjection: i(a.meta),
1629
1629
  htmlLang: r
@@ -1653,14 +1653,14 @@ import {
1653
1653
  return;
1654
1654
  }
1655
1655
  c();
1656
- }, X = T({ scope: "voltro:dev:web" }), zr = T({ scope: "vite" }), Br = await (async () => {
1656
+ }, X = T({ scope: "voltro:dev:web" }), Br = T({ scope: "vite" }), Vr = await (async () => {
1657
1657
  try {
1658
- let e = f(u(h(import.meta.url)), "..", "package.json"), t = await j.readFile(e, "utf8");
1658
+ let e = f(u(h(import.meta.url)), "..", "package.json"), t = await A.readFile(e, "utf8");
1659
1659
  return JSON.parse(t).version ?? "0.0.0";
1660
1660
  } catch {
1661
1661
  return "0.0.0";
1662
1662
  }
1663
- })(), Vr = async () => {
1663
+ })(), Hr = async () => {
1664
1664
  try {
1665
1665
  let e = u(h(import.meta.url)), t = m(e, "..", "..", "devtools");
1666
1666
  if (O(f(t, "package.json"))) return t;
@@ -1669,7 +1669,7 @@ import {
1669
1669
  } catch {
1670
1670
  return null;
1671
1671
  }
1672
- }, Hr = (e, t) => e.disableDevtools || !t ? [] : [
1672
+ }, Ur = (e, t) => e.disableDevtools || !t ? [] : [
1673
1673
  "",
1674
1674
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1675
1675
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1679,12 +1679,12 @@ import {
1679
1679
  " await import('@voltro/devtools/styles.css')",
1680
1680
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1681
1681
  "}"
1682
- ], Ur = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Wr = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Gr = (e) => e.sentry ? [
1682
+ ], Wr = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Gr = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Kr = (e) => e.sentry ? [
1683
1683
  "",
1684
1684
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1685
1685
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1686
1686
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1687
- ] : [], Kr = (e) => e.env ? ["import './env.public'"] : [], qr = (e) => {
1687
+ ] : [], qr = (e) => e.env ? ["import './env.public'"] : [], Jr = (e) => {
1688
1688
  let t = [], n = m(e);
1689
1689
  for (;;) {
1690
1690
  O(f(n, "pnpm-workspace.yaml")) && t.push(n);
@@ -1693,32 +1693,32 @@ import {
1693
1693
  n = e;
1694
1694
  }
1695
1695
  return t;
1696
- }, Jr = yn, Yr = (e) => {
1696
+ }, Yr = Nn, Xr = (e) => {
1697
1697
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1698
1698
  let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1699
1699
  if (t) return `island-${t[1]}`;
1700
- }, Xr = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Zr = (e) => e.startsWith("(") && e.endsWith(")"), Qr = (e) => e.filter((e) => !Zr(e)), $r = (e) => {
1701
- let n = e.replace(t, "").split("/").filter(Boolean).filter((e) => !Zr(e));
1700
+ }, Zr = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Qr = (e) => e.startsWith("(") && e.endsWith(")"), $r = (e) => e.filter((e) => !Qr(e)), ei = (e) => {
1701
+ let n = e.replace(t, "").split("/").filter(Boolean).filter((e) => !Qr(e));
1702
1702
  return n.length === 0 ? "/" : "/" + n.join("/");
1703
- }, ei = (e) => `${e.replace(t, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Z = (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}`, Q = async (n) => {
1703
+ }, ti = (e) => `${e.replace(t, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, Z = (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}`, Q = async (n) => {
1704
1704
  let r = [], i = [], a = async (n, o) => {
1705
1705
  let s = [];
1706
1706
  try {
1707
- s = await j.readdir(n, { withFileTypes: !0 });
1707
+ s = await A.readdir(n, { withFileTypes: !0 });
1708
1708
  } catch {
1709
1709
  return;
1710
1710
  }
1711
- let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Jr(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1711
+ let c = s.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = s.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Yr(e.name)).map((e) => e.name).sort(), u = new Set(l), d = o.join("/");
1712
1712
  if (l.some((t) => e.has(t))) {
1713
1713
  let t = u.has("layout.tsx"), r = !1;
1714
1714
  if (t) try {
1715
- let e = await j.readFile(f(n, "layout.tsx"), "utf8");
1716
- r = Xr.test(e);
1715
+ let e = await A.readFile(f(n, "layout.tsx"), "utf8");
1716
+ r = Zr.test(e);
1717
1717
  } catch {}
1718
1718
  i.push({
1719
1719
  dir: d,
1720
1720
  chain: o,
1721
- contributesToUrl: o.length === 0 || !Zr(o[o.length - 1]),
1721
+ contributesToUrl: o.length === 0 || !Qr(o[o.length - 1]),
1722
1722
  hasLayout: t,
1723
1723
  hasLayoutLoader: r,
1724
1724
  hasError: u.has("error.tsx"),
@@ -1732,8 +1732,8 @@ import {
1732
1732
  let n = d ? `${d}/${e}` : e;
1733
1733
  r.push({
1734
1734
  file: n,
1735
- pattern: $r(n),
1736
- ident: ei(n),
1735
+ pattern: ei(n),
1736
+ ident: ti(n),
1737
1737
  dirChain: o
1738
1738
  });
1739
1739
  }
@@ -1752,14 +1752,14 @@ import {
1752
1752
  dirs: s,
1753
1753
  orphanedSpecials: c
1754
1754
  };
1755
- }, ti = (e, t) => {
1755
+ }, ni = (e, t) => {
1756
1756
  let n = [];
1757
1757
  for (let r = 0; r <= t.length; r++) {
1758
1758
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1759
1759
  a && n.push(a);
1760
1760
  }
1761
1761
  return n;
1762
- }, ni = async (e) => {
1762
+ }, ri = async (e) => {
1763
1763
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1764
1764
  return {
1765
1765
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1781,10 +1781,10 @@ import {
1781
1781
  })),
1782
1782
  segmentLoaderData: o
1783
1783
  };
1784
- }, ri = (e) => {
1785
- let t = Qr(e);
1784
+ }, ii = (e) => {
1785
+ let t = $r(e);
1786
1786
  return t.length === 0 ? "" : "/" + t.join("/");
1787
- }, ii = [
1787
+ }, ai = [
1788
1788
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1789
1789
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1790
1790
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1877,7 +1877,7 @@ import {
1877
1877
  " _vdtErrorStart('Build error')",
1878
1878
  " })",
1879
1879
  "}"
1880
- ].join("\n"), ai = (e) => {
1880
+ ].join("\n"), oi = (e) => {
1881
1881
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1882
1882
  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, "\\$&"));
1883
1883
  let a = i.join("/");
@@ -1886,8 +1886,8 @@ import {
1886
1886
  paramNames: t,
1887
1887
  priority: n
1888
1888
  };
1889
- }, oi = (e) => e.map((e) => {
1890
- let { regex: t, paramNames: n, priority: r } = ai(e.pattern);
1889
+ }, si = (e) => e.map((e) => {
1890
+ let { regex: t, paramNames: n, priority: r } = oi(e.pattern);
1891
1891
  return {
1892
1892
  pattern: e.pattern,
1893
1893
  file: e.file,
@@ -1896,7 +1896,7 @@ import {
1896
1896
  paramNames: n,
1897
1897
  priority: r
1898
1898
  };
1899
- }).slice().sort((e, t) => e.priority - t.priority), si = (e, t) => {
1899
+ }).slice().sort((e, t) => e.priority - t.priority), ci = (e, t) => {
1900
1900
  for (let n of t) {
1901
1901
  let t = n.regex.exec(e);
1902
1902
  if (!t) continue;
@@ -1908,13 +1908,13 @@ import {
1908
1908
  };
1909
1909
  }
1910
1910
  return null;
1911
- }, ci = async (e, t) => {
1911
+ }, li = async (e, t) => {
1912
1912
  let n = e;
1913
1913
  for (;;) {
1914
1914
  let e = f(n, "node_modules", t);
1915
1915
  try {
1916
- if ((await j.stat(e)).isDirectory()) {
1917
- let t = await j.realpath(e);
1916
+ if ((await A.stat(e)).isDirectory()) {
1917
+ let t = await A.realpath(e);
1918
1918
  return t.includes("/node_modules/") ? null : t;
1919
1919
  }
1920
1920
  } catch {}
@@ -1922,7 +1922,7 @@ import {
1922
1922
  if (r === n) return null;
1923
1923
  n = r;
1924
1924
  }
1925
- }, li = async (e) => {
1925
+ }, ui = async (e) => {
1926
1926
  try {
1927
1927
  let t = await import(g(f(e, "app.config.ts")).href), n = t.default?.port, r = typeof n == "number" ? n : 4e3, i = t.default?.transport?.wsPath, a = typeof i == "string" && i.startsWith("/") ? i : void 0;
1928
1928
  return a ? {
@@ -1931,7 +1931,7 @@ import {
1931
1931
  } : { port: r };
1932
1932
  } catch {}
1933
1933
  return { port: 4e3 };
1934
- }, ui = (e, t) => ({
1934
+ }, di = (e, t) => ({
1935
1935
  name: e,
1936
1936
  pkg: t.package,
1937
1937
  browserWsUrl: t.url,
@@ -1939,7 +1939,7 @@ import {
1939
1939
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1940
1940
  ...t.headers ? { headers: t.headers } : {},
1941
1941
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1942
- }), di = (e, t, n) => {
1942
+ }), fi = (e, t, n) => {
1943
1943
  let r = t.transport?.wsPath ?? n.wsPath;
1944
1944
  return {
1945
1945
  name: e,
@@ -1951,7 +1951,7 @@ import {
1951
1951
  ...t.headers ? { headers: t.headers } : {},
1952
1952
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1953
1953
  };
1954
- }, fi = (e) => {
1954
+ }, pi = (e) => {
1955
1955
  let t = /* @__PURE__ */ new Map();
1956
1956
  for (let n of e) {
1957
1957
  if (n.proxyTarget === void 0) continue;
@@ -1959,43 +1959,43 @@ import {
1959
1959
  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>.`);
1960
1960
  t.set(n.browserWsUrl, n.name);
1961
1961
  }
1962
- }, pi = async (e, t) => {
1962
+ }, mi = async (e, t) => {
1963
1963
  let n = Object.entries(t.apis ?? {}), r = [];
1964
1964
  for (let [t, i] of n) {
1965
1965
  if (i.url) {
1966
- r.push(ui(t, i));
1966
+ r.push(di(t, i));
1967
1967
  continue;
1968
1968
  }
1969
- let n = await ci(e, i.package);
1969
+ let n = await li(e, i.package);
1970
1970
  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.`);
1971
- r.push(di(t, i, await li(n)));
1971
+ r.push(fi(t, i, await ui(n)));
1972
1972
  }
1973
- return fi(r), r;
1974
- }, mi = (e) => {
1973
+ return pi(r), r;
1974
+ }, hi = (e) => {
1975
1975
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
1976
1976
  let t = new URL(e);
1977
1977
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
1978
1978
  } catch {
1979
1979
  return;
1980
1980
  }
1981
- }, hi = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, gi = (e) => process.env[hi(e)] ?? process.env.VOLTRO_API_ORIGIN, _i = (e, t) => {
1981
+ }, gi = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, _i = (e) => process.env[gi(e)] ?? process.env.VOLTRO_API_ORIGIN, vi = (e, t) => {
1982
1982
  if (!e) return;
1983
- let n = gi(e.name) ?? e.serverOrigin;
1983
+ let n = _i(e.name) ?? e.serverOrigin;
1984
1984
  if (n) {
1985
- let e = mi(n);
1985
+ let e = hi(n);
1986
1986
  if (e) return e;
1987
1987
  }
1988
1988
  if (t?.allowDevProxy && e.proxyTarget) {
1989
- let t = mi(e.proxyTarget);
1989
+ let t = hi(e.proxyTarget);
1990
1990
  if (t) return t;
1991
1991
  }
1992
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return mi(e.browserWsUrl);
1993
- }, vi = (e, t, n) => {
1992
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return hi(e.browserWsUrl);
1993
+ }, yi = (e, t, n) => {
1994
1994
  if (!e) {
1995
1995
  if (n?.apiName === void 0) return;
1996
1996
  let e = n.apiName;
1997
1997
  return async () => {
1998
- 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 ${hi(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.`);
1998
+ 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 ${gi(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.`);
1999
1999
  };
2000
2000
  }
2001
2001
  return async (r, i) => {
@@ -2017,7 +2017,7 @@ import {
2017
2017
  });
2018
2018
  } catch (t) {
2019
2019
  let i = t?.cause?.code ?? String(t?.message ?? t);
2020
- throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${hi(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 });
2020
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${gi(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 });
2021
2021
  }
2022
2022
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2023
2023
  let s = await o.json();
@@ -2036,7 +2036,7 @@ import {
2036
2036
  if (u) return l;
2037
2037
  };
2038
2038
  }, $ = async (e, t, n, r = {}) => {
2039
- let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = O(f(e, "node_modules", "@voltro", "devtools", "package.json")) || await Vr() !== null, s = t.theme === "system" ? [
2039
+ let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = O(f(e, "node_modules", "@voltro", "devtools", "package.json")) || await Hr() !== null, s = t.theme === "system" ? [
2040
2040
  " <script>",
2041
2041
  " (function () {",
2042
2042
  " var root = document.documentElement",
@@ -2075,7 +2075,7 @@ import {
2075
2075
  "</html>",
2076
2076
  ""
2077
2077
  ].join("\n"), l = f(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: p } = await Q(l);
2078
- await Un(l, u);
2078
+ await rr(l, u);
2079
2079
  for (let e of p) X.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.`);
2080
2080
  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'`);
2081
2081
  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"));
@@ -2090,13 +2090,13 @@ import {
2090
2090
  e.hasLayout && e.hasLayoutLoader ? n.push(`import * as ${Z(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && n.push(`import ${Z(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && n.push(`import ${Z(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && n.push(`import ${Z(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && n.push(`import ${Z(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2091
2091
  }
2092
2092
  let r = u.map((e) => {
2093
- let t = ti(d, e.dirChain).map((e) => {
2093
+ let t = ni(d, e.dirChain).map((e) => {
2094
2094
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2095
2095
  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(", ")} }`;
2096
2096
  }).join(",\n");
2097
2097
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2098
2098
  }), i = d.filter((e) => e.hasNotFound).map((e) => {
2099
- let t = ri(e.chain), n = ti(d, e.chain).map((e) => {
2099
+ let t = ii(e.chain), n = ni(d, e.chain).map((e) => {
2100
2100
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2101
2101
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2102
2102
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
@@ -2335,14 +2335,14 @@ import {
2335
2335
  "// resolved apis map. Side-effect only — no local component definitions —",
2336
2336
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2337
2337
  "",
2338
- ...Kr(t),
2338
+ ...qr(t),
2339
2339
  "import { mount } from '@voltro/web'",
2340
2340
  ...g,
2341
2341
  "import { App } from './app'",
2342
2342
  "import { preloadCurrentRoute } from './routeTable'",
2343
- ...Wr(t),
2344
- ...Hr(t, o),
2345
2343
  ...Gr(t),
2344
+ ...Ur(t, o),
2345
+ ...Kr(t),
2346
2346
  "",
2347
2347
  "// Preload the current route's page chunk BEFORE hydration so the first",
2348
2348
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2359,10 +2359,10 @@ import {
2359
2359
  " apis: {",
2360
2360
  ..._,
2361
2361
  " },",
2362
- ...Ur(t, o),
2362
+ ...Wr(t, o),
2363
2363
  "})",
2364
2364
  "",
2365
- ii
2365
+ ai
2366
2366
  ].join("\n");
2367
2367
  } else v = "", y = "", b = [
2368
2368
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
@@ -2370,43 +2370,43 @@ import {
2370
2370
  "// and calls mount(). Side-effect only, no component definitions, so the",
2371
2371
  "// user's component file remains the Fast Refresh boundary.",
2372
2372
  "",
2373
- ...Kr(t),
2373
+ ...qr(t),
2374
2374
  "import { mount } from '@voltro/web'",
2375
2375
  ...g,
2376
2376
  "import App from '../src/App'",
2377
- ...Wr(t),
2378
- ...Hr(t, o),
2379
2377
  ...Gr(t),
2378
+ ...Ur(t, o),
2379
+ ...Kr(t),
2380
2380
  "",
2381
2381
  "mount(App, {",
2382
2382
  " apis: {",
2383
2383
  ..._,
2384
2384
  " },",
2385
- ...Ur(t, o),
2385
+ ...Wr(t, o),
2386
2386
  "})",
2387
2387
  "",
2388
- ii
2388
+ ai
2389
2389
  ].join("\n");
2390
2390
  let x = f(e, ".framework");
2391
- await j.mkdir(x, { recursive: !0 }), t.env ? await tt(x, r) : await j.rm(f(x, "env.public.ts"), { force: !0 }), await j.writeFile(f(x, "index.html"), c, "utf8"), await j.writeFile(f(x, "main.tsx"), b, "utf8"), v ? (await j.writeFile(f(x, "app.tsx"), v, "utf8"), await j.writeFile(f(x, "routeTable.ts"), y, "utf8")) : (await j.rm(f(x, "app.tsx"), { force: !0 }), await j.rm(f(x, "routeTable.ts"), { force: !0 }));
2391
+ await A.mkdir(x, { recursive: !0 }), t.env ? await ht(x, r) : await A.rm(f(x, "env.public.ts"), { force: !0 }), await A.writeFile(f(x, "index.html"), c, "utf8"), await A.writeFile(f(x, "main.tsx"), b, "utf8"), v ? (await A.writeFile(f(x, "app.tsx"), v, "utf8"), await A.writeFile(f(x, "routeTable.ts"), y, "utf8")) : (await A.rm(f(x, "app.tsx"), { force: !0 }), await A.rm(f(x, "routeTable.ts"), { force: !0 }));
2392
2392
  let S = f(e, ".gitignore"), C = "";
2393
2393
  try {
2394
- C = await j.readFile(S, "utf8");
2394
+ C = await A.readFile(S, "utf8");
2395
2395
  } catch {}
2396
2396
  let w = ["/.framework/"], T = new Set(C.split("\n").map((e) => e.trim())), E = w.filter((e) => !T.has(e));
2397
2397
  if (E.length > 0) {
2398
2398
  let e = C === "" || C.endsWith("\n") ? "" : "\n";
2399
2399
  try {
2400
- await j.appendFile(S, `${e}${E.join("\n")}\n`, "utf8");
2400
+ await A.appendFile(S, `${e}${E.join("\n")}\n`, "utf8");
2401
2401
  } catch (e) {
2402
2402
  X.warn(`could not add ${E.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2403
2403
  }
2404
2404
  }
2405
- }, yi = async (e, t) => {
2405
+ }, bi = async (e, t) => {
2406
2406
  try {
2407
2407
  let n = f(u(e), "project.json");
2408
2408
  if (!O(n)) return;
2409
- let r = await j.readFile(n, "utf8"), i = JSON.parse(r).apps ?? {}, a = e.split("/").filter(Boolean).pop() ?? "", o = [];
2409
+ let r = await A.readFile(n, "utf8"), i = JSON.parse(r).apps ?? {}, a = e.split("/").filter(Boolean).pop() ?? "", o = [];
2410
2410
  for (let [e, n] of Object.entries(i)) e !== a && n.port === t && o.push(e);
2411
2411
  if (o.length === 0) return;
2412
2412
  X.warn("sibling app(s) claim the same port — only one boots", {
@@ -2415,36 +2415,36 @@ import {
2415
2415
  projectJson: n
2416
2416
  });
2417
2417
  } catch {}
2418
- }, bi = (e) => f(e, ".framework", "dist", "server", "appConfig.js"), xi = async (e) => {
2419
- let t = bi(e), n = O(t) ? t : f(e, "app.config.ts");
2418
+ }, xi = (e) => f(e, ".framework", "dist", "server", "appConfig.js"), Si = async (e) => {
2419
+ let t = xi(e), n = O(t) ? t : f(e, "app.config.ts");
2420
2420
  try {
2421
2421
  let e = (await import(g(n).href)).default;
2422
2422
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2423
2423
  } catch {
2424
2424
  return null;
2425
2425
  }
2426
- }, Si = async (e) => {
2427
- let t = await xi(e);
2426
+ }, Ci = async (e) => {
2427
+ let t = await Si(e);
2428
2428
  if (!t) return {
2429
2429
  ran: !1,
2430
2430
  exitCode: 0
2431
2431
  };
2432
- gn();
2433
- let n = Rt();
2434
- Jt(n), X.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2435
- let u = await pi(e, t);
2432
+ An();
2433
+ let n = Qt();
2434
+ ln(n), X.info("booting voltro dev (web)", { app: t.name ?? "(unnamed)" });
2435
+ let u = await mi(e, t);
2436
2436
  for (let e of u) X.info("api wired", {
2437
2437
  name: e.name,
2438
2438
  pkg: e.pkg,
2439
2439
  ...e.proxyTarget ? { proxyTo: e.proxyTarget } : { directWs: e.browserWsUrl }
2440
2440
  });
2441
- We(e).then((e) => {
2441
+ Ge(e).then((e) => {
2442
2442
  for (let t of e.files) if (t.action === "created") {
2443
2443
  let e = t.path.split("/").pop() ?? t.path;
2444
2444
  X.info(`${e} seeded`, { path: t.path });
2445
2445
  }
2446
2446
  }).catch(() => {});
2447
- let { resolved: d } = await nt({
2447
+ let { resolved: d } = await gt({
2448
2448
  rawEnv: t.env,
2449
2449
  appType: "web",
2450
2450
  root: e,
@@ -2456,8 +2456,8 @@ import {
2456
2456
  ".framework/main.tsx",
2457
2457
  ...t.env ? [".framework/env.public.ts"] : []
2458
2458
  ] });
2459
- 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 = nr("web", _, g), y = lr(_);
2460
- await er({
2459
+ 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 = at("web", _, g), y = ur(_);
2460
+ await rt({
2461
2461
  id: v,
2462
2462
  name: _,
2463
2463
  kind: "web",
@@ -2465,19 +2465,22 @@ import {
2465
2465
  pid: process.pid,
2466
2466
  status: "booting",
2467
2467
  logFile: y.path
2468
- }).catch(() => {}), await yi(e, g);
2469
- let { pages: b, dirs: x } = await Q(f(e, "src", "pages")), S = x.map((e) => ({
2468
+ }).catch(() => {}), await bi(e, g);
2469
+ let { pages: b, dirs: x } = await Q(f(e, "src", "pages")), S = {
2470
+ dirs: x,
2471
+ ssrRoutes: si(b)
2472
+ }, C = x.map((e) => ({
2470
2473
  dir: e.dir,
2471
2474
  hasLayout: e.hasLayout,
2472
2475
  hasError: e.hasError,
2473
2476
  hasPending: e.hasPending,
2474
2477
  hasNotFound: e.hasNotFound
2475
- })), C = await It({
2478
+ })), w = await Xt({
2476
2479
  appRoot: e,
2477
2480
  pages: b
2478
2481
  });
2479
- C.wrote && X.debug("routes codegen wrote", { path: p(e, C.path) });
2480
- let w = await Ye("vite", () => import("vite")), T = (await import("@vitejs/plugin-react")).default, D = (await import("@tailwindcss/vite")).default, k = f(e, ".framework"), A = f(e, "src"), M = /* @__PURE__ */ new Set([
2482
+ w.wrote && X.debug("routes codegen wrote", { path: p(e, w.path) });
2483
+ let T = await lt("vite", () => import("vite")), D = (await import("@vitejs/plugin-react")).default, ee = (await import("@tailwindcss/vite")).default, k = f(e, ".framework"), j = f(e, "src"), M = /* @__PURE__ */ new Set([
2481
2484
  ".framework",
2482
2485
  "node_modules",
2483
2486
  "dist",
@@ -2489,70 +2492,71 @@ import {
2489
2492
  name: "framework:watch-app-sources",
2490
2493
  async configureServer(t) {
2491
2494
  try {
2492
- let n = (await j.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !M.has(e.name));
2495
+ let n = (await A.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !M.has(e.name));
2493
2496
  for (let r of n) t.watcher.add(f(e, r.name));
2494
- n.length === 0 && t.watcher.add(A);
2497
+ n.length === 0 && t.watcher.add(j);
2495
2498
  } catch {
2496
- t.watcher.add(A);
2499
+ t.watcher.add(j);
2497
2500
  }
2498
2501
  try {
2499
- let n = await j.readFile(f(e, "package.json"), "utf8"), r = JSON.parse(n), i = Object.keys({
2502
+ let n = await A.readFile(f(e, "package.json"), "utf8"), r = JSON.parse(n), i = Object.keys({
2500
2503
  ...r.dependencies,
2501
2504
  ...r.devDependencies
2502
2505
  });
2503
2506
  await Promise.all(i.map(async (n) => {
2504
- let r = await ci(e, n);
2507
+ let r = await li(e, n);
2505
2508
  if (!r) return;
2506
2509
  let i = f(r, "src");
2507
2510
  try {
2508
- (await j.stat(i)).isDirectory() && t.watcher.add(i);
2511
+ (await A.stat(i)).isDirectory() && t.watcher.add(i);
2509
2512
  } catch {}
2510
2513
  }));
2511
2514
  } catch {}
2512
2515
  }
2513
- }, P = f(e, "src", "pages"), ee = (e) => e.endsWith(".tsx") && (e === P || e.startsWith(P + "/")), F = (e) => e === P || e.startsWith(P + "/"), te = async (n) => {
2516
+ }, P = f(e, "src", "pages"), F = (e) => e.endsWith(".tsx") && (e === P || e.startsWith(P + "/")), te = (e) => e === P || e.startsWith(P + "/"), I = async (n) => {
2514
2517
  try {
2515
2518
  let r = Date.now();
2516
2519
  await $(e, t, u, h);
2517
- let { pages: i } = await Q(P);
2518
- await It({
2520
+ let { pages: i, dirs: a } = await Q(P);
2521
+ await Xt({
2519
2522
  appRoot: e,
2520
2523
  pages: i
2521
- }), X.info("page tree regenerated", {
2524
+ }), S.dirs = a, S.ssrRoutes = si(i), X.info("page tree regenerated", {
2522
2525
  reason: n,
2523
- ms: Date.now() - r
2526
+ ms: Date.now() - r,
2527
+ routes: S.ssrRoutes.length
2524
2528
  });
2525
2529
  } catch (e) {
2526
2530
  X.error("page tree regen failed", { reason: n }, e);
2527
2531
  }
2528
- }, I = {
2532
+ }, ne = {
2529
2533
  name: "framework:regenerate-on-page-tree-change",
2530
2534
  configureServer(t) {
2531
2535
  let n = null, r = [], i = (e) => {
2532
2536
  r.push(e), n && clearTimeout(n), n = setTimeout(() => {
2533
2537
  n = null;
2534
2538
  let e = r.length === 1 ? r[0] : `${r.length} events (${r[0]}, …)`;
2535
- r.length = 0, te(e);
2539
+ r.length = 0, I(e);
2536
2540
  }, 50);
2537
2541
  };
2538
2542
  t.watcher.on("add", (t) => {
2539
- ee(t) && i(`add ${p(e, t)}`);
2543
+ F(t) && i(`add ${p(e, t)}`);
2540
2544
  }), t.watcher.on("unlink", (t) => {
2541
- ee(t) && i(`unlink ${p(e, t)}`);
2545
+ F(t) && i(`unlink ${p(e, t)}`);
2542
2546
  }), t.watcher.on("addDir", (t) => {
2543
- F(t) && i(`addDir ${p(e, t)}`);
2547
+ te(t) && i(`addDir ${p(e, t)}`);
2544
2548
  }), t.watcher.on("unlinkDir", (t) => {
2545
- F(t) && i(`unlinkDir ${p(e, t)}`);
2549
+ te(t) && i(`unlinkDir ${p(e, t)}`);
2546
2550
  });
2547
2551
  }
2548
- }, L = f(e, "app.config.ts"), R = (e) => {
2549
- if (!le(e.env)) return "";
2552
+ }, L = f(e, "app.config.ts"), re = (e) => {
2553
+ if (!de(e.env)) return "";
2550
2554
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2551
2555
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2552
- }, ne = (e, t) => {
2556
+ }, ie = (e, t) => {
2553
2557
  let n = [];
2554
- 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"), R(e) !== R(t) && n.push("env"), n;
2555
- }, re = t, ie = m(L), ae = {
2558
+ 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;
2559
+ }, ae = t, oe = m(L), se = {
2556
2560
  name: "framework:watch-app-config",
2557
2561
  async configureServer(t) {
2558
2562
  t.watcher.add(L), X.info("watching app.config.ts for changes", { path: p(e, L) });
@@ -2581,11 +2585,11 @@ import {
2581
2585
  theme: r.theme,
2582
2586
  port: r.port,
2583
2587
  name: r.name
2584
- }), JSON.stringify(r) === JSON.stringify(re)) {
2588
+ }), JSON.stringify(r) === JSON.stringify(ae)) {
2585
2589
  X.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2586
2590
  return;
2587
2591
  }
2588
- let i = ne(re, r);
2592
+ let i = ie(ae, r);
2589
2593
  if (i.length > 0) {
2590
2594
  X.warn("app.config.ts changed — hard restart required", { fields: i });
2591
2595
  try {
@@ -2607,7 +2611,7 @@ import {
2607
2611
  }
2608
2612
  try {
2609
2613
  let n = Date.now();
2610
- await $(e, r, await pi(e, r)), re = r, t.ws && t.ws.send({
2614
+ await $(e, r, await mi(e, r)), ae = r, t.ws && t.ws.send({
2611
2615
  type: "full-reload",
2612
2616
  path: "*"
2613
2617
  }), X.info("app.config.ts soft-regen", {
@@ -2617,7 +2621,7 @@ import {
2617
2621
  } catch (e) {
2618
2622
  X.error("app.config.ts soft-regen failed", {}, e);
2619
2623
  }
2620
- }, o = (e) => l(e) === "app.config.ts" ? e === L || m(e) === ie : !1;
2624
+ }, o = (e) => l(e) === "app.config.ts" ? e === L || m(e) === oe : !1;
2621
2625
  t.watcher.on("change", (e) => {
2622
2626
  o(e) && (X.info("app.config.ts change event (chokidar)", { file: e }), i());
2623
2627
  }), t.watcher.on("add", (e) => {
@@ -2631,27 +2635,27 @@ import {
2631
2635
  } catch (e) {
2632
2636
  X.warn("app.config.ts polling watcher could not attach", {}, e);
2633
2637
  }
2634
- ht(ft, X, {
2638
+ kt(Et, X, {
2635
2639
  root: e,
2636
2640
  onBeforeRestart: () => t.close()
2637
2641
  });
2638
2642
  }
2639
- }, oe = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, se = {
2643
+ }, ce = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, le = {
2640
2644
  name: "framework:suppress-api-hmr",
2641
2645
  handleHotUpdate(e) {
2642
- if (oe.test(e.file)) return [];
2646
+ if (ce.test(e.file)) return [];
2643
2647
  }
2644
- }, ce = {
2648
+ }, ue = {
2645
2649
  name: "framework:reoptimize-on-rpcgroup-change",
2646
2650
  async configureServer(t) {
2647
2651
  let n = /* @__PURE__ */ new Map();
2648
2652
  for (let r of u) {
2649
2653
  if (!r.proxyTarget) continue;
2650
- let i = await ci(e, r.pkg);
2654
+ let i = await li(e, r.pkg);
2651
2655
  if (!i) continue;
2652
2656
  let a = f(i, "rpcGroup.generated.ts");
2653
2657
  try {
2654
- n.set(a, await j.readFile(a, "utf8"));
2658
+ n.set(a, await A.readFile(a, "utf8"));
2655
2659
  } catch {
2656
2660
  n.set(a, "");
2657
2661
  }
@@ -2666,7 +2670,7 @@ import {
2666
2670
  for (let [e, t] of n) {
2667
2671
  let i;
2668
2672
  try {
2669
- i = await j.readFile(e, "utf8");
2673
+ i = await A.readFile(e, "utf8");
2670
2674
  } catch {
2671
2675
  continue;
2672
2676
  }
@@ -2675,7 +2679,7 @@ import {
2675
2679
  if (r !== null) {
2676
2680
  i = !0, X.info(`rpcGroup changed (${p(e, r)}) — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)`);
2677
2681
  try {
2678
- await j.rm(f(k, ".vite", "deps"), {
2682
+ await A.rm(f(k, ".vite", "deps"), {
2679
2683
  recursive: !0,
2680
2684
  force: !0
2681
2685
  }), await t.restart(!0);
@@ -2690,9 +2694,9 @@ import {
2690
2694
  };
2691
2695
  t.watcher.on("change", o), t.watcher.on("add", o);
2692
2696
  }
2693
- }, z = {}, ue = (e) => (t) => {
2697
+ }, R = {}, fe = (e) => (t) => {
2694
2698
  t.on("proxyReq", (t, n) => {
2695
- mn(t, n, {
2699
+ On(t, n, {
2696
2700
  target: e,
2697
2701
  token: process.env.VOLTRO_INSPECT_TOKEN,
2698
2702
  isLoopback: r
@@ -2701,26 +2705,26 @@ import {
2701
2705
  };
2702
2706
  for (let e of u) {
2703
2707
  if (!e.proxyTarget) continue;
2704
- z[e.browserWsUrl] = {
2708
+ R[e.browserWsUrl] = {
2705
2709
  target: e.proxyTarget,
2706
2710
  ws: !0,
2707
2711
  changeOrigin: !0,
2708
2712
  ...e.wsPath ? {} : { rewrite: () => "/ws" }
2709
2713
  };
2710
2714
  let t = e.proxyTarget.replace(/^ws/, "http");
2711
- z[`/_voltro/api/${e.name}`] = {
2715
+ R[`/_voltro/api/${e.name}`] = {
2712
2716
  target: t,
2713
2717
  changeOrigin: !0,
2714
2718
  rewrite: (t) => t.replace(RegExp(`^/_voltro/api/${e.name}`), ""),
2715
- configure: ue(t)
2719
+ configure: fe(t)
2716
2720
  };
2717
2721
  }
2718
2722
  for (let [e, n] of Object.entries(t.proxies ?? {})) {
2719
- if (z[e]) {
2723
+ if (R[e]) {
2720
2724
  X.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
2721
2725
  continue;
2722
2726
  }
2723
- z[e] = {
2727
+ R[e] = {
2724
2728
  target: n.target,
2725
2729
  changeOrigin: n.changeOrigin ?? !0,
2726
2730
  ...n.rewrite === void 0 ? {} : { rewrite: (t) => t.replace(RegExp(`^${e}`), n.rewrite) }
@@ -2730,7 +2734,7 @@ import {
2730
2734
  ...n.rewrite === void 0 ? {} : { rewrite: n.rewrite }
2731
2735
  });
2732
2736
  }
2733
- let de = {
2737
+ let pe = {
2734
2738
  name: "framework:inspect",
2735
2739
  configureServer(l) {
2736
2740
  let u = null, d = async () => {
@@ -2742,7 +2746,7 @@ import {
2742
2746
  pattern: n.pattern,
2743
2747
  file: n.file,
2744
2748
  dirChain: n.dirChain,
2745
- renderMode: Fn(r, f("src", "pages", n.file)),
2749
+ renderMode: Yn(r, f("src", "pages", n.file)),
2746
2750
  interactive: r.interactive ?? "full",
2747
2751
  tenantAware: r.tenantAware === !0,
2748
2752
  revalidateMs: G(r.revalidate),
@@ -2861,7 +2865,7 @@ import {
2861
2865
  for (let [t, n] of Object.entries(e.headers ?? {})) n !== void 0 && (u[String(t).toLowerCase()] = Array.isArray(n) ? n.join(", ") : String(n));
2862
2866
  let f = l.split("?")[0];
2863
2867
  if (e.method === "GET" && (f === "/_voltro/inspect/logs" || l.startsWith("/_voltro/inspect/logs?"))) {
2864
- let e = c(u.origin), t = cn(l, Kt(), u);
2868
+ let e = c(u.origin), t = Sn(l, sn(), u);
2865
2869
  r.statusCode = t.status, r.setHeader("content-type", t.contentType);
2866
2870
  for (let [t, n] of Object.entries(e)) r.setHeader(t, n);
2867
2871
  r.end(t.body);
@@ -2879,7 +2883,7 @@ import {
2879
2883
  e.setEncoding("utf-8"), e.on("data", (e) => {
2880
2884
  a += e;
2881
2885
  }), e.on("end", () => {
2882
- let e = tn(a, n);
2886
+ let e = gn(a, n);
2883
2887
  r.statusCode = e.status, r.setHeader("content-type", e.contentType);
2884
2888
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2885
2889
  r.end(e.body);
@@ -2910,14 +2914,14 @@ import {
2910
2914
  for (let [e, n] of Object.entries(t)) r.setHeader(e, n);
2911
2915
  r.flushHeaders?.(), r.write("retry: 5000\n\n");
2912
2916
  let s = l.indexOf("?");
2913
- if (!(s !== -1 && new URLSearchParams(l.slice(s + 1)).get("live") === "1")) for (let e of n.buffered()) r.write(zt(e));
2917
+ if (!(s !== -1 && new URLSearchParams(l.slice(s + 1)).get("live") === "1")) for (let e of n.buffered()) r.write($t(e));
2914
2918
  let d = n.subscribe((e) => {
2915
2919
  try {
2916
- r.write(zt(e));
2920
+ r.write($t(e));
2917
2921
  } catch {}
2918
2922
  }), f = setInterval(() => {
2919
2923
  try {
2920
- r.write(Bt());
2924
+ r.write(en());
2921
2925
  } catch {}
2922
2926
  }, 15e3), p = () => {
2923
2927
  clearInterval(f), d();
@@ -2930,7 +2934,7 @@ import {
2930
2934
  kind: "web",
2931
2935
  meta: {
2932
2936
  name: t.name ?? "(unnamed)",
2933
- voltroVersion: Br,
2937
+ voltroVersion: Vr,
2934
2938
  port: g,
2935
2939
  mode: "dev",
2936
2940
  apis: Object.entries(t.apis ?? {}).map(([e, t]) => {
@@ -2942,13 +2946,13 @@ import {
2942
2946
  })
2943
2947
  },
2944
2948
  routes: await d(),
2945
- dirs: S,
2949
+ dirs: C,
2946
2950
  cache: () => ({
2947
2951
  backend: "memory",
2948
2952
  size: 0,
2949
2953
  entries: []
2950
2954
  }),
2951
- env: () => it(t.name ?? "app", { contract: le(t.env) ? t.env : void 0 })
2955
+ env: () => vt(t.name ?? "app", { contract: de(t.env) ? t.env : void 0 })
2952
2956
  }, u, { method: e.method ?? "GET" });
2953
2957
  if (n === null) return a();
2954
2958
  r.statusCode = n.status, r.setHeader("content-type", n.contentType);
@@ -2959,21 +2963,35 @@ import {
2959
2963
  }
2960
2964
  });
2961
2965
  }
2962
- }, fe = t.name === "voltroDashboard" ? {
2966
+ }, me = t.name === "voltroDashboard" ? {
2963
2967
  name: "framework:dashboard-registry",
2964
2968
  configureServer(e) {
2965
2969
  e.middlewares.use(async (e, t, n) => {
2966
2970
  if (!(e.url ?? "").startsWith("/api/dashboard/registry")) return n();
2967
2971
  try {
2968
- let e = await $n();
2972
+ let e = await nt();
2969
2973
  t.statusCode = 200, t.setHeader("content-type", "application/json; charset=utf-8"), t.end(JSON.stringify(e));
2970
2974
  } catch (e) {
2971
2975
  t.statusCode = 500, t.setHeader("content-type", "text/plain"), t.end(`registry read error: ${e.message}`);
2972
2976
  }
2973
2977
  });
2974
2978
  }
2975
- } : null, pe = oi(b), me = /* @__PURE__ */ new Set(), he = wt(), ge = Et({
2976
- limit: he,
2979
+ } : null, he = /* @__PURE__ */ new Set(), ge = (e, t, n, r, i) => {
2980
+ if (X.error(`${t} render failed`, {
2981
+ pathname: n,
2982
+ pattern: r
2983
+ }, i), e.headersSent) {
2984
+ e.end();
2985
+ return;
2986
+ }
2987
+ e.writeHead(500, {
2988
+ "content-type": "text/plain; charset=utf-8",
2989
+ "x-voltro-rendered-by": `${t}-failed`
2990
+ });
2991
+ let a = i instanceof Error ? i.stack ?? i.message : String(i);
2992
+ e.end(`${t} render failed for ${n}\n\n${a}\n`);
2993
+ }, z = Rt(), ye = Bt({
2994
+ limit: z,
2977
2995
  onColdStart: (e) => X.debug("ssr cold-compile start", { id: e }),
2978
2996
  onColdEnd: (e, { durationMs: t, failed: n }) => X.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
2979
2997
  id: e,
@@ -2981,18 +2999,18 @@ import {
2981
2999
  ...n ? { failed: !0 } : {}
2982
3000
  })
2983
3001
  });
2984
- X.debug(`ssr cold-compile concurrency ${he}`, { concurrency: he });
2985
- let ye = null, be = async () => (ye === null && (ye = await j.readFile(f(e, ".framework", "index.html"), "utf8")), ye), xe = {
3002
+ X.debug(`ssr cold-compile concurrency ${z}`, { concurrency: z });
3003
+ let be = null, xe = async () => (be === null && (be = await A.readFile(f(e, ".framework", "index.html"), "utf8")), be), Se = {
2986
3004
  name: "framework:ssr",
2987
3005
  configureServer(t) {
2988
- let n = (e) => ge.load(e, async () => await t.ssrLoadModule(e));
3006
+ let n = (e) => ye.load(e, async () => await t.ssrLoadModule(e));
2989
3007
  t.middlewares.use(async (r, i, a) => {
2990
3008
  if (r.method !== "GET" && r.method !== "HEAD") return a();
2991
3009
  let o = r.url ?? "/", s = o.indexOf("?"), c = (s === -1 ? o : o.slice(0, s)) || "/";
2992
3010
  if (c.startsWith("/@") || c.startsWith("/node_modules/") || c.startsWith("/.framework/") || c.startsWith("/_voltro/") || c === "/main.tsx" || c === "/index.html" || c === "/sw.js" || c === "/favicon.ico" || c === "/robots.txt" || /\.[a-z0-9]+$/i.test(c)) return a();
2993
- let l = si(c, pe);
3011
+ let l = ci(c, S.ssrRoutes);
2994
3012
  if (!l) return a();
2995
- let d = !me.has(l.route.pattern), p = Date.now();
3013
+ let d = !he.has(l.route.pattern), p = Date.now();
2996
3014
  d && X.info(`ssr compiling ${l.route.pattern}`, {
2997
3015
  pattern: l.route.pattern,
2998
3016
  pathname: c
@@ -3012,15 +3030,15 @@ import {
3012
3030
  }
3013
3031
  };
3014
3032
  try {
3015
- let s = await h("loadPage", async () => await n(f(e, "src", "pages", l.route.file))), _ = Fn(s, f("src", "pages", l.route.file)), v = ti(x, l.route.dirChain), y = _ === "spa" && v.some((e) => e.hasLayout);
3033
+ let s = await h("loadPage", async () => await n(f(e, "src", "pages", l.route.file))), _ = Yn(s, f("src", "pages", l.route.file)), v = ni(S.dirs, l.route.dirChain), y = _ === "spa" && v.some((e) => e.hasLayout);
3016
3034
  if (_ !== "ssr" && _ !== "isr" && !y) return a();
3017
3035
  let b = {};
3018
3036
  for (let [e, t] of Object.entries(r.headers ?? {})) typeof t == "string" ? b[e] = t : Array.isArray(t) && (b[e] = t.join(", "));
3019
- let S = vi(_i(u[0], { allowDevProxy: !0 }), b.cookie, { apiName: u[0]?.name }), C = new AbortController(), w = () => C.abort();
3037
+ let x = yi(vi(u[0], { allowDevProxy: !0 }), b.cookie, { apiName: u[0]?.name }), C = new AbortController(), w = () => C.abort();
3020
3038
  i.once("close", w);
3021
3039
  let T = null, E = [], D = {};
3022
3040
  try {
3023
- (await n("@voltro/web/ssr")).beginStoreSeeds(), {chain: E, segmentLoaderData: D} = await h("loadChain", () => ni({
3041
+ (await n("@voltro/web/ssr")).beginStoreSeeds(), {chain: E, segmentLoaderData: D} = await h("loadChain", () => ri({
3024
3042
  entries: v,
3025
3043
  loadLayout: (t) => n(f(e, "src", "pages", t.dir, "layout.tsx")),
3026
3044
  loadError: (t) => n(f(e, "src", "pages", t.dir, "error.tsx")),
@@ -3030,7 +3048,7 @@ import {
3030
3048
  pathname: c,
3031
3049
  signal: C.signal,
3032
3050
  headers: b,
3033
- query: S
3051
+ query: x
3034
3052
  }
3035
3053
  }));
3036
3054
  let t = s.loader;
@@ -3039,12 +3057,12 @@ import {
3039
3057
  pathname: c,
3040
3058
  signal: C.signal,
3041
3059
  headers: b,
3042
- query: S
3060
+ query: x
3043
3061
  })));
3044
3062
  } finally {
3045
3063
  i.off("close", w);
3046
3064
  }
3047
- let O = await h("loadSsrHelpers", async () => await n("@voltro/web/ssr")), k = {
3065
+ let O = await h("loadSsrHelpers", async () => await n("@voltro/web/ssr")), ee = {
3048
3066
  pattern: l.route.pattern,
3049
3067
  Component: s.default,
3050
3068
  meta: s.meta,
@@ -3053,32 +3071,32 @@ import {
3053
3071
  Pending: s.Pending,
3054
3072
  renderMode: _,
3055
3073
  chain: E
3056
- }, A = {
3074
+ }, k = {
3057
3075
  cookies: O.parseCookieHeader(b.cookie),
3058
3076
  headers: b,
3059
3077
  url: o
3060
- }, j = s.interactive ?? "full", M = y ? Dr({
3078
+ }, A = s.interactive ?? "full", j = y ? Or({
3061
3079
  helpers: O,
3062
3080
  page: `src/pages/${l.route.file}`,
3063
- interactive: j,
3081
+ interactive: A,
3064
3082
  delivery: "stream",
3065
3083
  renderInput: {
3066
- descriptor: k,
3084
+ descriptor: ee,
3067
3085
  params: l.params,
3068
3086
  pathname: c,
3069
3087
  segmentLoaderData: D,
3070
- requestContext: A
3088
+ requestContext: k
3071
3089
  }
3072
- }) : null, N = y ? null : Er({
3090
+ }) : null, M = y ? null : Dr({
3073
3091
  helpers: O,
3074
3092
  page: `src/pages/${l.route.file}`,
3075
3093
  pathname: c,
3076
3094
  renderMode: _,
3077
- interactive: j,
3095
+ interactive: A,
3078
3096
  loaderData: T,
3079
3097
  segmentLoaderData: D,
3080
3098
  pageLoaderRan: typeof s.loader == "function"
3081
- }), P = [];
3099
+ }), N = [];
3082
3100
  await h("collectCss", async () => {
3083
3101
  let t = /* @__PURE__ */ new Set(), n = [
3084
3102
  f(e, "src", "pages", l.route.file),
@@ -3089,20 +3107,20 @@ import {
3089
3107
  ]),
3090
3108
  f(e, ".framework", "main.tsx")
3091
3109
  ];
3092
- for (let e of n) await g(e, t, P);
3110
+ for (let e of n) await g(e, t, N);
3093
3111
  });
3094
- let ee = await h("readShell", be), F = await h("transformShell", () => t.transformIndexHtml(o, ee)), te = P.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), I = A.cookies["voltro:locale"] ?? "en", L = Date.now();
3095
- if (M) {
3096
- let e = (e) => kr({
3112
+ let P = await h("readShell", xe), F = await h("transformShell", () => t.transformIndexHtml(o, P)), te = N.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), I = k.cookies["voltro:locale"] ?? "en", ne = Date.now();
3113
+ if (j) {
3114
+ let e = (e) => Ar({
3097
3115
  helpers: O,
3098
- prepared: M,
3116
+ prepared: j,
3099
3117
  meta: e,
3100
- interactive: j,
3118
+ interactive: A,
3101
3119
  extra: [te]
3102
3120
  });
3103
- if (M.hasDeferred) Rr({
3121
+ if (j.hasDeferred) zr({
3104
3122
  res: i,
3105
- shell: Ir({
3123
+ shell: Lr({
3106
3124
  shell: F,
3107
3125
  inlineModuleScriptsAsync: !0
3108
3126
  }),
@@ -3113,41 +3131,38 @@ import {
3113
3131
  },
3114
3132
  headInjection: e,
3115
3133
  render: (e) => O.renderPageToStream({
3116
- ...M.renderInput,
3134
+ ...j.renderInput,
3117
3135
  ...e
3118
3136
  }),
3119
3137
  onShellError: (e) => {
3120
- X.warn("spa-shell-dev shell render failed; falling back to SPA shell", {
3121
- pathname: c,
3122
- pattern: l.route.pattern
3123
- }, e), a();
3138
+ ge(i, "spa-shell-dev", c, l.route.pattern, e);
3124
3139
  }
3125
3140
  });
3126
3141
  else {
3127
- let t = Or({
3142
+ let t = kr({
3128
3143
  helpers: O,
3129
- prepared: M
3144
+ prepared: j
3130
3145
  }), n = F.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${I}"`);
3131
3146
  i.statusCode = 200, i.setHeader("content-type", "text/html; charset=utf-8"), i.setHeader("x-voltro-rendered-by", "spa-shell-dev"), i.end(n);
3132
3147
  }
3133
- } else if (N) {
3148
+ } else if (M) {
3134
3149
  let e = (e) => [
3135
3150
  te,
3136
3151
  O.renderMetaToHtml(e),
3137
- `<meta name="voltro-interactive" content="${j}" />`,
3138
- ...N.hasDeferred ? [O.renderDeferredRegistryScript()] : [],
3139
- O.renderRouterStateScript(N.stateInput)
3152
+ `<meta name="voltro-interactive" content="${A}" />`,
3153
+ ...M.hasDeferred ? [O.renderDeferredRegistryScript()] : [],
3154
+ O.renderRouterStateScript(M.stateInput)
3140
3155
  ].filter((e) => e.length > 0).join("\n "), t = {
3141
- descriptor: k,
3156
+ descriptor: ee,
3142
3157
  params: l.params,
3143
3158
  pathname: c,
3144
- loaderData: N.loaderData,
3145
- segmentLoaderData: N.segmentLoaderData,
3146
- requestContext: A
3159
+ loaderData: M.loaderData,
3160
+ segmentLoaderData: M.segmentLoaderData,
3161
+ requestContext: k
3147
3162
  };
3148
- if (_ === "ssr" && j === "full") Rr({
3163
+ if (_ === "ssr" && A === "full") zr({
3149
3164
  res: i,
3150
- shell: Ir({
3165
+ shell: Lr({
3151
3166
  shell: F,
3152
3167
  inlineModuleScriptsAsync: !0
3153
3168
  }),
@@ -3162,10 +3177,7 @@ import {
3162
3177
  ...e
3163
3178
  }),
3164
3179
  onShellError: (e) => {
3165
- X.warn("ssr-dev shell render failed; falling back to SPA shell", {
3166
- pathname: c,
3167
- pattern: l.route.pattern
3168
- }, e), a();
3180
+ ge(i, "ssr-dev", c, l.route.pattern, e);
3169
3181
  }
3170
3182
  });
3171
3183
  else {
@@ -3173,57 +3185,54 @@ import {
3173
3185
  i.statusCode = 200, i.setHeader("content-type", "text/html; charset=utf-8"), i.setHeader("x-voltro-rendered-by", "ssr-dev"), i.end(a);
3174
3186
  }
3175
3187
  }
3176
- m.render = Date.now() - L;
3177
- let R = Date.now() - p;
3178
- d ? (me.add(l.route.pattern), X.info(`ssr compiled ${l.route.pattern} in ${R}ms`, {
3188
+ m.render = Date.now() - ne;
3189
+ let L = Date.now() - p;
3190
+ d ? (he.add(l.route.pattern), X.info(`ssr compiled ${l.route.pattern} in ${L}ms`, {
3179
3191
  pattern: l.route.pattern,
3180
3192
  pathname: c,
3181
- elapsedMs: R,
3193
+ elapsedMs: L,
3182
3194
  cold: !0,
3183
3195
  phases: m
3184
- })) : R > 200 && X.info(`ssr rendered ${c} in ${R}ms`, {
3196
+ })) : L > 200 && X.info(`ssr rendered ${c} in ${L}ms`, {
3185
3197
  pattern: l.route.pattern,
3186
3198
  pathname: c,
3187
- elapsedMs: R,
3199
+ elapsedMs: L,
3188
3200
  cold: !1,
3189
3201
  phases: m
3190
3202
  });
3191
3203
  } catch (e) {
3192
- if (Tr(e)) {
3204
+ if (Er(e)) {
3193
3205
  X.error("ssr-dev render refused", {
3194
3206
  pathname: c,
3195
3207
  pattern: l.route.pattern
3196
3208
  }, e), i.statusCode = 500, i.setHeader("content-type", "text/plain; charset=utf-8"), i.end(e.message);
3197
3209
  return;
3198
3210
  }
3199
- X.warn("ssr-dev render failed; falling back to SPA shell", {
3200
- pathname: c,
3201
- pattern: l.route.pattern
3202
- }, e), a();
3211
+ ge(i, "ssr-dev", c, l.route.pattern, e);
3203
3212
  }
3204
3213
  });
3205
3214
  }
3206
- }, B = Date.now(), Se = w.version ?? "?", V = await Vr(), Ce = f(e, "node_modules", "@voltro", "ui-shadcn"), H = O(f(Ce, "package.json")) ? Ce : null, we = [], Te = await (async () => {
3215
+ }, B = Date.now(), Ce = T.version ?? "?", V = await Hr(), we = f(e, "node_modules", "@voltro", "ui-shadcn"), H = O(f(we, "package.json")) ? we : null, Te = [], Ee = await (async () => {
3207
3216
  let t = [];
3208
3217
  for (let n of u) {
3209
3218
  if (!n.proxyTarget) continue;
3210
- let r = await ci(e, n.pkg);
3219
+ let r = await li(e, n.pkg);
3211
3220
  if (r) try {
3212
- t.push(await j.readFile(f(r, "rpcGroup.generated.ts"), "utf8"));
3221
+ t.push(await A.readFile(f(r, "rpcGroup.generated.ts"), "utf8"));
3213
3222
  } catch {}
3214
3223
  }
3215
3224
  if (t.length === 0) return !1;
3216
3225
  let n = _e("sha1").update(t.join("\0")).digest("hex"), r = f(k, ".voltro-rpcgroup-optimize"), i = "";
3217
3226
  try {
3218
- i = (await j.readFile(r, "utf8")).trim();
3227
+ i = (await A.readFile(r, "utf8")).trim();
3219
3228
  } catch {}
3220
3229
  if (i === n) return !1;
3221
3230
  try {
3222
- await j.writeFile(r, n);
3231
+ await A.writeFile(r, n);
3223
3232
  } catch {}
3224
3233
  return !0;
3225
3234
  })();
3226
- Te && X.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client"), await (await w.createServer({
3235
+ Ee && X.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client"), await (await T.createServer({
3227
3236
  root: k,
3228
3237
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3229
3238
  ssr: { noExternal: ["react-intl"] },
@@ -3255,40 +3264,40 @@ import {
3255
3264
  replacement: f(H, "src/index.ts")
3256
3265
  }
3257
3266
  ] : [],
3258
- ...qe(e)
3267
+ ...st(e)
3259
3268
  ]
3260
3269
  },
3261
3270
  optimizeDeps: {
3262
- include: [...u.map((e) => `${e.pkg}/rpcGroup`), ...we],
3263
- force: Te
3271
+ include: [...u.map((e) => `${e.pkg}/rpcGroup`), ...Te],
3272
+ force: Ee
3264
3273
  },
3265
- customLogger: Ct(),
3274
+ customLogger: Lt(),
3266
3275
  plugins: [
3267
- kn(f(e, "src", "pages")),
3268
- T(),
3276
+ Un(f(e, "src", "pages")),
3269
3277
  D(),
3278
+ ee(),
3270
3279
  N,
3271
- I,
3272
- ae,
3280
+ ne,
3273
3281
  se,
3274
- ce,
3275
- de,
3276
- xe,
3277
- ...fe ? [fe] : []
3282
+ le,
3283
+ ue,
3284
+ pe,
3285
+ Se,
3286
+ ...me ? [me] : []
3278
3287
  ],
3279
3288
  server: {
3280
3289
  port: g,
3281
3290
  strictPort: !0,
3282
3291
  host: !0,
3283
3292
  allowedHosts: t.allowedHosts === !0 || [...t.allowedHosts ?? []],
3284
- proxy: z,
3285
- fs: { allow: [e, ...qr(e)] }
3293
+ proxy: R,
3294
+ fs: { allow: [e, ...Jr(e)] }
3286
3295
  },
3287
3296
  appType: "spa",
3288
3297
  cacheDir: f(k, ".vite"),
3289
3298
  publicDir: f(e, "public")
3290
- })).listen(), zr.info(`v${Se} ready in ${Date.now() - B}ms`, {
3291
- version: Se,
3299
+ })).listen(), Br.info(`v${Ce} ready in ${Date.now() - B}ms`, {
3300
+ version: Ce,
3292
3301
  bootMs: Date.now() - B
3293
3302
  }), X.info(`listening on http://localhost:${g}`, {
3294
3303
  port: g,
@@ -3299,7 +3308,7 @@ import {
3299
3308
  target: e.proxyTarget
3300
3309
  }), X.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3301
3310
  try {
3302
- await er({
3311
+ await rt({
3303
3312
  id: v,
3304
3313
  name: _,
3305
3314
  kind: "web",
@@ -3308,13 +3317,13 @@ import {
3308
3317
  status: "live",
3309
3318
  logFile: y.path
3310
3319
  });
3311
- let t = mr(e);
3320
+ let t = hr(e);
3312
3321
  if (t) {
3313
- let e = await Cr({ dashboardAppPath: t });
3322
+ let e = await wr({ dashboardAppPath: t });
3314
3323
  e.status === "launched" ? X.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && X.debug(`dashboard already running on :${e.port}`, { port: e.port });
3315
3324
  }
3316
3325
  setInterval(() => {
3317
- er({
3326
+ rt({
3318
3327
  id: v,
3319
3328
  name: _,
3320
3329
  kind: "web",
@@ -3325,7 +3334,7 @@ import {
3325
3334
  }).catch(() => {});
3326
3335
  }, 1e4).unref();
3327
3336
  let n = () => {
3328
- tr(v), y.dispose();
3337
+ it(v), y.dispose();
3329
3338
  };
3330
3339
  process.on("SIGINT", n), process.on("SIGTERM", n);
3331
3340
  } catch (e) {
@@ -3337,16 +3346,16 @@ import {
3337
3346
  url: `http://localhost:${g}`,
3338
3347
  bootMs: Date.now() - B
3339
3348
  }), new Promise(() => {});
3340
- }, Ci = async (e) => {
3349
+ }, wi = async (e) => {
3341
3350
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
3342
- let t = await xi(e);
3351
+ let t = await Si(e);
3343
3352
  if (!t) return {
3344
3353
  ran: !1,
3345
3354
  exitCode: 0
3346
3355
  };
3347
3356
  let n = Date.now(), r = X.child("serve");
3348
3357
  r.info("booting voltro serve (preview)", { app: t.name ?? "(unnamed)" });
3349
- let i = await pi(e, t);
3358
+ let i = await mi(e, t);
3350
3359
  for (let e of i) r.info("api wired", {
3351
3360
  name: e.name,
3352
3361
  pkg: e.pkg
@@ -3354,21 +3363,21 @@ import {
3354
3363
  await $(e, t, i);
3355
3364
  {
3356
3365
  let { pages: t } = await Q(f(e, "src", "pages"));
3357
- await It({
3366
+ await Xt({
3358
3367
  appRoot: e,
3359
3368
  pages: t
3360
3369
  });
3361
3370
  }
3362
- let a = t.port ?? 5173, o = await Ye("vite", () => import("vite")), s = (await import("@vitejs/plugin-react")).default, c = f(e, ".framework");
3371
+ let a = t.port ?? 5173, o = await lt("vite", () => import("vite")), s = (await import("@vitejs/plugin-react")).default, c = f(e, ".framework");
3363
3372
  X.info("running production build"), await o.build({
3364
3373
  root: c,
3365
3374
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3366
3375
  plugins: [s()],
3367
- customLogger: Ct(),
3376
+ customLogger: Lt(),
3368
3377
  resolve: { dedupe: ["react", "react-dom"] },
3369
3378
  build: {
3370
3379
  outDir: "dist",
3371
- rollupOptions: { output: { manualChunks: Yr } }
3380
+ rollupOptions: { output: { manualChunks: Xr } }
3372
3381
  },
3373
3382
  publicDir: f(e, "public")
3374
3383
  });
@@ -3388,14 +3397,14 @@ import {
3388
3397
  extras: d,
3389
3398
  bootMs: Date.now() - n
3390
3399
  }), new Promise(() => {});
3391
- }, wi = 5e3, Ti = 6e4, Ei = (e, t) => {
3400
+ }, Ti = 5e3, Ei = 6e4, Di = (e, t) => {
3392
3401
  if (e.length === 0) return 0;
3393
3402
  if (e.length === 1) return e[0];
3394
3403
  let n = t * (e.length - 1), r = Math.floor(n), i = Math.ceil(n);
3395
3404
  if (r === i) return e[r];
3396
3405
  let a = n - r;
3397
3406
  return e[r] * (1 - a) + e[i] * a;
3398
- }, Di = (e) => {
3407
+ }, Oi = (e) => {
3399
3408
  if (e.length === 0) return {
3400
3409
  p50: 0,
3401
3410
  p95: 0,
@@ -3407,18 +3416,18 @@ import {
3407
3416
  let t = e.slice().sort((e, t) => e - t), n = 0;
3408
3417
  for (let e of t) n += e;
3409
3418
  return {
3410
- p50: Ei(t, .5),
3411
- p95: Ei(t, .95),
3412
- p99: Ei(t, .99),
3419
+ p50: Di(t, .5),
3420
+ p95: Di(t, .95),
3421
+ p99: Di(t, .99),
3413
3422
  mean: n / t.length,
3414
3423
  min: t[0],
3415
3424
  max: t[t.length - 1]
3416
3425
  };
3417
- }, Oi = (e = {}) => {
3418
- let t = e.maxSamples ?? wi, n = e.defaultWindowMs ?? Ti, r = [];
3426
+ }, ki = (e = {}) => {
3427
+ let t = e.maxSamples ?? Ti, n = e.defaultWindowMs ?? Ei, r = [];
3419
3428
  return {
3420
3429
  record(e) {
3421
- R(e), r.push({
3430
+ L(e), r.push({
3422
3431
  ...e,
3423
3432
  ts: Date.now()
3424
3433
  }), r.length > t && r.shift();
@@ -3444,7 +3453,7 @@ import {
3444
3453
  tag: e.tag,
3445
3454
  count: e.samples.length,
3446
3455
  errorCount: n,
3447
- latencyMs: Di(t)
3456
+ latencyMs: Oi(t)
3448
3457
  });
3449
3458
  }
3450
3459
  return c.sort((e, t) => t.count - e.count), {
@@ -3457,4 +3466,4 @@ import {
3457
3466
  };
3458
3467
  };
3459
3468
  //#endregion
3460
- export { ht as $, tr as A, bn as B, Cr as C, ur as D, lr as E, In as F, Jt as G, cn as H, jn as I, Rt as J, Kt as K, Nn as L, Rn as M, Bn as N, nr as O, An as P, wt as Q, Fn as R, pr as S, cr as T, rn as U, pn as V, tn as W, It as X, Bt as Y, Et as Z, Er as _, Ce as _t, ni as a, ot as at, kr as b, pi as c, at as ct, Yr as d, $e as dt, pt as et, Q as f, Ye as ft, Tr as g, V as gt, Rr as h, Ge as ht, vi as i, lt as it, er as j, $n as k, Si as l, nt as lt, Ir as m, We as mt, Xr as n, st as nt, ti as o, G as ot, $ as p, qe as pt, zt as q, _i as r, ct as rt, xi as s, it as st, Oi as t, ft as tt, Ci as u, et as ut, Dr as v, mr as w, hr as x, Or as y, yn as z };
3469
+ export { St as $, Wn as A, gn as B, wr as C, dr as D, ur as E, Nn as F, en as G, sn as H, Pn as I, Rt as J, Xt as K, Dn as L, Gn as M, qn as N, Qn as O, Yn as P, xt as Q, Sn as R, mr as S, lr as T, $t as U, ln as V, Qt as W, Dt as X, kt as Y, Et as Z, Dr as _, we as _t, ri as a, gt as at, Ar as b, mi as c, lt as ct, Xr as d, nt as dt, Ct as et, Q as f, it as ft, Er as g, V as gt, zr as h, Ke as ht, yi as i, yt as it, Xn as j, er as k, Ci as l, st as lt, Lr as m, Ge as mt, Zr as n, G as nt, ni as o, mt as ot, $ as p, rt as pt, Bt as q, vi as r, vt as rt, Si as s, pt as st, ki as t, bt as tt, wi as u, at as ut, Or as v, hr as w, gr as x, kr as y, vn as z };