@voltro/cli 0.55.0 → 0.57.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 (175) hide show
  1. package/CHANGELOG.md +691 -0
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/apiBuild-B83Cb2Rv.js +2 -0
  4. package/dist/{apiBuild-CMvLJM_K.js → apiBuild-DDr2aNFd.js} +119 -88
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-S0QOzqPT.js → build-QKP6Bm0J.js} +308 -279
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-DNkY5kwF.js → checkCommand-BISqx1OJ.js} +1 -1
  9. package/dist/{checkCommand-fbj9GDjN.js → checkCommand-DUtMWjcR.js} +6 -6
  10. package/dist/{clusterCmd-DrVFCzSj.js → clusterCmd-CdLB1GkT.js} +1 -1
  11. package/dist/{codegen-SIepQtUl.js → codegen-Bth5lUTU.js} +2 -1
  12. package/dist/codegen-DbH7NbCR.js +2 -0
  13. package/dist/{codegenCommand-3TDJezom.js → codegenCommand-DnVuDxwT.js} +11 -11
  14. package/dist/{codemodRunner-C2zxZUIw.js → codemodRunner-BlQPfjzA.js} +222 -0
  15. package/dist/{commands-BBYJ7Q3B.js → commands-CRbxgxv0.js} +35 -35
  16. package/dist/{dashboardCommand-D2kmyCLL.js → dashboardCommand-Bf_-Ne3P.js} +5 -5
  17. package/dist/{dataCommand-BEPPQiTl.js → dataCommand-BoBJJ-Gb.js} +3 -3
  18. package/dist/{dbCommand-DZTmOFT4.js → dbCommand-CMAIz-Bf.js} +457 -441
  19. package/dist/dbCommand-DHi_RuDl.js +2 -0
  20. package/dist/dev-Bl9HqtV7.js +3 -0
  21. package/dist/{dev-Ca_A_S9v.js → dev-DOEJXicj.js} +2623 -2485
  22. package/dist/{doctorCommand-CGZJK_4o.js → doctorCommand-BrWu67JZ.js} +524 -280
  23. package/dist/doctorCommand-DrQv9SL3.js +2 -0
  24. package/dist/{dormancyCommand-DY2rYpTa.js → dormancyCommand-xn2y-pJm.js} +1 -1
  25. package/dist/{embeddingsCommand-BoCqZsgp.js → embeddingsCommand-Cn5MbRDM.js} +1 -1
  26. package/dist/emptyResultHeadline-Csa5fZOF.js +18 -0
  27. package/dist/{envCommand-Bxy2fOjc.js → envCommand-UJmJIbs9.js} +8 -8
  28. package/dist/{evolveCommand-BsbZ-XDg.js → evolveCommand-Db30twUy.js} +2 -2
  29. package/dist/frameworkTableAssembly-B96WCNJA.js +2 -0
  30. package/dist/{frameworkTableAssembly-Do-cf6RJ.js → frameworkTableAssembly-vfkzuzEo.js} +131 -104
  31. package/dist/index.js +1 -1
  32. package/dist/{infoCommand-EmM3jPKD.js → infoCommand-BjVXpMlP.js} +1 -1
  33. package/dist/inspect-B0hL41s0.js +2 -0
  34. package/dist/inspect-DZnan87F.js +1500 -0
  35. package/dist/{inspectCmd-niF97fAq.js → inspectCmd-CP-G0sVK.js} +1 -1
  36. package/dist/{inspectFetch-EMuhTG_9.js → inspectFetch-BU1NyzxV.js} +36 -24
  37. package/dist/{inspectMetrics-CGF94puw.js → inspectMetrics-BY0Sjb2F.js} +19 -19
  38. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-C5y9HyrG.js} +59 -54
  39. package/dist/{manifestBuild-DjX5MoXy.js → manifestBuild-DnbFKF6w.js} +1 -1
  40. package/dist/manifestBuild-UXrnUcXP.js +2 -0
  41. package/dist/{migrate-CGFZS-1a.js → migrate-DtC3lu7H.js} +4 -4
  42. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  43. package/dist/{probeCommand-Bs3iVBSL.js → probeCommand-C5fuN6Z2.js} +2 -2
  44. package/dist/{runtimeTrace-C1BTpHGQ.js → runtimeTrace-BQL_lfz6.js} +1 -1
  45. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  46. package/dist/{sdkgen-CXMwLg9n.js → sdkgen-CMUPrDjH.js} +1 -1
  47. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  48. package/dist/serveCommand-B_w-Mpb_.js +2544 -0
  49. package/dist/serveCommand-Dtb48ffg.js +2 -0
  50. package/dist/serveEntry.js +1 -1
  51. package/dist/{start-EOV7s1NZ.js → start-YaUehtDV.js} +580 -558
  52. package/dist/{start-DH7cat4-.js → start-s25GAIgn.js} +1 -1
  53. package/dist/startEntry.js +1 -1
  54. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  55. package/dist/{test-DO27-x2P.js → test-jipIQ5Mx.js} +1 -1
  56. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-C1qKa94g.js} +69 -64
  57. package/dist/{updateCommand-C_jN1w18.js → updateCommand-C9n_Z_oG.js} +8 -2
  58. package/dist/updateCommand-DsXEAHbd.js +2 -0
  59. package/dist/webDev-B6ZMX42w.js +2 -0
  60. package/dist/{webDev-B7vNj4Bq.js → webDev-BgdkyjP6.js} +1379 -1303
  61. package/dist/{webhooksCommand-B1LVcyO3.js → webhooksCommand-CYXTNvXq.js} +2 -2
  62. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  63. package/package.json +55 -19
  64. package/templates/AGENTS.core.md +20 -1
  65. package/templates/AGENTS.md +21 -2
  66. package/templates/agent-docs/_index.md +1 -1
  67. package/templates/agent-docs/_manifest.json +2 -2
  68. package/templates/agent-docs/ai.md +1 -1
  69. package/templates/agent-docs/authentication.md +34 -19
  70. package/templates/agent-docs/cli.md +170 -0
  71. package/templates/agent-docs/configuration.md +29 -4
  72. package/templates/agent-docs/data.md +145 -5
  73. package/templates/agent-docs/database/scaling.md +50 -2
  74. package/templates/agent-docs/deployment.md +75 -1
  75. package/templates/agent-docs/internationalization.md +32 -0
  76. package/templates/agent-docs/local-first-mobile.md +9 -2
  77. package/templates/agent-docs/observability.md +227 -0
  78. package/templates/agent-docs/plugins/audit.md +21 -5
  79. package/templates/agent-docs/plugins/billing.md +17 -0
  80. package/templates/agent-docs/plugins/broadcast.md +2 -1
  81. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  82. package/templates/agent-docs/plugins/row-history.md +11 -0
  83. package/templates/agent-docs/plugins.md +19 -0
  84. package/templates/agent-docs/reference.md +1 -0
  85. package/templates/agent-docs/scheduling.md +23 -0
  86. package/templates/agent-docs/schema-driven-ui.md +81 -0
  87. package/templates/agent-docs/templates/appshells.md +3 -3
  88. package/templates/agent-docs/whats-new.md +133 -77
  89. package/templates/apps/api-ai/package.json +6 -6
  90. package/templates/apps/api-auth/package.json +8 -8
  91. package/templates/apps/api-backend/package.json +7 -7
  92. package/templates/apps/api-backend-deactivation/package.json +7 -7
  93. package/templates/apps/api-backend-mail/package.json +8 -8
  94. package/templates/apps/api-backend-mariadb/package.json +9 -9
  95. package/templates/apps/api-backend-sqlite/package.json +8 -8
  96. package/templates/apps/api-backend-storage/package.json +8 -8
  97. package/templates/apps/api-cms/package.json +9 -9
  98. package/templates/apps/api-collab/package.json +8 -8
  99. package/templates/apps/api-data-advanced/package.json +8 -8
  100. package/templates/apps/api-durable/package.json +8 -8
  101. package/templates/apps/api-feature-flags/package.json +9 -9
  102. package/templates/apps/api-governance/package.json +8 -8
  103. package/templates/apps/api-kv/package.json +8 -8
  104. package/templates/apps/api-moderation/package.json +8 -8
  105. package/templates/apps/api-observability/package.json +8 -8
  106. package/templates/apps/api-ratelimit/package.json +8 -8
  107. package/templates/apps/api-rbac/package.json +8 -8
  108. package/templates/apps/api-rest/package.json +7 -7
  109. package/templates/apps/api-row-history/package.json +8 -8
  110. package/templates/apps/api-saas/package.json +11 -11
  111. package/templates/apps/api-saas-starter/package.json +10 -10
  112. package/templates/apps/api-search/package.json +8 -8
  113. package/templates/apps/api-status/package.json +8 -8
  114. package/templates/apps/api-webhooks/package.json +9 -9
  115. package/templates/apps/changelog/package.json +7 -7
  116. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  117. package/templates/apps/edge-functions/package.json +2 -2
  118. package/templates/apps/frontend-admin/package.json +7 -8
  119. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  120. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  121. package/templates/apps/frontend-app/package.json +8 -9
  122. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  123. package/templates/apps/frontend-auth/package.json +7 -8
  124. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  125. package/templates/apps/frontend-blank/package.json +6 -7
  126. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  127. package/templates/apps/frontend-cms/package.json +8 -9
  128. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  129. package/templates/apps/frontend-collab/README.md +7 -2
  130. package/templates/apps/frontend-collab/package.json +9 -10
  131. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  132. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  133. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  134. package/templates/apps/frontend-contact/package.json +7 -7
  135. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  136. package/templates/apps/frontend-dashboard/package.json +6 -7
  137. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  138. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  139. package/templates/apps/frontend-docs/package.json +8 -8
  140. package/templates/apps/frontend-i18n/package.json +6 -6
  141. package/templates/apps/frontend-landing/package.json +7 -7
  142. package/templates/apps/frontend-portal/package.json +7 -8
  143. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  144. package/templates/apps/frontend-saas/package.json +7 -8
  145. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  146. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  147. package/templates/apps/frontend-spa/package.json +6 -7
  148. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  149. package/templates/apps/frontend-ssr/package.json +6 -7
  150. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  151. package/templates/apps/frontend-ssr-api/package.json +7 -8
  152. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  153. package/templates/apps/frontend-static-blog/package.json +8 -8
  154. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  155. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  156. package/templates/apps/frontend-status/package.json +7 -8
  157. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  158. package/templates/apps/mobile-app/package.json +4 -4
  159. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  160. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  161. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  162. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  163. package/dist/apiBuild-Cl0IDx8c.js +0 -2
  164. package/dist/codegen-CN6vMM4J.js +0 -2
  165. package/dist/dbCommand-BTyBGhIA.js +0 -2
  166. package/dist/dev-DfVZaoys.js +0 -3
  167. package/dist/doctorCommand-djmqEcDC.js +0 -2
  168. package/dist/frameworkTableAssembly-Df2Ymp2f.js +0 -2
  169. package/dist/inspect-DCqILJ1G.js +0 -1197
  170. package/dist/inspect-DGJwpOAb.js +0 -2
  171. package/dist/manifestBuild-CJ2zvPvT.js +0 -2
  172. package/dist/serveCommand-C7IrCD58.js +0 -2445
  173. package/dist/serveCommand-Cjt5S9hD.js +0 -2
  174. package/dist/updateCommand-nnFjDbl4.js +0 -2
  175. package/dist/webDev-1XpVnYkW.js +0 -2
@@ -1,43 +1,49 @@
1
1
  import { i as e, t } from "./nodeEnvironment-cGFAj1J8.js";
2
- import { r as n } from "./appPort-B_HpJ_ck.js";
3
- import { $ as r, A as i, At as a, B as o, C as s, D as c, E as l, F as u, G as d, H as f, I as ee, J as te, K as p, Kt as m, L as ne, M as h, Mt as g, N as re, O as ie, Ot as _, R as v, S as y, T as b, Tt as x, U as S, Ut as ae, V as C, W as oe, X as se, Y as w, Z as T, at as E, bt as D, ct as ce, et as le, ht as ue, i as de, j as fe, jt as O, k as pe, kt as k, l as me, lt as he, m as ge, mt as A, n as j, nt as M, o as _e, ot as N, p as ve, q as P, s as F, st as ye, w as be, x as xe, z as Se } from "./webDev-B7vNj4Bq.js";
4
- import { o as Ce, t as we } from "./connectionConfig-Bk9IC7D0.js";
5
- import { A as I, D as Te, a as Ee, h as De, j as Oe, k as ke } from "./inspect-DCqILJ1G.js";
6
- import { n as Ae, r as je, t as Me } from "./inspectMetrics-CGF94puw.js";
7
- import { a as Ne, c as L, d as Pe, f as Fe, l as Ie, p as R, u as Le } from "./renderModeScan-43yQ2opo.js";
8
- import { i as Re, n as ze, r as Be, t as Ve } from "./runtimeRegistry-DMeKfTHP.js";
9
- import { n as He } from "./logFileSink-B4uP8pvf.js";
10
- import { t as Ue } from "./bootTiming-BdyP9nYw.js";
11
- import { dirname as z, extname as B, join as V, resolve as We } from "node:path";
12
- import { promises as H } from "node:fs";
13
- import { fileURLToPath as Ge, pathToFileURL as U } from "node:url";
14
- import { createLogger as W, printReadyBlock as Ke } from "@voltro/logger";
15
- import { Effect as qe } from "effect";
16
- import { maybeCompress as G, snapshotMetricsSync as Je } from "@voltro/runtime";
17
- import { createHash as K } from "node:crypto";
18
- import { resolveBroadcastProvider as Ye } from "@voltro/plugin-broadcast";
19
- import { createServer as Xe } from "node:http";
2
+ import { $ as n, A as r, B as i, C as a, Ct as o, D as s, E as c, F as l, Ft as u, G as d, H as f, I as p, J as m, K as h, Kt as ee, L as g, M as _, Mt as v, N as y, Nt as b, O as x, Ot as S, P as C, Pt as w, Q as T, Qt as te, S as E, T as ne, U as re, V as ie, W as D, X as ae, Xt as oe, Y as se, Yt as O, Z as ce, Zt as le, _t as ue, a as k, c as de, dt as fe, et as pe, h as me, it as A, j, jt as he, k as M, lt as N, m as P, n as ge, ot as _e, q as F, rt as ve, s as ye, tt as be, u as xe, vt as Se, w as Ce, z as we } from "./webDev-BgdkyjP6.js";
3
+ import { A as I, I as Te, M as Ee, O as De, g as Oe, j as ke, o as Ae } from "./inspect-DZnan87F.js";
4
+ import { r as je } from "./appPort-B_HpJ_ck.js";
5
+ import { o as Me, t as Ne } from "./connectionConfig-Bk9IC7D0.js";
6
+ import { n as Pe, r as Fe, t as Ie } from "./inspectMetrics-BY0Sjb2F.js";
7
+ import { a as Le, c as Re, d as ze, f as Be, l as Ve, p as L, u as He } from "./renderModeScan-43yQ2opo.js";
8
+ import { i as Ue, n as We, r as Ge, t as Ke } from "./runtimeRegistry-DMeKfTHP.js";
9
+ import { n as qe } from "./logFileSink-B4uP8pvf.js";
10
+ import { t as Je } from "./bootTiming-BdyP9nYw.js";
11
+ import { a as Ye, n as Xe, r as Ze, t as Qe } from "./staticCachePolicy-CIyj6DbS.js";
12
+ import { extname as R, join as z, resolve as B } from "node:path";
13
+ import { promises as V } from "node:fs";
14
+ import { pathToFileURL as H } from "node:url";
15
+ import { createLogger as U, printReadyBlock as $e } from "@voltro/logger";
16
+ import { appMode as et, frameworkVersion as tt, setProcessBootPath as nt } from "@voltro/protocol/identity";
17
+ import { applyKeepAlive as rt, maybeCompress as W, negotiateEncoding as it, resolveKeepAlive as at, snapshotMetricsSync as ot } from "@voltro/runtime";
18
+ import { Effect as st } from "effect";
19
+ import { createHash as G } from "node:crypto";
20
+ import { resolveBroadcastProvider as ct } from "@voltro/plugin-broadcast";
21
+ import { createServer as lt } from "node:http";
20
22
  //#region src/httpResponseWrite.ts
21
- var Ze = (e) => `W/"${K("md5").update(e).digest("hex")}"`, Qe = (e) => {
23
+ var ut = (e) => `W/"${G("md5").update(e).digest("hex")}"`, dt = (e) => {
22
24
  let { response: t, status: n, headers: r, body: i, requestHeaders: a } = e, o = r["cache-control"], s = (typeof o == "string" ? o : "").toLowerCase();
23
25
  if (i === void 0 || n !== 200 || s.includes("no-store")) return !1;
24
- let c = r["content-type"], l = typeof c == "string" ? c : void 0, u = Ze(i), d = a["if-none-match"];
25
- if (d !== void 0 && d.split(",").some((e) => e.trim() === u)) return t.writeHead(304, {
26
+ let c = r["content-type"], l = typeof c == "string" ? c : void 0, u = r.etag, d = typeof u == "string" ? u : ut(i), f = a["if-none-match"];
27
+ if (f !== void 0 && f.split(",").some((e) => e.trim() === d)) return t.writeHead(304, {
26
28
  ...r,
27
- etag: u
29
+ etag: d
28
30
  }), t.end(), !0;
29
- let f = G({
31
+ if (r["content-encoding"] !== void 0) return t.writeHead(n, {
32
+ ...r,
33
+ etag: d
34
+ }), t.end(i), !0;
35
+ let p = W({
30
36
  body: typeof i == "string" ? new TextEncoder().encode(i) : new Uint8Array(i),
31
37
  contentType: l,
32
38
  acceptEncoding: a["accept-encoding"],
33
39
  options: e.compression
34
- }), ee = {
40
+ }), m = {
35
41
  ...r,
36
- ...f.headers,
37
- etag: u
42
+ ...p.headers,
43
+ etag: d
38
44
  };
39
- return f.compressed && delete ee["content-length"], t.writeHead(n, ee), t.end(Buffer.from(f.bytes)), !0;
40
- }, q = W({ scope: "voltro:start:cdc" }), $e = (e) => (t) => {
45
+ return p.compressed && delete m["content-length"], t.writeHead(n, m), t.end(Buffer.from(p.bytes)), !0;
46
+ }, K = U({ scope: "voltro:start:cdc" }), ft = (e) => (t) => {
41
47
  let n = 0;
42
48
  for (let [r, i] of e.tableSubscriptionsByPattern) {
43
49
  if (!i.includes(t)) continue;
@@ -48,15 +54,15 @@ var Ze = (e) => `W/"${K("md5").update(e).digest("hex")}"`, Qe = (e) => {
48
54
  }));
49
55
  }
50
56
  return n;
51
- }, et = () => we() ? Ce() : null, tt = (e) => {
52
- let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = $e(e), i = null, a = null;
57
+ }, pt = () => Ne() ? Me() : null, mt = (e) => {
58
+ let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = ft(e), i = null, a = null;
53
59
  return {
54
60
  start: async () => {
55
61
  let o = e.tableSubscriptionsByPattern.size > 0, s = e.onRevalidate !== void 0;
56
- if (!o && !s) return q.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
57
- let c = et();
58
- if (!c && !o) return q.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
59
- if (!c) return q.warn(`${e.tableSubscriptionsByPattern.size} route(s) declare \`cacheInvalidatesOn\` and will NOT be invalidated live — no database is configured for this web process. Set DB_URL (or DB_HOST / PG_HOST) so the CDC listener can connect; until then those routes go stale until their \`revalidate\` window expires.`, { routes: [...e.tableSubscriptionsByPattern.keys()] }), !1;
62
+ if (!o && !s) return K.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
63
+ let c = pt();
64
+ if (!c && !o) return K.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
65
+ if (!c) return K.warn(`${e.tableSubscriptionsByPattern.size} route(s) declare \`cacheInvalidatesOn\` and will NOT be invalidated live — no database is configured for this web process. Set DB_URL (or DB_HOST / PG_HOST) so the CDC listener can connect; until then those routes go stale until their \`revalidate\` window expires.`, { routes: [...e.tableSubscriptionsByPattern.keys()] }), !1;
60
66
  i = new (await (import("pg"))).default.Client(c), await i.connect(), a = (i) => {
61
67
  if (i.channel === n && i.payload && e.onRevalidate) {
62
68
  e.onRevalidate(i.payload);
@@ -67,18 +73,18 @@ var Ze = (e) => `W/"${K("md5").update(e).digest("hex")}"`, Qe = (e) => {
67
73
  try {
68
74
  a = JSON.parse(i.payload);
69
75
  } catch (e) {
70
- q.warn("bad CDC payload", {}, e);
76
+ K.warn("bad CDC payload", {}, e);
71
77
  return;
72
78
  }
73
79
  let o = r(a.table);
74
- o > 0 && q.info(`${a.op} on '${a.table}' → dropped ${o} cache entries`, {
80
+ o > 0 && K.info(`${a.op} on '${a.table}' → dropped ${o} cache entries`, {
75
81
  op: a.op,
76
82
  table: a.table,
77
83
  dropped: o
78
84
  });
79
85
  }, i.on("notification", a), o && await i.query(`LISTEN ${t}`), s && await i.query(`LISTEN ${n}`);
80
86
  let l = [...o ? [t] : [], ...s ? [n] : []];
81
- return q.info(`LISTEN ${l.join(", ")}`, {
87
+ return K.info(`LISTEN ${l.join(", ")}`, {
82
88
  channels: l,
83
89
  ..."connectionString" in c ? { target: c.connectionString.replace(/\/\/[^@/]*@/, "//") } : {
84
90
  host: c.host,
@@ -96,7 +102,7 @@ var Ze = (e) => `W/"${K("md5").update(e).digest("hex")}"`, Qe = (e) => {
96
102
  }
97
103
  }
98
104
  };
99
- }, J = W({ scope: "voltro:start:isr-cache" }), nt = "voltro_isr_cache", Y = (e) => `
105
+ }, q = U({ scope: "voltro:start:isr-cache" }), ht = "voltro_isr_cache", J = (e) => `
100
106
  CREATE TABLE IF NOT EXISTS ${e} (
101
107
  cache_key TEXT PRIMARY KEY,
102
108
  html TEXT NOT NULL,
@@ -107,9 +113,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
107
113
  stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
108
114
  );
109
115
  CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
110
- `, rt = (e) => {
111
- let t = e.tableName ?? nt, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
112
- i || (i = !0, await n.query(Y(t)));
116
+ `, gt = (e) => {
117
+ let t = e.tableName ?? ht, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
118
+ i || (i = !0, await n.query(J(t)));
113
119
  })().then(async () => {
114
120
  let e = await n.query(`SELECT * FROM ${t}`);
115
121
  for (let t of e.rows) r.set(t.cache_key, {
@@ -121,10 +127,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
121
127
  staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
122
128
  });
123
129
  }).catch((e) => {
124
- J.warn("postgres bootstrap failed", {}, e);
130
+ q.warn("postgres bootstrap failed", {}, e);
125
131
  }), o = (e, t) => {
126
132
  a.then(() => n.query(e, t)).catch((e) => {
127
- J.warn("postgres write failed", {}, e);
133
+ q.warn("postgres write failed", {}, e);
128
134
  });
129
135
  }, s = /* @__PURE__ */ new Map(), c = (e) => {
130
136
  s.set(e, (s.get(e) ?? 0) + 1);
@@ -175,21 +181,21 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
175
181
  return Array.from(r.entries());
176
182
  }
177
183
  };
178
- }, X = W({ scope: "voltro:start:revalidate" }), it = (e) => {
184
+ }, Y = U({ scope: "voltro:start:revalidate" }), _t = (e) => {
179
185
  try {
180
186
  let t = JSON.parse(e);
181
187
  return (t.kind === "path" || t.kind === "table" || t.kind === "tag") && typeof t.value == "string" && t.value.length > 0 && (t.tenant === void 0 || typeof t.tenant == "string") ? {
182
188
  kind: t.kind,
183
189
  value: t.value,
184
190
  ...t.tenant === void 0 ? {} : { tenant: t.tenant }
185
- } : (X.warn("bad revalidation payload (shape)", { payload: e }), null);
191
+ } : (Y.warn("bad revalidation payload (shape)", { payload: e }), null);
186
192
  } catch {
187
- return X.warn("bad revalidation payload (not JSON)", { payload: e }), null;
193
+ return Y.warn("bad revalidation payload (not JSON)", { payload: e }), null;
188
194
  }
189
- }, at = (e, t) => {
195
+ }, vt = (e, t) => {
190
196
  if (t.kind === "table" || t.kind === "tag") {
191
197
  let n = e.tableSink(t.value);
192
- return X.info(`revalidate ${t.kind} '${t.value}' → dropped ${n} cache entries`, {
198
+ return Y.info(`revalidate ${t.kind} '${t.value}' → dropped ${n} cache entries`, {
193
199
  kind: t.kind,
194
200
  value: t.value,
195
201
  dropped: n
@@ -198,7 +204,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
198
204
  let n = t.value, r = (e) => t.tenant === void 0 || e.split("|").includes(`tenant=${t.tenant}`), i = e.regexByPattern.get(n);
199
205
  if (i !== void 0) {
200
206
  let a = e.renderModeByPattern.get(n);
201
- if (a !== "isr") return X.error(`revalidatePath('${n}') targets a '${a ?? "unknown"}' route — only \`renderMode: 'isr'\` routes have cache entries to drop. Static HTML is a build artifact this process never re-renders; rebuild to change it.`, {
207
+ if (a !== "isr") return Y.error(`revalidatePath('${n}') targets a '${a ?? "unknown"}' route — only \`renderMode: 'isr'\` routes have cache entries to drop. Static HTML is a build artifact this process never re-renders; rebuild to change it.`, {
202
208
  path: n,
203
209
  renderMode: a ?? "unknown"
204
210
  }), 0;
@@ -206,34 +212,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
206
212
  let t = e.split("|")[0] ?? e;
207
213
  return i.test(t) && r(e);
208
214
  });
209
- return X.info(`revalidate path pattern '${n}' → dropped ${o} cache entries`, {
215
+ return Y.info(`revalidate path pattern '${n}' → dropped ${o} cache entries`, {
210
216
  path: n,
211
217
  dropped: o,
212
218
  ...t.tenant === void 0 ? {} : { tenant: t.tenant }
213
219
  }), o;
214
220
  }
215
221
  let a = [...e.regexByPattern.entries()].find(([, e]) => e.test(n));
216
- if (a === void 0) return X.error(`revalidatePath('${n}') matches no declared route — nothing was dropped. Pass a declared route pattern (e.g. /blog/[slug]) or a concrete path of one.`, { path: n }), 0;
222
+ if (a === void 0) return Y.error(`revalidatePath('${n}') matches no declared route — nothing was dropped. Pass a declared route pattern (e.g. /blog/[slug]) or a concrete path of one.`, { path: n }), 0;
217
223
  let o = e.renderModeByPattern.get(a[0]);
218
- if (o !== "isr") return X.error(`revalidatePath('${n}') targets a '${o ?? "unknown"}' route (${a[0]}) — only \`renderMode: 'isr'\` routes have cache entries to drop.`, {
224
+ if (o !== "isr") return Y.error(`revalidatePath('${n}') targets a '${o ?? "unknown"}' route (${a[0]}) — only \`renderMode: 'isr'\` routes have cache entries to drop.`, {
219
225
  path: n,
220
226
  route: a[0],
221
227
  renderMode: o ?? "unknown"
222
228
  }), 0;
223
229
  let s = e.cache.invalidateBy((e) => (e.split("|")[0] ?? e) === n && r(e));
224
- return X.info(`revalidate path '${n}' → dropped ${s} cache entries`, {
230
+ return Y.info(`revalidate path '${n}' → dropped ${s} cache entries`, {
225
231
  path: n,
226
232
  dropped: s,
227
233
  ...t.tenant === void 0 ? {} : { tenant: t.tenant }
228
234
  }), s;
229
- }, Z = W({ scope: "voltro:start" }), ot = await (async () => {
230
- try {
231
- let e = V(z(Ge(import.meta.url)), "..", "package.json"), t = await H.readFile(e, "utf8");
232
- return JSON.parse(t).version ?? "0.0.0";
233
- } catch {
234
- return "0.0.0";
235
- }
236
- })(), st = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", ct = (e) => e instanceof Error && e._voltroControl === "not-found", lt = {
235
+ }, X = U({ scope: "voltro:start" }), yt = tt() ?? "unknown", bt = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", Z = (e) => e instanceof Error && e._voltroControl === "not-found", xt = {
237
236
  ".html": "text/html; charset=utf-8",
238
237
  ".js": "application/javascript",
239
238
  ".mjs": "application/javascript",
@@ -251,13 +250,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
251
250
  ".woff": "font/woff",
252
251
  ".woff2": "font/woff2",
253
252
  ".txt": "text/plain; charset=utf-8"
254
- }, ut = (e) => lt[B(e).toLowerCase()] ?? "application/octet-stream", dt = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), ft = async (e) => {
253
+ }, St = (e) => xt[R(e).toLowerCase()] ?? "application/octet-stream", Ct = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), Q = async (e) => {
255
254
  try {
256
- return await H.stat(e), !0;
255
+ return await V.stat(e), !0;
257
256
  } catch {
258
257
  return !1;
259
258
  }
260
- }, pt = (e) => {
259
+ }, wt = (e) => {
261
260
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
262
261
  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, "\\$&"));
263
262
  let a = i.join("/");
@@ -266,8 +265,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
266
265
  paramNames: t,
267
266
  priority: n
268
267
  };
269
- }, mt = (e) => e.map((e) => {
270
- let { regex: t, paramNames: n, priority: r } = pt(e.pattern);
268
+ }, Tt = (e) => e.map((e) => {
269
+ let { regex: t, paramNames: n, priority: r } = wt(e.pattern);
271
270
  return {
272
271
  pattern: e.pattern,
273
272
  file: e.file,
@@ -276,7 +275,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
276
275
  paramNames: n,
277
276
  priority: r
278
277
  };
279
- }).slice().sort((e, t) => e.priority - t.priority), ht = (e, t) => {
278
+ }).slice().sort((e, t) => e.priority - t.priority), Et = (e, t) => {
280
279
  for (let n of t) {
281
280
  let t = n.regex.exec(e);
282
281
  if (!t) continue;
@@ -288,7 +287,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
288
287
  };
289
288
  }
290
289
  return null;
291
- }, gt = null, _t, vt = (e, t) => t === void 0 ? Promise.resolve() : (_t ??= (async () => {
290
+ }, Dt = null, Ot, kt = (e, t) => t === void 0 ? Promise.resolve() : (Ot ??= (async () => {
292
291
  try {
293
292
  let n = await e.getHelpers(), r = n.apiDescriptors?.[t];
294
293
  if (r === void 0) return;
@@ -296,79 +295,79 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
296
295
  if (i === void 0) return;
297
296
  i(t, await r());
298
297
  } catch {}
299
- })(), _t), yt = async (e) => {
300
- let { provider: t, route: n, params: r, pathname: a, dirs: s, shellTemplate: d, requestHeaders: m, requestUrl: g = "", apiOrigin: re, apiName: ie } = e;
301
- await vt(t, ie);
302
- let { search: _ } = se(g), v = await ee(ne(e.middlewares ?? [], {
303
- route: n.pattern,
304
- pathname: a
298
+ })(), Ot), At = async (e) => {
299
+ let { provider: t, route: a, params: o, pathname: s, dirs: c, shellTemplate: l, requestHeaders: u, requestUrl: f = "", apiOrigin: ee, apiName: g } = e;
300
+ await kt(t, g);
301
+ let { search: _ } = pe(f), v = await i(ie(e.middlewares ?? [], {
302
+ route: a.pattern,
303
+ pathname: s
305
304
  }), {
306
- pathname: a,
305
+ pathname: s,
307
306
  search: _,
308
- headers: m,
309
- cookies: u(m.cookie),
310
- route: n.pattern
311
- }, e.onCookieWarning), y = await t.getPage(n.pattern, n.file), x = e.forceSsrRender === !0 ? "ssr" : L(y, n.file), ae = x === "isr" && y.ppr === !0, T = x === "isr" && e.holesOnly !== !0 ? i(v.headers) : v.headers, E = _e(re, T.cookie, {
312
- apiName: ie,
313
- headers: T
307
+ headers: u,
308
+ cookies: we(u.cookie),
309
+ route: a.pattern
310
+ }, e.onCookieWarning), b = await t.getPage(a.pattern, a.file), x = e.forceSsrRender === !0 ? "ssr" : Re(b, a.file), S = x === "isr" && b.ppr === !0, w = x === "isr" && e.holesOnly !== !0 ? C(v.headers) : v.headers, te = ye(ee, w.cookie, {
311
+ apiName: g,
312
+ headers: w
314
313
  });
315
314
  if (e.holesOnly === !0) {
316
- if (typeof y.loader != "function") return null;
315
+ if (typeof b.loader != "function") return null;
317
316
  let e = new AbortController();
318
317
  return {
319
318
  holes: {
320
- loader: y.loader,
319
+ loader: b.loader,
321
320
  ctx: {
322
- params: r,
323
- pathname: a,
321
+ params: o,
322
+ pathname: s,
324
323
  search: _,
325
324
  signal: e.signal,
326
- headers: T,
327
- query: E,
325
+ headers: w,
326
+ query: te,
328
327
  isServer: !0
329
328
  },
330
329
  helpers: await t.getHelpers(),
331
- page: n.pattern
330
+ page: a.pattern
332
331
  },
333
332
  setCookies: v.setCookies
334
333
  };
335
334
  }
336
- let D = x === "spa" && me(s, n.dirChain).some((e) => e.hasLayout);
337
- if (x !== "ssr" && x !== "isr" && !D) return null;
338
- let ce = me(s, n.dirChain), le = {}, ue = null, de, fe = new AbortController(), O = ae ? c(T, n.pattern) : T;
335
+ let E = x === "spa" && xe(c, a.dirChain).some((e) => e.hasLayout);
336
+ if (x !== "ssr" && x !== "isr" && !E) return null;
337
+ let ne = xe(c, a.dirChain), oe = {}, se = null, O, le = new AbortController(), ue = S ? j(w, a.pattern) : w;
339
338
  try {
340
- (await t.getHelpers()).beginStoreSeeds(), {chain: de, segmentLoaderData: le} = await F({
341
- entries: ce,
339
+ (await t.getHelpers()).beginStoreSeeds(), {chain: O, segmentLoaderData: oe} = await de({
340
+ entries: ne,
342
341
  loadLayout: (e) => t.getLayout(e.dir),
343
342
  loadError: (e) => t.getError(e.dir),
344
343
  loadPending: (e) => t.getPending(e.dir),
345
344
  ctx: {
346
- params: r,
347
- pathname: a,
345
+ params: o,
346
+ pathname: s,
348
347
  search: _,
349
- signal: fe.signal,
350
- headers: O,
351
- query: E,
348
+ signal: le.signal,
349
+ headers: ue,
350
+ query: te,
352
351
  isServer: !0
353
352
  }
354
- }), typeof y.loader == "function" && !D && (ue = await y.loader({
355
- params: r,
356
- pathname: a,
353
+ }), typeof b.loader == "function" && !E && (se = await b.loader({
354
+ params: o,
355
+ pathname: s,
357
356
  search: _,
358
- signal: fe.signal,
359
- headers: O,
360
- query: E,
357
+ signal: le.signal,
358
+ headers: ue,
359
+ query: te,
361
360
  isServer: !0
362
361
  }));
363
362
  } catch (e) {
364
- if (st(e)) return {
363
+ if (bt(e)) return {
365
364
  control: "redirect",
366
365
  status: e.status,
367
366
  location: e.location,
368
367
  setCookies: v.setCookies,
369
368
  responseHeaders: v.responseHeaders
370
369
  };
371
- if (ct(e)) return {
370
+ if (Z(e)) return {
372
371
  control: "not-found",
373
372
  setCookies: v.setCookies,
374
373
  responseHeaders: v.responseHeaders
@@ -376,79 +375,79 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
376
375
  throw e;
377
376
  }
378
377
  let k = await t.getHelpers();
379
- D || await Se({
380
- pageMod: y,
381
- params: r,
382
- query: E,
383
- apiName: ie,
378
+ E || await re({
379
+ pageMod: b,
380
+ params: o,
381
+ query: te,
382
+ apiName: g,
384
383
  seed: k.seedPreloadedSubscription,
385
384
  seedFailure: k.seedPreloadedSubscriptionFailure,
386
- onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
385
+ onError: ({ tag: e, apiName: t }, n) => X.warn("preload seed failed", {
387
386
  tag: e,
388
387
  apiName: t,
389
- pathname: a
388
+ pathname: s
390
389
  }, n)
391
390
  });
392
- let he = {
393
- pattern: n.pattern,
394
- Component: y.default,
395
- meta: y.meta,
396
- loader: y.loader,
397
- ErrorBoundary: y.ErrorBoundary,
398
- Pending: y.Pending,
391
+ let fe = {
392
+ pattern: a.pattern,
393
+ Component: b.default,
394
+ meta: b.meta,
395
+ loader: b.loader,
396
+ ErrorBoundary: b.ErrorBoundary,
397
+ Pending: b.Pending,
399
398
  renderMode: x,
400
- chain: de
399
+ chain: O
401
400
  };
402
- if (x === "isr" && v.cspNonce !== void 0) throw Error(`page '${n.pattern}' is renderMode 'isr' while middleware.ts mints a cspNonce — an isr render is CACHED and a cached nonce is a lie the browser enforces. Use renderMode 'ssr' for nonce'd pages, or a hash-based CSP for isr.`);
403
- let ge = {
404
- cookies: ae ? l(pe(v.cookies), n.pattern) : x === "isr" ? pe(v.cookies) : v.cookies,
405
- headers: O,
406
- url: g,
401
+ if (x === "isr" && v.cspNonce !== void 0) throw Error(`page '${a.pattern}' is renderMode 'isr' while middleware.ts mints a cspNonce — an isr render is CACHED and a cached nonce is a lie the browser enforces. Use renderMode 'ssr' for nonce'd pages, or a hash-based CSP for isr.`);
402
+ let me = {
403
+ cookies: S ? r(y(v.cookies), a.pattern) : x === "isr" ? y(v.cookies) : v.cookies,
404
+ headers: ue,
405
+ url: f,
407
406
  ...e.formFlash === void 0 ? {} : { formFlash: e.formFlash }
408
- }, A = k.i18n?.resolve(T.cookie, T["accept-language"]), j = {
409
- lang: A?.locale ?? ge.cookies["voltro:locale"] ?? "en",
407
+ }, A = k.i18n?.resolve(w.cookie, w["accept-language"]), he = {
408
+ lang: A?.locale ?? me.cookies["voltro:locale"] ?? "en",
410
409
  ...A?.timeZone === void 0 ? {} : { timeZone: A.timeZone },
411
410
  renderedAt: Date.now()
412
- }, M = y.interactive ?? "full";
413
- if (D) {
414
- let e = P({
411
+ }, N = b.interactive ?? "full";
412
+ if (E) {
413
+ let e = ce({
415
414
  helpers: k,
416
- page: n.pattern,
417
- interactive: M,
415
+ page: a.pattern,
416
+ interactive: N,
418
417
  delivery: "stream",
419
418
  renderInput: {
420
- descriptor: he,
421
- params: r,
422
- pathname: a,
419
+ descriptor: fe,
420
+ params: o,
421
+ pathname: s,
423
422
  search: _,
424
- segmentLoaderData: le,
425
- requestContext: ge,
423
+ segmentLoaderData: oe,
424
+ requestContext: me,
426
425
  ...A ? {
427
426
  outerWrap: A.outerWrap,
428
427
  locale: A.locale
429
428
  } : {}
430
429
  }
431
- }), t = (t) => w({
430
+ }), t = (t) => n({
432
431
  helpers: k,
433
432
  prepared: e,
434
433
  meta: t,
435
- interactive: M
434
+ interactive: N
436
435
  });
437
436
  if (e.hasDeferred) {
438
- let n = f({ shell: d });
437
+ let n = h({ shell: l });
439
438
  return {
440
439
  renderMode: "spa",
441
440
  setCookies: v.setCookies,
442
441
  responseHeaders: v.responseHeaders,
443
- stream: (r) => oe({
442
+ stream: (r) => m({
444
443
  res: r,
445
444
  shell: n,
446
- documentAttrs: j,
445
+ documentAttrs: he,
447
446
  headers: {
448
447
  ...v.responseHeaders,
449
448
  "content-type": "text/html; charset=utf-8",
450
449
  "x-voltro-rendered-by": "spa",
451
- ...h(v.setCookies)
450
+ ...p(v.setCookies)
452
451
  },
453
452
  headInjection: t,
454
453
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
@@ -458,101 +457,101 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
458
457
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce }
459
458
  }),
460
459
  onShellError: (e) => {
461
- Z.error("spa layout shell render failed", { pathname: a }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
460
+ X.error("spa layout shell render failed", { pathname: s }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
462
461
  }
463
462
  })
464
463
  };
465
464
  }
466
- let i = te({
465
+ let r = T({
467
466
  helpers: k,
468
467
  prepared: e
469
- }), s = o(C(d.replace("<div id=\"root\"></div>", `<div id="root">${i.body}</div>`), t(i.meta)), j);
468
+ }), i = D(d(l.replace("<div id=\"root\"></div>", `<div id="root">${r.body}</div>`), t(r.meta)), he);
470
469
  return {
471
- html: v.cspNonce === void 0 ? s : S(s, v.cspNonce),
470
+ html: v.cspNonce === void 0 ? i : F(i, v.cspNonce),
472
471
  renderMode: "spa",
473
472
  revalidateMs: null,
474
473
  setCookies: v.setCookies,
475
474
  responseHeaders: v.responseHeaders
476
475
  };
477
476
  }
478
- let N = p({
477
+ let P = ae({
479
478
  helpers: k,
480
- page: n.pattern,
481
- pathname: a,
479
+ page: a.pattern,
480
+ pathname: s,
482
481
  renderMode: x,
483
- interactive: M,
484
- loaderData: ue,
485
- segmentLoaderData: le,
486
- pageLoaderRan: typeof y.loader == "function",
487
- ...ae ? { ppr: !0 } : {}
482
+ interactive: N,
483
+ loaderData: se,
484
+ segmentLoaderData: oe,
485
+ pageLoaderRan: typeof b.loader == "function",
486
+ ...S ? { ppr: !0 } : {}
488
487
  });
489
- ae && b(N.stateInput, n.pattern);
490
- let ve = {
491
- descriptor: he,
492
- params: r,
493
- pathname: a,
488
+ S && M(P.stateInput, a.pattern);
489
+ let ge = {
490
+ descriptor: fe,
491
+ params: o,
492
+ pathname: s,
494
493
  search: _,
495
- loaderData: N.loaderData,
496
- segmentLoaderData: N.segmentLoaderData,
497
- requestContext: ge,
494
+ loaderData: P.loaderData,
495
+ segmentLoaderData: P.segmentLoaderData,
496
+ requestContext: me,
498
497
  ...A ? {
499
498
  outerWrap: A.outerWrap,
500
499
  locale: A.locale
501
500
  } : {}
502
- }, ye = (t) => {
503
- if (gt === null || x !== "ssr" && x !== "isr" || typeof y.ogImage != "function" || t.includes("og:image")) return "";
504
- let r = T["x-tenant"], i = gt.signOgUrl({
505
- pattern: n.pattern,
501
+ }, _e = (t) => {
502
+ if (Dt === null || x !== "ssr" && x !== "isr" || typeof b.ogImage != "function" || t.includes("og:image")) return "";
503
+ let n = w["x-tenant"], r = Dt.signOgUrl({
504
+ pattern: a.pattern,
506
505
  params: e.params,
507
- ...r === void 0 ? {} : { tenant: r }
506
+ ...n === void 0 ? {} : { tenant: n }
508
507
  });
509
- return `<meta property="og:image" content="${i}" /><meta name="twitter:image" content="${i}" /><meta name="twitter:card" content="summary_large_image" />`;
510
- }, be = (e) => [
511
- k.renderMetaToHtml(e) + ye(k.renderMetaToHtml(e)),
512
- `<meta name="voltro-interactive" content="${M}" />`,
513
- ...N.hasDeferred ? [k.renderDeferredRegistryScript()] : [],
514
- k.renderRouterStateScript(N.stateInput)
508
+ return `<meta property="og:image" content="${r}" /><meta name="twitter:image" content="${r}" /><meta name="twitter:card" content="summary_large_image" />`;
509
+ }, ve = (e) => [
510
+ k.renderMetaToHtml(e) + _e(k.renderMetaToHtml(e)),
511
+ `<meta name="voltro-interactive" content="${N}" />`,
512
+ ...P.hasDeferred ? [k.renderDeferredRegistryScript()] : [],
513
+ k.renderRouterStateScript(P.stateInput)
515
514
  ].filter((e) => e.length > 0).join("\n ");
516
- if (x === "ssr" && M === "full" && e.buffered !== !0) {
517
- let e = f({ shell: d });
515
+ if (x === "ssr" && N === "full" && e.buffered !== !0) {
516
+ let e = h({ shell: l });
518
517
  return {
519
518
  renderMode: "ssr",
520
519
  setCookies: v.setCookies,
521
- stream: (t) => oe({
520
+ stream: (t) => m({
522
521
  res: t,
523
522
  shell: e,
524
- documentAttrs: j,
523
+ documentAttrs: he,
525
524
  headers: {
526
525
  ...v.responseHeaders,
527
526
  "content-type": "text/html; charset=utf-8",
528
527
  "x-voltro-rendered-by": "ssr",
529
- ...h(v.setCookies)
528
+ ...p(v.setCookies)
530
529
  },
531
- headInjection: be,
530
+ headInjection: ve,
532
531
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
533
532
  render: (e) => k.renderPageToStream({
534
- ...ve,
533
+ ...ge,
535
534
  ...e,
536
535
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce }
537
536
  }),
538
537
  onShellError: (e) => {
539
- Z.error("ssr shell render failed", { pathname: a }, e), t.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), t.end("server error");
538
+ X.error("ssr shell render failed", { pathname: s }, e), t.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), t.end("server error");
540
539
  }
541
540
  })
542
541
  };
543
542
  }
544
- let { html: xe, meta: Ce } = k.renderPageToHtml(ve), we = be(Ce), I = o(C(d.replace("<div id=\"root\"></div>", `<div id="root">${xe}</div>`), we), j);
545
- M === "none" && (I = dt(I));
546
- let Te = x === "isr" ? R(y.revalidate) : null;
543
+ let { html: be, meta: Se } = k.renderPageToHtml(ge), Ce = ve(Se), I = D(d(l.replace("<div id=\"root\"></div>", `<div id="root">${be}</div>`), Ce), he);
544
+ N === "none" && (I = Ct(I));
545
+ let Te = x === "isr" ? L(b.revalidate) : null;
547
546
  return {
548
- html: v.cspNonce === void 0 ? I : S(I, v.cspNonce),
547
+ html: v.cspNonce === void 0 ? I : F(I, v.cspNonce),
549
548
  renderMode: x,
550
549
  revalidateMs: Te,
551
550
  setCookies: v.setCookies,
552
551
  responseHeaders: v.responseHeaders
553
552
  };
554
- }, Q = (e) => e === "" ? "/" : e, bt = async (e) => {
555
- let t = await import(U(e).href);
553
+ }, $ = (e) => e === "" ? "/" : e, jt = async (e) => {
554
+ let t = await import(H(e).href);
556
555
  return {
557
556
  kind: "bundle",
558
557
  getPageMeta: () => t.pageMeta,
@@ -562,18 +561,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
562
561
  return typeof r == "function" ? await r() : r;
563
562
  },
564
563
  async getLayout(e) {
565
- let n = t.layouts[Q(e)];
566
- if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${Q(e)}`);
564
+ let n = t.layouts[$(e)];
565
+ if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${$(e)}`);
567
566
  return typeof n == "function" ? await n() : n;
568
567
  },
569
568
  async getError(e) {
570
- let n = t.errors[Q(e)];
571
- if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${Q(e)}`);
569
+ let n = t.errors[$(e)];
570
+ if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${$(e)}`);
572
571
  return typeof n == "function" ? await n() : n;
573
572
  },
574
573
  async getPending(e) {
575
- let n = t.pendings[Q(e)];
576
- if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${Q(e)}`);
574
+ let n = t.pendings[$(e)];
575
+ if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${$(e)}`);
577
576
  return typeof n == "function" ? await n() : n;
578
577
  },
579
578
  async getHelpers() {
@@ -581,8 +580,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
581
580
  },
582
581
  async close() {}
583
582
  };
584
- }, xt = async (e, t) => {
585
- let n = await m("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
583
+ }, Mt = async (e, t) => {
584
+ let n = await O("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
586
585
  root: t,
587
586
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
588
587
  plugins: [r(), i()],
@@ -599,10 +598,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
599
598
  },
600
599
  appType: "custom",
601
600
  logLevel: "warn"
602
- }), o = V(e, "src", "pages"), s = (e) => e === "" ? o : V(o, e), c = O({
603
- limit: g(),
604
- onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
605
- onColdEnd: (e, { durationMs: t, failed: n }) => Z.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
601
+ }), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c = w({
602
+ limit: u(),
603
+ onColdStart: (e) => X.debug("ssr cold-compile start", { id: e }),
604
+ onColdEnd: (e, { durationMs: t, failed: n }) => X.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
606
605
  id: e,
607
606
  ms: t,
608
607
  ...n ? { failed: !0 } : {}
@@ -611,16 +610,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
611
610
  return {
612
611
  kind: "middleware",
613
612
  async getPage(e, t) {
614
- return l(V(o, t));
613
+ return l(z(o, t));
615
614
  },
616
615
  async getLayout(e) {
617
- return l(V(s(e), "layout.tsx"));
616
+ return l(z(s(e), "layout.tsx"));
618
617
  },
619
618
  async getError(e) {
620
- return l(V(s(e), "error.tsx"));
619
+ return l(z(s(e), "error.tsx"));
621
620
  },
622
621
  async getPending(e) {
623
- return l(V(s(e), "loading.tsx"));
622
+ return l(z(s(e), "loading.tsx"));
624
623
  },
625
624
  async getHelpers() {
626
625
  return await l("@voltro/web/ssr");
@@ -629,172 +628,172 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
629
628
  await a.close();
630
629
  }
631
630
  };
632
- }, $ = async (t) => {
633
- let i = Ue(), o = await ve(t);
634
- if (!o) return {
631
+ }, Nt = async (t) => {
632
+ let n = Je(), r = await P(t);
633
+ if (!r) return {
635
634
  ran: !1,
636
635
  exitCode: 0
637
636
  };
638
- if (o.type !== "web") return Z.error("only web apps are supported by `voltro start`"), {
637
+ if (r.type !== "web") return X.error("only web apps are supported by `voltro start`"), {
639
638
  ran: !0,
640
639
  exitCode: 1
641
640
  };
642
641
  {
643
- let e = y(o);
644
- if (e !== void 0) return Z.error(`voltro start: refusing to boot — ${e}`), {
642
+ let e = a(r);
643
+ if (e !== void 0) return X.error(`voltro start: refusing to boot — ${e}`), {
645
644
  ran: !0,
646
645
  exitCode: 1
647
646
  };
648
647
  }
649
- let { resolved: c } = await ae({
650
- rawEnv: o.env,
648
+ let { resolved: u } = await ee({
649
+ rawEnv: r.env,
651
650
  appType: "web",
652
651
  root: t,
653
- log: Z,
652
+ log: X,
654
653
  generateTypes: !1
655
- }), l = c.publicValues;
656
- i.mark("config");
657
- let f = ce();
658
- E(f), Z.info("booting voltro start", { app: o.name ?? "(unnamed)" });
659
- let te = n({
654
+ }), d = u.publicValues;
655
+ n.mark("config");
656
+ let p = le();
657
+ N(p), X.info("booting voltro start", { app: r.name ?? "(unnamed)" });
658
+ let m = je({
660
659
  kind: "web",
661
- configPort: o.port,
660
+ configPort: r.port,
662
661
  env: process.env,
663
- dashboardPin: process.env[T] === "1"
662
+ dashboardPin: process.env[be] === "1"
664
663
  });
665
- for (let e of te.warnings) Z.warn(e);
666
- let p = te.port, m = V(t, ".framework"), h = V(m, "dist"), g = V(h, "index.html");
667
- if (!await ft(g)) return Z.error("no built dist found — run `voltro build` first", { distDir: h }), {
664
+ for (let e of m.warnings) X.warn(e);
665
+ let h = m.port, y = z(t, ".framework"), C = z(y, "dist"), w = z(C, "index.html");
666
+ if (!await Q(w)) return X.error("no built dist found — run `voltro build` first", { distDir: C }), {
668
667
  ran: !0,
669
668
  exitCode: 1
670
669
  };
671
- let b = o.name ?? "unnamed", S = Ve("web", b, p), C = He(b);
672
- await Re({
673
- id: S,
674
- name: b,
670
+ let T = r.name ?? "unnamed", re = Ke("web", T, h), D = qe(T);
671
+ await Ue({
672
+ id: re,
673
+ name: T,
675
674
  kind: "web",
676
- url: `http://localhost:${p}`,
675
+ url: `http://localhost:${h}`,
677
676
  pid: process.pid,
678
677
  status: "booting",
679
- logFile: C.path
678
+ logFile: D.path
680
679
  }).catch(() => {});
681
- let oe = V(h, "_voltro", "shell.html"), w = await ft(oe) ? await H.readFile(oe, "utf8") : await H.readFile(g, "utf8"), O = await ge(t, o), pe = Ae(o), P = j(O[0]), F = O[0]?.name, Se = /* @__PURE__ */ new Set(), L = (e) => {
682
- Se.has(e.name) || (Se.add(e.name), Z.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
680
+ let ae = z(C, "_voltro", "shell.html"), O = await Q(ae) ? await V.readFile(ae, "utf8") : await V.readFile(w, "utf8"), ce = await me(t, r), de = Pe(r), j = Ye(r), M = ge(ce[0]), F = ce[0]?.name, Re = /* @__PURE__ */ new Set(), L = (e) => {
681
+ Re.has(e.name) || (Re.add(e.name), X.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
683
682
  cookie: e.name,
684
683
  hint: "If your IdP client reads this from `document.cookie` (Supabase's `createBrowserClient` does), pass `httpOnly: false`. Otherwise the SSR render succeeds and the user is signed out at the first client-side call. Set `httpOnly: true` explicitly to silence this."
685
684
  }));
686
- }, R = await re(t);
687
- R.length > 0 && Z.info(`middleware.ts loaded — ${R.length} middleware(s): ` + R.map((e) => e.exportName).join(", "));
688
- let z, B = null, We = process.env.SSR_CACHE === "postgres";
689
- if (We && we()) B = new (await (import("pg"))).default.Client(Ce()), await B.connect(), z = rt({ client: B }), Z.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
690
- else if (We) {
685
+ }, R = await g(t);
686
+ R.length > 0 && X.info(`middleware.ts loaded — ${R.length} middleware(s): ` + R.map((e) => e.exportName).join(", "));
687
+ let B, H = null, U = process.env.SSR_CACHE === "postgres";
688
+ if (U && Ne()) H = new (await (import("pg"))).default.Client(Me()), await H.connect(), B = gt({ client: H }), X.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
689
+ else if (U) {
691
690
  let t = "SSR_CACHE=postgres, but nothing in the environment names a database (looked for DB_URL, DB_PRIMARY_URL, DB_DIRECT_URL, DB_MIGRATE_URL, DB_HOST, PG_HOST).";
692
- if (e()) throw Z.fatal(`${t} Refusing to fall back to the per-process memory cache: it is not shared between instances and does not survive a restart, so the pages this process serves would differ from its replicas' with nothing to indicate it.`), Error("[voltro start] SSR_CACHE=postgres with no database configured");
693
- z = Fe(), Z.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
694
- } else z = Fe(), Z.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
695
- await s(t, o, O, l);
696
- let Ge = V(t, "src", "pages"), { pages: U, dirs: W } = await xe(Ge), G = mt(U);
697
- fe(R, G.map((e) => e.pattern)), i.mark("scan");
698
- let K = V(h, "server", "ssrEntry.js"), Ze = await ft(K);
699
- if (!Ze && process.env.NODE_ENV === "production") throw Z.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${K} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${K}`);
700
- let q = Ze ? await bt(K) : await xt(t, m);
701
- Z.info(`ssr loader: ${q.kind}`, {
691
+ if (e()) throw X.fatal(`${t} Refusing to fall back to the per-process memory cache: it is not shared between instances and does not survive a restart, so the pages this process serves would differ from its replicas' with nothing to indicate it.`), Error("[voltro start] SSR_CACHE=postgres with no database configured");
692
+ B = Be(), X.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
693
+ } else B = Be(), X.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
694
+ await Ce(t, r, ce, d);
695
+ let tt = z(t, "src", "pages"), { pages: nt, dirs: W } = await E(tt), G = Tt(nt);
696
+ l(R, G.map((e) => e.pattern)), n.mark("scan");
697
+ let K = z(C, "server", "ssrEntry.js"), pt = await Q(K);
698
+ if (!pt && process.env.NODE_ENV === "production") throw X.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${K} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${K}`);
699
+ let q = pt ? await jt(K) : await Mt(t, y);
700
+ X.info(`ssr loader: ${q.kind}`, {
702
701
  kind: q.kind,
703
702
  ...q.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
704
- }), i.mark("provider");
705
- let et = q.getPageMeta?.();
706
- D(t);
707
- let J = /* @__PURE__ */ new Map(), nt = 0;
708
- for (let e of U) {
709
- let t = et?.[e.pattern];
703
+ }), n.mark("provider");
704
+ let ht = q.getPageMeta?.();
705
+ o(t);
706
+ let J = /* @__PURE__ */ new Map(), Y = 0;
707
+ for (let e of nt) {
708
+ let t = ht?.[e.pattern];
710
709
  if (t) {
711
710
  J.set(e.pattern, t);
712
711
  continue;
713
712
  }
714
713
  try {
715
714
  let t = await q.getPage(e.pattern, e.file);
716
- J.set(e.pattern, Ne(t, e.file)), nt++;
715
+ J.set(e.pattern, Le(t, e.file)), Y++;
717
716
  } catch (t) {
718
- Z.warn("failed to load page metadata", { pattern: e.pattern }, t);
717
+ X.warn("failed to load page metadata", { pattern: e.pattern }, t);
719
718
  }
720
719
  }
721
- let Y = /* @__PURE__ */ new Map();
720
+ let bt = /* @__PURE__ */ new Map();
722
721
  for (let [e, t] of J) {
723
722
  if (t.interactive !== "islands") continue;
724
- let n = V(h, "island-shells", `${x(e)}.html`);
723
+ let n = z(C, "island-shells", `${S(e)}.html`);
725
724
  try {
726
- Y.set(e, await H.readFile(n, "utf8"));
725
+ bt.set(e, await V.readFile(n, "utf8"));
727
726
  } catch {
728
- Z.warn("islands page has no built per-page shell — serving the full app shell", {
727
+ X.warn("islands page has no built per-page shell — serving the full app shell", {
729
728
  pattern: e,
730
729
  expected: n
731
730
  });
732
731
  }
733
732
  }
734
- Z.info(`registered ${J.size} route(s)`, {
733
+ X.info(`registered ${J.size} route(s)`, {
735
734
  count: J.size,
736
- fromManifest: J.size - nt,
737
- fromModules: nt
738
- }), i.mark("routes");
739
- let X = /* @__PURE__ */ new Set();
740
- for (let e of G) J.get(e.pattern)?.renderMode === "spa" && me(W, e.dirChain).some((e) => e.hasLayout) && X.add(e.pattern);
741
- X.size > 0 && Z.info(`${X.size} spa route(s) render an SSR layout shell`, { patterns: [...X] });
742
- let st = /* @__PURE__ */ new Map();
743
- for (let [e, t] of J) t.cacheInvalidatesOn.length > 0 && st.set(e, t.cacheInvalidatesOn);
744
- let ct = /* @__PURE__ */ new Map();
745
- for (let e of G) ct.set(e.pattern, e.regex);
735
+ fromManifest: J.size - Y,
736
+ fromModules: Y
737
+ }), n.mark("routes");
738
+ let Z = /* @__PURE__ */ new Set();
739
+ for (let e of G) J.get(e.pattern)?.renderMode === "spa" && xe(W, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
740
+ Z.size > 0 && X.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
741
+ let xt = /* @__PURE__ */ new Map();
742
+ for (let [e, t] of J) t.cacheInvalidatesOn.length > 0 && xt.set(e, t.cacheInvalidatesOn);
743
+ let Ct = /* @__PURE__ */ new Map();
744
+ for (let e of G) Ct.set(e.pattern, e.regex);
746
745
  {
747
746
  let n = new Set([...J].filter(([, e]) => (e.renderMode === "ssr" || e.renderMode === "isr") && e.hasOgImage).map(([e]) => e));
748
747
  if (n.size > 0) {
749
- let { secret: r, fromEnv: i } = ue();
750
- if (!i && e()) throw Z.fatal(`${n.size} ssr route(s) export ogImage, but VOLTRO_OG_SECRET is unset. Behind a load balancer the signing replica and the fetching replica differ, so a per-boot secret would 403 every cross-replica image fetch. Set VOLTRO_OG_SECRET (any long random value, same on every replica).`), Error("[voltro start] ssr ogImage routes need VOLTRO_OG_SECRET in a deploy environment");
751
- let a = new Map(U.map((e) => [e.pattern, e.file]));
752
- gt = A({
748
+ let { secret: i, fromEnv: a } = Se();
749
+ if (!a && e()) throw X.fatal(`${n.size} ssr route(s) export ogImage, but VOLTRO_OG_SECRET is unset. Behind a load balancer the signing replica and the fetching replica differ, so a per-boot secret would 403 every cross-replica image fetch. Set VOLTRO_OG_SECRET (any long random value, same on every replica).`), Error("[voltro start] ssr ogImage routes need VOLTRO_OG_SECRET in a deploy environment");
750
+ let o = new Map(nt.map((e) => [e.pattern, e.file]));
751
+ Dt = ue({
753
752
  root: t,
754
- fonts: o.fonts,
755
- cache: z,
756
- secret: r,
753
+ fonts: r.fonts,
754
+ cache: B,
755
+ secret: i,
757
756
  isOgSsrRoute: (e) => n.has(e),
758
757
  getPageModule: async (e) => {
759
- let t = a.get(e);
758
+ let t = o.get(e);
760
759
  return t === void 0 ? null : await q.getPage(e, t);
761
760
  }
762
- }), Z.info(`og route active for ${n.size} ssr route(s)`, { secret: i ? "env" : "per-boot" });
761
+ }), X.info(`og route active for ${n.size} ssr route(s)`, { secret: a ? "env" : "per-boot" });
763
762
  }
764
763
  }
765
- let lt = /* @__PURE__ */ new Map();
766
- for (let [e, t] of J) lt.set(e, t.renderMode);
767
- let dt = [...J.values()].some((e) => e.renderMode === "isr"), pt = {
768
- cache: z,
769
- tableSink: $e({
770
- cache: z,
771
- tableSubscriptionsByPattern: st,
772
- regexByPattern: ct
764
+ let wt = /* @__PURE__ */ new Map();
765
+ for (let [e, t] of J) wt.set(e, t.renderMode);
766
+ let Ot = [...J.values()].some((e) => e.renderMode === "isr"), kt = {
767
+ cache: B,
768
+ tableSink: ft({
769
+ cache: B,
770
+ tableSubscriptionsByPattern: xt,
771
+ regexByPattern: Ct
773
772
  }),
774
- regexByPattern: ct,
775
- renderModeByPattern: lt
776
- }, _t = (e) => {
777
- let t = it(e);
778
- t && at(pt, t);
779
- }, vt = tt({
780
- cache: z,
781
- tableSubscriptionsByPattern: st,
782
- regexByPattern: ct,
783
- ...dt ? { onRevalidate: _t } : {}
784
- }), Q = await vt.start(), $ = null, St = null;
785
- if (dt) {
786
- let e = Ye({}, process.env);
773
+ regexByPattern: Ct,
774
+ renderModeByPattern: wt
775
+ }, $ = (e) => {
776
+ let t = _t(e);
777
+ t && vt(kt, t);
778
+ }, Nt = mt({
779
+ cache: B,
780
+ tableSubscriptionsByPattern: xt,
781
+ regexByPattern: Ct,
782
+ ...Ot ? { onRevalidate: $ } : {}
783
+ }), Pt = await Nt.start(), Ft = null, It = null;
784
+ if (Ot) {
785
+ let e = ct({}, process.env);
787
786
  if (e.crossReplica) try {
788
- St = e.provider;
789
- let t = je(process.env);
790
- $ = await qe.runPromise(e.provider.subscribe(t, _t)), Z.info(`revalidation subscriber: broker (${e.provider.name})`, { channel: t });
787
+ It = e.provider;
788
+ let t = Fe(process.env);
789
+ Ft = await st.runPromise(e.provider.subscribe(t, $)), X.info(`revalidation subscriber: broker (${e.provider.name})`, { channel: t });
791
790
  } catch (e) {
792
- Z.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), St = null;
791
+ X.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), It = null;
793
792
  }
794
- Q && $ === null && Z.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !Q && $ === null && Z.warn("isr routes exist, but this web process has NO revalidation transport: no database is configured for the LISTEN line and no broker is configured. `revalidatePath` / `revalidateTable` / `revalidateTag` from the api will not reach this process — cached pages stay until their own `revalidate` window expires. Set DB_URL (postgres) or BROADCAST_URL (redis:// or nats://) on BOTH the api and this web deployment.");
793
+ Pt && Ft === null && X.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !Pt && Ft === null && X.warn("isr routes exist, but this web process has NO revalidation transport: no database is configured for the LISTEN line and no broker is configured. `revalidatePath` / `revalidateTable` / `revalidateTag` from the api will not reach this process — cached pages stay until their own `revalidate` window expires. Set DB_URL (postgres) or BROADCAST_URL (redis:// or nats://) on BOTH the api and this web deployment.");
795
794
  }
796
- i.mark("cdc");
797
- let Ct = Me(), wt = U.map((e) => {
795
+ n.mark("cdc");
796
+ let Lt = Ie(), Rt = nt.map((e) => {
798
797
  let t = J.get(e.pattern);
799
798
  return {
800
799
  pattern: e.pattern,
@@ -810,20 +809,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
810
809
  hasMeta: t?.hasMeta ?? !1,
811
810
  hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
812
811
  };
813
- }), Tt = W.map((e) => ({
812
+ }), zt = W.map((e) => ({
814
813
  dir: e.dir,
815
814
  hasLayout: e.hasLayout,
816
815
  hasError: e.hasError,
817
816
  hasPending: e.hasPending,
818
817
  hasNotFound: e.hasNotFound
819
- })), Et = B ? "postgres" : "memory", Dt = {
818
+ })), Bt = H ? "postgres" : "memory", Vt = {
820
819
  kind: "web",
821
820
  meta: {
822
- name: o.name ?? "(unnamed)",
823
- voltroVersion: ot,
824
- port: p,
825
- mode: "start",
826
- apis: Object.entries(o.apis ?? {}).map(([e, t]) => {
821
+ name: r.name ?? "(unnamed)",
822
+ voltroVersion: yt,
823
+ port: h,
824
+ mode: et(),
825
+ apis: Object.entries(r.apis ?? {}).map(([e, t]) => {
827
826
  let n = {
828
827
  name: e,
829
828
  package: t.package
@@ -831,10 +830,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
831
830
  return t.url !== void 0 && (n.url = t.url), n;
832
831
  })
833
832
  },
834
- routes: wt,
835
- dirs: Tt,
833
+ routes: Rt,
834
+ dirs: zt,
836
835
  cache: () => {
837
- let e = Date.now(), t = z.snapshot().map(([t, n]) => ({
836
+ let e = Date.now(), t = B.snapshot().map(([t, n]) => ({
838
837
  key: t,
839
838
  renderedAt: n.renderedAt,
840
839
  expiresAt: n.expiresAt,
@@ -845,16 +844,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
845
844
  staleWhileRevalidateMs: n.staleWhileRevalidateMs
846
845
  }));
847
846
  return {
848
- backend: Et,
849
- size: z.size(),
847
+ backend: Bt,
848
+ size: B.size(),
850
849
  entries: t
851
850
  };
852
851
  },
853
- metrics: () => Je()
854
- }, Ot = async (e, n) => {
855
- let r = e.split("?")[0] ?? "/";
856
- if (o.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
857
- let e = await ze();
852
+ metrics: () => ot()
853
+ }, Ht = async (e, n) => {
854
+ let a = e.split("?")[0] ?? "/";
855
+ if (r.name === "voltroDashboard" && a === "/api/dashboard/registry") try {
856
+ let e = await We();
858
857
  return {
859
858
  status: 200,
860
859
  headers: { "content-type": "application/json; charset=utf-8" },
@@ -867,7 +866,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
867
866
  body: `registry read error: ${e.message}`
868
867
  };
869
868
  }
870
- if (o.name === "voltroDashboard" && r === "/api/dashboard/config") {
869
+ if (r.name === "voltroDashboard" && a === "/api/dashboard/config") {
871
870
  let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
872
871
  if (e && e.trim().length > 0) {
873
872
  let n;
@@ -896,27 +895,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
896
895
  body: JSON.stringify({ apps: t })
897
896
  };
898
897
  }
899
- if (gt !== null && r === "/_voltro/og") {
900
- let t = await gt.handle(new URL(e, "http://localhost"));
898
+ if (Dt !== null && a === "/_voltro/og") {
899
+ let t = await Dt.handle(new URL(e, "http://localhost"));
901
900
  if (t !== null) return {
902
901
  status: t.status,
903
902
  headers: { ...t.headers },
904
903
  body: Buffer.from(t.body)
905
904
  };
906
905
  }
907
- if (r === "/_voltro/inspect/logs") {
908
- let t = M(e, N(), n);
906
+ if (a === "/_voltro/inspect/logs") {
907
+ let t = _e(e, fe(), n);
909
908
  return {
910
909
  status: t.status,
911
910
  headers: {
912
911
  "content-type": t.contentType,
913
- ...Te(n.origin)
912
+ ...De(n.origin)
914
913
  },
915
914
  body: t.body
916
915
  };
917
916
  }
918
- if (r !== "/_voltro/inspect/stream") {
919
- let t = De(e, Dt, n);
917
+ if (a !== "/_voltro/inspect/stream") {
918
+ let t = Oe(e, Vt, n);
920
919
  if (t !== null) return {
921
920
  status: t.status,
922
921
  headers: {
@@ -926,67 +925,93 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
926
925
  body: t.body
927
926
  };
928
927
  }
929
- let i = ht(r, G), a = i ? J.get(i.route.pattern)?.renderMode : void 0, s = a === "ssr" || a === "isr" || (i ? X.has(i.route.pattern) : !1), c = [];
930
- if (!s && R.length > 0) {
931
- let t = ne(R, {
928
+ let o = Et(a, G), s = o ? J.get(o.route.pattern)?.renderMode : void 0, c = s === "ssr" || s === "isr" || (o ? Z.has(o.route.pattern) : !1), l = [];
929
+ if (!c && R.length > 0) {
930
+ let t = ie(R, {
932
931
  route: void 0,
933
- pathname: r
932
+ pathname: a
934
933
  });
935
934
  if (t !== void 0) {
936
- let i = await ee(t, {
937
- pathname: r,
938
- search: e.slice(r.length),
935
+ let r = await i(t, {
936
+ pathname: a,
937
+ search: e.slice(a.length),
939
938
  headers: n,
940
- cookies: u(n.cookie),
939
+ cookies: we(n.cookie),
941
940
  route: void 0
942
941
  });
943
- c.push(...i.setCookies);
942
+ l.push(...r.setCookies);
944
943
  }
945
944
  }
946
- let l = (e) => c.length === 0 ? e : {
945
+ let u = (e) => l.length === 0 ? e : {
947
946
  ...e,
948
- "set-cookie": c.map(v)
949
- }, te = r === "/" ? V(h, "index.html") : V(h, r.replace(/^\//, ""), "index.html");
950
- if (!s && await ft(te)) {
951
- let e = await H.readFile(te);
947
+ "set-cookie": l.map(f)
948
+ }, d = a === "/" ? z(C, "index.html") : z(C, a.replace(/^\//, ""), "index.html");
949
+ if (!c && await Q(d)) {
950
+ let e = await V.readFile(d);
952
951
  return {
953
952
  status: 200,
954
- headers: l({ "content-type": "text/html; charset=utf-8" }),
953
+ headers: u({
954
+ "content-type": "text/html; charset=utf-8",
955
+ "cache-control": Ze(j)
956
+ }),
955
957
  body: e
956
958
  };
957
959
  }
958
- if (/\.[a-z0-9]+$/i.test(r)) {
959
- let e = V(h, r.replace(/^\//, ""));
960
- if (await ft(e)) {
961
- let t = await H.readFile(e);
960
+ if (a.endsWith(".map")) return {
961
+ status: 404,
962
+ headers: { "content-type": "text/plain; charset=utf-8" },
963
+ body: "not found"
964
+ };
965
+ if (/\.[a-z0-9]+$/i.test(a)) {
966
+ let e = z(C, a.replace(/^\//, ""));
967
+ if (await Q(e)) {
968
+ let t = Qe(a, j), r = it(n["accept-encoding"]), i = r === "br" ? `${e}.br` : r === "gzip" ? `${e}.gz` : void 0;
969
+ if (i !== void 0 && await Q(i)) {
970
+ let n = await V.readFile(e);
971
+ return {
972
+ status: 200,
973
+ headers: u({
974
+ "content-type": St(e),
975
+ "cache-control": t,
976
+ "content-encoding": r === "br" ? "br" : "gzip",
977
+ vary: "Accept-Encoding",
978
+ etag: ut(n)
979
+ }),
980
+ body: await V.readFile(i)
981
+ };
982
+ }
983
+ let o = await V.readFile(e);
962
984
  return {
963
985
  status: 200,
964
- headers: l({ "content-type": ut(e) }),
965
- body: t
986
+ headers: u({
987
+ "content-type": St(e),
988
+ "cache-control": t
989
+ }),
990
+ body: o
966
991
  };
967
992
  }
968
993
  }
969
- let p = ht(r, G);
970
- if (!p) {
971
- let i = de(W, r);
972
- if (i !== void 0) try {
973
- let a = await yt({
994
+ let m = Et(a, G);
995
+ if (!m) {
996
+ let r = k(W, a);
997
+ if (r !== void 0) try {
998
+ let i = await At({
974
999
  provider: q,
975
1000
  root: t,
976
1001
  route: {
977
1002
  pattern: "<not-found>",
978
- file: i.dir === "" ? "not-found.tsx" : `${i.dir}/not-found.tsx`,
979
- dirChain: i.chain,
1003
+ file: r.dir === "" ? "not-found.tsx" : `${r.dir}/not-found.tsx`,
1004
+ dirChain: r.chain,
980
1005
  regex: /^$/,
981
1006
  paramNames: [],
982
1007
  priority: 2 ** 53 - 1
983
1008
  },
984
1009
  params: {},
985
- pathname: r,
1010
+ pathname: a,
986
1011
  dirs: W,
987
- shellTemplate: w,
1012
+ shellTemplate: O,
988
1013
  requestHeaders: n,
989
- apiOrigin: P,
1014
+ apiOrigin: M,
990
1015
  apiName: F,
991
1016
  middlewares: R,
992
1017
  onCookieWarning: L,
@@ -994,184 +1019,188 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
994
1019
  buffered: !0,
995
1020
  forceSsrRender: !0
996
1021
  });
997
- if (a && "html" in a && typeof a.html == "string") return {
1022
+ if (i && "html" in i && typeof i.html == "string") return {
998
1023
  status: 404,
999
- headers: l({
1024
+ headers: u({
1000
1025
  "content-type": "text/html; charset=utf-8",
1001
1026
  "x-voltro-rendered-by": "ssr-not-found"
1002
1027
  }),
1003
- body: a.html
1028
+ body: i.html
1004
1029
  };
1005
1030
  } catch (e) {
1006
- Z.warn("not-found.tsx failed to render — serving the plain 404", { pathname: r }, e instanceof Error ? e : Error(String(e)));
1031
+ X.warn("not-found.tsx failed to render — serving the plain 404", { pathname: a }, e instanceof Error ? e : Error(String(e)));
1007
1032
  }
1008
1033
  return {
1009
1034
  status: 404,
1010
- headers: l({
1035
+ headers: u({
1011
1036
  "content-type": "text/plain",
1012
1037
  "x-voltro-rendered-by": "plain-not-found"
1013
1038
  }),
1014
1039
  body: "not found"
1015
1040
  };
1016
1041
  }
1017
- let m = J.get(p.route.pattern), g = n["x-tenant"] ?? "anonymous", re = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, _ = Ie(r, {
1018
- ...m?.tenantAware ? { tenant: g } : {},
1019
- ...re ? { locale: re } : {}
1020
- }), y = m?.ppr === !0 && m.renderMode === "isr", b = (i, a) => ({
1042
+ let h = J.get(m.route.pattern), ee = n["x-tenant"] ?? "anonymous", g = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, v = Ve(a, {
1043
+ ...h?.tenantAware ? { tenant: ee } : {},
1044
+ ...g ? { locale: g } : {}
1045
+ }), y = h?.ppr === !0 && h.renderMode === "isr", b = (r, i) => ({
1021
1046
  status: 200,
1022
1047
  headers: {},
1023
1048
  body: "",
1024
1049
  stream: (o) => {
1025
- ie(p.route.pattern), o.writeHead(200, {
1050
+ _(m.route.pattern), o.writeHead(200, {
1026
1051
  "content-type": "text/html; charset=utf-8",
1027
1052
  "x-voltro-rendered-by": "isr",
1028
1053
  "x-voltro-ppr": "shell+holes",
1029
- ...a
1030
- }), o.write(i), (async () => {
1054
+ ...i
1055
+ }), o.write(r), (async () => {
1031
1056
  try {
1032
- let i = await yt({
1057
+ let r = await At({
1033
1058
  provider: q,
1034
1059
  root: t,
1035
- route: p.route,
1036
- params: p.params,
1037
- pathname: r,
1060
+ route: m.route,
1061
+ params: m.params,
1062
+ pathname: a,
1038
1063
  dirs: W,
1039
- shellTemplate: Y.get(p.route.pattern) ?? w,
1064
+ shellTemplate: bt.get(m.route.pattern) ?? O,
1040
1065
  requestHeaders: n,
1041
- apiOrigin: P,
1066
+ apiOrigin: M,
1042
1067
  apiName: F,
1043
1068
  middlewares: R,
1044
1069
  onCookieWarning: L,
1045
1070
  requestUrl: e,
1046
1071
  holesOnly: !0
1047
1072
  });
1048
- i !== null && "holes" in i ? await be({
1049
- loader: i.holes.loader,
1050
- ctx: i.holes.ctx,
1073
+ r !== null && "holes" in r ? await x({
1074
+ loader: r.holes.loader,
1075
+ ctx: r.holes.ctx,
1051
1076
  res: o,
1052
- helpers: i.holes.helpers,
1053
- page: i.holes.page,
1054
- log: Z
1077
+ helpers: r.holes.helpers,
1078
+ page: r.holes.page,
1079
+ log: X
1055
1080
  }) : o.writableEnded || o.end();
1056
1081
  } catch (e) {
1057
- Z.warn("ppr hole pass failed", { url: r }, e), o.writableEnded || o.end();
1082
+ X.warn("ppr hole pass failed", { url: a }, e), o.writableEnded || o.end();
1058
1083
  }
1059
1084
  })();
1060
1085
  }
1061
- }), x = z.get(_), S = Date.now();
1062
- if (x && Le(x, S)) return f.emit("cache", {
1086
+ }), S = B.get(v), w = Date.now();
1087
+ if (S && He(S, w)) return p.emit("cache", {
1063
1088
  kind: "HIT",
1064
- key: _,
1065
- ageMs: S - x.renderedAt
1066
- }), y ? b(x.html, {
1089
+ key: v,
1090
+ ageMs: w - S.renderedAt
1091
+ }), y ? b(S.html, {
1092
+ "cache-control": Xe(j, S.revalidateMs, S.staleWhileRevalidateMs),
1067
1093
  "x-voltro-cache": "HIT",
1068
- "x-voltro-cache-key": _,
1069
- "x-voltro-cache-age-ms": String(S - x.renderedAt)
1094
+ "x-voltro-cache-key": v,
1095
+ "x-voltro-cache-age-ms": String(w - S.renderedAt)
1070
1096
  }) : {
1071
1097
  status: 200,
1072
1098
  headers: {
1073
1099
  "content-type": "text/html; charset=utf-8",
1100
+ "cache-control": Xe(j, S.revalidateMs, S.staleWhileRevalidateMs),
1074
1101
  "x-voltro-rendered-by": "isr",
1075
1102
  "x-voltro-cache": "HIT",
1076
- "x-voltro-cache-key": _,
1077
- "x-voltro-cache-age-ms": String(S - x.renderedAt)
1103
+ "x-voltro-cache-key": v,
1104
+ "x-voltro-cache-age-ms": String(w - S.renderedAt)
1078
1105
  },
1079
- body: x.html
1106
+ body: S.html
1080
1107
  };
1081
- if (x && Pe(x, S)) {
1082
- f.emit("cache", {
1108
+ if (S && ze(S, w)) {
1109
+ p.emit("cache", {
1083
1110
  kind: "STALE",
1084
- key: _,
1085
- ageMs: S - x.renderedAt
1111
+ key: v,
1112
+ ageMs: w - S.renderedAt
1086
1113
  });
1087
- let i = z.generation(_);
1114
+ let r = B.generation(v);
1088
1115
  return (async () => {
1089
1116
  try {
1090
- let a = await yt({
1117
+ let i = await At({
1091
1118
  provider: q,
1092
1119
  root: t,
1093
- route: p.route,
1094
- params: p.params,
1095
- pathname: r,
1120
+ route: m.route,
1121
+ params: m.params,
1122
+ pathname: a,
1096
1123
  dirs: W,
1097
- shellTemplate: Y.get(p.route.pattern) ?? w,
1124
+ shellTemplate: bt.get(m.route.pattern) ?? O,
1098
1125
  requestHeaders: n,
1099
- apiOrigin: P,
1126
+ apiOrigin: M,
1100
1127
  apiName: F,
1101
1128
  middlewares: R,
1102
1129
  onCookieWarning: L,
1103
1130
  requestUrl: e,
1104
1131
  buffered: !0
1105
1132
  });
1106
- if (a && "html" in a && a.renderMode === "isr" && a.revalidateMs !== null) {
1107
- let e = J.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
1108
- z.set(_, {
1109
- html: a.html,
1133
+ if (i && "html" in i && i.renderMode === "isr" && i.revalidateMs !== null) {
1134
+ let e = J.get(m.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
1135
+ B.set(v, {
1136
+ html: i.html,
1110
1137
  renderedAt: t,
1111
- expiresAt: t + a.revalidateMs,
1112
- servableUntil: t + a.revalidateMs + e,
1113
- revalidateMs: a.revalidateMs,
1138
+ expiresAt: t + i.revalidateMs,
1139
+ servableUntil: t + i.revalidateMs + e,
1140
+ revalidateMs: i.revalidateMs,
1114
1141
  staleWhileRevalidateMs: e
1115
- }, { ifGeneration: i }) || Z.info("SWR refresh discarded — the entry was purged while it rendered", { key: _ });
1142
+ }, { ifGeneration: r }) || X.info("SWR refresh discarded — the entry was purged while it rendered", { key: v });
1116
1143
  }
1117
1144
  } catch (e) {
1118
- Z.warn("background SWR refresh failed", { url: r }, e);
1145
+ X.warn("background SWR refresh failed", { url: a }, e);
1119
1146
  }
1120
- })(), y ? b(x.html, {
1147
+ })(), y ? b(S.html, {
1148
+ "cache-control": Xe(j, S.revalidateMs, S.staleWhileRevalidateMs),
1121
1149
  "x-voltro-cache": "STALE",
1122
- "x-voltro-cache-key": _,
1123
- "x-voltro-cache-age-ms": String(S - x.renderedAt)
1150
+ "x-voltro-cache-key": v,
1151
+ "x-voltro-cache-age-ms": String(w - S.renderedAt)
1124
1152
  }) : {
1125
1153
  status: 200,
1126
1154
  headers: {
1127
1155
  "content-type": "text/html; charset=utf-8",
1156
+ "cache-control": Xe(j, S.revalidateMs, S.staleWhileRevalidateMs),
1128
1157
  "x-voltro-rendered-by": "isr",
1129
1158
  "x-voltro-cache": "STALE",
1130
- "x-voltro-cache-key": _,
1131
- "x-voltro-cache-age-ms": String(S - x.renderedAt)
1159
+ "x-voltro-cache-key": v,
1160
+ "x-voltro-cache-age-ms": String(w - S.renderedAt)
1132
1161
  },
1133
- body: x.html
1162
+ body: S.html
1134
1163
  };
1135
1164
  }
1136
1165
  try {
1137
- let i = z.generation(_), a = await yt({
1166
+ let r = B.generation(v), i = await At({
1138
1167
  provider: q,
1139
1168
  root: t,
1140
- route: p.route,
1141
- params: p.params,
1142
- pathname: r,
1169
+ route: m.route,
1170
+ params: m.params,
1171
+ pathname: a,
1143
1172
  dirs: W,
1144
- shellTemplate: Y.get(p.route.pattern) ?? w,
1173
+ shellTemplate: bt.get(m.route.pattern) ?? O,
1145
1174
  requestHeaders: n,
1146
- apiOrigin: P,
1175
+ apiOrigin: M,
1147
1176
  apiName: F,
1148
1177
  middlewares: R,
1149
1178
  onCookieWarning: L,
1150
1179
  requestUrl: e
1151
1180
  });
1152
- if (!a) return {
1181
+ if (!i) return {
1153
1182
  status: 200,
1154
1183
  headers: {
1155
1184
  "content-type": "text/html; charset=utf-8",
1156
1185
  "x-voltro-rendered-by": "spa-fallback"
1157
1186
  },
1158
- body: w
1187
+ body: O
1159
1188
  };
1160
- let o = a.setCookies ?? [], s = a.responseHeaders ?? {}, c = (e) => ({
1189
+ let o = i.setCookies ?? [], s = i.responseHeaders ?? {}, c = (e) => ({
1161
1190
  ...s,
1162
1191
  ...e,
1163
- ...o.length === 0 ? {} : { "set-cookie": o.map(v) }
1192
+ ...o.length === 0 ? {} : { "set-cookie": o.map(f) }
1164
1193
  });
1165
- if ("stream" in a) return {
1194
+ if ("stream" in i) return {
1166
1195
  status: 200,
1167
- headers: { "x-voltro-rendered-by": a.renderMode },
1196
+ headers: { "x-voltro-rendered-by": i.renderMode },
1168
1197
  body: "",
1169
- stream: a.stream
1198
+ stream: i.stream
1170
1199
  };
1171
- if ("control" in a) return a.control === "redirect" ? {
1172
- status: a.status,
1200
+ if ("control" in i) return i.control === "redirect" ? {
1201
+ status: i.status,
1173
1202
  headers: c({
1174
- location: a.location,
1203
+ location: i.location,
1175
1204
  "x-voltro-rendered-by": "loader-redirect"
1176
1205
  }),
1177
1206
  body: ""
@@ -1183,40 +1212,40 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1183
1212
  }),
1184
1213
  body: "not found"
1185
1214
  };
1186
- if ("holes" in a) throw Error("renderPageForRequest returned a holes arm without holesOnly");
1215
+ if ("holes" in i) throw Error("renderPageForRequest returned a holes arm without holesOnly");
1187
1216
  let l = c({
1188
1217
  "content-type": "text/html; charset=utf-8",
1189
- "x-voltro-rendered-by": a.renderMode
1218
+ "x-voltro-rendered-by": i.renderMode
1190
1219
  });
1191
- if (a.renderMode === "isr" && a.revalidateMs !== null) {
1192
- let e = Date.now(), t = J.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0;
1193
- z.set(_, {
1194
- html: a.html,
1220
+ if (i.renderMode === "isr" && i.revalidateMs !== null) {
1221
+ let e = Date.now(), t = J.get(m.route.pattern)?.staleWhileRevalidateMs ?? 0;
1222
+ B.set(v, {
1223
+ html: i.html,
1195
1224
  renderedAt: e,
1196
- expiresAt: e + a.revalidateMs,
1197
- servableUntil: e + a.revalidateMs + t,
1198
- revalidateMs: a.revalidateMs,
1225
+ expiresAt: e + i.revalidateMs,
1226
+ servableUntil: e + i.revalidateMs + t,
1227
+ revalidateMs: i.revalidateMs,
1199
1228
  staleWhileRevalidateMs: t
1200
- }, { ifGeneration: i }) || Z.info("miss fill discarded — the entry was purged while it rendered", { key: _ }), l["x-voltro-cache"] = "MISS", l["x-voltro-cache-key"] = _, l["x-voltro-cache-revalidate-ms"] = String(a.revalidateMs), t > 0 && (l["x-voltro-cache-swr-ms"] = String(t)), f.emit("cache", {
1229
+ }, { ifGeneration: r }) || X.info("miss fill discarded — the entry was purged while it rendered", { key: v }), l["x-voltro-cache"] = "MISS", l["x-voltro-cache-key"] = v, l["x-voltro-cache-revalidate-ms"] = String(i.revalidateMs), t > 0 && (l["x-voltro-cache-swr-ms"] = String(t)), p.emit("cache", {
1201
1230
  kind: "MISS",
1202
- key: _,
1203
- revalidateMs: a.revalidateMs,
1231
+ key: v,
1232
+ revalidateMs: i.revalidateMs,
1204
1233
  swrMs: t
1205
1234
  });
1206
- } else a.renderMode === "isr" && (l["x-voltro-cache"] = "BYPASS", f.emit("cache", {
1235
+ } else i.renderMode === "isr" && (l["x-voltro-cache"] = "BYPASS", p.emit("cache", {
1207
1236
  kind: "BYPASS",
1208
- key: _
1237
+ key: v
1209
1238
  }));
1210
- return y && a.renderMode === "isr" ? b(a.html, {
1239
+ return y && i.renderMode === "isr" ? b(i.html, {
1211
1240
  "x-voltro-cache": l["x-voltro-cache"] ?? "MISS",
1212
- "x-voltro-cache-key": _
1241
+ "x-voltro-cache-key": v
1213
1242
  }) : {
1214
1243
  status: 200,
1215
1244
  headers: l,
1216
- body: a.html
1245
+ body: i.html
1217
1246
  };
1218
1247
  } catch (e) {
1219
- return Z.error("render error", { url: r }, e), d(e) ? {
1248
+ return X.error("render error", { url: a }, e), se(e) ? {
1220
1249
  status: 500,
1221
1250
  headers: {
1222
1251
  "content-type": "text/plain; charset=utf-8",
@@ -1236,35 +1265,35 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1236
1265
  body: "server error"
1237
1266
  };
1238
1267
  }
1239
- }, kt = !1, At = a({
1268
+ }, Ut = !1, Wt = s(r.health, () => Ut), Gt = b({
1240
1269
  apiName: F,
1241
- apiOrigin: P,
1270
+ apiOrigin: M,
1242
1271
  loadDescriptors: async () => {
1243
1272
  if (F === void 0) return;
1244
1273
  let e = (await q.getHelpers()).apiDescriptors?.[F];
1245
1274
  return e === void 0 ? void 0 : await e();
1246
1275
  },
1247
- rpcQuery: (e, t) => _e(P, e, {
1276
+ rpcQuery: (e, t) => ye(M, e, {
1248
1277
  apiName: F,
1249
1278
  headers: t
1250
1279
  }),
1251
1280
  resolveLocale: async (e, t) => {
1252
- let n = await q.getHelpers(), r = k(t, n.i18n?.locales);
1281
+ let n = await q.getHelpers(), r = v(t, n.i18n?.locales);
1253
1282
  return r === void 0 ? n.i18n?.resolve(e.cookie, e["accept-language"])?.locale ?? "en" : r;
1254
1283
  },
1255
1284
  renderErrorPage: async ({ path: e, headers: n, flash: r }) => {
1256
- let { pathname: i } = se(e), a = ht(i, G);
1285
+ let { pathname: i } = pe(e), a = Et(i, G);
1257
1286
  if (!a) return;
1258
- let o = await yt({
1287
+ let o = await At({
1259
1288
  provider: q,
1260
1289
  root: t,
1261
1290
  route: a.route,
1262
1291
  params: a.params,
1263
1292
  pathname: i,
1264
1293
  dirs: W,
1265
- shellTemplate: w,
1294
+ shellTemplate: O,
1266
1295
  requestHeaders: n,
1267
- apiOrigin: P,
1296
+ apiOrigin: M,
1268
1297
  apiName: F,
1269
1298
  middlewares: R,
1270
1299
  onCookieWarning: L,
@@ -1274,50 +1303,43 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1274
1303
  });
1275
1304
  return o !== null && "html" in o ? o.html : void 0;
1276
1305
  }
1277
- }), jt = Xe(async (e, t) => {
1278
- let n = e.url ?? "/", r = Date.now(), i = {};
1279
- for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
1280
- let a = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
1281
- if (a === "/internal/liveness") {
1282
- t.writeHead(200, {
1283
- "content-type": "text/plain",
1284
- "cache-control": "no-store"
1285
- }), t.end("ok");
1286
- return;
1287
- }
1288
- if (a === "/internal/readiness") {
1289
- let e = kt ? 200 : 503;
1290
- t.writeHead(e, {
1306
+ }), Kt = at(r), qt = lt(async (e, t) => {
1307
+ let n = e.url ?? "/", i = Date.now(), a = {};
1308
+ for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (a[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
1309
+ let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase(), l = c(Wt, o);
1310
+ if (l !== void 0) {
1311
+ let e = await ne(Wt, l);
1312
+ t.writeHead(e.status, {
1291
1313
  "content-type": "text/plain",
1292
1314
  "cache-control": "no-store"
1293
- }), t.end(kt ? "ready" : "not-ready");
1315
+ }), t.end(e.body);
1294
1316
  return;
1295
1317
  }
1296
- if (!(a.startsWith(_) && await At(e, t))) {
1297
- if (s === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
1298
- let e = Te(i.origin);
1318
+ if (!(o.startsWith(he) && await Gt(e, t))) {
1319
+ if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
1320
+ let e = De(a.origin);
1299
1321
  t.writeHead(204, e), t.end();
1300
1322
  return;
1301
1323
  }
1302
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
1324
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
1303
1325
  let r = new URL(n, "http://x").searchParams.get("target");
1304
1326
  if (!r) {
1305
1327
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1306
1328
  return;
1307
1329
  }
1308
- if (!ke(r)) {
1330
+ if (!I(r)) {
1309
1331
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1310
1332
  return;
1311
1333
  }
1312
1334
  try {
1313
- let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
1314
- a ? n.authorization = Array.isArray(a) ? a[0] : a : Oe(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
1335
+ let n = { accept: a.accept ?? "application/json" }, i = a.authorization;
1336
+ i ? n.authorization = Array.isArray(i) ? i[0] : i : Ee(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
1315
1337
  let o;
1316
1338
  if (s && s !== "GET" && s !== "HEAD") {
1317
1339
  let t = [];
1318
1340
  for await (let n of e) t.push(n);
1319
1341
  o = Buffer.concat(t);
1320
- let r = i["content-type"];
1342
+ let r = a["content-type"];
1321
1343
  r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
1322
1344
  }
1323
1345
  let c = await fetch(r, {
@@ -1335,27 +1357,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1335
1357
  }
1336
1358
  return;
1337
1359
  }
1338
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
1360
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
1339
1361
  let r = new URL(n, "http://x").searchParams.get("target");
1340
1362
  if (!r) {
1341
1363
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1342
1364
  return;
1343
1365
  }
1344
- if (!ke(r)) {
1366
+ if (!I(r)) {
1345
1367
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1346
1368
  return;
1347
1369
  }
1348
- let a = new AbortController();
1349
- e.on("close", () => a.abort()), t.on("close", () => a.abort());
1370
+ let i = new AbortController();
1371
+ e.on("close", () => i.abort()), t.on("close", () => i.abort());
1350
1372
  try {
1351
- let e = i.authorization ?? (Oe(r) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), n = await fetch(r, {
1373
+ let e = Te(a, r), n = await fetch(r, {
1352
1374
  redirect: "manual",
1353
1375
  method: "GET",
1354
1376
  headers: {
1355
1377
  accept: "text/event-stream",
1356
1378
  ...e ? { authorization: Array.isArray(e) ? e[0] : e } : {}
1357
1379
  },
1358
- signal: a.signal
1380
+ signal: i.signal
1359
1381
  });
1360
1382
  if (!n.ok || !n.body) {
1361
1383
  t.writeHead(n.status, { "content-type": "text/plain" }), t.end(`upstream ${n.status}`);
@@ -1382,16 +1404,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1382
1404
  }
1383
1405
  return;
1384
1406
  }
1385
- if (a === "/_voltro/inspect/stream") {
1386
- let n = Te(i.origin);
1387
- if (I()) {
1407
+ if (o === "/_voltro/inspect/stream") {
1408
+ let n = De(a.origin);
1409
+ if (ke()) {
1388
1410
  t.writeHead(503, {
1389
1411
  "content-type": "application/json",
1390
1412
  ...n
1391
1413
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
1392
1414
  return;
1393
1415
  }
1394
- let r = Ee(i, "GET");
1416
+ let r = Ae(a, "GET");
1395
1417
  if (!r.ok) {
1396
1418
  t.writeHead(401, {
1397
1419
  "content-type": "application/json",
@@ -1409,37 +1431,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1409
1431
  "x-accel-buffering": "no",
1410
1432
  ...n
1411
1433
  }), t.flushHeaders(), t.write("retry: 5000\n\n");
1412
- for (let e of f.buffered()) t.write(ye(e));
1413
- let a = f.subscribe((e) => {
1414
- t.write(ye(e));
1434
+ for (let e of p.buffered()) t.write(oe(e));
1435
+ let i = p.subscribe((e) => {
1436
+ t.write(oe(e));
1415
1437
  }), o = setInterval(() => {
1416
- t.write(he());
1438
+ t.write(te());
1417
1439
  }, 15e3), s = () => {
1418
- clearInterval(o), a();
1440
+ clearInterval(o), i();
1419
1441
  };
1420
1442
  e.on("close", s), t.on("close", s);
1421
1443
  return;
1422
1444
  }
1423
1445
  try {
1424
- let e = await Ot(n, i);
1425
- if (e.stream ? e.stream(t) : Qe({
1446
+ let e = await Ht(n, a);
1447
+ if (e.stream ? e.stream(t) : dt({
1426
1448
  response: t,
1427
1449
  status: e.status,
1428
1450
  headers: e.headers,
1429
1451
  body: e.body,
1430
- requestHeaders: i,
1431
- compression: pe.compression
1432
- }) || (t.writeHead(e.status, e.headers), t.end(e.body)), !a.startsWith("/_voltro/inspect")) {
1433
- let t = Date.now() - r;
1434
- f.emit("request", {
1435
- url: a,
1452
+ requestHeaders: a,
1453
+ compression: de.compression
1454
+ }) || (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
1455
+ let t = Date.now() - i;
1456
+ p.emit("request", {
1457
+ url: o,
1436
1458
  status: e.status,
1437
1459
  durationMs: t,
1438
1460
  renderedBy: e.headers["x-voltro-rendered-by"],
1439
1461
  cache: e.headers["x-voltro-cache"]
1440
1462
  });
1441
- let n = ht(a, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1442
- Ct.record({
1463
+ let n = Et(o, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1464
+ Lt.record({
1443
1465
  kind: "request",
1444
1466
  tag: n,
1445
1467
  durationMs: t,
@@ -1451,77 +1473,77 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1451
1473
  }
1452
1474
  }
1453
1475
  });
1454
- await new Promise((e) => jt.listen(p, "::", e)), kt = !0, i.mark("ready"), Z.info(`listening on http://localhost:${p}`, {
1455
- port: p,
1456
- distDir: h
1457
- }), Z.debug("dynamic + ssr/isr routes resolve via SSR loader");
1476
+ await new Promise((e) => qt.listen(h, "::", e)), Ut = !0, n.mark("ready"), rt(qt, Kt), X.info(`listening on http://localhost:${h}`, {
1477
+ port: h,
1478
+ distDir: C
1479
+ }), X.debug("dynamic + ssr/isr routes resolve via SSR loader");
1458
1480
  try {
1459
- await Re({
1460
- id: S,
1461
- name: b,
1481
+ await Ue({
1482
+ id: re,
1483
+ name: T,
1462
1484
  kind: "web",
1463
- url: `http://localhost:${p}`,
1485
+ url: `http://localhost:${h}`,
1464
1486
  pid: process.pid,
1465
1487
  status: "live",
1466
- logFile: C.path
1488
+ logFile: D.path
1467
1489
  });
1468
- let e = le(t);
1490
+ let e = A(t);
1469
1491
  if (e) {
1470
- let t = await r({ dashboardAppPath: e });
1471
- t.status === "launched" ? Z.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && Z.debug(`dashboard already running on :${t.port}`, { port: t.port });
1492
+ let t = await ve({ dashboardAppPath: e });
1493
+ t.status === "launched" ? X.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && X.debug(`dashboard already running on :${t.port}`, { port: t.port });
1472
1494
  }
1473
1495
  setInterval(() => {
1474
- Re({
1475
- id: S,
1476
- name: b,
1496
+ Ue({
1497
+ id: re,
1498
+ name: T,
1477
1499
  kind: "web",
1478
- url: `http://localhost:${p}`,
1500
+ url: `http://localhost:${h}`,
1479
1501
  pid: process.pid,
1480
1502
  status: "live",
1481
- logFile: C.path
1503
+ logFile: D.path
1482
1504
  }).catch(() => {});
1483
1505
  }, 1e4).unref();
1484
1506
  } catch (e) {
1485
- Z.warn("runtime-registry write failed", {}, e);
1507
+ X.warn("runtime-registry write failed", {}, e);
1486
1508
  }
1487
- Ke({
1488
- app: o.name ?? "unnamed",
1509
+ $e({
1510
+ app: r.name ?? "unnamed",
1489
1511
  kind: "web",
1490
- url: `http://localhost:${p}`,
1491
- bootMs: i.total()
1512
+ url: `http://localhost:${h}`,
1513
+ bootMs: n.total()
1492
1514
  });
1493
- let Mt = i.phaseBreakdown();
1494
- Z.info(`start: ready in ${i.total()}ms`, {
1495
- bootMs: i.total(),
1496
- ...Mt ? { phases: Mt } : {}
1515
+ let Jt = n.phaseBreakdown();
1516
+ X.info(`start: ready in ${n.total()}ms`, {
1517
+ bootMs: n.total(),
1518
+ ...Jt ? { phases: Jt } : {}
1497
1519
  });
1498
- let Nt = !1, Pt = (e) => async () => {
1499
- if (!Nt) {
1500
- if (Nt = !0, Z.info(`received ${e}, shutting down`, { signal: e }), jt.close(), await vt.stop(), $) try {
1501
- $();
1520
+ let Yt = !1, Xt = (e) => async () => {
1521
+ if (!Yt) {
1522
+ if (Yt = !0, X.info(`received ${e}, shutting down`, { signal: e }), qt.close(), await Nt.stop(), Ft) try {
1523
+ Ft();
1502
1524
  } catch {}
1503
- if (St) try {
1504
- await qe.runPromise(St.close());
1525
+ if (It) try {
1526
+ await st.runPromise(It.close());
1505
1527
  } catch {}
1506
- if (B) try {
1507
- await B.end();
1528
+ if (H) try {
1529
+ await H.end();
1508
1530
  } catch {}
1509
- await q.close(), await Be(S), await C.dispose(), process.exit(0);
1531
+ await q.close(), await Ge(re), await D.dispose(), process.exit(0);
1510
1532
  }
1511
1533
  };
1512
- process.on("SIGINT", Pt("SIGINT")), process.on("SIGTERM", Pt("SIGTERM"));
1513
- let Ft = process.ppid;
1514
- if (Ft > 1) {
1534
+ process.on("SIGINT", Xt("SIGINT")), process.on("SIGTERM", Xt("SIGTERM"));
1535
+ let Zt = process.ppid;
1536
+ if (Zt > 1) {
1515
1537
  let e = setInterval(() => {
1516
- (process.ppid !== Ft || process.ppid === 1) && (clearInterval(e), Pt("SIGTERM")());
1538
+ (process.ppid !== Zt || process.ppid === 1) && (clearInterval(e), Xt("SIGTERM")());
1517
1539
  }, 2e3);
1518
1540
  e.unref();
1519
1541
  }
1520
1542
  return new Promise(() => {});
1521
- }, St = async (e) => {
1522
- t("start");
1523
- let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await $(We(n));
1524
- return r.ran ? r.exitCode : (Z.error("no web app found at this path"), 1);
1543
+ }, Pt = async (e) => {
1544
+ nt("start"), t("start");
1545
+ let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await Nt(B(n));
1546
+ return r.ran ? r.exitCode : (X.error("no web app found at this path"), 1);
1525
1547
  };
1526
1548
  //#endregion
1527
- export { $ as n, St as t };
1549
+ export { Nt as n, Pt as t };