@voltro/cli 0.54.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 (173) hide show
  1. package/CHANGELOG.md +639 -2
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/{apiBuild-DTWp0S_q.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-D4ygSbnV.js → build-CI36wL4R.js} +339 -314
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-Dg1G7Gwd.js → checkCommand-CAwFXrxA.js} +6 -6
  9. package/dist/{checkCommand-L7DTlpIF.js → checkCommand-D0QV_zM_.js} +1 -1
  10. package/dist/{clusterCmd-DrVFCzSj.js → clusterCmd-CdLB1GkT.js} +1 -1
  11. package/dist/{codegen-DSLM8Su9.js → codegen-Bth5lUTU.js} +76 -64
  12. package/dist/codegen-DbH7NbCR.js +2 -0
  13. package/dist/{codegenCommand-CG_Vx4lc.js → codegenCommand-CidbQzbv.js} +15 -14
  14. package/dist/{codemodRunner-Cd4xkC6u.js → codemodRunner-BlQPfjzA.js} +277 -0
  15. package/dist/{commands-6Kzi92Np.js → commands-CWjfThXv.js} +35 -35
  16. package/dist/{dashboardCommand-Cq1PWvI1.js → dashboardCommand-BekcY5Ls.js} +3 -3
  17. package/dist/{dataCommand-DYzW8vkv.js → dataCommand-2pccgbIy.js} +267 -195
  18. package/dist/{dbCommand-B4NWZtGL.js → dbCommand-DpK_vQET.js} +457 -441
  19. package/dist/dbCommand-DrycGWWt.js +2 -0
  20. package/dist/{dev-cKUiZZsB.js → dev-B9Gz0k85.js} +1 -1
  21. package/dist/{dev-CmuvUKRq.js → dev-Dw263KPu.js} +2598 -2452
  22. package/dist/doctorCommand-BMWs6aVm.js +2 -0
  23. package/dist/{doctorCommand-DCiFVMtZ.js → doctorCommand-aR_bFmIi.js} +353 -251
  24. package/dist/{dormancyCommand-w1TrmgYP.js → dormancyCommand-eXTQMbHU.js} +1 -1
  25. package/dist/{embeddingsCommand-CMgPyRTr.js → embeddingsCommand-CTmiQvwa.js} +1 -1
  26. package/dist/{envCommand-Cyynmcfa.js → envCommand-BDUgV7EM.js} +12 -12
  27. package/dist/{evolveCommand-BwvQ8dVH.js → evolveCommand-YV8qW1LU.js} +2 -2
  28. package/dist/frameworkTableAssembly-CGNC0qr7.js +2 -0
  29. package/dist/{frameworkTableAssembly-D7LJuALW.js → frameworkTableAssembly-DNOFXfEQ.js} +102 -100
  30. package/dist/index.js +1 -1
  31. package/dist/{infoCommand-DlYlUPqs.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/interruptedReplace-CwnkBb2X.js +41 -0
  38. package/dist/interruptedReplace-qzmFI020.js +2 -0
  39. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-BU8uCdys.js} +1 -1
  40. package/dist/{manifestBuild-Cqgsx2bM.js → manifestBuild-CEkjfpwc.js} +1 -1
  41. package/dist/manifestBuild-DIa_s6u0.js +2 -0
  42. package/dist/{migrate-BK_Bbx-_.js → migrate-SICulyz1.js} +2 -2
  43. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  44. package/dist/{probeCommand-_C0YU207.js → probeCommand-6HxEkNDG.js} +2 -2
  45. package/dist/{runtimeTrace-CGWx1Q6l.js → runtimeTrace-DgYMc09E.js} +1 -1
  46. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  47. package/dist/{sdkgen-CDGHQUFj.js → sdkgen-PY-umd6O.js} +1 -1
  48. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  49. package/dist/serveCommand-BITS8Hpj.js +2 -0
  50. package/dist/{serveCommand-Bje09q1v.js → serveCommand-DIJ3ma76.js} +951 -909
  51. package/dist/serveEntry.js +1 -1
  52. package/dist/{start-Clz-1BHB.js → start-B9NGB8gn.js} +627 -588
  53. package/dist/{start-B0bnJgxI.js → start-BFQQkL1i.js} +1 -1
  54. package/dist/startEntry.js +1 -1
  55. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  56. package/dist/{test-D_kW4KMj.js → test-jipIQ5Mx.js} +1 -1
  57. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-BWYDqMy6.js} +1 -1
  58. package/dist/{updateCommand-CRJlAOaM.js → updateCommand-C9n_Z_oG.js} +8 -2
  59. package/dist/updateCommand-DsXEAHbd.js +2 -0
  60. package/dist/webDev-C2dRz9s5.js +2 -0
  61. package/dist/{webDev-DSI9SOhs.js → webDev-C53hJdcL.js} +1265 -1288
  62. package/dist/{webhooksCommand-BvzXNHji.js → webhooksCommand-uuPu8qQX.js} +1 -1
  63. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  64. package/package.json +67 -19
  65. package/templates/AGENTS.core.md +20 -1
  66. package/templates/AGENTS.md +21 -2
  67. package/templates/agent-docs/_index.md +1 -1
  68. package/templates/agent-docs/_manifest.json +1 -1
  69. package/templates/agent-docs/authentication.md +49 -6
  70. package/templates/agent-docs/cli.md +216 -11
  71. package/templates/agent-docs/data.md +209 -18
  72. package/templates/agent-docs/database/scaling.md +40 -1
  73. package/templates/agent-docs/deployment.md +53 -1
  74. package/templates/agent-docs/internationalization.md +32 -0
  75. package/templates/agent-docs/local-first-mobile.md +9 -2
  76. package/templates/agent-docs/observability.md +227 -0
  77. package/templates/agent-docs/plugins/billing.md +15 -0
  78. package/templates/agent-docs/plugins/broadcast.md +2 -1
  79. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  80. package/templates/agent-docs/plugins/row-history.md +11 -0
  81. package/templates/agent-docs/plugins.md +65 -8
  82. package/templates/agent-docs/reference.md +5 -3
  83. package/templates/agent-docs/routing.md +18 -0
  84. package/templates/agent-docs/schema-driven-ui.md +125 -0
  85. package/templates/agent-docs/templates/appshells.md +3 -3
  86. package/templates/agent-docs/whats-new.md +408 -106
  87. package/templates/apps/api-ai/package.json +6 -6
  88. package/templates/apps/api-auth/package.json +8 -8
  89. package/templates/apps/api-backend/package.json +7 -7
  90. package/templates/apps/api-backend-deactivation/package.json +7 -7
  91. package/templates/apps/api-backend-mail/package.json +8 -8
  92. package/templates/apps/api-backend-mariadb/package.json +9 -9
  93. package/templates/apps/api-backend-sqlite/package.json +8 -8
  94. package/templates/apps/api-backend-storage/package.json +8 -8
  95. package/templates/apps/api-cms/package.json +9 -9
  96. package/templates/apps/api-collab/package.json +8 -8
  97. package/templates/apps/api-data-advanced/package.json +8 -8
  98. package/templates/apps/api-durable/package.json +8 -8
  99. package/templates/apps/api-feature-flags/package.json +9 -9
  100. package/templates/apps/api-governance/package.json +8 -8
  101. package/templates/apps/api-kv/package.json +8 -8
  102. package/templates/apps/api-moderation/package.json +8 -8
  103. package/templates/apps/api-observability/package.json +8 -8
  104. package/templates/apps/api-ratelimit/package.json +8 -8
  105. package/templates/apps/api-rbac/package.json +8 -8
  106. package/templates/apps/api-rest/package.json +7 -7
  107. package/templates/apps/api-row-history/package.json +8 -8
  108. package/templates/apps/api-saas/package.json +11 -11
  109. package/templates/apps/api-saas-starter/package.json +10 -10
  110. package/templates/apps/api-search/package.json +8 -8
  111. package/templates/apps/api-status/package.json +8 -8
  112. package/templates/apps/api-webhooks/package.json +9 -9
  113. package/templates/apps/changelog/package.json +7 -7
  114. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  115. package/templates/apps/edge-functions/package.json +2 -2
  116. package/templates/apps/frontend-admin/package.json +7 -8
  117. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  118. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  119. package/templates/apps/frontend-app/package.json +8 -9
  120. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  121. package/templates/apps/frontend-auth/package.json +7 -8
  122. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  123. package/templates/apps/frontend-blank/package.json +6 -7
  124. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  125. package/templates/apps/frontend-cms/package.json +8 -9
  126. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  127. package/templates/apps/frontend-collab/README.md +7 -2
  128. package/templates/apps/frontend-collab/package.json +9 -10
  129. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  130. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  131. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  132. package/templates/apps/frontend-contact/package.json +7 -7
  133. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  134. package/templates/apps/frontend-dashboard/package.json +6 -7
  135. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  136. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  137. package/templates/apps/frontend-docs/package.json +8 -8
  138. package/templates/apps/frontend-i18n/package.json +6 -6
  139. package/templates/apps/frontend-landing/package.json +7 -7
  140. package/templates/apps/frontend-portal/package.json +7 -8
  141. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  142. package/templates/apps/frontend-saas/package.json +7 -8
  143. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  144. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  145. package/templates/apps/frontend-spa/package.json +6 -7
  146. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  147. package/templates/apps/frontend-ssr/package.json +6 -7
  148. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  149. package/templates/apps/frontend-ssr-api/package.json +7 -8
  150. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  151. package/templates/apps/frontend-static-blog/package.json +8 -8
  152. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  153. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  154. package/templates/apps/frontend-status/package.json +7 -8
  155. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  156. package/templates/apps/mobile-app/package.json +4 -4
  157. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  158. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  159. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  160. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  161. package/dist/apiBuild-CeUN55uk.js +0 -2
  162. package/dist/codegen-DjgxEOnD.js +0 -2
  163. package/dist/dbCommand-CSFWs9ev.js +0 -2
  164. package/dist/doctorCommand-J3qu4E0Y.js +0 -2
  165. package/dist/frameworkTableAssembly-IPD1pUnZ.js +0 -2
  166. package/dist/inspect-Bd8-9wsi.js +0 -1193
  167. package/dist/inspect-CuoDInfZ.js +0 -2
  168. package/dist/interruptedReplace-C3O3M1MM.js +0 -28
  169. package/dist/interruptedReplace-CvmiAM9K.js +0 -2
  170. package/dist/manifestBuild-C4-J1-m_.js +0 -2
  171. package/dist/serveCommand-BiPe8BJm.js +0 -2
  172. package/dist/updateCommand-CIoVDKnj.js +0 -2
  173. package/dist/webDev-DlvZO30c.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 p, K as m, Kt as h, L as te, M as g, Mt as _, N as ne, O as re, Ot as v, R as y, S as b, T as x, Tt as S, U as C, Ut as ie, V as w, W as ae, X as oe, Y as T, Z as E, at as D, bt as O, ct as se, et as ce, ht as le, i as ue, j as de, jt as k, k as fe, kt as A, l as pe, lt as me, m as he, mt as j, n as M, nt as N, o as ge, ot as P, p as _e, q as F, s as I, st as ve, w as ye, x as be, z as xe } from "./webDev-DSI9SOhs.js";
4
- import { o as Se, t as Ce } from "./connectionConfig-Bk9IC7D0.js";
5
- import { A as L, D as we, a as Te, h as Ee, j as De, k as Oe } from "./inspect-Bd8-9wsi.js";
6
- import { n as ke, r as Ae, t as je } from "./inspectMetrics-CGF94puw.js";
7
- import { a as Me, c as R, d as Ne, f as Pe, l as Fe, p as z, u as Ie } from "./renderModeScan-43yQ2opo.js";
8
- import { i as Le, n as Re, r as ze, t as Be } from "./runtimeRegistry-DMeKfTHP.js";
9
- import { n as Ve } from "./logFileSink-B4uP8pvf.js";
10
- import { t as He } from "./bootTiming-BdyP9nYw.js";
11
- import { dirname as B, extname as V, join as H, resolve as Ue } from "node:path";
12
- import { promises as U } from "node:fs";
13
- import { fileURLToPath as We, pathToFileURL as W } from "node:url";
14
- import { createLogger as G, printReadyBlock as Ge } from "@voltro/logger";
15
- import { Effect as Ke } from "effect";
16
- import { maybeCompress as K, snapshotMetricsSync as qe } from "@voltro/runtime";
17
- import { createHash as q } from "node:crypto";
18
- import { resolveBroadcastProvider as Je } from "@voltro/plugin-broadcast";
19
- import { createServer as Ye } 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 Xe = (e) => `W/"${q("md5").update(e).digest("hex")}"`, Ze = (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 = Xe(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 = K({
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
- }, J = G({ scope: "voltro:start:cdc" }), Qe = (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 Xe = (e) => `W/"${q("md5").update(e).digest("hex")}"`, Ze = (e) => {
48
54
  }));
49
55
  }
50
56
  return n;
51
- }, $e = () => Ce() ? Se() : null, et = (e) => {
52
- let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = Qe(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 J.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
57
- let c = $e();
58
- if (!c && !o) return J.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
59
- if (!c) return J.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 Xe = (e) => `W/"${q("md5").update(e).digest("hex")}"`, Ze = (e) => {
67
73
  try {
68
74
  a = JSON.parse(i.payload);
69
75
  } catch (e) {
70
- J.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 && J.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 J.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 Xe = (e) => `W/"${q("md5").update(e).digest("hex")}"`, Ze = (e) => {
96
102
  }
97
103
  }
98
104
  };
99
- }, Y = G({ scope: "voltro:start:isr-cache" }), tt = "voltro_isr_cache", X = (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
- `, nt = (e) => {
111
- let t = e.tableName ?? tt, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
112
- i || (i = !0, await n.query(X(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
- Y.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
- Y.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
- }, Z = G({ scope: "voltro:start:revalidate" }), rt = (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
- } : (Z.warn("bad revalidation payload (shape)", { payload: e }), null);
191
+ } : (J.warn("bad revalidation payload (shape)", { payload: e }), null);
186
192
  } catch {
187
- return Z.warn("bad revalidation payload (not JSON)", { payload: e }), null;
193
+ return J.warn("bad revalidation payload (not JSON)", { payload: e }), null;
188
194
  }
189
- }, it = (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 Z.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 Z.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 Z.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 Z.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 Z.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 Z.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
- }, Q = G({ scope: "voltro:start" }), at = await (async () => {
230
- try {
231
- let e = H(B(We(import.meta.url)), "..", "package.json"), t = await U.readFile(e, "utf8");
232
- return JSON.parse(t).version ?? "0.0.0";
233
- } catch {
234
- return "0.0.0";
235
- }
236
- })(), ot = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", st = (e) => e instanceof Error && e._voltroControl === "not-found", ct = {
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
- }, lt = (e) => ct[V(e).toLowerCase()] ?? "application/octet-stream", ut = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), dt = 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 U.stat(e), !0;
255
+ return await B.stat(e), !0;
257
256
  } catch {
258
257
  return !1;
259
258
  }
260
- }, ft = (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
- }, pt = (e) => e.map((e) => {
270
- let { regex: t, paramNames: n, priority: r } = ft(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), mt = (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,261 +287,271 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
288
287
  };
289
288
  }
290
289
  return null;
291
- }, ht = null, gt = async (e) => {
292
- let { provider: t, route: n, params: r, pathname: a, dirs: s, shellTemplate: d, requestHeaders: h, requestUrl: _ = "", apiOrigin: ne, apiName: re } = e, { search: v } = oe(_), y = await ee(te(e.middlewares ?? [], {
293
- route: n.pattern,
294
- pathname: a
290
+ }, Tt = null, Et, Dt = (e, t) => t === void 0 ? Promise.resolve() : (Et ??= (async () => {
291
+ try {
292
+ let n = await e.getHelpers(), r = n.apiDescriptors?.[t];
293
+ if (r === void 0) return;
294
+ let i = n.registerSsrApiDescriptors;
295
+ if (i === void 0) return;
296
+ i(t, await r());
297
+ } catch {}
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
295
304
  }), {
296
- pathname: a,
297
- search: v,
298
- headers: h,
299
- cookies: u(h.cookie),
300
- route: n.pattern
301
- }, e.onCookieWarning), b = await t.getPage(n.pattern, n.file), S = e.forceSsrRender === !0 ? "ssr" : R(b, n.file), ie = S === "isr" && b.ppr === !0, E = S === "isr" && e.holesOnly !== !0 ? i(y.headers) : y.headers, D = ge(ne, E.cookie, {
302
- apiName: re,
303
- headers: E
305
+ pathname: o,
306
+ search: _,
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
304
313
  });
305
314
  if (e.holesOnly === !0) {
306
- if (typeof b.loader != "function") return null;
315
+ if (typeof y.loader != "function") return null;
307
316
  let e = new AbortController();
308
317
  return {
309
318
  holes: {
310
- loader: b.loader,
319
+ loader: y.loader,
311
320
  ctx: {
312
- params: r,
313
- pathname: a,
314
- search: v,
321
+ params: a,
322
+ pathname: o,
323
+ search: _,
315
324
  signal: e.signal,
316
- headers: E,
317
- query: D,
325
+ headers: w,
326
+ query: E,
318
327
  isServer: !0
319
328
  },
320
329
  helpers: await t.getHelpers(),
321
- page: n.pattern
330
+ page: r.pattern
322
331
  },
323
- setCookies: y.setCookies
332
+ setCookies: v.setCookies
324
333
  };
325
334
  }
326
- let O = S === "spa" && pe(s, n.dirChain).some((e) => e.hasLayout);
327
- if (S !== "ssr" && S !== "isr" && !O) return null;
328
- let se = pe(s, n.dirChain), ce = {}, le = null, ue, de = new AbortController(), k = ie ? c(E, n.pattern) : E;
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;
329
338
  try {
330
- (await t.getHelpers()).beginStoreSeeds(), {chain: ue, segmentLoaderData: ce} = await I({
331
- entries: se,
339
+ (await t.getHelpers()).beginStoreSeeds(), {chain: pe, segmentLoaderData: de} = await le({
340
+ entries: ue,
332
341
  loadLayout: (e) => t.getLayout(e.dir),
333
342
  loadError: (e) => t.getError(e.dir),
334
343
  loadPending: (e) => t.getPending(e.dir),
335
344
  ctx: {
336
- params: r,
337
- pathname: a,
338
- search: v,
339
- signal: de.signal,
340
- headers: k,
341
- query: D,
345
+ params: a,
346
+ pathname: o,
347
+ search: _,
348
+ signal: k.signal,
349
+ headers: me,
350
+ query: E,
342
351
  isServer: !0
343
352
  }
344
- }), typeof b.loader == "function" && !O && (le = await b.loader({
345
- params: r,
346
- pathname: a,
347
- search: v,
348
- signal: de.signal,
349
- headers: k,
350
- query: D,
353
+ }), typeof y.loader == "function" && !ce && (fe = await y.loader({
354
+ params: a,
355
+ pathname: o,
356
+ search: _,
357
+ signal: k.signal,
358
+ headers: me,
359
+ query: E,
351
360
  isServer: !0
352
361
  }));
353
362
  } catch (e) {
354
- if (ot(e)) return {
363
+ if (vt(e)) return {
355
364
  control: "redirect",
356
365
  status: e.status,
357
366
  location: e.location,
358
- setCookies: y.setCookies,
359
- responseHeaders: y.responseHeaders
367
+ setCookies: v.setCookies,
368
+ responseHeaders: v.responseHeaders
360
369
  };
361
- if (st(e)) return {
370
+ if (X(e)) return {
362
371
  control: "not-found",
363
- setCookies: y.setCookies,
364
- responseHeaders: y.responseHeaders
372
+ setCookies: v.setCookies,
373
+ responseHeaders: v.responseHeaders
365
374
  };
366
375
  throw e;
367
376
  }
368
377
  let A = await t.getHelpers();
369
- O || await xe({
370
- pageMod: b,
371
- params: r,
372
- query: D,
373
- apiName: re,
378
+ ce || await i({
379
+ pageMod: y,
380
+ params: a,
381
+ query: E,
382
+ apiName: m,
374
383
  seed: A.seedPreloadedSubscription,
375
384
  seedFailure: A.seedPreloadedSubscriptionFailure,
376
- onError: ({ tag: e, apiName: t }, n) => Q.warn("preload seed failed", {
385
+ onError: ({ tag: e, apiName: t }, n) => Y.warn("preload seed failed", {
377
386
  tag: e,
378
387
  apiName: t,
379
- pathname: a
388
+ pathname: o
380
389
  }, n)
381
390
  });
382
- let me = {
383
- pattern: n.pattern,
384
- Component: b.default,
385
- meta: b.meta,
386
- loader: b.loader,
387
- ErrorBoundary: b.ErrorBoundary,
388
- Pending: b.Pending,
389
- renderMode: S,
390
- chain: ue
391
- };
392
- if (S === "isr" && y.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.`);
393
391
  let he = {
394
- cookies: ie ? l(fe(y.cookies), n.pattern) : S === "isr" ? fe(y.cookies) : y.cookies,
395
- headers: k,
396
- url: _,
392
+ pattern: r.pattern,
393
+ Component: y.default,
394
+ meta: y.meta,
395
+ loader: y.loader,
396
+ ErrorBoundary: y.ErrorBoundary,
397
+ Pending: y.Pending,
398
+ renderMode: b,
399
+ chain: pe
400
+ };
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.`);
402
+ let ge = {
403
+ cookies: x ? s(n(v.cookies), r.pattern) : b === "isr" ? n(v.cookies) : v.cookies,
404
+ headers: me,
405
+ url: ne,
397
406
  ...e.formFlash === void 0 ? {} : { formFlash: e.formFlash }
398
- }, j = A.i18n?.resolve(E.cookie, E["accept-language"]), M = {
399
- lang: j?.locale ?? he.cookies["voltro:locale"] ?? "en",
400
- ...j?.timeZone === void 0 ? {} : { timeZone: j.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 },
401
410
  renderedAt: Date.now()
402
- }, N = b.interactive ?? "full";
403
- if (O) {
404
- let e = F({
411
+ }, N = y.interactive ?? "full";
412
+ if (ce) {
413
+ let e = te({
405
414
  helpers: A,
406
- page: n.pattern,
415
+ page: r.pattern,
407
416
  interactive: N,
408
417
  delivery: "stream",
409
418
  renderInput: {
410
- descriptor: me,
411
- params: r,
412
- pathname: a,
413
- search: v,
414
- segmentLoaderData: ce,
415
- requestContext: he,
416
- ...j ? {
417
- outerWrap: j.outerWrap,
418
- locale: j.locale
419
+ descriptor: he,
420
+ params: a,
421
+ pathname: o,
422
+ search: _,
423
+ segmentLoaderData: de,
424
+ requestContext: ge,
425
+ ...M ? {
426
+ outerWrap: M.outerWrap,
427
+ locale: M.locale
419
428
  } : {}
420
429
  }
421
- }), t = (t) => T({
430
+ }), t = (t) => D({
422
431
  helpers: A,
423
432
  prepared: e,
424
433
  meta: t,
425
434
  interactive: N
426
435
  });
427
436
  if (e.hasDeferred) {
428
- let n = f({ shell: d });
437
+ let n = S({ shell: u });
429
438
  return {
430
439
  renderMode: "spa",
431
- setCookies: y.setCookies,
432
- responseHeaders: y.responseHeaders,
433
- stream: (r) => ae({
440
+ setCookies: v.setCookies,
441
+ responseHeaders: v.responseHeaders,
442
+ stream: (r) => d({
434
443
  res: r,
435
444
  shell: n,
436
- documentAttrs: M,
445
+ documentAttrs: _e,
437
446
  headers: {
438
- ...y.responseHeaders,
447
+ ...v.responseHeaders,
439
448
  "content-type": "text/html; charset=utf-8",
440
449
  "x-voltro-rendered-by": "spa",
441
- ...g(y.setCookies)
450
+ ...h(v.setCookies)
442
451
  },
443
452
  headInjection: t,
444
- ...y.cspNonce === void 0 ? {} : { nonce: y.cspNonce },
453
+ ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
445
454
  render: (t) => A.renderPageToStream({
446
455
  ...e.renderInput,
447
456
  ...t,
448
- ...y.cspNonce === void 0 ? {} : { nonce: y.cspNonce }
457
+ ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce }
449
458
  }),
450
459
  onShellError: (e) => {
451
- Q.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");
452
461
  }
453
462
  })
454
463
  };
455
464
  }
456
- let i = p({
465
+ let n = oe({
457
466
  helpers: A,
458
467
  prepared: e
459
- }), s = o(w(d.replace("<div id=\"root\"></div>", `<div id="root">${i.body}</div>`), t(i.meta)), M);
468
+ }), i = C(p(u.replace("<div id=\"root\"></div>", `<div id="root">${n.body}</div>`), t(n.meta)), _e);
460
469
  return {
461
- html: y.cspNonce === void 0 ? s : C(s, y.cspNonce),
470
+ html: v.cspNonce === void 0 ? i : T(i, v.cspNonce),
462
471
  renderMode: "spa",
463
472
  revalidateMs: null,
464
- setCookies: y.setCookies,
465
- responseHeaders: y.responseHeaders
473
+ setCookies: v.setCookies,
474
+ responseHeaders: v.responseHeaders
466
475
  };
467
476
  }
468
- let P = m({
477
+ let P = j({
469
478
  helpers: A,
470
- page: n.pattern,
471
- pathname: a,
472
- renderMode: S,
479
+ page: r.pattern,
480
+ pathname: o,
481
+ renderMode: b,
473
482
  interactive: N,
474
- loaderData: le,
475
- segmentLoaderData: ce,
476
- pageLoaderRan: typeof b.loader == "function",
477
- ...ie ? { ppr: !0 } : {}
483
+ loaderData: fe,
484
+ segmentLoaderData: de,
485
+ pageLoaderRan: typeof y.loader == "function",
486
+ ...x ? { ppr: !0 } : {}
478
487
  });
479
- ie && x(P.stateInput, n.pattern);
480
- let _e = {
481
- descriptor: me,
482
- params: r,
483
- pathname: a,
484
- search: v,
488
+ x && l(P.stateInput, r.pattern);
489
+ let be = {
490
+ descriptor: he,
491
+ params: a,
492
+ pathname: o,
493
+ search: _,
485
494
  loaderData: P.loaderData,
486
495
  segmentLoaderData: P.segmentLoaderData,
487
- requestContext: he,
488
- ...j ? {
489
- outerWrap: j.outerWrap,
490
- locale: j.locale
496
+ requestContext: ge,
497
+ ...M ? {
498
+ outerWrap: M.outerWrap,
499
+ locale: M.locale
491
500
  } : {}
492
- }, ve = (t) => {
493
- if (ht === null || S !== "ssr" && S !== "isr" || typeof b.ogImage != "function" || t.includes("og:image")) return "";
494
- let r = E["x-tenant"], i = ht.signOgUrl({
495
- 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,
496
505
  params: e.params,
497
- ...r === void 0 ? {} : { tenant: r }
506
+ ...n === void 0 ? {} : { tenant: n }
498
507
  });
499
508
  return `<meta property="og:image" content="${i}" /><meta name="twitter:image" content="${i}" /><meta name="twitter:card" content="summary_large_image" />`;
500
- }, ye = (e) => [
501
- A.renderMetaToHtml(e) + ve(A.renderMetaToHtml(e)),
509
+ }, Se = (e) => [
510
+ A.renderMetaToHtml(e) + xe(A.renderMetaToHtml(e)),
502
511
  `<meta name="voltro-interactive" content="${N}" />`,
503
512
  ...P.hasDeferred ? [A.renderDeferredRegistryScript()] : [],
504
513
  A.renderRouterStateScript(P.stateInput)
505
514
  ].filter((e) => e.length > 0).join("\n ");
506
- if (S === "ssr" && N === "full" && e.buffered !== !0) {
507
- let e = f({ shell: d });
515
+ if (b === "ssr" && N === "full" && e.buffered !== !0) {
516
+ let e = S({ shell: u });
508
517
  return {
509
518
  renderMode: "ssr",
510
- setCookies: y.setCookies,
511
- stream: (t) => ae({
519
+ setCookies: v.setCookies,
520
+ stream: (t) => d({
512
521
  res: t,
513
522
  shell: e,
514
- documentAttrs: M,
523
+ documentAttrs: _e,
515
524
  headers: {
516
- ...y.responseHeaders,
525
+ ...v.responseHeaders,
517
526
  "content-type": "text/html; charset=utf-8",
518
527
  "x-voltro-rendered-by": "ssr",
519
- ...g(y.setCookies)
528
+ ...h(v.setCookies)
520
529
  },
521
- headInjection: ye,
522
- ...y.cspNonce === void 0 ? {} : { nonce: y.cspNonce },
530
+ headInjection: Se,
531
+ ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce },
523
532
  render: (e) => A.renderPageToStream({
524
- ..._e,
533
+ ...be,
525
534
  ...e,
526
- ...y.cspNonce === void 0 ? {} : { nonce: y.cspNonce }
535
+ ...v.cspNonce === void 0 ? {} : { nonce: v.cspNonce }
527
536
  }),
528
537
  onShellError: (e) => {
529
- Q.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");
530
539
  }
531
540
  })
532
541
  };
533
542
  }
534
- let { html: be, meta: Se } = A.renderPageToHtml(_e), Ce = ye(Se), L = o(w(d.replace("<div id=\"root\"></div>", `<div id="root">${be}</div>`), Ce), M);
535
- N === "none" && (L = ut(L));
536
- let we = S === "isr" ? z(b.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;
537
546
  return {
538
- html: y.cspNonce === void 0 ? L : C(L, y.cspNonce),
539
- renderMode: S,
540
- revalidateMs: we,
541
- setCookies: y.setCookies,
542
- responseHeaders: y.responseHeaders
547
+ html: v.cspNonce === void 0 ? F : T(F, v.cspNonce),
548
+ renderMode: b,
549
+ revalidateMs: Ee,
550
+ setCookies: v.setCookies,
551
+ responseHeaders: v.responseHeaders
543
552
  };
544
- }, $ = (e) => e === "" ? "/" : e, _t = async (e) => {
545
- let t = await import(W(e).href);
553
+ }, Q = (e) => e === "" ? "/" : e, kt = async (e) => {
554
+ let t = await import(V(e).href);
546
555
  return {
547
556
  kind: "bundle",
548
557
  getPageMeta: () => t.pageMeta,
@@ -552,18 +561,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
552
561
  return typeof r == "function" ? await r() : r;
553
562
  },
554
563
  async getLayout(e) {
555
- let n = t.layouts[$(e)];
556
- if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${$(e)}`);
564
+ let n = t.layouts[Q(e)];
565
+ if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${Q(e)}`);
557
566
  return typeof n == "function" ? await n() : n;
558
567
  },
559
568
  async getError(e) {
560
- let n = t.errors[$(e)];
561
- if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${$(e)}`);
569
+ let n = t.errors[Q(e)];
570
+ if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${Q(e)}`);
562
571
  return typeof n == "function" ? await n() : n;
563
572
  },
564
573
  async getPending(e) {
565
- let n = t.pendings[$(e)];
566
- if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${$(e)}`);
574
+ let n = t.pendings[Q(e)];
575
+ if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${Q(e)}`);
567
576
  return typeof n == "function" ? await n() : n;
568
577
  },
569
578
  async getHelpers() {
@@ -571,11 +580,11 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
571
580
  },
572
581
  async close() {}
573
582
  };
574
- }, vt = async (e, t) => {
575
- let n = await h("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({
576
585
  root: t,
577
586
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
578
- plugins: [r(), i()],
587
+ plugins: [i(), a()],
579
588
  resolve: { dedupe: [
580
589
  "react",
581
590
  "react-dom",
@@ -589,203 +598,203 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
589
598
  },
590
599
  appType: "custom",
591
600
  logLevel: "warn"
592
- }), o = H(e, "src", "pages"), s = (e) => e === "" ? o : H(o, e), c = k({
593
- limit: _(),
594
- onColdStart: (e) => Q.debug("ssr cold-compile start", { id: e }),
595
- onColdEnd: (e, { durationMs: t, failed: n }) => Q.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`, {
596
605
  id: e,
597
606
  ms: t,
598
607
  ...n ? { failed: !0 } : {}
599
608
  })
600
- }), l = (e) => c.load(e, async () => await a.ssrLoadModule(e));
609
+ }), u = (e) => l.load(e, async () => await o.ssrLoadModule(e));
601
610
  return {
602
611
  kind: "middleware",
603
612
  async getPage(e, t) {
604
- return l(H(o, t));
613
+ return u(R(s, t));
605
614
  },
606
615
  async getLayout(e) {
607
- return l(H(s(e), "layout.tsx"));
616
+ return u(R(c(e), "layout.tsx"));
608
617
  },
609
618
  async getError(e) {
610
- return l(H(s(e), "error.tsx"));
619
+ return u(R(c(e), "error.tsx"));
611
620
  },
612
621
  async getPending(e) {
613
- return l(H(s(e), "loading.tsx"));
622
+ return u(R(c(e), "loading.tsx"));
614
623
  },
615
624
  async getHelpers() {
616
- return await l("@voltro/web/ssr");
625
+ return await u("@voltro/web/ssr");
617
626
  },
618
627
  async close() {
619
- await a.close();
628
+ await o.close();
620
629
  }
621
630
  };
622
- }, yt = async (t) => {
623
- let i = He(), o = await _e(t);
624
- if (!o) return {
631
+ }, jt = async (t) => {
632
+ let n = Ke(), r = await me(t);
633
+ if (!r) return {
625
634
  ran: !1,
626
635
  exitCode: 0
627
636
  };
628
- if (o.type !== "web") return Q.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`"), {
629
638
  ran: !0,
630
639
  exitCode: 1
631
640
  };
632
641
  {
633
- let e = b(o);
634
- if (e !== void 0) return Q.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}`), {
635
644
  ran: !0,
636
645
  exitCode: 1
637
646
  };
638
647
  }
639
- let { resolved: c } = await ie({
640
- rawEnv: o.env,
648
+ let { resolved: i } = await w({
649
+ rawEnv: r.env,
641
650
  appType: "web",
642
651
  root: t,
643
- log: Q,
652
+ log: Y,
644
653
  generateTypes: !1
645
- }), l = c.publicValues;
646
- i.mark("config");
647
- let f = se();
648
- D(f), Q.info("booting voltro start", { app: o.name ?? "(unnamed)" });
649
- let p = 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({
650
659
  kind: "web",
651
- configPort: o.port,
660
+ configPort: r.port,
652
661
  env: process.env,
653
- dashboardPin: process.env[E] === "1"
662
+ dashboardPin: process.env[y] === "1"
654
663
  });
655
- for (let e of p.warnings) Q.warn(e);
656
- let m = p.port, h = H(t, ".framework"), g = H(h, "dist"), _ = H(g, "index.html");
657
- if (!await dt(_)) return Q.error("no built dist found — run `voltro build` first", { distDir: g }), {
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 }), {
658
667
  ran: !0,
659
668
  exitCode: 1
660
669
  };
661
- let x = o.name ?? "unnamed", C = Be("web", x, m), w = Ve(x);
662
- await Le({
670
+ let S = r.name ?? "unnamed", C = We("web", S, p), T = Ge(S);
671
+ await Ve({
663
672
  id: C,
664
- name: x,
673
+ name: S,
665
674
  kind: "web",
666
- url: `http://localhost:${m}`,
675
+ url: `http://localhost:${p}`,
667
676
  pid: process.pid,
668
677
  status: "booting",
669
- logFile: w.path
678
+ logFile: T.path
670
679
  }).catch(() => {});
671
- let ae = H(g, "_voltro", "shell.html"), T = await dt(ae) ? await U.readFile(ae, "utf8") : await U.readFile(_, "utf8"), k = await he(t, o), fe = ke(o), F = M(k[0]), I = k[0]?.name, xe = /* @__PURE__ */ new Set(), R = (e) => {
672
- xe.has(e.name) || (xe.add(e.name), Q.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`, {
673
682
  cookie: e.name,
674
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."
675
684
  }));
676
- }, z = await ne(t);
677
- z.length > 0 && Q.info(`middleware.ts loaded — ${z.length} middleware(s): ` + z.map((e) => e.exportName).join(", "));
678
- let B, V = null, Ue = process.env.SSR_CACHE === "postgres";
679
- if (Ue && Ce()) V = new (await (import("pg"))).default.Client(Se()), await V.connect(), B = nt({ client: V }), Q.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
680
- else if (Ue) {
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) {
681
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).";
682
- if (e()) throw Q.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");
683
- B = Pe(), Q.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
684
- } else B = Pe(), Q.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
685
- await s(t, o, k, l);
686
- let We = H(t, "src", "pages"), { pages: W, dirs: G } = await be(We), K = pt(W);
687
- de(z, K.map((e) => e.pattern)), i.mark("scan");
688
- let q = H(g, "server", "ssrEntry.js"), Xe = await dt(q);
689
- if (!Xe && process.env.NODE_ENV === "production") throw Q.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${q} 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 ${q}`);
690
- let J = Xe ? await _t(q) : await vt(t, h);
691
- Q.info(`ssr loader: ${J.kind}`, {
692
- kind: J.kind,
693
- ...J.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
694
- }), i.mark("provider");
695
- let $e = J.getPageMeta?.();
696
- O(t);
697
- let Y = /* @__PURE__ */ new Map(), tt = 0;
698
- for (let e of W) {
699
- let t = $e?.[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];
700
709
  if (t) {
701
- Y.set(e.pattern, t);
710
+ q.set(e.pattern, t);
702
711
  continue;
703
712
  }
704
713
  try {
705
- let t = await J.getPage(e.pattern, e.file);
706
- Y.set(e.pattern, Me(t, e.file)), tt++;
714
+ let t = await K.getPage(e.pattern, e.file);
715
+ q.set(e.pattern, Fe(t, e.file)), J++;
707
716
  } catch (t) {
708
- Q.warn("failed to load page metadata", { pattern: e.pattern }, t);
717
+ Y.warn("failed to load page metadata", { pattern: e.pattern }, t);
709
718
  }
710
719
  }
711
- let X = /* @__PURE__ */ new Map();
712
- for (let [e, t] of Y) {
720
+ let vt = /* @__PURE__ */ new Map();
721
+ for (let [e, t] of q) {
713
722
  if (t.interactive !== "islands") continue;
714
- let n = H(g, "island-shells", `${S(e)}.html`);
723
+ let n = R(h, "island-shells", `${o(e)}.html`);
715
724
  try {
716
- X.set(e, await U.readFile(n, "utf8"));
725
+ vt.set(e, await B.readFile(n, "utf8"));
717
726
  } catch {
718
- Q.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", {
719
728
  pattern: e,
720
729
  expected: n
721
730
  });
722
731
  }
723
732
  }
724
- Q.info(`registered ${Y.size} route(s)`, {
725
- count: Y.size,
726
- fromManifest: Y.size - tt,
727
- fromModules: tt
728
- }), i.mark("routes");
729
- let Z = /* @__PURE__ */ new Set();
730
- for (let e of K) Y.get(e.pattern)?.renderMode === "spa" && pe(G, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
731
- Z.size > 0 && Q.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
732
- let ot = /* @__PURE__ */ new Map();
733
- for (let [e, t] of Y) t.cacheInvalidatesOn.length > 0 && ot.set(e, t.cacheInvalidatesOn);
734
- let st = /* @__PURE__ */ new Map();
735
- for (let e of K) st.set(e.pattern, e.regex);
733
+ Y.info(`registered ${q.size} route(s)`, {
734
+ count: q.size,
735
+ fromManifest: q.size - J,
736
+ fromModules: J
737
+ }), n.mark("routes");
738
+ let X = /* @__PURE__ */ new Set();
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);
736
745
  {
737
- let n = new Set([...Y].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));
738
747
  if (n.size > 0) {
739
- let { secret: r, fromEnv: i } = le();
740
- if (!i && e()) throw Q.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");
741
- let a = new Map(W.map((e) => [e.pattern, e.file]));
742
- ht = j({
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({
743
752
  root: t,
744
- fonts: o.fonts,
745
- cache: B,
746
- secret: r,
753
+ fonts: r.fonts,
754
+ cache: z,
755
+ secret: i,
747
756
  isOgSsrRoute: (e) => n.has(e),
748
757
  getPageModule: async (e) => {
749
- let t = a.get(e);
750
- return t === void 0 ? null : await J.getPage(e, t);
758
+ let t = o.get(e);
759
+ return t === void 0 ? null : await K.getPage(e, t);
751
760
  }
752
- }), Q.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" });
753
762
  }
754
763
  }
755
- let ct = /* @__PURE__ */ new Map();
756
- for (let [e, t] of Y) ct.set(e, t.renderMode);
757
- let ut = [...Y.values()].some((e) => e.renderMode === "isr"), ft = {
758
- cache: B,
759
- tableSink: Qe({
760
- cache: B,
761
- tableSubscriptionsByPattern: ot,
762
- regexByPattern: st
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 = {
767
+ cache: z,
768
+ tableSink: ut({
769
+ cache: z,
770
+ tableSubscriptionsByPattern: yt,
771
+ regexByPattern: xt
763
772
  }),
764
- regexByPattern: st,
765
- renderModeByPattern: ct
766
- }, $ = (e) => {
767
- let t = rt(e);
768
- t && it(ft, t);
769
- }, yt = et({
770
- cache: B,
771
- tableSubscriptionsByPattern: ot,
772
- regexByPattern: st,
773
- ...ut ? { onRevalidate: $ } : {}
774
- }), bt = await yt.start(), xt = null, St = null;
775
- if (ut) {
776
- let e = Je({}, process.env);
773
+ regexByPattern: xt,
774
+ renderModeByPattern: St
775
+ }, Q = (e) => {
776
+ let t = ht(e);
777
+ t && gt(Dt, t);
778
+ }, jt = ft({
779
+ cache: z,
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);
777
786
  if (e.crossReplica) try {
778
- St = e.provider;
779
- let t = Ae(process.env);
780
- xt = await Ke.runPromise(e.provider.subscribe(t, $)), Q.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 });
781
790
  } catch (e) {
782
- Q.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), St = null;
791
+ Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), Nt = null;
783
792
  }
784
- bt && xt === null && Q.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !bt && xt === null && Q.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.");
785
794
  }
786
- i.mark("cdc");
787
- let Ct = je(), wt = W.map((e) => {
788
- let t = Y.get(e.pattern);
795
+ n.mark("cdc");
796
+ let Pt = Pe(), Ft = et.map((e) => {
797
+ let t = q.get(e.pattern);
789
798
  return {
790
799
  pattern: e.pattern,
791
800
  file: e.file,
@@ -800,20 +809,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
800
809
  hasMeta: t?.hasMeta ?? !1,
801
810
  hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
802
811
  };
803
- }), Tt = G.map((e) => ({
812
+ }), It = U.map((e) => ({
804
813
  dir: e.dir,
805
814
  hasLayout: e.hasLayout,
806
815
  hasError: e.hasError,
807
816
  hasPending: e.hasPending,
808
817
  hasNotFound: e.hasNotFound
809
- })), Et = V ? "postgres" : "memory", Dt = {
818
+ })), Lt = V ? "postgres" : "memory", Rt = {
810
819
  kind: "web",
811
820
  meta: {
812
- name: o.name ?? "(unnamed)",
813
- voltroVersion: at,
814
- port: m,
815
- mode: "start",
816
- apis: Object.entries(o.apis ?? {}).map(([e, t]) => {
821
+ name: r.name ?? "(unnamed)",
822
+ voltroVersion: _t,
823
+ port: p,
824
+ mode: Qe(),
825
+ apis: Object.entries(r.apis ?? {}).map(([e, t]) => {
817
826
  let n = {
818
827
  name: e,
819
828
  package: t.package
@@ -821,10 +830,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
821
830
  return t.url !== void 0 && (n.url = t.url), n;
822
831
  })
823
832
  },
824
- routes: wt,
825
- dirs: Tt,
833
+ routes: Ft,
834
+ dirs: It,
826
835
  cache: () => {
827
- let e = Date.now(), t = B.snapshot().map(([t, n]) => ({
836
+ let e = Date.now(), t = z.snapshot().map(([t, n]) => ({
828
837
  key: t,
829
838
  renderedAt: n.renderedAt,
830
839
  expiresAt: n.expiresAt,
@@ -835,16 +844,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
835
844
  staleWhileRevalidateMs: n.staleWhileRevalidateMs
836
845
  }));
837
846
  return {
838
- backend: Et,
839
- size: B.size(),
847
+ backend: Lt,
848
+ size: z.size(),
840
849
  entries: t
841
850
  };
842
851
  },
843
- metrics: () => qe()
844
- }, Ot = async (e, n) => {
845
- let r = e.split("?")[0] ?? "/";
846
- if (o.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
847
- let e = await Re();
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();
848
857
  return {
849
858
  status: 200,
850
859
  headers: { "content-type": "application/json; charset=utf-8" },
@@ -857,7 +866,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
857
866
  body: `registry read error: ${e.message}`
858
867
  };
859
868
  }
860
- if (o.name === "voltroDashboard" && r === "/api/dashboard/config") {
869
+ if (r.name === "voltroDashboard" && i === "/api/dashboard/config") {
861
870
  let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
862
871
  if (e && e.trim().length > 0) {
863
872
  let n;
@@ -886,27 +895,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
886
895
  body: JSON.stringify({ apps: t })
887
896
  };
888
897
  }
889
- if (ht !== null && r === "/_voltro/og") {
890
- let t = await ht.handle(new URL(e, "http://localhost"));
898
+ if (Tt !== null && i === "/_voltro/og") {
899
+ let t = await Tt.handle(new URL(e, "http://localhost"));
891
900
  if (t !== null) return {
892
901
  status: t.status,
893
902
  headers: { ...t.headers },
894
903
  body: Buffer.from(t.body)
895
904
  };
896
905
  }
897
- if (r === "/_voltro/inspect/logs") {
898
- let t = N(e, P(), n);
906
+ if (i === "/_voltro/inspect/logs") {
907
+ let t = _e(e, N(), n);
899
908
  return {
900
909
  status: t.status,
901
910
  headers: {
902
911
  "content-type": t.contentType,
903
- ...we(n.origin)
912
+ ...F(n.origin)
904
913
  },
905
914
  body: t.body
906
915
  };
907
916
  }
908
- if (r !== "/_voltro/inspect/stream") {
909
- let t = Ee(e, Dt, n);
917
+ if (i !== "/_voltro/inspect/stream") {
918
+ let t = Ee(e, Rt, n);
910
919
  if (t !== null) return {
911
920
  status: t.status,
912
921
  headers: {
@@ -916,227 +925,257 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
916
925
  body: t.body
917
926
  };
918
927
  }
919
- let i = mt(r, K), a = i ? Y.get(i.route.pattern)?.renderMode : void 0, s = a === "ssr" || a === "isr" || (i ? Z.has(i.route.pattern) : !1), c = [];
920
- if (!s && z.length > 0) {
921
- let t = te(z, {
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, {
922
931
  route: void 0,
923
- pathname: r
932
+ pathname: i
924
933
  });
925
934
  if (t !== void 0) {
926
- let i = await ee(t, {
927
- pathname: r,
928
- search: e.slice(r.length),
935
+ let r = await ie(t, {
936
+ pathname: i,
937
+ search: e.slice(i.length),
929
938
  headers: n,
930
- cookies: u(n.cookie),
939
+ cookies: ee(n.cookie),
931
940
  route: void 0
932
941
  });
933
- c.push(...i.setCookies);
942
+ c.push(...r.setCookies);
934
943
  }
935
944
  }
936
- let l = (e) => c.length === 0 ? e : {
945
+ let u = (e) => c.length === 0 ? e : {
937
946
  ...e,
938
- "set-cookie": c.map(y)
939
- }, p = r === "/" ? H(g, "index.html") : H(g, r.replace(/^\//, ""), "index.html");
940
- if (!s && await dt(p)) {
941
- let e = await U.readFile(p);
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);
942
951
  return {
943
952
  status: 200,
944
- 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
+ }),
945
957
  body: e
946
958
  };
947
959
  }
948
- if (/\.[a-z0-9]+$/i.test(r)) {
949
- let e = H(g, r.replace(/^\//, ""));
950
- if (await dt(e)) {
951
- let t = await U.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);
952
984
  return {
953
985
  status: 200,
954
- headers: l({ "content-type": lt(e) }),
955
- body: t
986
+ headers: u({
987
+ "content-type": bt(e),
988
+ "cache-control": t
989
+ }),
990
+ body: o
956
991
  };
957
992
  }
958
993
  }
959
- let m = mt(r, K);
960
- if (!m) {
961
- let i = ue(G, r);
962
- if (i !== void 0) try {
963
- let a = await gt({
964
- provider: J,
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,
965
1000
  root: t,
966
1001
  route: {
967
1002
  pattern: "<not-found>",
968
- file: i.dir === "" ? "not-found.tsx" : `${i.dir}/not-found.tsx`,
969
- dirChain: i.chain,
1003
+ file: r.dir === "" ? "not-found.tsx" : `${r.dir}/not-found.tsx`,
1004
+ dirChain: r.chain,
970
1005
  regex: /^$/,
971
1006
  paramNames: [],
972
1007
  priority: 2 ** 53 - 1
973
1008
  },
974
1009
  params: {},
975
- pathname: r,
976
- dirs: G,
977
- shellTemplate: T,
1010
+ pathname: i,
1011
+ dirs: U,
1012
+ shellTemplate: D,
978
1013
  requestHeaders: n,
979
- apiOrigin: F,
980
- apiName: I,
981
- middlewares: z,
982
- onCookieWarning: R,
1014
+ apiOrigin: k,
1015
+ apiName: j,
1016
+ middlewares: L,
1017
+ onCookieWarning: I,
983
1018
  requestUrl: e,
984
1019
  buffered: !0,
985
1020
  forceSsrRender: !0
986
1021
  });
987
1022
  if (a && "html" in a && typeof a.html == "string") return {
988
1023
  status: 404,
989
- headers: l({
1024
+ headers: u({
990
1025
  "content-type": "text/html; charset=utf-8",
991
1026
  "x-voltro-rendered-by": "ssr-not-found"
992
1027
  }),
993
1028
  body: a.html
994
1029
  };
995
1030
  } catch (e) {
996
- Q.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)));
997
1032
  }
998
1033
  return {
999
1034
  status: 404,
1000
- headers: l({
1035
+ headers: u({
1001
1036
  "content-type": "text/plain",
1002
1037
  "x-voltro-rendered-by": "plain-not-found"
1003
1038
  }),
1004
1039
  body: "not found"
1005
1040
  };
1006
1041
  }
1007
- let h = Y.get(m.route.pattern), _ = n["x-tenant"] ?? "anonymous", ne = (await J.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, v = Fe(r, {
1008
- ...h?.tenantAware ? { tenant: _ } : {},
1009
- ...ne ? { locale: ne } : {}
1010
- }), b = h?.ppr === !0 && h.renderMode === "isr", x = (i, a) => ({
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 } : {},
1044
+ ...re ? { locale: re } : {}
1045
+ }), g = p?.ppr === !0 && p.renderMode === "isr", _ = (r, a) => ({
1011
1046
  status: 200,
1012
1047
  headers: {},
1013
1048
  body: "",
1014
1049
  stream: (o) => {
1015
- re(m.route.pattern), o.writeHead(200, {
1050
+ pe(f.route.pattern), o.writeHead(200, {
1016
1051
  "content-type": "text/html; charset=utf-8",
1017
1052
  "x-voltro-rendered-by": "isr",
1018
1053
  "x-voltro-ppr": "shell+holes",
1019
1054
  ...a
1020
- }), o.write(i), (async () => {
1055
+ }), o.write(r), (async () => {
1021
1056
  try {
1022
- let i = await gt({
1023
- provider: J,
1057
+ let r = await Ot({
1058
+ provider: K,
1024
1059
  root: t,
1025
- route: m.route,
1026
- params: m.params,
1027
- pathname: r,
1028
- dirs: G,
1029
- shellTemplate: X.get(m.route.pattern) ?? T,
1060
+ route: f.route,
1061
+ params: f.params,
1062
+ pathname: i,
1063
+ dirs: U,
1064
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1030
1065
  requestHeaders: n,
1031
- apiOrigin: F,
1032
- apiName: I,
1033
- middlewares: z,
1034
- onCookieWarning: R,
1066
+ apiOrigin: k,
1067
+ apiName: j,
1068
+ middlewares: L,
1069
+ onCookieWarning: I,
1035
1070
  requestUrl: e,
1036
1071
  holesOnly: !0
1037
1072
  });
1038
- i !== null && "holes" in i ? await ye({
1039
- loader: i.holes.loader,
1040
- ctx: i.holes.ctx,
1073
+ r !== null && "holes" in r ? await x({
1074
+ loader: r.holes.loader,
1075
+ ctx: r.holes.ctx,
1041
1076
  res: o,
1042
- helpers: i.holes.helpers,
1043
- page: i.holes.page,
1044
- log: Q
1077
+ helpers: r.holes.helpers,
1078
+ page: r.holes.page,
1079
+ log: Y
1045
1080
  }) : o.writableEnded || o.end();
1046
1081
  } catch (e) {
1047
- Q.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();
1048
1083
  }
1049
1084
  })();
1050
1085
  }
1051
- }), S = B.get(v), C = Date.now();
1052
- if (S && Ie(S, C)) return f.emit("cache", {
1086
+ }), v = z.get(m), y = Date.now();
1087
+ if (v && Be(v, y)) return l.emit("cache", {
1053
1088
  kind: "HIT",
1054
- key: v,
1055
- ageMs: C - S.renderedAt
1056
- }), b ? x(S.html, {
1089
+ key: m,
1090
+ ageMs: y - v.renderedAt
1091
+ }), g ? _(v.html, {
1092
+ "cache-control": Je(O, v.revalidateMs, v.staleWhileRevalidateMs),
1057
1093
  "x-voltro-cache": "HIT",
1058
- "x-voltro-cache-key": v,
1059
- "x-voltro-cache-age-ms": String(C - S.renderedAt)
1094
+ "x-voltro-cache-key": m,
1095
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1060
1096
  }) : {
1061
1097
  status: 200,
1062
1098
  headers: {
1063
1099
  "content-type": "text/html; charset=utf-8",
1100
+ "cache-control": Je(O, v.revalidateMs, v.staleWhileRevalidateMs),
1064
1101
  "x-voltro-rendered-by": "isr",
1065
1102
  "x-voltro-cache": "HIT",
1066
- "x-voltro-cache-key": v,
1067
- "x-voltro-cache-age-ms": String(C - S.renderedAt)
1103
+ "x-voltro-cache-key": m,
1104
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1068
1105
  },
1069
- body: S.html
1106
+ body: v.html
1070
1107
  };
1071
- if (S && Ne(S, C)) {
1072
- f.emit("cache", {
1108
+ if (v && Le(v, y)) {
1109
+ l.emit("cache", {
1073
1110
  kind: "STALE",
1074
- key: v,
1075
- ageMs: C - S.renderedAt
1111
+ key: m,
1112
+ ageMs: y - v.renderedAt
1076
1113
  });
1077
- let i = B.generation(v);
1114
+ let r = z.generation(m);
1078
1115
  return (async () => {
1079
1116
  try {
1080
- let a = await gt({
1081
- provider: J,
1117
+ let a = await Ot({
1118
+ provider: K,
1082
1119
  root: t,
1083
- route: m.route,
1084
- params: m.params,
1085
- pathname: r,
1086
- dirs: G,
1087
- shellTemplate: X.get(m.route.pattern) ?? T,
1120
+ route: f.route,
1121
+ params: f.params,
1122
+ pathname: i,
1123
+ dirs: U,
1124
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1088
1125
  requestHeaders: n,
1089
- apiOrigin: F,
1090
- apiName: I,
1091
- middlewares: z,
1092
- onCookieWarning: R,
1126
+ apiOrigin: k,
1127
+ apiName: j,
1128
+ middlewares: L,
1129
+ onCookieWarning: I,
1093
1130
  requestUrl: e,
1094
1131
  buffered: !0
1095
1132
  });
1096
1133
  if (a && "html" in a && a.renderMode === "isr" && a.revalidateMs !== null) {
1097
- let e = Y.get(m.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
1098
- B.set(v, {
1134
+ let e = q.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
1135
+ z.set(m, {
1099
1136
  html: a.html,
1100
1137
  renderedAt: t,
1101
1138
  expiresAt: t + a.revalidateMs,
1102
1139
  servableUntil: t + a.revalidateMs + e,
1103
1140
  revalidateMs: a.revalidateMs,
1104
1141
  staleWhileRevalidateMs: e
1105
- }, { ifGeneration: i }) || Q.info("SWR refresh discarded — the entry was purged while it rendered", { key: v });
1142
+ }, { ifGeneration: r }) || Y.info("SWR refresh discarded — the entry was purged while it rendered", { key: m });
1106
1143
  }
1107
1144
  } catch (e) {
1108
- Q.warn("background SWR refresh failed", { url: r }, e);
1145
+ Y.warn("background SWR refresh failed", { url: i }, e);
1109
1146
  }
1110
- })(), b ? x(S.html, {
1147
+ })(), g ? _(v.html, {
1148
+ "cache-control": Je(O, v.revalidateMs, v.staleWhileRevalidateMs),
1111
1149
  "x-voltro-cache": "STALE",
1112
- "x-voltro-cache-key": v,
1113
- "x-voltro-cache-age-ms": String(C - S.renderedAt)
1150
+ "x-voltro-cache-key": m,
1151
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1114
1152
  }) : {
1115
1153
  status: 200,
1116
1154
  headers: {
1117
1155
  "content-type": "text/html; charset=utf-8",
1156
+ "cache-control": Je(O, v.revalidateMs, v.staleWhileRevalidateMs),
1118
1157
  "x-voltro-rendered-by": "isr",
1119
1158
  "x-voltro-cache": "STALE",
1120
- "x-voltro-cache-key": v,
1121
- "x-voltro-cache-age-ms": String(C - S.renderedAt)
1159
+ "x-voltro-cache-key": m,
1160
+ "x-voltro-cache-age-ms": String(y - v.renderedAt)
1122
1161
  },
1123
- body: S.html
1162
+ body: v.html
1124
1163
  };
1125
1164
  }
1126
1165
  try {
1127
- let i = B.generation(v), a = await gt({
1128
- provider: J,
1166
+ let r = z.generation(m), a = await Ot({
1167
+ provider: K,
1129
1168
  root: t,
1130
- route: m.route,
1131
- params: m.params,
1132
- pathname: r,
1133
- dirs: G,
1134
- shellTemplate: X.get(m.route.pattern) ?? T,
1169
+ route: f.route,
1170
+ params: f.params,
1171
+ pathname: i,
1172
+ dirs: U,
1173
+ shellTemplate: vt.get(f.route.pattern) ?? D,
1135
1174
  requestHeaders: n,
1136
- apiOrigin: F,
1137
- apiName: I,
1138
- middlewares: z,
1139
- onCookieWarning: R,
1175
+ apiOrigin: k,
1176
+ apiName: j,
1177
+ middlewares: L,
1178
+ onCookieWarning: I,
1140
1179
  requestUrl: e
1141
1180
  });
1142
1181
  if (!a) return {
@@ -1145,12 +1184,12 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1145
1184
  "content-type": "text/html; charset=utf-8",
1146
1185
  "x-voltro-rendered-by": "spa-fallback"
1147
1186
  },
1148
- body: T
1187
+ body: D
1149
1188
  };
1150
1189
  let o = a.setCookies ?? [], s = a.responseHeaders ?? {}, c = (e) => ({
1151
1190
  ...s,
1152
1191
  ...e,
1153
- ...o.length === 0 ? {} : { "set-cookie": o.map(y) }
1192
+ ...o.length === 0 ? {} : { "set-cookie": o.map(Se) }
1154
1193
  });
1155
1194
  if ("stream" in a) return {
1156
1195
  status: 200,
@@ -1174,39 +1213,39 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1174
1213
  body: "not found"
1175
1214
  };
1176
1215
  if ("holes" in a) throw Error("renderPageForRequest returned a holes arm without holesOnly");
1177
- let l = c({
1216
+ let u = c({
1178
1217
  "content-type": "text/html; charset=utf-8",
1179
1218
  "x-voltro-rendered-by": a.renderMode
1180
1219
  });
1181
1220
  if (a.renderMode === "isr" && a.revalidateMs !== null) {
1182
- let e = Date.now(), t = Y.get(m.route.pattern)?.staleWhileRevalidateMs ?? 0;
1183
- B.set(v, {
1221
+ let e = Date.now(), t = q.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0;
1222
+ z.set(m, {
1184
1223
  html: a.html,
1185
1224
  renderedAt: e,
1186
1225
  expiresAt: e + a.revalidateMs,
1187
1226
  servableUntil: e + a.revalidateMs + t,
1188
1227
  revalidateMs: a.revalidateMs,
1189
1228
  staleWhileRevalidateMs: t
1190
- }, { ifGeneration: i }) || Q.info("miss fill discarded — the entry was purged while it rendered", { key: v }), l["x-voltro-cache"] = "MISS", l["x-voltro-cache-key"] = v, l["x-voltro-cache-revalidate-ms"] = String(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", {
1191
1230
  kind: "MISS",
1192
- key: v,
1231
+ key: m,
1193
1232
  revalidateMs: a.revalidateMs,
1194
1233
  swrMs: t
1195
1234
  });
1196
- } 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", {
1197
1236
  kind: "BYPASS",
1198
- key: v
1237
+ key: m
1199
1238
  }));
1200
- return b && a.renderMode === "isr" ? x(a.html, {
1201
- "x-voltro-cache": l["x-voltro-cache"] ?? "MISS",
1202
- "x-voltro-cache-key": v
1239
+ return g && a.renderMode === "isr" ? _(a.html, {
1240
+ "x-voltro-cache": u["x-voltro-cache"] ?? "MISS",
1241
+ "x-voltro-cache-key": m
1203
1242
  }) : {
1204
1243
  status: 200,
1205
- headers: l,
1244
+ headers: u,
1206
1245
  body: a.html
1207
1246
  };
1208
1247
  } catch (e) {
1209
- return Q.error("render error", { url: r }, e), d(e) ? {
1248
+ return Y.error("render error", { url: i }, e), ne(e) ? {
1210
1249
  status: 500,
1211
1250
  headers: {
1212
1251
  "content-type": "text/plain; charset=utf-8",
@@ -1226,88 +1265,88 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1226
1265
  body: "server error"
1227
1266
  };
1228
1267
  }
1229
- }, kt = !1, At = a({
1230
- apiName: I,
1231
- apiOrigin: F,
1268
+ }, Bt = !1, Vt = _({
1269
+ apiName: j,
1270
+ apiOrigin: k,
1232
1271
  loadDescriptors: async () => {
1233
- if (I === void 0) return;
1234
- let e = (await J.getHelpers()).apiDescriptors?.[I];
1272
+ if (j === void 0) return;
1273
+ let e = (await K.getHelpers()).apiDescriptors?.[j];
1235
1274
  return e === void 0 ? void 0 : await e();
1236
1275
  },
1237
- rpcQuery: (e, t) => ge(F, e, {
1238
- apiName: I,
1276
+ rpcQuery: (e, t) => ve(k, e, {
1277
+ apiName: j,
1239
1278
  headers: t
1240
1279
  }),
1241
1280
  resolveLocale: async (e, t) => {
1242
- let n = await J.getHelpers(), r = A(t, n.i18n?.locales);
1281
+ let n = await K.getHelpers(), r = c(t, n.i18n?.locales);
1243
1282
  return r === void 0 ? n.i18n?.resolve(e.cookie, e["accept-language"])?.locale ?? "en" : r;
1244
1283
  },
1245
1284
  renderErrorPage: async ({ path: e, headers: n, flash: r }) => {
1246
- let { pathname: i } = oe(e), a = mt(i, K);
1285
+ let { pathname: i } = se(e), a = wt(i, W);
1247
1286
  if (!a) return;
1248
- let o = await gt({
1249
- provider: J,
1287
+ let o = await Ot({
1288
+ provider: K,
1250
1289
  root: t,
1251
1290
  route: a.route,
1252
1291
  params: a.params,
1253
1292
  pathname: i,
1254
- dirs: G,
1255
- shellTemplate: T,
1293
+ dirs: U,
1294
+ shellTemplate: D,
1256
1295
  requestHeaders: n,
1257
- apiOrigin: F,
1258
- apiName: I,
1259
- middlewares: z,
1260
- onCookieWarning: R,
1296
+ apiOrigin: k,
1297
+ apiName: j,
1298
+ middlewares: L,
1299
+ onCookieWarning: I,
1261
1300
  requestUrl: e,
1262
1301
  formFlash: r,
1263
1302
  buffered: !0
1264
1303
  });
1265
1304
  return o !== null && "html" in o ? o.html : void 0;
1266
1305
  }
1267
- }), jt = Ye(async (e, t) => {
1268
- let n = e.url ?? "/", r = Date.now(), i = {};
1269
- for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
1270
- let a = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
1271
- 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") {
1272
1311
  t.writeHead(200, {
1273
1312
  "content-type": "text/plain",
1274
1313
  "cache-control": "no-store"
1275
1314
  }), t.end("ok");
1276
1315
  return;
1277
1316
  }
1278
- if (a === "/internal/readiness") {
1279
- let e = kt ? 200 : 503;
1317
+ if (o === "/internal/readiness") {
1318
+ let e = Bt ? 200 : 503;
1280
1319
  t.writeHead(e, {
1281
1320
  "content-type": "text/plain",
1282
1321
  "cache-control": "no-store"
1283
- }), t.end(kt ? "ready" : "not-ready");
1322
+ }), t.end(Bt ? "ready" : "not-ready");
1284
1323
  return;
1285
1324
  }
1286
- if (!(a.startsWith(v) && await At(e, t))) {
1287
- if (s === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
1288
- let e = we(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);
1289
1328
  t.writeHead(204, e), t.end();
1290
1329
  return;
1291
1330
  }
1292
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
1331
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
1293
1332
  let r = new URL(n, "http://x").searchParams.get("target");
1294
1333
  if (!r) {
1295
1334
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1296
1335
  return;
1297
1336
  }
1298
- if (!Oe(r)) {
1337
+ if (!Ce(r)) {
1299
1338
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1300
1339
  return;
1301
1340
  }
1302
1341
  try {
1303
- let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
1304
- a ? n.authorization = Array.isArray(a) ? a[0] : a : De(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}`);
1305
1344
  let o;
1306
1345
  if (s && s !== "GET" && s !== "HEAD") {
1307
1346
  let t = [];
1308
1347
  for await (let n of e) t.push(n);
1309
1348
  o = Buffer.concat(t);
1310
- let r = i["content-type"];
1349
+ let r = a["content-type"];
1311
1350
  r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
1312
1351
  }
1313
1352
  let c = await fetch(r, {
@@ -1325,27 +1364,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1325
1364
  }
1326
1365
  return;
1327
1366
  }
1328
- if (o.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
1367
+ if (r.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
1329
1368
  let r = new URL(n, "http://x").searchParams.get("target");
1330
1369
  if (!r) {
1331
1370
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
1332
1371
  return;
1333
1372
  }
1334
- if (!Oe(r)) {
1373
+ if (!Ce(r)) {
1335
1374
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
1336
1375
  return;
1337
1376
  }
1338
- let a = new AbortController();
1339
- 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());
1340
1379
  try {
1341
- let e = i.authorization ?? (De(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, {
1342
1381
  redirect: "manual",
1343
1382
  method: "GET",
1344
1383
  headers: {
1345
1384
  accept: "text/event-stream",
1346
1385
  ...e ? { authorization: Array.isArray(e) ? e[0] : e } : {}
1347
1386
  },
1348
- signal: a.signal
1387
+ signal: i.signal
1349
1388
  });
1350
1389
  if (!n.ok || !n.body) {
1351
1390
  t.writeHead(n.status, { "content-type": "text/plain" }), t.end(`upstream ${n.status}`);
@@ -1372,16 +1411,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1372
1411
  }
1373
1412
  return;
1374
1413
  }
1375
- if (a === "/_voltro/inspect/stream") {
1376
- let n = we(i.origin);
1377
- if (L()) {
1414
+ if (o === "/_voltro/inspect/stream") {
1415
+ let n = F(a.origin);
1416
+ if (De()) {
1378
1417
  t.writeHead(503, {
1379
1418
  "content-type": "application/json",
1380
1419
  ...n
1381
1420
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
1382
1421
  return;
1383
1422
  }
1384
- let r = Te(i, "GET");
1423
+ let r = Oe(a, "GET");
1385
1424
  if (!r.ok) {
1386
1425
  t.writeHead(401, {
1387
1426
  "content-type": "application/json",
@@ -1399,37 +1438,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1399
1438
  "x-accel-buffering": "no",
1400
1439
  ...n
1401
1440
  }), t.flushHeaders(), t.write("retry: 5000\n\n");
1402
- for (let e of f.buffered()) t.write(ve(e));
1403
- let a = f.subscribe((e) => {
1404
- t.write(ve(e));
1441
+ for (let e of l.buffered()) t.write(f(e));
1442
+ let i = l.subscribe((e) => {
1443
+ t.write(f(e));
1405
1444
  }), o = setInterval(() => {
1406
- t.write(me());
1445
+ t.write(M());
1407
1446
  }, 15e3), s = () => {
1408
- clearInterval(o), a();
1447
+ clearInterval(o), i();
1409
1448
  };
1410
1449
  e.on("close", s), t.on("close", s);
1411
1450
  return;
1412
1451
  }
1413
1452
  try {
1414
- let e = await Ot(n, i);
1415
- if (e.stream ? e.stream(t) : Ze({
1453
+ let e = await zt(n, a);
1454
+ if (e.stream ? e.stream(t) : lt({
1416
1455
  response: t,
1417
1456
  status: e.status,
1418
1457
  headers: e.headers,
1419
1458
  body: e.body,
1420
- requestHeaders: i,
1421
- compression: fe.compression
1422
- }) || (t.writeHead(e.status, e.headers), t.end(e.body)), !a.startsWith("/_voltro/inspect")) {
1423
- let t = Date.now() - r;
1424
- f.emit("request", {
1425
- 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,
1426
1465
  status: e.status,
1427
1466
  durationMs: t,
1428
1467
  renderedBy: e.headers["x-voltro-rendered-by"],
1429
1468
  cache: e.headers["x-voltro-cache"]
1430
1469
  });
1431
- let n = mt(a, K)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1432
- Ct.record({
1470
+ let n = wt(o, W)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
1471
+ Pt.record({
1433
1472
  kind: "request",
1434
1473
  tag: n,
1435
1474
  durationMs: t,
@@ -1441,77 +1480,77 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1441
1480
  }
1442
1481
  }
1443
1482
  });
1444
- await new Promise((e) => jt.listen(m, "::", e)), kt = !0, i.mark("ready"), Q.info(`listening on http://localhost:${m}`, {
1445
- port: m,
1446
- distDir: g
1447
- }), Q.debug("dynamic + ssr/isr routes resolve via SSR loader");
1483
+ await new Promise((e) => Ut.listen(p, "::", e)), Bt = !0, n.mark("ready"), tt(Ut, Ht), Y.info(`listening on http://localhost:${p}`, {
1484
+ port: p,
1485
+ distDir: h
1486
+ }), Y.debug("dynamic + ssr/isr routes resolve via SSR loader");
1448
1487
  try {
1449
- await Le({
1488
+ await Ve({
1450
1489
  id: C,
1451
- name: x,
1490
+ name: S,
1452
1491
  kind: "web",
1453
- url: `http://localhost:${m}`,
1492
+ url: `http://localhost:${p}`,
1454
1493
  pid: process.pid,
1455
1494
  status: "live",
1456
- logFile: w.path
1495
+ logFile: T.path
1457
1496
  });
1458
- let e = ce(t);
1497
+ let e = P(t);
1459
1498
  if (e) {
1460
- let t = await r({ dashboardAppPath: e });
1461
- t.status === "launched" ? Q.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && Q.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 });
1462
1501
  }
1463
1502
  setInterval(() => {
1464
- Le({
1503
+ Ve({
1465
1504
  id: C,
1466
- name: x,
1505
+ name: S,
1467
1506
  kind: "web",
1468
- url: `http://localhost:${m}`,
1507
+ url: `http://localhost:${p}`,
1469
1508
  pid: process.pid,
1470
1509
  status: "live",
1471
- logFile: w.path
1510
+ logFile: T.path
1472
1511
  }).catch(() => {});
1473
1512
  }, 1e4).unref();
1474
1513
  } catch (e) {
1475
- Q.warn("runtime-registry write failed", {}, e);
1514
+ Y.warn("runtime-registry write failed", {}, e);
1476
1515
  }
1477
- Ge({
1478
- app: o.name ?? "unnamed",
1516
+ Ze({
1517
+ app: r.name ?? "unnamed",
1479
1518
  kind: "web",
1480
- url: `http://localhost:${m}`,
1481
- bootMs: i.total()
1519
+ url: `http://localhost:${p}`,
1520
+ bootMs: n.total()
1482
1521
  });
1483
- let Mt = i.phaseBreakdown();
1484
- Q.info(`start: ready in ${i.total()}ms`, {
1485
- bootMs: i.total(),
1486
- ...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 } : {}
1487
1526
  });
1488
- let Nt = !1, Pt = (e) => async () => {
1489
- if (!Nt) {
1490
- if (Nt = !0, Q.info(`received ${e}, shutting down`, { signal: e }), jt.close(), await yt.stop(), xt) try {
1491
- xt();
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 {
1530
+ $();
1492
1531
  } catch {}
1493
- if (St) try {
1494
- await Ke.runPromise(St.close());
1532
+ if (Nt) try {
1533
+ await at.runPromise(Nt.close());
1495
1534
  } catch {}
1496
1535
  if (V) try {
1497
1536
  await V.end();
1498
1537
  } catch {}
1499
- await J.close(), await ze(C), await w.dispose(), process.exit(0);
1538
+ await K.close(), await Ue(C), await T.dispose(), process.exit(0);
1500
1539
  }
1501
1540
  };
1502
- process.on("SIGINT", Pt("SIGINT")), process.on("SIGTERM", Pt("SIGTERM"));
1503
- let Ft = process.ppid;
1504
- if (Ft > 1) {
1541
+ process.on("SIGINT", Kt("SIGINT")), process.on("SIGTERM", Kt("SIGTERM"));
1542
+ let qt = process.ppid;
1543
+ if (qt > 1) {
1505
1544
  let e = setInterval(() => {
1506
- (process.ppid !== Ft || process.ppid === 1) && (clearInterval(e), Pt("SIGTERM")());
1545
+ (process.ppid !== qt || process.ppid === 1) && (clearInterval(e), Kt("SIGTERM")());
1507
1546
  }, 2e3);
1508
1547
  e.unref();
1509
1548
  }
1510
1549
  return new Promise(() => {});
1511
- }, bt = async (e) => {
1512
- t("start");
1513
- let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await yt(Ue(n));
1514
- return r.ran ? r.exitCode : (Q.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);
1515
1554
  };
1516
1555
  //#endregion
1517
- export { yt as n, bt as t };
1556
+ export { jt as n, Mt as t };