@voltro/cli 0.55.0 → 0.56.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 (165) hide show
  1. package/CHANGELOG.md +497 -0
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/{apiBuild-CMvLJM_K.js → apiBuild-Bdaetr37.js} +119 -88
  4. package/dist/apiBuild-Vw1figjO.js +2 -0
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-S0QOzqPT.js → build-CI36wL4R.js} +337 -312
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-fbj9GDjN.js → checkCommand-CAwFXrxA.js} +6 -6
  9. package/dist/{checkCommand-DNkY5kwF.js → checkCommand-D0QV_zM_.js} +1 -1
  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-CidbQzbv.js} +10 -10
  14. package/dist/{codemodRunner-C2zxZUIw.js → codemodRunner-BlQPfjzA.js} +222 -0
  15. package/dist/{commands-BBYJ7Q3B.js → commands-CWjfThXv.js} +35 -35
  16. package/dist/{dashboardCommand-D2kmyCLL.js → dashboardCommand-BekcY5Ls.js} +3 -3
  17. package/dist/{dataCommand-BEPPQiTl.js → dataCommand-2pccgbIy.js} +3 -3
  18. package/dist/{dbCommand-DZTmOFT4.js → dbCommand-DpK_vQET.js} +457 -441
  19. package/dist/dbCommand-DrycGWWt.js +2 -0
  20. package/dist/{dev-DfVZaoys.js → dev-B9Gz0k85.js} +1 -1
  21. package/dist/{dev-Ca_A_S9v.js → dev-Dw263KPu.js} +2603 -2482
  22. package/dist/doctorCommand-BMWs6aVm.js +2 -0
  23. package/dist/{doctorCommand-CGZJK_4o.js → doctorCommand-aR_bFmIi.js} +353 -251
  24. package/dist/{dormancyCommand-DY2rYpTa.js → dormancyCommand-eXTQMbHU.js} +1 -1
  25. package/dist/{embeddingsCommand-BoCqZsgp.js → embeddingsCommand-CTmiQvwa.js} +1 -1
  26. package/dist/{envCommand-Bxy2fOjc.js → envCommand-BDUgV7EM.js} +12 -12
  27. package/dist/{evolveCommand-BsbZ-XDg.js → evolveCommand-YV8qW1LU.js} +2 -2
  28. package/dist/frameworkTableAssembly-CGNC0qr7.js +2 -0
  29. package/dist/{frameworkTableAssembly-Do-cf6RJ.js → frameworkTableAssembly-DNOFXfEQ.js} +92 -84
  30. package/dist/index.js +1 -1
  31. package/dist/{infoCommand-EmM3jPKD.js → infoCommand-BjVXpMlP.js} +1 -1
  32. package/dist/inspect-CNYvNXPU.js +1484 -0
  33. package/dist/inspect-S2rWy1Ys.js +2 -0
  34. package/dist/{inspectCmd-niF97fAq.js → inspectCmd-CP-G0sVK.js} +1 -1
  35. package/dist/{inspectFetch-EMuhTG_9.js → inspectFetch-BU1NyzxV.js} +36 -24
  36. package/dist/{inspectMetrics-CGF94puw.js → inspectMetrics-BY0Sjb2F.js} +19 -19
  37. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-BU8uCdys.js} +1 -1
  38. package/dist/{manifestBuild-DjX5MoXy.js → manifestBuild-CEkjfpwc.js} +1 -1
  39. package/dist/manifestBuild-DIa_s6u0.js +2 -0
  40. package/dist/{migrate-CGFZS-1a.js → migrate-SICulyz1.js} +2 -2
  41. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  42. package/dist/{probeCommand-Bs3iVBSL.js → probeCommand-6HxEkNDG.js} +2 -2
  43. package/dist/{runtimeTrace-C1BTpHGQ.js → runtimeTrace-DgYMc09E.js} +1 -1
  44. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  45. package/dist/{sdkgen-CXMwLg9n.js → sdkgen-PY-umd6O.js} +1 -1
  46. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  47. package/dist/serveCommand-BITS8Hpj.js +2 -0
  48. package/dist/{serveCommand-C7IrCD58.js → serveCommand-DIJ3ma76.js} +910 -870
  49. package/dist/serveEntry.js +1 -1
  50. package/dist/{start-EOV7s1NZ.js → start-B9NGB8gn.js} +575 -546
  51. package/dist/{start-DH7cat4-.js → start-BFQQkL1i.js} +1 -1
  52. package/dist/startEntry.js +1 -1
  53. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  54. package/dist/{test-DO27-x2P.js → test-jipIQ5Mx.js} +1 -1
  55. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-BWYDqMy6.js} +1 -1
  56. package/dist/{updateCommand-C_jN1w18.js → updateCommand-C9n_Z_oG.js} +8 -2
  57. package/dist/updateCommand-DsXEAHbd.js +2 -0
  58. package/dist/webDev-C2dRz9s5.js +2 -0
  59. package/dist/{webDev-B7vNj4Bq.js → webDev-C53hJdcL.js} +1240 -1271
  60. package/dist/{webhooksCommand-B1LVcyO3.js → webhooksCommand-uuPu8qQX.js} +1 -1
  61. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  62. package/package.json +55 -19
  63. package/templates/AGENTS.core.md +20 -1
  64. package/templates/AGENTS.md +21 -2
  65. package/templates/agent-docs/_index.md +1 -1
  66. package/templates/agent-docs/_manifest.json +1 -1
  67. package/templates/agent-docs/cli.md +122 -0
  68. package/templates/agent-docs/data.md +145 -5
  69. package/templates/agent-docs/database/scaling.md +40 -1
  70. package/templates/agent-docs/deployment.md +53 -1
  71. package/templates/agent-docs/internationalization.md +32 -0
  72. package/templates/agent-docs/local-first-mobile.md +9 -2
  73. package/templates/agent-docs/observability.md +227 -0
  74. package/templates/agent-docs/plugins/billing.md +15 -0
  75. package/templates/agent-docs/plugins/broadcast.md +2 -1
  76. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  77. package/templates/agent-docs/plugins/row-history.md +11 -0
  78. package/templates/agent-docs/plugins.md +19 -0
  79. package/templates/agent-docs/templates/appshells.md +3 -3
  80. package/templates/agent-docs/whats-new.md +432 -73
  81. package/templates/apps/api-ai/package.json +6 -6
  82. package/templates/apps/api-auth/package.json +8 -8
  83. package/templates/apps/api-backend/package.json +7 -7
  84. package/templates/apps/api-backend-deactivation/package.json +7 -7
  85. package/templates/apps/api-backend-mail/package.json +8 -8
  86. package/templates/apps/api-backend-mariadb/package.json +9 -9
  87. package/templates/apps/api-backend-sqlite/package.json +8 -8
  88. package/templates/apps/api-backend-storage/package.json +8 -8
  89. package/templates/apps/api-cms/package.json +9 -9
  90. package/templates/apps/api-collab/package.json +8 -8
  91. package/templates/apps/api-data-advanced/package.json +8 -8
  92. package/templates/apps/api-durable/package.json +8 -8
  93. package/templates/apps/api-feature-flags/package.json +9 -9
  94. package/templates/apps/api-governance/package.json +8 -8
  95. package/templates/apps/api-kv/package.json +8 -8
  96. package/templates/apps/api-moderation/package.json +8 -8
  97. package/templates/apps/api-observability/package.json +8 -8
  98. package/templates/apps/api-ratelimit/package.json +8 -8
  99. package/templates/apps/api-rbac/package.json +8 -8
  100. package/templates/apps/api-rest/package.json +7 -7
  101. package/templates/apps/api-row-history/package.json +8 -8
  102. package/templates/apps/api-saas/package.json +11 -11
  103. package/templates/apps/api-saas-starter/package.json +10 -10
  104. package/templates/apps/api-search/package.json +8 -8
  105. package/templates/apps/api-status/package.json +8 -8
  106. package/templates/apps/api-webhooks/package.json +9 -9
  107. package/templates/apps/changelog/package.json +7 -7
  108. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  109. package/templates/apps/edge-functions/package.json +2 -2
  110. package/templates/apps/frontend-admin/package.json +7 -8
  111. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  112. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  113. package/templates/apps/frontend-app/package.json +8 -9
  114. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  115. package/templates/apps/frontend-auth/package.json +7 -8
  116. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  117. package/templates/apps/frontend-blank/package.json +6 -7
  118. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  119. package/templates/apps/frontend-cms/package.json +8 -9
  120. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  121. package/templates/apps/frontend-collab/README.md +7 -2
  122. package/templates/apps/frontend-collab/package.json +9 -10
  123. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  124. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  125. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  126. package/templates/apps/frontend-contact/package.json +7 -7
  127. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  128. package/templates/apps/frontend-dashboard/package.json +6 -7
  129. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  130. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  131. package/templates/apps/frontend-docs/package.json +8 -8
  132. package/templates/apps/frontend-i18n/package.json +6 -6
  133. package/templates/apps/frontend-landing/package.json +7 -7
  134. package/templates/apps/frontend-portal/package.json +7 -8
  135. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  136. package/templates/apps/frontend-saas/package.json +7 -8
  137. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  138. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  139. package/templates/apps/frontend-spa/package.json +6 -7
  140. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  141. package/templates/apps/frontend-ssr/package.json +6 -7
  142. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  143. package/templates/apps/frontend-ssr-api/package.json +7 -8
  144. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  145. package/templates/apps/frontend-static-blog/package.json +8 -8
  146. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  147. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  148. package/templates/apps/frontend-status/package.json +7 -8
  149. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  150. package/templates/apps/mobile-app/package.json +4 -4
  151. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  152. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  153. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  154. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  155. package/dist/apiBuild-Cl0IDx8c.js +0 -2
  156. package/dist/codegen-CN6vMM4J.js +0 -2
  157. package/dist/dbCommand-BTyBGhIA.js +0 -2
  158. package/dist/doctorCommand-djmqEcDC.js +0 -2
  159. package/dist/frameworkTableAssembly-Df2Ymp2f.js +0 -2
  160. package/dist/inspect-DCqILJ1G.js +0 -1197
  161. package/dist/inspect-DGJwpOAb.js +0 -2
  162. package/dist/manifestBuild-CJ2zvPvT.js +0 -2
  163. package/dist/serveCommand-Cjt5S9hD.js +0 -2
  164. package/dist/updateCommand-nnFjDbl4.js +0 -2
  165. 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 { A as n, At as r, B as i, C as a, Ct as o, D as s, Dt as c, E as l, Et as u, G as d, Gt as f, H as p, I as ee, J as te, K as ne, Kt as re, L as ie, M as m, N as h, O as g, Ot as _, P as v, Q as y, R as ae, S as b, T as x, U as S, V as C, Vt as w, W as T, Wt as E, X as D, Y as oe, Z as se, a as ce, c as le, et as ue, ft as de, h as fe, j as O, k as pe, kt as k, m as me, n as A, ot as he, pt as ge, q as j, qt as M, rt as _e, s as ve, st as N, tt as P, u as ye, vt as be, w as xe, z as Se } from "./webDev-C53hJdcL.js";
3
+ import { A as Ce, I as we, M as Te, O as F, g as Ee, j as De, o as Oe } from "./inspect-CNYvNXPU.js";
4
+ import { r as ke } from "./appPort-B_HpJ_ck.js";
5
+ import { o as Ae, t as je } from "./connectionConfig-Bk9IC7D0.js";
6
+ import { n as Me, r as Ne, t as Pe } from "./inspectMetrics-BY0Sjb2F.js";
7
+ import { a as Fe, c as Ie, d as Le, f as Re, l as ze, p as I, u as Be } from "./renderModeScan-43yQ2opo.js";
8
+ import { i as Ve, n as He, r as Ue, t as We } from "./runtimeRegistry-DMeKfTHP.js";
9
+ import { n as Ge } from "./logFileSink-B4uP8pvf.js";
10
+ import { t as Ke } from "./bootTiming-BdyP9nYw.js";
11
+ import { a as qe, n as Je, r as Ye, t as Xe } from "./staticCachePolicy-CIyj6DbS.js";
12
+ import { extname as L, join as R, resolve as z } from "node:path";
13
+ import { promises as B } from "node:fs";
14
+ import { pathToFileURL as V } from "node:url";
15
+ import { createLogger as H, printReadyBlock as Ze } from "@voltro/logger";
16
+ import { appMode as Qe, frameworkVersion as $e, setProcessBootPath as et } from "@voltro/protocol/identity";
17
+ import { applyKeepAlive as tt, maybeCompress as U, negotiateEncoding as nt, resolveKeepAlive as rt, snapshotMetricsSync as it } from "@voltro/runtime";
18
+ import { Effect as at } from "effect";
19
+ import { createHash as W } from "node:crypto";
20
+ import { resolveBroadcastProvider as ot } from "@voltro/plugin-broadcast";
21
+ import { createServer as st } from "node:http";
20
22
  //#region src/httpResponseWrite.ts
21
- var Ze = (e) => `W/"${K("md5").update(e).digest("hex")}"`, Qe = (e) => {
23
+ var ct = (e) => `W/"${W("md5").update(e).digest("hex")}"`, lt = (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 : ct(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 = U({
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
40
  }), ee = {
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 ee["content-length"], t.writeHead(n, ee), t.end(Buffer.from(p.bytes)), !0;
46
+ }, G = H({ scope: "voltro:start:cdc" }), ut = (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
+ }, dt = () => je() ? Ae() : null, ft = (e) => {
58
+ let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = ut(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 G.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
63
+ let c = dt();
64
+ if (!c && !o) return G.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
65
+ if (!c) return G.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
+ G.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 && G.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 G.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
+ }, K = H({ scope: "voltro:start:isr-cache" }), pt = "voltro_isr_cache", q = (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
+ `, mt = (e) => {
117
+ let t = e.tableName ?? pt, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
118
+ i || (i = !0, await n.query(q(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
+ K.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
+ K.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
+ }, J = H({ scope: "voltro:start:revalidate" }), ht = (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
+ } : (J.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 J.warn("bad revalidation payload (not JSON)", { payload: e }), null;
188
194
  }
189
- }, at = (e, t) => {
195
+ }, gt = (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 J.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 J.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 J.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 J.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 J.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 J.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
+ }, Y = H({ scope: "voltro:start" }), _t = $e() ?? "unknown", vt = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", X = (e) => e instanceof Error && e._voltroControl === "not-found", yt = {
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
+ }, bt = (e) => yt[L(e).toLowerCase()] ?? "application/octet-stream", xt = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), Z = async (e) => {
255
254
  try {
256
- return await H.stat(e), !0;
255
+ return await B.stat(e), !0;
257
256
  } catch {
258
257
  return !1;
259
258
  }
260
- }, pt = (e) => {
259
+ }, St = (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
+ }, Ct = (e) => e.map((e) => {
269
+ let { regex: t, paramNames: n, priority: r } = St(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), wt = (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
+ }, Tt = null, Et, Dt = (e, t) => t === void 0 ? Promise.resolve() : (Et ??= (async () => {
292
291
  try {
293
292
  let n = await e.getHelpers(), r = n.apiDescriptors?.[t];
294
293
  if (r === void 0) return;
@@ -296,21 +295,21 @@ 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
+ })(), Et), Ot = async (e) => {
299
+ let { provider: t, route: r, params: a, pathname: o, dirs: c, shellTemplate: u, requestHeaders: f, requestUrl: ne = "", apiOrigin: re, apiName: m } = e;
300
+ await Dt(t, m);
301
+ let { search: _ } = se(ne), v = await ie(ae(e.middlewares ?? [], {
302
+ route: r.pattern,
303
+ pathname: o
305
304
  }), {
306
- pathname: a,
305
+ pathname: o,
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: f,
308
+ cookies: ee(f.cookie),
309
+ route: r.pattern
310
+ }, e.onCookieWarning), y = await t.getPage(r.pattern, r.file), b = e.forceSsrRender === !0 ? "ssr" : Ie(y, r.file), x = b === "isr" && y.ppr === !0, w = b === "isr" && e.holesOnly !== !0 ? O(v.headers) : v.headers, E = ve(re, w.cookie, {
311
+ apiName: m,
312
+ headers: w
314
313
  });
315
314
  if (e.holesOnly === !0) {
316
315
  if (typeof y.loader != "function") return null;
@@ -319,131 +318,131 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
319
318
  holes: {
320
319
  loader: y.loader,
321
320
  ctx: {
322
- params: r,
323
- pathname: a,
321
+ params: a,
322
+ pathname: o,
324
323
  search: _,
325
324
  signal: e.signal,
326
- headers: T,
325
+ headers: w,
327
326
  query: E,
328
327
  isServer: !0
329
328
  },
330
329
  helpers: await t.getHelpers(),
331
- page: n.pattern
330
+ page: r.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 ce = b === "spa" && ye(c, r.dirChain).some((e) => e.hasLayout);
336
+ if (b !== "ssr" && b !== "isr" && !ce) return null;
337
+ let ue = ye(c, r.dirChain), de = {}, fe = null, pe, k = new AbortController(), me = x ? g(w, r.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: pe, segmentLoaderData: de} = await le({
340
+ entries: ue,
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: a,
346
+ pathname: o,
348
347
  search: _,
349
- signal: fe.signal,
350
- headers: O,
348
+ signal: k.signal,
349
+ headers: me,
351
350
  query: E,
352
351
  isServer: !0
353
352
  }
354
- }), typeof y.loader == "function" && !D && (ue = await y.loader({
355
- params: r,
356
- pathname: a,
353
+ }), typeof y.loader == "function" && !ce && (fe = await y.loader({
354
+ params: a,
355
+ pathname: o,
357
356
  search: _,
358
- signal: fe.signal,
359
- headers: O,
357
+ signal: k.signal,
358
+ headers: me,
360
359
  query: E,
361
360
  isServer: !0
362
361
  }));
363
362
  } catch (e) {
364
- if (st(e)) return {
363
+ if (vt(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 (X(e)) return {
372
371
  control: "not-found",
373
372
  setCookies: v.setCookies,
374
373
  responseHeaders: v.responseHeaders
375
374
  };
376
375
  throw e;
377
376
  }
378
- let k = await t.getHelpers();
379
- D || await Se({
377
+ let A = await t.getHelpers();
378
+ ce || await i({
380
379
  pageMod: y,
381
- params: r,
380
+ params: a,
382
381
  query: E,
383
- apiName: ie,
384
- seed: k.seedPreloadedSubscription,
385
- seedFailure: k.seedPreloadedSubscriptionFailure,
386
- onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
382
+ apiName: m,
383
+ seed: A.seedPreloadedSubscription,
384
+ seedFailure: A.seedPreloadedSubscriptionFailure,
385
+ onError: ({ tag: e, apiName: t }, n) => Y.warn("preload seed failed", {
387
386
  tag: e,
388
387
  apiName: t,
389
- pathname: a
388
+ pathname: o
390
389
  }, n)
391
390
  });
392
391
  let he = {
393
- pattern: n.pattern,
392
+ pattern: r.pattern,
394
393
  Component: y.default,
395
394
  meta: y.meta,
396
395
  loader: y.loader,
397
396
  ErrorBoundary: y.ErrorBoundary,
398
397
  Pending: y.Pending,
399
- renderMode: x,
400
- chain: de
398
+ renderMode: b,
399
+ chain: pe
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.`);
401
+ if (b === "isr" && v.cspNonce !== void 0) throw Error(`page '${r.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
402
  let ge = {
404
- cookies: ae ? l(pe(v.cookies), n.pattern) : x === "isr" ? pe(v.cookies) : v.cookies,
405
- headers: O,
406
- url: g,
403
+ cookies: x ? s(n(v.cookies), r.pattern) : b === "isr" ? n(v.cookies) : v.cookies,
404
+ headers: me,
405
+ url: ne,
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",
410
- ...A?.timeZone === void 0 ? {} : { timeZone: A.timeZone },
407
+ }, M = A.i18n?.resolve(w.cookie, w["accept-language"]), _e = {
408
+ lang: M?.locale ?? ge.cookies["voltro:locale"] ?? "en",
409
+ ...M?.timeZone === void 0 ? {} : { timeZone: M.timeZone },
411
410
  renderedAt: Date.now()
412
- }, M = y.interactive ?? "full";
413
- if (D) {
414
- let e = P({
415
- helpers: k,
416
- page: n.pattern,
417
- interactive: M,
411
+ }, N = y.interactive ?? "full";
412
+ if (ce) {
413
+ let e = te({
414
+ helpers: A,
415
+ page: r.pattern,
416
+ interactive: N,
418
417
  delivery: "stream",
419
418
  renderInput: {
420
419
  descriptor: he,
421
- params: r,
422
- pathname: a,
420
+ params: a,
421
+ pathname: o,
423
422
  search: _,
424
- segmentLoaderData: le,
423
+ segmentLoaderData: de,
425
424
  requestContext: ge,
426
- ...A ? {
427
- outerWrap: A.outerWrap,
428
- locale: A.locale
425
+ ...M ? {
426
+ outerWrap: M.outerWrap,
427
+ locale: M.locale
429
428
  } : {}
430
429
  }
431
- }), t = (t) => w({
432
- helpers: k,
430
+ }), t = (t) => D({
431
+ helpers: A,
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 = S({ shell: u });
439
438
  return {
440
439
  renderMode: "spa",
441
440
  setCookies: v.setCookies,
442
441
  responseHeaders: v.responseHeaders,
443
- stream: (r) => oe({
442
+ stream: (r) => d({
444
443
  res: r,
445
444
  shell: n,
446
- documentAttrs: j,
445
+ documentAttrs: _e,
447
446
  headers: {
448
447
  ...v.responseHeaders,
449
448
  "content-type": "text/html; charset=utf-8",
@@ -452,107 +451,107 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
452
451
  },
453
452
  headInjection: t,
454
453
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
455
- render: (t) => k.renderPageToStream({
454
+ render: (t) => A.renderPageToStream({
456
455
  ...e.renderInput,
457
456
  ...t,
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
+ Y.error("spa layout shell render failed", { pathname: o }, 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({
467
- helpers: k,
465
+ let n = oe({
466
+ helpers: A,
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 = C(p(u.replace("<div id=\"root\"></div>", `<div id="root">${n.body}</div>`), t(n.meta)), _e);
470
469
  return {
471
- html: v.cspNonce === void 0 ? s : S(s, v.cspNonce),
470
+ html: v.cspNonce === void 0 ? i : T(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({
479
- helpers: k,
480
- page: n.pattern,
481
- pathname: a,
482
- renderMode: x,
483
- interactive: M,
484
- loaderData: ue,
485
- segmentLoaderData: le,
477
+ let P = j({
478
+ helpers: A,
479
+ page: r.pattern,
480
+ pathname: o,
481
+ renderMode: b,
482
+ interactive: N,
483
+ loaderData: fe,
484
+ segmentLoaderData: de,
486
485
  pageLoaderRan: typeof y.loader == "function",
487
- ...ae ? { ppr: !0 } : {}
486
+ ...x ? { ppr: !0 } : {}
488
487
  });
489
- ae && b(N.stateInput, n.pattern);
490
- let ve = {
488
+ x && l(P.stateInput, r.pattern);
489
+ let be = {
491
490
  descriptor: he,
492
- params: r,
493
- pathname: a,
491
+ params: a,
492
+ pathname: o,
494
493
  search: _,
495
- loaderData: N.loaderData,
496
- segmentLoaderData: N.segmentLoaderData,
494
+ loaderData: P.loaderData,
495
+ segmentLoaderData: P.segmentLoaderData,
497
496
  requestContext: ge,
498
- ...A ? {
499
- outerWrap: A.outerWrap,
500
- locale: A.locale
497
+ ...M ? {
498
+ outerWrap: M.outerWrap,
499
+ locale: M.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
+ }, xe = (t) => {
502
+ if (Tt === null || b !== "ssr" && b !== "isr" || typeof y.ogImage != "function" || t.includes("og:image")) return "";
503
+ let n = w["x-tenant"], i = Tt.signOgUrl({
504
+ pattern: r.pattern,
506
505
  params: e.params,
507
- ...r === void 0 ? {} : { tenant: r }
506
+ ...n === void 0 ? {} : { tenant: n }
508
507
  });
509
508
  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)
509
+ }, Se = (e) => [
510
+ A.renderMetaToHtml(e) + xe(A.renderMetaToHtml(e)),
511
+ `<meta name="voltro-interactive" content="${N}" />`,
512
+ ...P.hasDeferred ? [A.renderDeferredRegistryScript()] : [],
513
+ A.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 (b === "ssr" && N === "full" && e.buffered !== !0) {
516
+ let e = S({ shell: u });
518
517
  return {
519
518
  renderMode: "ssr",
520
519
  setCookies: v.setCookies,
521
- stream: (t) => oe({
520
+ stream: (t) => d({
522
521
  res: t,
523
522
  shell: e,
524
- documentAttrs: j,
523
+ documentAttrs: _e,
525
524
  headers: {
526
525
  ...v.responseHeaders,
527
526
  "content-type": "text/html; charset=utf-8",
528
527
  "x-voltro-rendered-by": "ssr",
529
528
  ...h(v.setCookies)
530
529
  },
531
- headInjection: be,
530
+ headInjection: Se,
532
531
  ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
533
- render: (e) => k.renderPageToStream({
534
- ...ve,
532
+ render: (e) => A.renderPageToStream({
533
+ ...be,
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
+ Y.error("ssr shell render failed", { pathname: o }, 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: Ce, meta: we } = A.renderPageToHtml(be), Te = Se(we), F = C(p(u.replace("<div id=\"root\"></div>", `<div id="root">${Ce}</div>`), Te), _e);
544
+ N === "none" && (F = xt(F));
545
+ let Ee = b === "isr" ? I(y.revalidate) : null;
547
546
  return {
548
- html: v.cspNonce === void 0 ? I : S(I, v.cspNonce),
549
- renderMode: x,
550
- revalidateMs: Te,
547
+ html: v.cspNonce === void 0 ? F : T(F, v.cspNonce),
548
+ renderMode: b,
549
+ revalidateMs: Ee,
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
+ }, Q = (e) => e === "" ? "/" : e, kt = async (e) => {
554
+ let t = await import(V(e).href);
556
555
  return {
557
556
  kind: "bundle",
558
557
  getPageMeta: () => t.pageMeta,
@@ -581,11 +580,11 @@ 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
+ }, At = async (e, t) => {
584
+ let n = await E("vite", () => import("vite")), i = (await import("@vitejs/plugin-react")).default, a = (await import("@tailwindcss/vite")).default, o = await n.createServer({
586
585
  root: t,
587
586
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
588
- plugins: [r(), i()],
587
+ plugins: [i(), a()],
589
588
  resolve: { dedupe: [
590
589
  "react",
591
590
  "react-dom",
@@ -599,203 +598,203 @@ 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
+ }), s = R(e, "src", "pages"), c = (e) => e === "" ? s : R(s, e), l = k({
602
+ limit: r(),
603
+ onColdStart: (e) => Y.debug("ssr cold-compile start", { id: e }),
604
+ onColdEnd: (e, { durationMs: t, failed: n }) => Y.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
606
605
  id: e,
607
606
  ms: t,
608
607
  ...n ? { failed: !0 } : {}
609
608
  })
610
- }), l = (e) => c.load(e, async () => await a.ssrLoadModule(e));
609
+ }), u = (e) => l.load(e, async () => await o.ssrLoadModule(e));
611
610
  return {
612
611
  kind: "middleware",
613
612
  async getPage(e, t) {
614
- return l(V(o, t));
613
+ return u(R(s, t));
615
614
  },
616
615
  async getLayout(e) {
617
- return l(V(s(e), "layout.tsx"));
616
+ return u(R(c(e), "layout.tsx"));
618
617
  },
619
618
  async getError(e) {
620
- return l(V(s(e), "error.tsx"));
619
+ return u(R(c(e), "error.tsx"));
621
620
  },
622
621
  async getPending(e) {
623
- return l(V(s(e), "loading.tsx"));
622
+ return u(R(c(e), "loading.tsx"));
624
623
  },
625
624
  async getHelpers() {
626
- return await l("@voltro/web/ssr");
625
+ return await u("@voltro/web/ssr");
627
626
  },
628
627
  async close() {
629
- await a.close();
628
+ await o.close();
630
629
  }
631
630
  };
632
- }, $ = async (t) => {
633
- let i = Ue(), o = await ve(t);
634
- if (!o) return {
631
+ }, jt = async (t) => {
632
+ let n = Ke(), r = await me(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 Y.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 Y.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: i } = await w({
649
+ rawEnv: r.env,
651
650
  appType: "web",
652
651
  root: t,
653
- log: Z,
652
+ log: Y,
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
+ }), s = i.publicValues;
655
+ n.mark("config");
656
+ let l = re();
657
+ he(l), Y.info("booting voltro start", { app: r.name ?? "(unnamed)" });
658
+ let d = ke({
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[y] === "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 d.warnings) Y.warn(e);
665
+ let p = d.port, te = R(t, ".framework"), h = R(te, "dist"), g = R(h, "index.html");
666
+ if (!await Z(g)) return Y.error("no built dist found — run `voltro build` first", { distDir: h }), {
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 S = r.name ?? "unnamed", C = We("web", S, p), T = Ge(S);
671
+ await Ve({
672
+ id: C,
673
+ name: S,
675
674
  kind: "web",
676
675
  url: `http://localhost:${p}`,
677
676
  pid: process.pid,
678
677
  status: "booting",
679
- logFile: C.path
678
+ logFile: T.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 E = R(h, "_voltro", "shell.html"), D = await Z(E) ? await B.readFile(E, "utf8") : await B.readFile(g, "utf8"), oe = await fe(t, r), le = Me(r), O = qe(r), k = A(oe[0]), j = oe[0]?.name, Ie = /* @__PURE__ */ new Set(), I = (e) => {
681
+ Ie.has(e.name) || (Ie.add(e.name), Y.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
+ }, L = await v(t);
686
+ L.length > 0 && Y.info(`middleware.ts loaded — ${L.length} middleware(s): ` + L.map((e) => e.exportName).join(", "));
687
+ let z, V = null, H = process.env.SSR_CACHE === "postgres";
688
+ if (H && je()) V = new (await (import("pg"))).default.Client(Ae()), await V.connect(), z = mt({ client: V }), Y.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
689
+ else if (H) {
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}`, {
702
- kind: q.kind,
703
- ...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];
691
+ if (e()) throw Y.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
+ z = Re(), Y.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
693
+ } else z = Re(), Y.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
694
+ await xe(t, r, oe, s);
695
+ let $e = R(t, "src", "pages"), { pages: et, dirs: U } = await b($e), W = Ct(et);
696
+ m(L, W.map((e) => e.pattern)), n.mark("scan");
697
+ let G = R(h, "server", "ssrEntry.js"), dt = await Z(G);
698
+ if (!dt && process.env.NODE_ENV === "production") throw Y.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${G} 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 ${G}`);
699
+ let K = dt ? await kt(G) : await At(t, te);
700
+ Y.info(`ssr loader: ${K.kind}`, {
701
+ kind: K.kind,
702
+ ...K.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
703
+ }), n.mark("provider");
704
+ let pt = K.getPageMeta?.();
705
+ be(t);
706
+ let q = /* @__PURE__ */ new Map(), J = 0;
707
+ for (let e of et) {
708
+ let t = pt?.[e.pattern];
710
709
  if (t) {
711
- J.set(e.pattern, t);
710
+ q.set(e.pattern, t);
712
711
  continue;
713
712
  }
714
713
  try {
715
- let t = await q.getPage(e.pattern, e.file);
716
- J.set(e.pattern, Ne(t, e.file)), nt++;
714
+ let t = await K.getPage(e.pattern, e.file);
715
+ q.set(e.pattern, Fe(t, e.file)), J++;
717
716
  } catch (t) {
718
- Z.warn("failed to load page metadata", { pattern: e.pattern }, t);
717
+ Y.warn("failed to load page metadata", { pattern: e.pattern }, t);
719
718
  }
720
719
  }
721
- let Y = /* @__PURE__ */ new Map();
722
- for (let [e, t] of J) {
720
+ let vt = /* @__PURE__ */ new Map();
721
+ for (let [e, t] of q) {
723
722
  if (t.interactive !== "islands") continue;
724
- let n = V(h, "island-shells", `${x(e)}.html`);
723
+ let n = R(h, "island-shells", `${o(e)}.html`);
725
724
  try {
726
- Y.set(e, await H.readFile(n, "utf8"));
725
+ vt.set(e, await B.readFile(n, "utf8"));
727
726
  } catch {
728
- Z.warn("islands page has no built per-page shell — serving the full app shell", {
727
+ Y.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)`, {
735
- count: J.size,
736
- fromManifest: J.size - nt,
737
- fromModules: nt
738
- }), i.mark("routes");
733
+ Y.info(`registered ${q.size} route(s)`, {
734
+ count: q.size,
735
+ fromManifest: q.size - J,
736
+ fromModules: J
737
+ }), n.mark("routes");
739
738
  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);
739
+ for (let e of W) q.get(e.pattern)?.renderMode === "spa" && ye(U, e.dirChain).some((e) => e.hasLayout) && X.add(e.pattern);
740
+ X.size > 0 && Y.info(`${X.size} spa route(s) render an SSR layout shell`, { patterns: [...X] });
741
+ let yt = /* @__PURE__ */ new Map();
742
+ for (let [e, t] of q) t.cacheInvalidatesOn.length > 0 && yt.set(e, t.cacheInvalidatesOn);
743
+ let xt = /* @__PURE__ */ new Map();
744
+ for (let e of W) xt.set(e.pattern, e.regex);
746
745
  {
747
- let n = new Set([...J].filter(([, e]) => (e.renderMode === "ssr" || e.renderMode === "isr") && e.hasOgImage).map(([e]) => e));
746
+ let n = new Set([...q].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 } = ge();
749
+ if (!a && e()) throw Y.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(et.map((e) => [e.pattern, e.file]));
751
+ Tt = de({
753
752
  root: t,
754
- fonts: o.fonts,
753
+ fonts: r.fonts,
755
754
  cache: z,
756
- secret: r,
755
+ secret: i,
757
756
  isOgSsrRoute: (e) => n.has(e),
758
757
  getPageModule: async (e) => {
759
- let t = a.get(e);
760
- return t === void 0 ? null : await q.getPage(e, t);
758
+ let t = o.get(e);
759
+ return t === void 0 ? null : await K.getPage(e, t);
761
760
  }
762
- }), Z.info(`og route active for ${n.size} ssr route(s)`, { secret: i ? "env" : "per-boot" });
761
+ }), Y.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 = {
764
+ let St = /* @__PURE__ */ new Map();
765
+ for (let [e, t] of q) St.set(e, t.renderMode);
766
+ let Et = [...q.values()].some((e) => e.renderMode === "isr"), Dt = {
768
767
  cache: z,
769
- tableSink: $e({
768
+ tableSink: ut({
770
769
  cache: z,
771
- tableSubscriptionsByPattern: st,
772
- regexByPattern: ct
770
+ tableSubscriptionsByPattern: yt,
771
+ regexByPattern: xt
773
772
  }),
774
- regexByPattern: ct,
775
- renderModeByPattern: lt
776
- }, _t = (e) => {
777
- let t = it(e);
778
- t && at(pt, t);
779
- }, vt = tt({
773
+ regexByPattern: xt,
774
+ renderModeByPattern: St
775
+ }, Q = (e) => {
776
+ let t = ht(e);
777
+ t && gt(Dt, t);
778
+ }, jt = ft({
780
779
  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);
780
+ tableSubscriptionsByPattern: yt,
781
+ regexByPattern: xt,
782
+ ...Et ? { onRevalidate: Q } : {}
783
+ }), Mt = await jt.start(), $ = null, Nt = null;
784
+ if (Et) {
785
+ let e = ot({}, 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
+ Nt = e.provider;
788
+ let t = Ne(process.env);
789
+ $ = await at.runPromise(e.provider.subscribe(t, Q)), Y.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
+ Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), Nt = 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
+ Mt && $ === null && Y.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !Mt && $ === null && Y.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) => {
798
- let t = J.get(e.pattern);
795
+ n.mark("cdc");
796
+ let Pt = Pe(), Ft = et.map((e) => {
797
+ let t = q.get(e.pattern);
799
798
  return {
800
799
  pattern: e.pattern,
801
800
  file: e.file,
@@ -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
+ }), It = U.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
+ })), Lt = V ? "postgres" : "memory", Rt = {
820
819
  kind: "web",
821
820
  meta: {
822
- name: o.name ?? "(unnamed)",
823
- voltroVersion: ot,
821
+ name: r.name ?? "(unnamed)",
822
+ voltroVersion: _t,
824
823
  port: p,
825
- mode: "start",
826
- apis: Object.entries(o.apis ?? {}).map(([e, t]) => {
824
+ mode: Qe(),
825
+ apis: Object.entries(r.apis ?? {}).map(([e, t]) => {
827
826
  let n = {
828
827
  name: e,
829
828
  package: t.package
@@ -831,8 +830,8 @@ 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: Ft,
834
+ dirs: It,
836
835
  cache: () => {
837
836
  let e = Date.now(), t = z.snapshot().map(([t, n]) => ({
838
837
  key: t,
@@ -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,
847
+ backend: Lt,
849
848
  size: z.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: () => it()
853
+ }, zt = async (e, n) => {
854
+ let i = e.split("?")[0] ?? "/";
855
+ if (r.name === "voltroDashboard" && i === "/api/dashboard/registry") try {
856
+ let e = await He();
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" && i === "/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 (Tt !== null && i === "/_voltro/og") {
899
+ let t = await Tt.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 (i === "/_voltro/inspect/logs") {
907
+ let t = _e(e, N(), n);
909
908
  return {
910
909
  status: t.status,
911
910
  headers: {
912
911
  "content-type": t.contentType,
913
- ...Te(n.origin)
912
+ ...F(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 (i !== "/_voltro/inspect/stream") {
918
+ let t = Ee(e, Rt, n);
920
919
  if (t !== null) return {
921
920
  status: t.status,
922
921
  headers: {
@@ -926,227 +925,257 @@ 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 a = wt(i, W), o = a ? q.get(a.route.pattern)?.renderMode : void 0, s = o === "ssr" || o === "isr" || (a ? X.has(a.route.pattern) : !1), c = [];
929
+ if (!s && L.length > 0) {
930
+ let t = ae(L, {
932
931
  route: void 0,
933
- pathname: r
932
+ pathname: i
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 ie(t, {
936
+ pathname: i,
937
+ search: e.slice(i.length),
939
938
  headers: n,
940
- cookies: u(n.cookie),
939
+ cookies: ee(n.cookie),
941
940
  route: void 0
942
941
  });
943
- c.push(...i.setCookies);
942
+ c.push(...r.setCookies);
944
943
  }
945
944
  }
946
- let l = (e) => c.length === 0 ? e : {
945
+ let u = (e) => c.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": c.map(Se)
948
+ }, d = i === "/" ? R(h, "index.html") : R(h, i.replace(/^\//, ""), "index.html");
949
+ if (!s && await Z(d)) {
950
+ let e = await B.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": Ye(O)
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 (i.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(i)) {
966
+ let e = R(h, i.replace(/^\//, ""));
967
+ if (await Z(e)) {
968
+ let t = Xe(i, O), r = nt(n["accept-encoding"]), a = r === "br" ? `${e}.br` : r === "gzip" ? `${e}.gz` : void 0;
969
+ if (a !== void 0 && await Z(a)) {
970
+ let n = await B.readFile(e);
971
+ return {
972
+ status: 200,
973
+ headers: u({
974
+ "content-type": bt(e),
975
+ "cache-control": t,
976
+ "content-encoding": r === "br" ? "br" : "gzip",
977
+ vary: "Accept-Encoding",
978
+ etag: ct(n)
979
+ }),
980
+ body: await B.readFile(a)
981
+ };
982
+ }
983
+ let o = await B.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": bt(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({
974
- provider: q,
994
+ let f = wt(i, W);
995
+ if (!f) {
996
+ let r = ce(U, i);
997
+ if (r !== void 0) try {
998
+ let a = await Ot({
999
+ provider: K,
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,
986
- dirs: W,
987
- shellTemplate: w,
1010
+ pathname: i,
1011
+ dirs: U,
1012
+ shellTemplate: D,
988
1013
  requestHeaders: n,
989
- apiOrigin: P,
990
- apiName: F,
991
- middlewares: R,
992
- onCookieWarning: L,
1014
+ apiOrigin: k,
1015
+ apiName: j,
1016
+ middlewares: L,
1017
+ onCookieWarning: I,
993
1018
  requestUrl: e,
994
1019
  buffered: !0,
995
1020
  forceSsrRender: !0
996
1021
  });
997
1022
  if (a && "html" in a && typeof a.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
1028
  body: a.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
+ Y.warn("not-found.tsx failed to render — serving the plain 404", { pathname: i }, 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 } : {},
1042
+ let p = q.get(f.route.pattern), te = n["x-tenant"] ?? "anonymous", re = (await K.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, m = ze(i, {
1043
+ ...p?.tenantAware ? { tenant: te } : {},
1019
1044
  ...re ? { locale: re } : {}
1020
- }), y = m?.ppr === !0 && m.renderMode === "isr", b = (i, a) => ({
1045
+ }), g = p?.ppr === !0 && p.renderMode === "isr", _ = (r, a) => ({
1021
1046
  status: 200,
1022
1047
  headers: {},
1023
1048
  body: "",
1024
1049
  stream: (o) => {
1025
- ie(p.route.pattern), o.writeHead(200, {
1050
+ pe(f.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
1054
  ...a
1030
- }), o.write(i), (async () => {
1055
+ }), o.write(r), (async () => {
1031
1056
  try {
1032
- let i = await yt({
1033
- provider: q,
1057
+ let r = await Ot({
1058
+ provider: K,
1034
1059
  root: t,
1035
- route: p.route,
1036
- params: p.params,
1037
- pathname: r,
1038
- dirs: W,
1039
- shellTemplate: Y.get(p.route.pattern) ?? w,
1060
+ route: f.route,
1061
+ params: f.params,
1062
+ pathname: i,
1063
+ dirs: U,
1064
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1040
1065
  requestHeaders: n,
1041
- apiOrigin: P,
1042
- apiName: F,
1043
- middlewares: R,
1044
- onCookieWarning: L,
1066
+ apiOrigin: k,
1067
+ apiName: j,
1068
+ middlewares: L,
1069
+ onCookieWarning: I,
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: Y
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
+ Y.warn("ppr hole pass failed", { url: i }, 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
+ }), v = z.get(m), y = Date.now();
1087
+ if (v && Be(v, y)) return l.emit("cache", {
1063
1088
  kind: "HIT",
1064
- key: _,
1065
- ageMs: S - x.renderedAt
1066
- }), y ? b(x.html, {
1089
+ key: m,
1090
+ ageMs: y - v.renderedAt
1091
+ }), g ? _(v.html, {
1092
+ "cache-control": Je(O, v.revalidateMs, v.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": m,
1095
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1070
1096
  }) : {
1071
1097
  status: 200,
1072
1098
  headers: {
1073
1099
  "content-type": "text/html; charset=utf-8",
1100
+ "cache-control": Je(O, v.revalidateMs, v.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": m,
1104
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1078
1105
  },
1079
- body: x.html
1106
+ body: v.html
1080
1107
  };
1081
- if (x && Pe(x, S)) {
1082
- f.emit("cache", {
1108
+ if (v && Le(v, y)) {
1109
+ l.emit("cache", {
1083
1110
  kind: "STALE",
1084
- key: _,
1085
- ageMs: S - x.renderedAt
1111
+ key: m,
1112
+ ageMs: y - v.renderedAt
1086
1113
  });
1087
- let i = z.generation(_);
1114
+ let r = z.generation(m);
1088
1115
  return (async () => {
1089
1116
  try {
1090
- let a = await yt({
1091
- provider: q,
1117
+ let a = await Ot({
1118
+ provider: K,
1092
1119
  root: t,
1093
- route: p.route,
1094
- params: p.params,
1095
- pathname: r,
1096
- dirs: W,
1097
- shellTemplate: Y.get(p.route.pattern) ?? w,
1120
+ route: f.route,
1121
+ params: f.params,
1122
+ pathname: i,
1123
+ dirs: U,
1124
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1098
1125
  requestHeaders: n,
1099
- apiOrigin: P,
1100
- apiName: F,
1101
- middlewares: R,
1102
- onCookieWarning: L,
1126
+ apiOrigin: k,
1127
+ apiName: j,
1128
+ middlewares: L,
1129
+ onCookieWarning: I,
1103
1130
  requestUrl: e,
1104
1131
  buffered: !0
1105
1132
  });
1106
1133
  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(_, {
1134
+ let e = q.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
1135
+ z.set(m, {
1109
1136
  html: a.html,
1110
1137
  renderedAt: t,
1111
1138
  expiresAt: t + a.revalidateMs,
1112
1139
  servableUntil: t + a.revalidateMs + e,
1113
1140
  revalidateMs: a.revalidateMs,
1114
1141
  staleWhileRevalidateMs: e
1115
- }, { ifGeneration: i }) || Z.info("SWR refresh discarded — the entry was purged while it rendered", { key: _ });
1142
+ }, { ifGeneration: r }) || Y.info("SWR refresh discarded — the entry was purged while it rendered", { key: m });
1116
1143
  }
1117
1144
  } catch (e) {
1118
- Z.warn("background SWR refresh failed", { url: r }, e);
1145
+ Y.warn("background SWR refresh failed", { url: i }, e);
1119
1146
  }
1120
- })(), y ? b(x.html, {
1147
+ })(), g ? _(v.html, {
1148
+ "cache-control": Je(O, v.revalidateMs, v.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": m,
1151
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1124
1152
  }) : {
1125
1153
  status: 200,
1126
1154
  headers: {
1127
1155
  "content-type": "text/html; charset=utf-8",
1156
+ "cache-control": Je(O, v.revalidateMs, v.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": m,
1160
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1132
1161
  },
1133
- body: x.html
1162
+ body: v.html
1134
1163
  };
1135
1164
  }
1136
1165
  try {
1137
- let i = z.generation(_), a = await yt({
1138
- provider: q,
1166
+ let r = z.generation(m), a = await Ot({
1167
+ provider: K,
1139
1168
  root: t,
1140
- route: p.route,
1141
- params: p.params,
1142
- pathname: r,
1143
- dirs: W,
1144
- shellTemplate: Y.get(p.route.pattern) ?? w,
1169
+ route: f.route,
1170
+ params: f.params,
1171
+ pathname: i,
1172
+ dirs: U,
1173
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1145
1174
  requestHeaders: n,
1146
- apiOrigin: P,
1147
- apiName: F,
1148
- middlewares: R,
1149
- onCookieWarning: L,
1175
+ apiOrigin: k,
1176
+ apiName: j,
1177
+ middlewares: L,
1178
+ onCookieWarning: I,
1150
1179
  requestUrl: e
1151
1180
  });
1152
1181
  if (!a) return {
@@ -1155,12 +1184,12 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1155
1184
  "content-type": "text/html; charset=utf-8",
1156
1185
  "x-voltro-rendered-by": "spa-fallback"
1157
1186
  },
1158
- body: w
1187
+ body: D
1159
1188
  };
1160
1189
  let o = a.setCookies ?? [], s = a.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(Se) }
1164
1193
  });
1165
1194
  if ("stream" in a) return {
1166
1195
  status: 200,
@@ -1184,39 +1213,39 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1184
1213
  body: "not found"
1185
1214
  };
1186
1215
  if ("holes" in a) throw Error("renderPageForRequest returned a holes arm without holesOnly");
1187
- let l = c({
1216
+ let u = c({
1188
1217
  "content-type": "text/html; charset=utf-8",
1189
1218
  "x-voltro-rendered-by": a.renderMode
1190
1219
  });
1191
1220
  if (a.renderMode === "isr" && a.revalidateMs !== null) {
1192
- let e = Date.now(), t = J.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0;
1193
- z.set(_, {
1221
+ let e = Date.now(), t = q.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0;
1222
+ z.set(m, {
1194
1223
  html: a.html,
1195
1224
  renderedAt: e,
1196
1225
  expiresAt: e + a.revalidateMs,
1197
1226
  servableUntil: e + a.revalidateMs + t,
1198
1227
  revalidateMs: a.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 }) || Y.info("miss fill discarded — the entry was purged while it rendered", { key: m }), u["x-voltro-cache"] = "MISS", u["x-voltro-cache-key"] = m, u["x-voltro-cache-revalidate-ms"] = String(a.revalidateMs), t > 0 && (u["x-voltro-cache-swr-ms"] = String(t)), l.emit("cache", {
1201
1230
  kind: "MISS",
1202
- key: _,
1231
+ key: m,
1203
1232
  revalidateMs: a.revalidateMs,
1204
1233
  swrMs: t
1205
1234
  });
1206
- } else a.renderMode === "isr" && (l["x-voltro-cache"] = "BYPASS", f.emit("cache", {
1235
+ } else a.renderMode === "isr" && (u["x-voltro-cache"] = "BYPASS", l.emit("cache", {
1207
1236
  kind: "BYPASS",
1208
- key: _
1237
+ key: m
1209
1238
  }));
1210
- return y && a.renderMode === "isr" ? b(a.html, {
1211
- "x-voltro-cache": l["x-voltro-cache"] ?? "MISS",
1212
- "x-voltro-cache-key": _
1239
+ return g && a.renderMode === "isr" ? _(a.html, {
1240
+ "x-voltro-cache": u["x-voltro-cache"] ?? "MISS",
1241
+ "x-voltro-cache-key": m
1213
1242
  }) : {
1214
1243
  status: 200,
1215
- headers: l,
1244
+ headers: u,
1216
1245
  body: a.html
1217
1246
  };
1218
1247
  } catch (e) {
1219
- return Z.error("render error", { url: r }, e), d(e) ? {
1248
+ return Y.error("render error", { url: i }, e), ne(e) ? {
1220
1249
  status: 500,
1221
1250
  headers: {
1222
1251
  "content-type": "text/plain; charset=utf-8",
@@ -1236,88 +1265,88 @@ 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({
1240
- apiName: F,
1241
- apiOrigin: P,
1268
+ }, Bt = !1, Vt = _({
1269
+ apiName: j,
1270
+ apiOrigin: k,
1242
1271
  loadDescriptors: async () => {
1243
- if (F === void 0) return;
1244
- let e = (await q.getHelpers()).apiDescriptors?.[F];
1272
+ if (j === void 0) return;
1273
+ let e = (await K.getHelpers()).apiDescriptors?.[j];
1245
1274
  return e === void 0 ? void 0 : await e();
1246
1275
  },
1247
- rpcQuery: (e, t) => _e(P, e, {
1248
- apiName: F,
1276
+ rpcQuery: (e, t) => ve(k, e, {
1277
+ apiName: j,
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 K.getHelpers(), r = c(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 } = se(e), a = wt(i, W);
1257
1286
  if (!a) return;
1258
- let o = await yt({
1259
- provider: q,
1287
+ let o = await Ot({
1288
+ provider: K,
1260
1289
  root: t,
1261
1290
  route: a.route,
1262
1291
  params: a.params,
1263
1292
  pathname: i,
1264
- dirs: W,
1265
- shellTemplate: w,
1293
+ dirs: U,
1294
+ shellTemplate: D,
1266
1295
  requestHeaders: n,
1267
- apiOrigin: P,
1268
- apiName: F,
1269
- middlewares: R,
1270
- onCookieWarning: L,
1296
+ apiOrigin: k,
1297
+ apiName: j,
1298
+ middlewares: L,
1299
+ onCookieWarning: I,
1271
1300
  requestUrl: e,
1272
1301
  formFlash: r,
1273
1302
  buffered: !0
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") {
1306
+ }), Ht = rt(r), Ut = st(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();
1310
+ if (o === "/internal/liveness") {
1282
1311
  t.writeHead(200, {
1283
1312
  "content-type": "text/plain",
1284
1313
  "cache-control": "no-store"
1285
1314
  }), t.end("ok");
1286
1315
  return;
1287
1316
  }
1288
- if (a === "/internal/readiness") {
1289
- let e = kt ? 200 : 503;
1317
+ if (o === "/internal/readiness") {
1318
+ let e = Bt ? 200 : 503;
1290
1319
  t.writeHead(e, {
1291
1320
  "content-type": "text/plain",
1292
1321
  "cache-control": "no-store"
1293
- }), t.end(kt ? "ready" : "not-ready");
1322
+ }), t.end(Bt ? "ready" : "not-ready");
1294
1323
  return;
1295
1324
  }
1296
- if (!(a.startsWith(_) && await At(e, t))) {
1297
- if (s === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
1298
- let e = Te(i.origin);
1325
+ if (!(o.startsWith(u) && await Vt(e, t))) {
1326
+ if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
1327
+ let e = F(a.origin);
1299
1328
  t.writeHead(204, e), t.end();
1300
1329
  return;
1301
1330
  }
1302
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
1331
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
1303
1332
  let r = new URL(n, "http://x").searchParams.get("target");
1304
1333
  if (!r) {
1305
1334
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1306
1335
  return;
1307
1336
  }
1308
- if (!ke(r)) {
1337
+ if (!Ce(r)) {
1309
1338
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1310
1339
  return;
1311
1340
  }
1312
1341
  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}`);
1342
+ let n = { accept: a.accept ?? "application/json" }, i = a.authorization;
1343
+ i ? n.authorization = Array.isArray(i) ? i[0] : i : Te(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
1315
1344
  let o;
1316
1345
  if (s && s !== "GET" && s !== "HEAD") {
1317
1346
  let t = [];
1318
1347
  for await (let n of e) t.push(n);
1319
1348
  o = Buffer.concat(t);
1320
- let r = i["content-type"];
1349
+ let r = a["content-type"];
1321
1350
  r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
1322
1351
  }
1323
1352
  let c = await fetch(r, {
@@ -1335,27 +1364,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1335
1364
  }
1336
1365
  return;
1337
1366
  }
1338
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
1367
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
1339
1368
  let r = new URL(n, "http://x").searchParams.get("target");
1340
1369
  if (!r) {
1341
1370
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1342
1371
  return;
1343
1372
  }
1344
- if (!ke(r)) {
1373
+ if (!Ce(r)) {
1345
1374
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1346
1375
  return;
1347
1376
  }
1348
- let a = new AbortController();
1349
- e.on("close", () => a.abort()), t.on("close", () => a.abort());
1377
+ let i = new AbortController();
1378
+ e.on("close", () => i.abort()), t.on("close", () => i.abort());
1350
1379
  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, {
1380
+ let e = we(a, r), n = await fetch(r, {
1352
1381
  redirect: "manual",
1353
1382
  method: "GET",
1354
1383
  headers: {
1355
1384
  accept: "text/event-stream",
1356
1385
  ...e ? { authorization: Array.isArray(e) ? e[0] : e } : {}
1357
1386
  },
1358
- signal: a.signal
1387
+ signal: i.signal
1359
1388
  });
1360
1389
  if (!n.ok || !n.body) {
1361
1390
  t.writeHead(n.status, { "content-type": "text/plain" }), t.end(`upstream ${n.status}`);
@@ -1382,16 +1411,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1382
1411
  }
1383
1412
  return;
1384
1413
  }
1385
- if (a === "/_voltro/inspect/stream") {
1386
- let n = Te(i.origin);
1387
- if (I()) {
1414
+ if (o === "/_voltro/inspect/stream") {
1415
+ let n = F(a.origin);
1416
+ if (De()) {
1388
1417
  t.writeHead(503, {
1389
1418
  "content-type": "application/json",
1390
1419
  ...n
1391
1420
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
1392
1421
  return;
1393
1422
  }
1394
- let r = Ee(i, "GET");
1423
+ let r = Oe(a, "GET");
1395
1424
  if (!r.ok) {
1396
1425
  t.writeHead(401, {
1397
1426
  "content-type": "application/json",
@@ -1409,37 +1438,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1409
1438
  "x-accel-buffering": "no",
1410
1439
  ...n
1411
1440
  }), 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));
1441
+ for (let e of l.buffered()) t.write(f(e));
1442
+ let i = l.subscribe((e) => {
1443
+ t.write(f(e));
1415
1444
  }), o = setInterval(() => {
1416
- t.write(he());
1445
+ t.write(M());
1417
1446
  }, 15e3), s = () => {
1418
- clearInterval(o), a();
1447
+ clearInterval(o), i();
1419
1448
  };
1420
1449
  e.on("close", s), t.on("close", s);
1421
1450
  return;
1422
1451
  }
1423
1452
  try {
1424
- let e = await Ot(n, i);
1425
- if (e.stream ? e.stream(t) : Qe({
1453
+ let e = await zt(n, a);
1454
+ if (e.stream ? e.stream(t) : lt({
1426
1455
  response: t,
1427
1456
  status: e.status,
1428
1457
  headers: e.headers,
1429
1458
  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,
1459
+ requestHeaders: a,
1460
+ compression: le.compression
1461
+ }) || (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
1462
+ let t = Date.now() - i;
1463
+ l.emit("request", {
1464
+ url: o,
1436
1465
  status: e.status,
1437
1466
  durationMs: t,
1438
1467
  renderedBy: e.headers["x-voltro-rendered-by"],
1439
1468
  cache: e.headers["x-voltro-cache"]
1440
1469
  });
1441
- let n = ht(a, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1442
- Ct.record({
1470
+ let n = wt(o, W)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1471
+ Pt.record({
1443
1472
  kind: "request",
1444
1473
  tag: n,
1445
1474
  durationMs: t,
@@ -1451,77 +1480,77 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1451
1480
  }
1452
1481
  }
1453
1482
  });
1454
- await new Promise((e) => jt.listen(p, "::", e)), kt = !0, i.mark("ready"), Z.info(`listening on http://localhost:${p}`, {
1483
+ await new Promise((e) => Ut.listen(p, "::", e)), Bt = !0, n.mark("ready"), tt(Ut, Ht), Y.info(`listening on http://localhost:${p}`, {
1455
1484
  port: p,
1456
1485
  distDir: h
1457
- }), Z.debug("dynamic + ssr/isr routes resolve via SSR loader");
1486
+ }), Y.debug("dynamic + ssr/isr routes resolve via SSR loader");
1458
1487
  try {
1459
- await Re({
1460
- id: S,
1461
- name: b,
1488
+ await Ve({
1489
+ id: C,
1490
+ name: S,
1462
1491
  kind: "web",
1463
1492
  url: `http://localhost:${p}`,
1464
1493
  pid: process.pid,
1465
1494
  status: "live",
1466
- logFile: C.path
1495
+ logFile: T.path
1467
1496
  });
1468
- let e = le(t);
1497
+ let e = P(t);
1469
1498
  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 });
1499
+ let t = await ue({ dashboardAppPath: e });
1500
+ t.status === "launched" ? Y.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && Y.debug(`dashboard already running on :${t.port}`, { port: t.port });
1472
1501
  }
1473
1502
  setInterval(() => {
1474
- Re({
1475
- id: S,
1476
- name: b,
1503
+ Ve({
1504
+ id: C,
1505
+ name: S,
1477
1506
  kind: "web",
1478
1507
  url: `http://localhost:${p}`,
1479
1508
  pid: process.pid,
1480
1509
  status: "live",
1481
- logFile: C.path
1510
+ logFile: T.path
1482
1511
  }).catch(() => {});
1483
1512
  }, 1e4).unref();
1484
1513
  } catch (e) {
1485
- Z.warn("runtime-registry write failed", {}, e);
1514
+ Y.warn("runtime-registry write failed", {}, e);
1486
1515
  }
1487
- Ke({
1488
- app: o.name ?? "unnamed",
1516
+ Ze({
1517
+ app: r.name ?? "unnamed",
1489
1518
  kind: "web",
1490
1519
  url: `http://localhost:${p}`,
1491
- bootMs: i.total()
1520
+ bootMs: n.total()
1492
1521
  });
1493
- let Mt = i.phaseBreakdown();
1494
- Z.info(`start: ready in ${i.total()}ms`, {
1495
- bootMs: i.total(),
1496
- ...Mt ? { phases: Mt } : {}
1522
+ let Wt = n.phaseBreakdown();
1523
+ Y.info(`start: ready in ${n.total()}ms`, {
1524
+ bootMs: n.total(),
1525
+ ...Wt ? { phases: Wt } : {}
1497
1526
  });
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 {
1527
+ let Gt = !1, Kt = (e) => async () => {
1528
+ if (!Gt) {
1529
+ if (Gt = !0, Y.info(`received ${e}, shutting down`, { signal: e }), Ut.close(), await jt.stop(), $) try {
1501
1530
  $();
1502
1531
  } catch {}
1503
- if (St) try {
1504
- await qe.runPromise(St.close());
1532
+ if (Nt) try {
1533
+ await at.runPromise(Nt.close());
1505
1534
  } catch {}
1506
- if (B) try {
1507
- await B.end();
1535
+ if (V) try {
1536
+ await V.end();
1508
1537
  } catch {}
1509
- await q.close(), await Be(S), await C.dispose(), process.exit(0);
1538
+ await K.close(), await Ue(C), await T.dispose(), process.exit(0);
1510
1539
  }
1511
1540
  };
1512
- process.on("SIGINT", Pt("SIGINT")), process.on("SIGTERM", Pt("SIGTERM"));
1513
- let Ft = process.ppid;
1514
- if (Ft > 1) {
1541
+ process.on("SIGINT", Kt("SIGINT")), process.on("SIGTERM", Kt("SIGTERM"));
1542
+ let qt = process.ppid;
1543
+ if (qt > 1) {
1515
1544
  let e = setInterval(() => {
1516
- (process.ppid !== Ft || process.ppid === 1) && (clearInterval(e), Pt("SIGTERM")());
1545
+ (process.ppid !== qt || process.ppid === 1) && (clearInterval(e), Kt("SIGTERM")());
1517
1546
  }, 2e3);
1518
1547
  e.unref();
1519
1548
  }
1520
1549
  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);
1550
+ }, Mt = async (e) => {
1551
+ et("start"), t("start");
1552
+ let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await jt(z(n));
1553
+ return r.ran ? r.exitCode : (Y.error("no web app found at this path"), 1);
1525
1554
  };
1526
1555
  //#endregion
1527
- export { $ as n, St as t };
1556
+ export { jt as n, Mt as t };