@voltro/cli 0.20.2 → 0.22.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 (75) hide show
  1. package/CHANGELOG.md +398 -0
  2. package/THIRD-PARTY-NOTICES.md +61 -61
  3. package/dist/{apiBuild-qZBEu59d.js → apiBuild-2zRxj2hJ.js} +93 -80
  4. package/dist/apiBuild-sqNmWmY5.js +2 -0
  5. package/dist/bin.js +41 -20
  6. package/dist/{commands-kYbfVoPO.js → commands-DGaeTn2f.js} +3055 -2640
  7. package/dist/dbCommand-CO3eSAZR.js +2 -0
  8. package/dist/{dbCommand-BPp9R0Wc.js → dbCommand-DVASmZj2.js} +305 -249
  9. package/dist/dev-BEYBSGJ7.js +3 -0
  10. package/dist/{dev-OHLsAq4K.js → dev-DeHVUxQx.js} +1732 -1686
  11. package/dist/index.js +1 -1
  12. package/dist/inspect-BA67TF6v.js +2 -0
  13. package/dist/inspect-_ldwsAwH.js +945 -0
  14. package/dist/{inspectMetrics-DvPNXmGA.js → inspectMetrics-4AVPn6IS.js} +584 -571
  15. package/dist/{manifestBuild-P9yuCY2d.js → manifestBuild-Bs1Uw22_.js} +1 -1
  16. package/dist/manifestBuild-i-fRHg_H.js +2 -0
  17. package/dist/serveCommand-DEVTtnLy.js +1161 -0
  18. package/dist/serveEntry.js +2 -2
  19. package/dist/{start-CXQ7WL1W.js → start-BjGUIIvj.js} +389 -389
  20. package/dist/startEntry.js +2 -2
  21. package/package.json +27 -27
  22. package/templates/AGENTS.md +1 -1
  23. package/templates/agent-docs/_index.md +1 -1
  24. package/templates/agent-docs/cli.md +181 -5
  25. package/templates/agent-docs/data.md +58 -0
  26. package/templates/agent-docs/database/migrations.md +175 -31
  27. package/templates/agent-docs/database/schema.md +7 -0
  28. package/templates/agent-docs/database/seedsdialects.md +3 -3
  29. package/templates/agent-docs/plugins.md +1 -1
  30. package/templates/agent-docs/schema-driven-ui.md +2 -2
  31. package/templates/agent-docs/templates/apibackends.md +1 -1
  32. package/templates/agent-docs/whats-new.md +236 -9
  33. package/templates/apps/api-ai/package.json +12 -12
  34. package/templates/apps/api-auth/package.json +13 -13
  35. package/templates/apps/api-backend/package.json +12 -12
  36. package/templates/apps/api-backend-deactivation/package.json +12 -12
  37. package/templates/apps/api-backend-mail/package.json +11 -11
  38. package/templates/apps/api-backend-mariadb/package.json +14 -14
  39. package/templates/apps/api-backend-storage/package.json +11 -11
  40. package/templates/apps/api-data-advanced/package.json +13 -13
  41. package/templates/apps/api-durable/package.json +13 -13
  42. package/templates/apps/api-feature-flags/package.json +14 -14
  43. package/templates/apps/api-governance/package.json +13 -13
  44. package/templates/apps/api-kv/package.json +13 -13
  45. package/templates/apps/api-moderation/package.json +13 -13
  46. package/templates/apps/api-observability/package.json +13 -13
  47. package/templates/apps/api-ratelimit/package.json +13 -13
  48. package/templates/apps/api-rbac/package.json +13 -13
  49. package/templates/apps/api-rest/package.json +12 -12
  50. package/templates/apps/api-saas/package.json +16 -16
  51. package/templates/apps/api-search/package.json +13 -13
  52. package/templates/apps/api-versioning/package.json +13 -13
  53. package/templates/apps/api-webhooks/package.json +14 -14
  54. package/templates/apps/changelog/package.json +8 -8
  55. package/templates/apps/edge-functions/package.json +5 -5
  56. package/templates/apps/frontend-admin/package.json +10 -10
  57. package/templates/apps/frontend-app/package.json +10 -10
  58. package/templates/apps/frontend-blank/package.json +9 -9
  59. package/templates/apps/frontend-contact/package.json +11 -11
  60. package/templates/apps/frontend-dashboard/package.json +9 -9
  61. package/templates/apps/frontend-docs/package.json +9 -9
  62. package/templates/apps/frontend-i18n/package.json +8 -8
  63. package/templates/apps/frontend-landing/package.json +9 -9
  64. package/templates/apps/frontend-spa/package.json +9 -9
  65. package/templates/apps/frontend-ssr/package.json +9 -9
  66. package/templates/apps/frontend-ssr-api/package.json +10 -10
  67. package/templates/apps/frontend-static-blog/package.json +8 -8
  68. package/dist/apiBuild-C9aHz4Yh.js +0 -2
  69. package/dist/dbCommand-DtUe-0dM.js +0 -2
  70. package/dist/dev-2AvdzDg2.js +0 -3
  71. package/dist/inspect-DcZ04OME.js +0 -2
  72. package/dist/inspect-Dwx0_tUj.js +0 -921
  73. package/dist/manifestBuild-D1MzJAiQ.js +0 -2
  74. package/dist/serveCommand-BKqTKWTX.js +0 -1136
  75. /package/templates/patches/{@effect__cluster@0.59.0.patch → @effect__cluster@0.60.0.patch} +0 -0
@@ -1,14 +1,14 @@
1
- import { A as e, C as t, E as n, F as r, G as i, H as a, J as o, K as s, O as c, Q as l, R as u, Y as ee, Z as d, _ as te, a as f, at as p, b as m, c as h, f as g, ft as _, g as v, h as y, i as b, it as ne, j as x, k as re, lt as S, m as C, nt as ie, o as w, ot as T, p as E, q as D, r as O, rt as k, s as A, t as j, v as M, w as ae, y as N } from "./inspectMetrics-DvPNXmGA.js";
2
- import { D as oe, E as se, T as ce, a as P, p as le, w as ue } from "./inspect-Dwx0_tUj.js";
3
- import { t as de } from "./bootTiming-BdyP9nYw.js";
4
- import { dirname as fe, extname as F, join as I, resolve as L } from "node:path";
5
- import { fileURLToPath as R, pathToFileURL as z } from "node:url";
6
- import { createLogger as B, printReadyBlock as pe } from "@voltro/logger";
7
- import { promises as V } from "node:fs";
8
- import { snapshotMetricsSync as me } from "@voltro/runtime";
9
- import { createServer as he } from "node:http";
1
+ import { $ as e, C as t, E as n, G as r, H as i, J as a, P as o, Q as s, R as c, U as l, V as u, W as d, _ as f, a as p, at as m, b as ee, c as h, ct as g, dt as _, et as te, f as v, ft as y, g as ne, h as b, i as re, j as ie, m as x, nt as S, o as ae, p as C, pt as w, q as T, r as E, s as D, t as O, tt as k, ut as A, v as j, w as oe, y as M } from "./inspectMetrics-4AVPn6IS.js";
2
+ import { D as se, E as ce, T as le, a as N, p as ue, w as de } from "./inspect-_ldwsAwH.js";
3
+ import { t as fe } from "./bootTiming-BdyP9nYw.js";
4
+ import { dirname as pe, extname as P, join as F, resolve as I } from "node:path";
5
+ import { fileURLToPath as L, pathToFileURL as R } from "node:url";
6
+ import { createLogger as z, printReadyBlock as me } from "@voltro/logger";
7
+ import { promises as B } from "node:fs";
8
+ import { snapshotMetricsSync as he } from "@voltro/runtime";
9
+ import { createServer as ge } from "node:http";
10
10
  //#region src/isrCdcInvalidator.ts
11
- var H = B({ scope: "voltro:start:cdc" }), U = (e) => (t) => {
11
+ var V = z({ scope: "voltro:start:cdc" }), H = (e) => (t) => {
12
12
  let n = 0;
13
13
  for (let [r, i] of e.tableSubscriptionsByPattern) {
14
14
  if (!i.includes(t)) continue;
@@ -19,23 +19,23 @@ var H = B({ scope: "voltro:start:cdc" }), U = (e) => (t) => {
19
19
  }));
20
20
  }
21
21
  return n;
22
- }, W = () => !process.env.PG_HOST && !process.env.PG_DATABASE ? null : {
22
+ }, U = () => !process.env.PG_HOST && !process.env.PG_DATABASE ? null : {
23
23
  host: process.env.PG_HOST ?? "localhost",
24
24
  port: Number(process.env.PG_PORT ?? 5432),
25
25
  user: process.env.PG_USER ?? "app",
26
26
  password: process.env.PG_PASSWORD ?? "app",
27
27
  database: process.env.PG_DATABASE ?? "app"
28
- }, ge = (e) => {
29
- let t = e.channel ?? "framework_changes", n = U(e), r = null, i = null;
28
+ }, _e = (e) => {
29
+ let t = e.channel ?? "framework_changes", n = H(e), r = null, i = null;
30
30
  return {
31
31
  start: async () => {
32
- let a = W();
32
+ let a = U();
33
33
  if (!a) {
34
- H.debug("skipped — no PG_* env vars set");
34
+ V.debug("skipped — no PG_* env vars set");
35
35
  return;
36
36
  }
37
37
  if (e.tableSubscriptionsByPattern.size === 0) {
38
- H.debug("skipped — no pages declare cacheInvalidatesOn");
38
+ V.debug("skipped — no pages declare cacheInvalidatesOn");
39
39
  return;
40
40
  }
41
41
  r = new (await (import("pg"))).default.Client(a), await r.connect(), i = (e) => {
@@ -44,16 +44,16 @@ var H = B({ scope: "voltro:start:cdc" }), U = (e) => (t) => {
44
44
  try {
45
45
  r = JSON.parse(e.payload);
46
46
  } catch (e) {
47
- H.warn("bad CDC payload", {}, e);
47
+ V.warn("bad CDC payload", {}, e);
48
48
  return;
49
49
  }
50
50
  let i = n(r.table);
51
- i > 0 && H.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
51
+ i > 0 && V.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
52
52
  op: r.op,
53
53
  table: r.table,
54
54
  dropped: i
55
55
  });
56
- }, r.on("notification", i), await r.query(`LISTEN ${t}`), H.info(`LISTEN ${t}`, {
56
+ }, r.on("notification", i), await r.query(`LISTEN ${t}`), V.info(`LISTEN ${t}`, {
57
57
  channel: t,
58
58
  host: a.host,
59
59
  port: a.port,
@@ -69,7 +69,7 @@ var H = B({ scope: "voltro:start:cdc" }), U = (e) => (t) => {
69
69
  }
70
70
  }
71
71
  };
72
- }, G = B({ scope: "voltro:start:isr-cache" }), K = "voltro_isr_cache", _e = (e) => `
72
+ }, W = z({ scope: "voltro:start:isr-cache" }), G = "voltro_isr_cache", ve = (e) => `
73
73
  CREATE TABLE IF NOT EXISTS ${e} (
74
74
  cache_key TEXT PRIMARY KEY,
75
75
  html TEXT NOT NULL,
@@ -80,9 +80,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
80
80
  stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
81
81
  );
82
82
  CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
83
- `, ve = (e) => {
84
- let t = e.tableName ?? K, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
85
- i || (i = !0, await n.query(_e(t)));
83
+ `, ye = (e) => {
84
+ let t = e.tableName ?? G, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
85
+ i || (i = !0, await n.query(ve(t)));
86
86
  })().then(async () => {
87
87
  let e = await n.query(`SELECT * FROM ${t}`);
88
88
  for (let t of e.rows) r.set(t.cache_key, {
@@ -94,10 +94,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
94
94
  staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
95
95
  });
96
96
  }).catch((e) => {
97
- G.warn("postgres bootstrap failed", {}, e);
97
+ W.warn("postgres bootstrap failed", {}, e);
98
98
  }), o = (e, t) => {
99
99
  a.then(() => n.query(e, t)).catch((e) => {
100
- G.warn("postgres write failed", {}, e);
100
+ W.warn("postgres write failed", {}, e);
101
101
  });
102
102
  };
103
103
  return {
@@ -142,14 +142,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
142
142
  return Array.from(r.entries());
143
143
  }
144
144
  };
145
- }, q = B({ scope: "voltro:start" }), ye = await (async () => {
145
+ }, K = z({ scope: "voltro:start" }), be = await (async () => {
146
146
  try {
147
- let e = I(fe(R(import.meta.url)), "..", "package.json"), t = await V.readFile(e, "utf8");
147
+ let e = F(pe(L(import.meta.url)), "..", "package.json"), t = await B.readFile(e, "utf8");
148
148
  return JSON.parse(t).version ?? "0.0.0";
149
149
  } catch {
150
150
  return "0.0.0";
151
151
  }
152
- })(), J = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", be = (e) => e instanceof Error && e._voltroControl === "not-found", Y = {
152
+ })(), q = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", xe = (e) => e instanceof Error && e._voltroControl === "not-found", J = {
153
153
  ".html": "text/html; charset=utf-8",
154
154
  ".js": "application/javascript",
155
155
  ".mjs": "application/javascript",
@@ -167,13 +167,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
167
167
  ".woff": "font/woff",
168
168
  ".woff2": "font/woff2",
169
169
  ".txt": "text/plain; charset=utf-8"
170
- }, xe = (e) => Y[F(e).toLowerCase()] ?? "application/octet-stream", X = (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) => {
170
+ }, Se = (e) => J[P(e).toLowerCase()] ?? "application/octet-stream", Y = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), X = async (e) => {
171
171
  try {
172
- return await V.stat(e), !0;
172
+ return await B.stat(e), !0;
173
173
  } catch {
174
174
  return !1;
175
175
  }
176
- }, Q = (e) => {
176
+ }, Z = (e) => {
177
177
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
178
178
  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, "\\$&"));
179
179
  let a = i.join("/");
@@ -182,8 +182,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
182
182
  paramNames: t,
183
183
  priority: n
184
184
  };
185
- }, Se = (e) => e.map((e) => {
186
- let { regex: t, paramNames: n, priority: r } = Q(e.pattern);
185
+ }, Ce = (e) => e.map((e) => {
186
+ let { regex: t, paramNames: n, priority: r } = Z(e.pattern);
187
187
  return {
188
188
  pattern: e.pattern,
189
189
  file: e.file,
@@ -192,7 +192,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
192
192
  paramNames: n,
193
193
  priority: r
194
194
  };
195
- }).slice().sort((e, t) => e.priority - t.priority), Ce = (e, t) => {
195
+ }).slice().sort((e, t) => e.priority - t.priority), we = (e, t) => {
196
196
  for (let n of t) {
197
197
  let t = n.regex.exec(e);
198
198
  if (!t) continue;
@@ -204,81 +204,81 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
204
204
  };
205
205
  }
206
206
  return null;
207
- }, we = async (e) => {
208
- let { provider: t, route: n, params: r, pathname: i, dirs: a, shellTemplate: o, requestHeaders: s, requestUrl: c = "", apiOrigin: l, apiName: ee } = e, d = b(l, s.cookie, { apiName: ee }), p = await t.getPage(n.pattern, n.file), h = u(p, n.file), g = h === "spa" && w(a, n.dirChain).some((e) => e.hasLayout);
209
- if (h !== "ssr" && h !== "isr" && !g) return null;
210
- let _ = w(a, n.dirChain), v = {}, ne = null, x, re = new AbortController();
207
+ }, Te = async (e) => {
208
+ let { provider: t, route: n, params: r, pathname: i, dirs: a, shellTemplate: s, requestHeaders: c, requestUrl: l = "", apiOrigin: u, apiName: d } = e, m = re(u, c.cookie, { apiName: d }), h = await t.getPage(n.pattern, n.file), g = o(h, n.file), _ = g === "spa" && ae(a, n.dirChain).some((e) => e.hasLayout);
209
+ if (g !== "ssr" && g !== "isr" && !_) return null;
210
+ let te = ae(a, n.dirChain), v = {}, y = null, ne, ie = new AbortController();
211
211
  try {
212
- (await t.getHelpers()).beginStoreSeeds(), {chain: x, segmentLoaderData: v} = await f({
213
- entries: _,
212
+ (await t.getHelpers()).beginStoreSeeds(), {chain: ne, segmentLoaderData: v} = await p({
213
+ entries: te,
214
214
  loadLayout: (e) => t.getLayout(e.dir),
215
215
  loadError: (e) => t.getError(e.dir),
216
216
  loadPending: (e) => t.getPending(e.dir),
217
217
  ctx: {
218
218
  params: r,
219
219
  pathname: i,
220
- signal: re.signal,
221
- headers: s,
222
- query: d
220
+ signal: ie.signal,
221
+ headers: c,
222
+ query: m
223
223
  }
224
- }), typeof p.loader == "function" && !g && (ne = await p.loader({
224
+ }), typeof h.loader == "function" && !_ && (y = await h.loader({
225
225
  params: r,
226
226
  pathname: i,
227
- signal: re.signal,
228
- headers: s,
229
- query: d
227
+ signal: ie.signal,
228
+ headers: c,
229
+ query: m
230
230
  }));
231
231
  } catch (e) {
232
- if (J(e)) return {
232
+ if (q(e)) return {
233
233
  control: "redirect",
234
234
  status: e.status,
235
235
  location: e.location
236
236
  };
237
- if (be(e)) return { control: "not-found" };
237
+ if (xe(e)) return { control: "not-found" };
238
238
  throw e;
239
239
  }
240
- let S = await t.getHelpers(), ie = {
240
+ let C = await t.getHelpers(), w = {
241
241
  pattern: n.pattern,
242
- Component: p.default,
243
- meta: p.meta,
244
- loader: p.loader,
245
- ErrorBoundary: p.ErrorBoundary,
246
- Pending: p.Pending,
247
- renderMode: h,
248
- chain: x
249
- }, E = {
250
- cookies: S.parseCookieHeader(s.cookie),
251
- headers: s,
252
- url: c
253
- }, D = S.i18n?.resolve(s.cookie, s["accept-language"]), O = p.interactive ?? "full";
254
- if (g) {
255
- let e = M({
256
- helpers: S,
242
+ Component: h.default,
243
+ meta: h.meta,
244
+ loader: h.loader,
245
+ ErrorBoundary: h.ErrorBoundary,
246
+ Pending: h.Pending,
247
+ renderMode: g,
248
+ chain: ne
249
+ }, T = {
250
+ cookies: C.parseCookieHeader(c.cookie),
251
+ headers: c,
252
+ url: l
253
+ }, E = C.i18n?.resolve(c.cookie, c["accept-language"]), D = h.interactive ?? "full";
254
+ if (_) {
255
+ let e = j({
256
+ helpers: C,
257
257
  page: n.pattern,
258
- interactive: O,
258
+ interactive: D,
259
259
  delivery: "stream",
260
260
  renderInput: {
261
- descriptor: ie,
261
+ descriptor: w,
262
262
  params: r,
263
263
  pathname: i,
264
264
  segmentLoaderData: v,
265
- requestContext: E,
266
- ...D ? {
267
- outerWrap: D.outerWrap,
268
- locale: D.locale
265
+ requestContext: T,
266
+ ...E ? {
267
+ outerWrap: E.outerWrap,
268
+ locale: E.locale
269
269
  } : {}
270
270
  }
271
- }), t = D?.locale ?? E.cookies["voltro:lang"] ?? "en", a = (t) => m({
272
- helpers: S,
271
+ }), t = E?.locale ?? T.cookies["voltro:lang"] ?? "en", a = (t) => ee({
272
+ helpers: C,
273
273
  prepared: e,
274
274
  meta: t,
275
- interactive: O
275
+ interactive: D
276
276
  });
277
277
  if (e.hasDeferred) {
278
- let n = C({ shell: o });
278
+ let n = x({ shell: s });
279
279
  return {
280
280
  renderMode: "spa",
281
- stream: (r) => y({
281
+ stream: (r) => b({
282
282
  res: r,
283
283
  shell: n,
284
284
  htmlLang: t,
@@ -287,57 +287,57 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
287
287
  "x-voltro-rendered-by": "spa"
288
288
  },
289
289
  headInjection: a,
290
- render: (t) => S.renderPageToStream({
290
+ render: (t) => C.renderPageToStream({
291
291
  ...e.renderInput,
292
292
  ...t
293
293
  }),
294
294
  onShellError: (e) => {
295
- q.error("spa layout shell render failed", { pathname: i }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
295
+ K.error("spa layout shell render failed", { pathname: i }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
296
296
  }
297
297
  })
298
298
  };
299
299
  }
300
- let s = N({
301
- helpers: S,
300
+ let o = M({
301
+ helpers: C,
302
302
  prepared: e
303
303
  });
304
304
  return {
305
- html: o.replace("<div id=\"root\"></div>", `<div id="root">${s.body}</div>`).replace("</head>", ` ${a(s.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${t}"`),
305
+ html: s.replace("<div id=\"root\"></div>", `<div id="root">${o.body}</div>`).replace("</head>", ` ${a(o.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${t}"`),
306
306
  renderMode: "spa",
307
307
  revalidateMs: null
308
308
  };
309
309
  }
310
- let k = te({
311
- helpers: S,
310
+ let O = f({
311
+ helpers: C,
312
312
  page: n.pattern,
313
313
  pathname: i,
314
- renderMode: h,
315
- interactive: O,
316
- loaderData: ne,
314
+ renderMode: g,
315
+ interactive: D,
316
+ loaderData: y,
317
317
  segmentLoaderData: v,
318
- pageLoaderRan: typeof p.loader == "function"
319
- }), A = {
320
- descriptor: ie,
318
+ pageLoaderRan: typeof h.loader == "function"
319
+ }), k = {
320
+ descriptor: w,
321
321
  params: r,
322
322
  pathname: i,
323
- loaderData: k.loaderData,
324
- segmentLoaderData: k.segmentLoaderData,
325
- requestContext: E,
326
- ...D ? {
327
- outerWrap: D.outerWrap,
328
- locale: D.locale
323
+ loaderData: O.loaderData,
324
+ segmentLoaderData: O.segmentLoaderData,
325
+ requestContext: T,
326
+ ...E ? {
327
+ outerWrap: E.outerWrap,
328
+ locale: E.locale
329
329
  } : {}
330
- }, j = (e) => [
331
- S.renderMetaToHtml(e),
332
- `<meta name="voltro-interactive" content="${O}" />`,
333
- ...k.hasDeferred ? [S.renderDeferredRegistryScript()] : [],
334
- S.renderRouterStateScript(k.stateInput)
330
+ }, A = (e) => [
331
+ C.renderMetaToHtml(e),
332
+ `<meta name="voltro-interactive" content="${D}" />`,
333
+ ...O.hasDeferred ? [C.renderDeferredRegistryScript()] : [],
334
+ C.renderRouterStateScript(O.stateInput)
335
335
  ].filter((e) => e.length > 0).join("\n ");
336
- if (h === "ssr" && O === "full" && e.buffered !== !0) {
337
- let e = D?.locale ?? E.cookies["voltro:lang"] ?? "en", t = C({ shell: o });
336
+ if (g === "ssr" && D === "full" && e.buffered !== !0) {
337
+ let e = E?.locale ?? T.cookies["voltro:lang"] ?? "en", t = x({ shell: s });
338
338
  return {
339
339
  renderMode: "ssr",
340
- stream: (n) => y({
340
+ stream: (n) => b({
341
341
  res: n,
342
342
  shell: t,
343
343
  htmlLang: e,
@@ -345,27 +345,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
345
345
  "content-type": "text/html; charset=utf-8",
346
346
  "x-voltro-rendered-by": "ssr"
347
347
  },
348
- headInjection: j,
349
- render: (e) => S.renderPageToStream({
350
- ...A,
348
+ headInjection: A,
349
+ render: (e) => C.renderPageToStream({
350
+ ...k,
351
351
  ...e
352
352
  }),
353
353
  onShellError: (e) => {
354
- q.error("ssr shell render failed", { pathname: i }, e), n.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), n.end("server error");
354
+ K.error("ssr shell render failed", { pathname: i }, e), n.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), n.end("server error");
355
355
  }
356
356
  })
357
357
  };
358
358
  }
359
- let { html: ae, meta: oe } = S.renderPageToHtml(A), se = j(oe), ce = D?.locale ?? E.cookies["voltro:lang"] ?? "en", P = o.replace("<div id=\"root\"></div>", `<div id="root">${ae}</div>`).replace("</head>", ` ${se}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${ce}"`);
360
- O === "none" && (P = X(P));
361
- let le = h === "isr" ? T(p.revalidate) : null;
359
+ let { html: oe, meta: se } = C.renderPageToHtml(k), ce = A(se), le = E?.locale ?? T.cookies["voltro:lang"] ?? "en", N = s.replace("<div id=\"root\"></div>", `<div id="root">${oe}</div>`).replace("</head>", ` ${ce}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${le}"`);
360
+ D === "none" && (N = Y(N));
361
+ let ue = g === "isr" ? S(h.revalidate) : null;
362
362
  return {
363
- html: P,
364
- renderMode: h,
365
- revalidateMs: le
363
+ html: N,
364
+ renderMode: g,
365
+ revalidateMs: ue
366
366
  };
367
- }, $ = (e) => e === "" ? "/" : e, Te = async (e) => {
368
- let t = await import(z(e).href);
367
+ }, Q = (e) => e === "" ? "/" : e, Ee = async (e) => {
368
+ let t = await import(R(e).href);
369
369
  return {
370
370
  kind: "bundle",
371
371
  getPageMeta: () => t.pageMeta,
@@ -375,18 +375,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
375
375
  return typeof r == "function" ? await r() : r;
376
376
  },
377
377
  async getLayout(e) {
378
- let n = t.layouts[$(e)];
379
- if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${$(e)}`);
378
+ let n = t.layouts[Q(e)];
379
+ if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${Q(e)}`);
380
380
  return typeof n == "function" ? await n() : n;
381
381
  },
382
382
  async getError(e) {
383
- let n = t.errors[$(e)];
384
- if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${$(e)}`);
383
+ let n = t.errors[Q(e)];
384
+ if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${Q(e)}`);
385
385
  return typeof n == "function" ? await n() : n;
386
386
  },
387
387
  async getPending(e) {
388
- let n = t.pendings[$(e)];
389
- if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${$(e)}`);
388
+ let n = t.pendings[Q(e)];
389
+ if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${Q(e)}`);
390
390
  return typeof n == "function" ? await n() : n;
391
391
  },
392
392
  async getHelpers() {
@@ -394,8 +394,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
394
394
  },
395
395
  async close() {}
396
396
  };
397
- }, Ee = async (e, t) => {
398
- let n = await _("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
397
+ }, De = async (e, t) => {
398
+ let n = await g("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, o = await n.createServer({
399
399
  root: t,
400
400
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
401
401
  plugins: [r(), i()],
@@ -407,129 +407,129 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
407
407
  },
408
408
  appType: "custom",
409
409
  logLevel: "warn"
410
- }), o = I(e, "src", "pages"), s = (e) => e === "" ? o : I(o, e), c = d({
411
- limit: l(),
412
- onColdStart: (e) => q.debug("ssr cold-compile start", { id: e }),
413
- onColdEnd: (e, { durationMs: t, failed: n }) => q.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
410
+ }), s = F(e, "src", "pages"), c = (e) => e === "" ? s : F(s, e), l = T({
411
+ limit: a(),
412
+ onColdStart: (e) => K.debug("ssr cold-compile start", { id: e }),
413
+ onColdEnd: (e, { durationMs: t, failed: n }) => K.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
414
414
  id: e,
415
415
  ms: t,
416
416
  ...n ? { failed: !0 } : {}
417
417
  })
418
- }), u = (e) => c.load(e, async () => await a.ssrLoadModule(e));
418
+ }), u = (e) => l.load(e, async () => await o.ssrLoadModule(e));
419
419
  return {
420
420
  kind: "middleware",
421
421
  async getPage(e, t) {
422
- return u(I(o, t));
422
+ return u(F(s, t));
423
423
  },
424
424
  async getLayout(e) {
425
- return u(I(s(e), "layout.tsx"));
425
+ return u(F(c(e), "layout.tsx"));
426
426
  },
427
427
  async getError(e) {
428
- return u(I(s(e), "error.tsx"));
428
+ return u(F(c(e), "error.tsx"));
429
429
  },
430
430
  async getPending(e) {
431
- return u(I(s(e), "loading.tsx"));
431
+ return u(F(c(e), "loading.tsx"));
432
432
  },
433
433
  async getHelpers() {
434
434
  return await u("@voltro/web/ssr");
435
435
  },
436
436
  async close() {
437
- await a.close();
437
+ await o.close();
438
438
  }
439
439
  };
440
- }, De = async (l) => {
441
- let u = de(), d = await A(l);
442
- if (!d) return {
440
+ }, Oe = async (a) => {
441
+ let o = fe(), f = await D(a);
442
+ if (!f) return {
443
443
  ran: !1,
444
444
  exitCode: 0
445
445
  };
446
- if (d.type !== "web") return q.error("only web apps are supported by `voltro start`"), {
446
+ if (f.type !== "web") return K.error("only web apps are supported by `voltro start`"), {
447
447
  ran: !0,
448
448
  exitCode: 1
449
449
  };
450
- let { resolved: te } = await S({
451
- rawEnv: d.env,
450
+ let { resolved: p } = await m({
451
+ rawEnv: f.env,
452
452
  appType: "web",
453
- root: l,
454
- log: q,
453
+ root: a,
454
+ log: K,
455
455
  generateTypes: !1
456
- }), f = te.publicValues;
457
- u.mark("config");
458
- let m = o();
459
- i(m), q.info("booting voltro start", { app: d.name ?? "(unnamed)" });
460
- let _ = (() => {
456
+ }), ee = p.publicValues;
457
+ o.mark("config");
458
+ let g = d();
459
+ u(g), K.info("booting voltro start", { app: f.name ?? "(unnamed)" });
460
+ let b = (() => {
461
461
  if (process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT) return Number(process.env.VOLTRO_DASHBOARD_PORT);
462
462
  if (process.env.PORT) {
463
463
  let e = Number(process.env.PORT);
464
464
  if (Number.isFinite(e) && e > 0) return e;
465
465
  }
466
- return d.port ?? 5173;
467
- })(), y = I(l, ".framework"), b = I(y, "dist"), C = I(b, "index.html");
468
- if (!await Z(C)) return q.error("no built dist found — run `voltro build` first", { distDir: b }), {
466
+ return f.port ?? 5173;
467
+ })(), re = F(a, ".framework"), x = F(re, "dist"), S = F(x, "index.html");
468
+ if (!await X(S)) return K.error("no built dist found — run `voltro build` first", { distDir: x }), {
469
469
  ran: !0,
470
470
  exitCode: 1
471
471
  };
472
- let T = d.name ?? "unnamed", M = c("web", T, _), N = n(T);
473
- await x({
474
- id: M,
472
+ let T = f.name ?? "unnamed", j = A("web", T, b), M = n(T);
473
+ await w({
474
+ id: j,
475
475
  name: T,
476
476
  kind: "web",
477
- url: `http://localhost:${_}`,
477
+ url: `http://localhost:${b}`,
478
478
  pid: process.pid,
479
479
  status: "booting",
480
- logFile: N.path
480
+ logFile: M.path
481
481
  }).catch(() => {});
482
- let fe = I(b, "_voltro", "shell.html"), F = await Z(fe) ? await V.readFile(fe, "utf8") : await V.readFile(C, "utf8"), L = await h(l, d), R = O(L[0]), z = L[0]?.name, B, H = null;
483
- process.env.SSR_CACHE === "postgres" && process.env.PG_HOST ? (H = new (await (import("pg"))).default.Client({
482
+ let pe = F(x, "_voltro", "shell.html"), P = await X(pe) ? await B.readFile(pe, "utf8") : await B.readFile(S, "utf8"), I = await h(a, f), L = E(I[0]), R = I[0]?.name, z, V = null;
483
+ process.env.SSR_CACHE === "postgres" && process.env.PG_HOST ? (V = new (await (import("pg"))).default.Client({
484
484
  host: process.env.PG_HOST,
485
485
  port: Number(process.env.PG_PORT ?? 5432),
486
486
  user: process.env.PG_USER ?? "app",
487
487
  password: process.env.PG_PASSWORD ?? "app",
488
488
  database: process.env.PG_DATABASE ?? "app"
489
- }), await H.connect(), B = ve({ client: H }), q.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (B = p(), q.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await E(l, d, L, f);
490
- let { pages: U, dirs: W } = await g(I(l, "src", "pages")), G = Se(U);
491
- u.mark("scan");
492
- let K = I(b, "server", "ssrEntry.js"), _e = await Z(K);
493
- if (!_e && process.env.NODE_ENV === "production") throw q.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${K} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${K}`);
494
- let J = _e ? await Te(K) : await Ee(l, y);
495
- q.info(`ssr loader: ${J.kind}`, {
496
- kind: J.kind,
497
- ...J.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
498
- }), u.mark("provider");
499
- let be = J.getPageMeta?.(), Y = /* @__PURE__ */ new Map(), X = 0;
500
- for (let e of U) {
501
- let t = be?.[e.pattern];
489
+ }), await V.connect(), z = ye({ client: V }), K.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (z = k(), K.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await C(a, f, I, ee);
490
+ let { pages: H, dirs: U } = await v(F(a, "src", "pages")), W = Ce(H);
491
+ o.mark("scan");
492
+ let G = F(x, "server", "ssrEntry.js"), ve = await X(G);
493
+ if (!ve && process.env.NODE_ENV === "production") throw K.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}`);
494
+ let q = ve ? await Ee(G) : await De(a, re);
495
+ K.info(`ssr loader: ${q.kind}`, {
496
+ kind: q.kind,
497
+ ...q.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
498
+ }), o.mark("provider");
499
+ let xe = q.getPageMeta?.(), J = /* @__PURE__ */ new Map(), Y = 0;
500
+ for (let e of H) {
501
+ let t = xe?.[e.pattern];
502
502
  if (t) {
503
- Y.set(e.pattern, t);
503
+ J.set(e.pattern, t);
504
504
  continue;
505
505
  }
506
506
  try {
507
- let t = await J.getPage(e.pattern, e.file);
508
- Y.set(e.pattern, r(t, e.file)), X++;
507
+ let t = await q.getPage(e.pattern, e.file);
508
+ J.set(e.pattern, ie(t, e.file)), Y++;
509
509
  } catch (t) {
510
- q.warn("failed to load page metadata", { pattern: e.pattern }, t);
510
+ K.warn("failed to load page metadata", { pattern: e.pattern }, t);
511
511
  }
512
512
  }
513
- q.info(`registered ${Y.size} route(s)`, {
514
- count: Y.size,
515
- fromManifest: Y.size - X,
516
- fromModules: X
517
- }), u.mark("routes");
518
- let Q = /* @__PURE__ */ new Set();
519
- for (let e of G) Y.get(e.pattern)?.renderMode === "spa" && w(W, e.dirChain).some((e) => e.hasLayout) && Q.add(e.pattern);
520
- Q.size > 0 && q.info(`${Q.size} spa route(s) render an SSR layout shell`, { patterns: [...Q] });
521
- let $ = /* @__PURE__ */ new Map();
522
- for (let [e, t] of Y) t.cacheInvalidatesOn.length > 0 && $.set(e, t.cacheInvalidatesOn);
523
- let De = /* @__PURE__ */ new Map();
524
- for (let e of G) De.set(e.pattern, e.regex);
525
- let Oe = ge({
526
- cache: B,
527
- tableSubscriptionsByPattern: $,
528
- regexByPattern: De
513
+ K.info(`registered ${J.size} route(s)`, {
514
+ count: J.size,
515
+ fromManifest: J.size - Y,
516
+ fromModules: Y
517
+ }), o.mark("routes");
518
+ let Z = /* @__PURE__ */ new Set();
519
+ for (let e of W) J.get(e.pattern)?.renderMode === "spa" && ae(U, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
520
+ Z.size > 0 && K.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
521
+ let Q = /* @__PURE__ */ new Map();
522
+ for (let [e, t] of J) t.cacheInvalidatesOn.length > 0 && Q.set(e, t.cacheInvalidatesOn);
523
+ let Oe = /* @__PURE__ */ new Map();
524
+ for (let e of W) Oe.set(e.pattern, e.regex);
525
+ let ke = _e({
526
+ cache: z,
527
+ tableSubscriptionsByPattern: Q,
528
+ regexByPattern: Oe
529
529
  });
530
- await Oe.start(), u.mark("cdc");
531
- let ke = j(), Ae = U.map((e) => {
532
- let t = Y.get(e.pattern);
530
+ await ke.start(), o.mark("cdc");
531
+ let Ae = O(), je = H.map((e) => {
532
+ let t = J.get(e.pattern);
533
533
  return {
534
534
  pattern: e.pattern,
535
535
  file: e.file,
@@ -544,20 +544,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
544
544
  hasMeta: t?.hasMeta ?? !1,
545
545
  hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
546
546
  };
547
- }), je = W.map((e) => ({
547
+ }), Me = U.map((e) => ({
548
548
  dir: e.dir,
549
549
  hasLayout: e.hasLayout,
550
550
  hasError: e.hasError,
551
551
  hasPending: e.hasPending,
552
552
  hasNotFound: e.hasNotFound
553
- })), Me = H ? "postgres" : "memory", Ne = {
553
+ })), Ne = V ? "postgres" : "memory", Pe = {
554
554
  kind: "web",
555
555
  meta: {
556
- name: d.name ?? "(unnamed)",
557
- voltroVersion: ye,
558
- port: _,
556
+ name: f.name ?? "(unnamed)",
557
+ voltroVersion: be,
558
+ port: b,
559
559
  mode: "start",
560
- apis: Object.entries(d.apis ?? {}).map(([e, t]) => {
560
+ apis: Object.entries(f.apis ?? {}).map(([e, t]) => {
561
561
  let n = {
562
562
  name: e,
563
563
  package: t.package
@@ -565,10 +565,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
565
565
  return t.url !== void 0 && (n.url = t.url), n;
566
566
  })
567
567
  },
568
- routes: Ae,
569
- dirs: je,
568
+ routes: je,
569
+ dirs: Me,
570
570
  cache: () => {
571
- let e = Date.now(), t = B.snapshot().map(([t, n]) => ({
571
+ let e = Date.now(), t = z.snapshot().map(([t, n]) => ({
572
572
  key: t,
573
573
  renderedAt: n.renderedAt,
574
574
  expiresAt: n.expiresAt,
@@ -579,16 +579,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
579
579
  staleWhileRevalidateMs: n.staleWhileRevalidateMs
580
580
  }));
581
581
  return {
582
- backend: Me,
583
- size: B.size(),
582
+ backend: Ne,
583
+ size: z.size(),
584
584
  entries: t
585
585
  };
586
586
  },
587
- metrics: () => me()
588
- }, Pe = async (e, t) => {
589
- let n = e.split("?")[0] ?? "/";
590
- if (d.name === "voltroDashboard" && n === "/api/dashboard/registry") try {
591
- let e = await re();
587
+ metrics: () => he()
588
+ }, Fe = async (t, n) => {
589
+ let r = t.split("?")[0] ?? "/";
590
+ if (f.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
591
+ let e = await _();
592
592
  return {
593
593
  status: 200,
594
594
  headers: { "content-type": "application/json; charset=utf-8" },
@@ -601,7 +601,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
601
601
  body: `registry read error: ${e.message}`
602
602
  };
603
603
  }
604
- if (d.name === "voltroDashboard" && n === "/api/dashboard/config") {
604
+ if (f.name === "voltroDashboard" && r === "/api/dashboard/config") {
605
605
  let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
606
606
  if (e && e.trim().length > 0) {
607
607
  let n;
@@ -630,103 +630,103 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
630
630
  body: JSON.stringify({ apps: t })
631
631
  };
632
632
  }
633
- if (n === "/_voltro/inspect/logs") {
634
- let n = a(e, s(), t);
633
+ if (r === "/_voltro/inspect/logs") {
634
+ let e = c(t, i(), n);
635
635
  return {
636
- status: n.status,
636
+ status: e.status,
637
637
  headers: {
638
- "content-type": n.contentType,
639
- ...ue(t.origin)
638
+ "content-type": e.contentType,
639
+ ...de(n.origin)
640
640
  },
641
- body: n.body
641
+ body: e.body
642
642
  };
643
643
  }
644
- if (n !== "/_voltro/inspect/stream") {
645
- let n = le(e, Ne, t);
646
- if (n !== null) return {
647
- status: n.status,
644
+ if (r !== "/_voltro/inspect/stream") {
645
+ let e = ue(t, Pe, n);
646
+ if (e !== null) return {
647
+ status: e.status,
648
648
  headers: {
649
- "content-type": n.contentType,
650
- ...n.headers ?? {}
649
+ "content-type": e.contentType,
650
+ ...e.headers ?? {}
651
651
  },
652
- body: n.body
652
+ body: e.body
653
653
  };
654
654
  }
655
- let r = Ce(n, G), i = r ? Y.get(r.route.pattern)?.renderMode : void 0, o = i === "ssr" || i === "isr" || (r ? Q.has(r.route.pattern) : !1), c = n === "/" ? I(b, "index.html") : I(b, n.replace(/^\//, ""), "index.html");
656
- if (!o && await Z(c)) return {
655
+ let o = we(r, W), l = o ? J.get(o.route.pattern)?.renderMode : void 0, u = l === "ssr" || l === "isr" || (o ? Z.has(o.route.pattern) : !1), d = r === "/" ? F(x, "index.html") : F(x, r.replace(/^\//, ""), "index.html");
656
+ if (!u && await X(d)) return {
657
657
  status: 200,
658
658
  headers: { "content-type": "text/html; charset=utf-8" },
659
- body: await V.readFile(c)
659
+ body: await B.readFile(d)
660
660
  };
661
- if (/\.[a-z0-9]+$/i.test(n)) {
662
- let e = I(b, n.replace(/^\//, ""));
663
- if (await Z(e)) {
664
- let t = await V.readFile(e);
661
+ if (/\.[a-z0-9]+$/i.test(r)) {
662
+ let e = F(x, r.replace(/^\//, ""));
663
+ if (await X(e)) {
664
+ let t = await B.readFile(e);
665
665
  return {
666
666
  status: 200,
667
- headers: { "content-type": xe(e) },
667
+ headers: { "content-type": Se(e) },
668
668
  body: t
669
669
  };
670
670
  }
671
671
  }
672
- let u = Ce(n, G);
673
- if (!u) return {
672
+ let p = we(r, W);
673
+ if (!p) return {
674
674
  status: 404,
675
675
  headers: { "content-type": "text/plain" },
676
676
  body: "not found"
677
677
  };
678
- let ee = Y.get(u.route.pattern), te = t["x-tenant"] ?? "anonymous", f = (await J.getHelpers()).i18n?.resolve(t.cookie, t["accept-language"])?.locale, p = ie(n, {
679
- ...ee?.tenantAware ? { tenant: te } : {},
680
- ...f ? { locale: f } : {}
681
- }), h = B.get(p), g = Date.now();
682
- if (h && k(h, g)) return m.emit("cache", {
678
+ let m = J.get(p.route.pattern), ee = n["x-tenant"] ?? "anonymous", h = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, v = s(r, {
679
+ ...m?.tenantAware ? { tenant: ee } : {},
680
+ ...h ? { locale: h } : {}
681
+ }), y = z.get(v), b = Date.now();
682
+ if (y && e(y, b)) return g.emit("cache", {
683
683
  kind: "HIT",
684
- key: p,
685
- ageMs: g - h.renderedAt
684
+ key: v,
685
+ ageMs: b - y.renderedAt
686
686
  }), {
687
687
  status: 200,
688
688
  headers: {
689
689
  "content-type": "text/html; charset=utf-8",
690
690
  "x-voltro-rendered-by": "isr",
691
691
  "x-voltro-cache": "HIT",
692
- "x-voltro-cache-key": p,
693
- "x-voltro-cache-age-ms": String(g - h.renderedAt)
692
+ "x-voltro-cache-key": v,
693
+ "x-voltro-cache-age-ms": String(b - y.renderedAt)
694
694
  },
695
- body: h.html
695
+ body: y.html
696
696
  };
697
- if (h && ne(h, g)) return m.emit("cache", {
697
+ if (y && te(y, b)) return g.emit("cache", {
698
698
  kind: "STALE",
699
- key: p,
700
- ageMs: g - h.renderedAt
699
+ key: v,
700
+ ageMs: b - y.renderedAt
701
701
  }), (async () => {
702
702
  try {
703
- let r = await we({
704
- provider: J,
705
- root: l,
706
- route: u.route,
707
- params: u.params,
708
- pathname: n,
709
- dirs: W,
710
- shellTemplate: F,
711
- requestHeaders: t,
712
- apiOrigin: R,
713
- apiName: z,
714
- requestUrl: e,
703
+ let e = await Te({
704
+ provider: q,
705
+ root: a,
706
+ route: p.route,
707
+ params: p.params,
708
+ pathname: r,
709
+ dirs: U,
710
+ shellTemplate: P,
711
+ requestHeaders: n,
712
+ apiOrigin: L,
713
+ apiName: R,
714
+ requestUrl: t,
715
715
  buffered: !0
716
716
  });
717
- if (r && "html" in r && r.renderMode === "isr" && r.revalidateMs !== null) {
718
- let e = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
719
- B.set(p, {
720
- html: r.html,
721
- renderedAt: t,
722
- expiresAt: t + r.revalidateMs,
723
- servableUntil: t + r.revalidateMs + e,
724
- revalidateMs: r.revalidateMs,
725
- staleWhileRevalidateMs: e
717
+ if (e && "html" in e && e.renderMode === "isr" && e.revalidateMs !== null) {
718
+ let t = J.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0, n = Date.now();
719
+ z.set(v, {
720
+ html: e.html,
721
+ renderedAt: n,
722
+ expiresAt: n + e.revalidateMs,
723
+ servableUntil: n + e.revalidateMs + t,
724
+ revalidateMs: e.revalidateMs,
725
+ staleWhileRevalidateMs: t
726
726
  });
727
727
  }
728
728
  } catch (e) {
729
- q.warn("background SWR refresh failed", { url: n }, e);
729
+ K.warn("background SWR refresh failed", { url: r }, e);
730
730
  }
731
731
  })(), {
732
732
  status: 200,
@@ -734,43 +734,43 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
734
734
  "content-type": "text/html; charset=utf-8",
735
735
  "x-voltro-rendered-by": "isr",
736
736
  "x-voltro-cache": "STALE",
737
- "x-voltro-cache-key": p,
738
- "x-voltro-cache-age-ms": String(g - h.renderedAt)
737
+ "x-voltro-cache-key": v,
738
+ "x-voltro-cache-age-ms": String(b - y.renderedAt)
739
739
  },
740
- body: h.html
740
+ body: y.html
741
741
  };
742
742
  try {
743
- let r = await we({
744
- provider: J,
745
- root: l,
746
- route: u.route,
747
- params: u.params,
748
- pathname: n,
749
- dirs: W,
750
- shellTemplate: F,
751
- requestHeaders: t,
752
- apiOrigin: R,
753
- apiName: z,
754
- requestUrl: e
743
+ let e = await Te({
744
+ provider: q,
745
+ root: a,
746
+ route: p.route,
747
+ params: p.params,
748
+ pathname: r,
749
+ dirs: U,
750
+ shellTemplate: P,
751
+ requestHeaders: n,
752
+ apiOrigin: L,
753
+ apiName: R,
754
+ requestUrl: t
755
755
  });
756
- if (!r) return {
756
+ if (!e) return {
757
757
  status: 200,
758
758
  headers: {
759
759
  "content-type": "text/html; charset=utf-8",
760
760
  "x-voltro-rendered-by": "spa-fallback"
761
761
  },
762
- body: F
762
+ body: P
763
763
  };
764
- if ("stream" in r) return {
764
+ if ("stream" in e) return {
765
765
  status: 200,
766
- headers: { "x-voltro-rendered-by": r.renderMode },
766
+ headers: { "x-voltro-rendered-by": e.renderMode },
767
767
  body: "",
768
- stream: r.stream
768
+ stream: e.stream
769
769
  };
770
- if ("control" in r) return r.control === "redirect" ? {
771
- status: r.status,
770
+ if ("control" in e) return e.control === "redirect" ? {
771
+ status: e.status,
772
772
  headers: {
773
- location: r.location,
773
+ location: e.location,
774
774
  "x-voltro-rendered-by": "loader-redirect"
775
775
  },
776
776
  body: ""
@@ -784,34 +784,34 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
784
784
  };
785
785
  let i = {
786
786
  "content-type": "text/html; charset=utf-8",
787
- "x-voltro-rendered-by": r.renderMode
787
+ "x-voltro-rendered-by": e.renderMode
788
788
  };
789
- if (r.renderMode === "isr" && r.revalidateMs !== null) {
790
- let e = Date.now(), t = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0;
791
- B.set(p, {
792
- html: r.html,
793
- renderedAt: e,
794
- expiresAt: e + r.revalidateMs,
795
- servableUntil: e + r.revalidateMs + t,
796
- revalidateMs: r.revalidateMs,
797
- staleWhileRevalidateMs: t
798
- }), i["x-voltro-cache"] = "MISS", i["x-voltro-cache-key"] = p, i["x-voltro-cache-revalidate-ms"] = String(r.revalidateMs), t > 0 && (i["x-voltro-cache-swr-ms"] = String(t)), m.emit("cache", {
789
+ if (e.renderMode === "isr" && e.revalidateMs !== null) {
790
+ let t = Date.now(), n = J.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0;
791
+ z.set(v, {
792
+ html: e.html,
793
+ renderedAt: t,
794
+ expiresAt: t + e.revalidateMs,
795
+ servableUntil: t + e.revalidateMs + n,
796
+ revalidateMs: e.revalidateMs,
797
+ staleWhileRevalidateMs: n
798
+ }), i["x-voltro-cache"] = "MISS", i["x-voltro-cache-key"] = v, i["x-voltro-cache-revalidate-ms"] = String(e.revalidateMs), n > 0 && (i["x-voltro-cache-swr-ms"] = String(n)), g.emit("cache", {
799
799
  kind: "MISS",
800
- key: p,
801
- revalidateMs: r.revalidateMs,
802
- swrMs: t
800
+ key: v,
801
+ revalidateMs: e.revalidateMs,
802
+ swrMs: n
803
803
  });
804
- } else r.renderMode === "isr" && (i["x-voltro-cache"] = "BYPASS", m.emit("cache", {
804
+ } else e.renderMode === "isr" && (i["x-voltro-cache"] = "BYPASS", g.emit("cache", {
805
805
  kind: "BYPASS",
806
- key: p
806
+ key: v
807
807
  }));
808
808
  return {
809
809
  status: 200,
810
810
  headers: i,
811
- body: r.html
811
+ body: e.html
812
812
  };
813
813
  } catch (e) {
814
- return q.error("render error", { url: n }, e), v(e) ? {
814
+ return K.error("render error", { url: r }, e), ne(e) ? {
815
815
  status: 500,
816
816
  headers: {
817
817
  "content-type": "text/plain; charset=utf-8",
@@ -824,56 +824,56 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
824
824
  body: "server error"
825
825
  };
826
826
  }
827
- }, Fe = !1, Ie = he(async (e, t) => {
828
- let n = e.url ?? "/", r = Date.now(), i = {};
829
- for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
830
- let a = n.split("?")[0] ?? "/", o = (e.method ?? "GET").toUpperCase();
831
- if (a === "/internal/liveness") {
827
+ }, Ie = !1, Le = ge(async (e, t) => {
828
+ let n = e.url ?? "/", i = Date.now(), a = {};
829
+ for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (a[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
830
+ let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
831
+ if (o === "/internal/liveness") {
832
832
  t.writeHead(200, {
833
833
  "content-type": "text/plain",
834
834
  "cache-control": "no-store"
835
835
  }), t.end("ok");
836
836
  return;
837
837
  }
838
- if (a === "/internal/readiness") {
839
- let e = Fe ? 200 : 503;
838
+ if (o === "/internal/readiness") {
839
+ let e = Ie ? 200 : 503;
840
840
  t.writeHead(e, {
841
841
  "content-type": "text/plain",
842
842
  "cache-control": "no-store"
843
- }), t.end(Fe ? "ready" : "not-ready");
843
+ }), t.end(Ie ? "ready" : "not-ready");
844
844
  return;
845
845
  }
846
- if (o === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
847
- let e = ue(i.origin);
846
+ if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
847
+ let e = de(a.origin);
848
848
  t.writeHead(204, e), t.end();
849
849
  return;
850
850
  }
851
- if (d.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
851
+ if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
852
852
  let r = new URL(n, "http://x").searchParams.get("target");
853
853
  if (!r) {
854
854
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
855
855
  return;
856
856
  }
857
- if (!ce(r)) {
857
+ if (!le(r)) {
858
858
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
859
859
  return;
860
860
  }
861
861
  try {
862
- let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
863
- a ? n.authorization = Array.isArray(a) ? a[0] : a : oe(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
864
- let s;
865
- if (o && o !== "GET" && o !== "HEAD") {
862
+ let n = { accept: a.accept ?? "application/json" }, i = a.authorization;
863
+ i ? n.authorization = Array.isArray(i) ? i[0] : i : se(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
864
+ let o;
865
+ if (s && s !== "GET" && s !== "HEAD") {
866
866
  let t = [];
867
867
  for await (let n of e) t.push(n);
868
- s = Buffer.concat(t);
869
- let r = i["content-type"];
868
+ o = Buffer.concat(t);
869
+ let r = a["content-type"];
870
870
  r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
871
871
  }
872
872
  let c = await fetch(r, {
873
873
  redirect: "manual",
874
- method: o,
874
+ method: s,
875
875
  headers: n,
876
- ...s ? { body: new Uint8Array(s.buffer, s.byteOffset, s.byteLength) } : {}
876
+ ...o ? { body: new Uint8Array(o.buffer, o.byteOffset, o.byteLength) } : {}
877
877
  }), l = Buffer.from(await c.arrayBuffer());
878
878
  t.writeHead(c.status, {
879
879
  "content-type": c.headers.get("content-type") ?? "application/octet-stream",
@@ -884,27 +884,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
884
884
  }
885
885
  return;
886
886
  }
887
- if (d.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
887
+ if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
888
888
  let r = new URL(n, "http://x").searchParams.get("target");
889
889
  if (!r) {
890
890
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
891
891
  return;
892
892
  }
893
- if (!ce(r)) {
893
+ if (!le(r)) {
894
894
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
895
895
  return;
896
896
  }
897
- let a = new AbortController();
898
- e.on("close", () => a.abort()), t.on("close", () => a.abort());
897
+ let i = new AbortController();
898
+ e.on("close", () => i.abort()), t.on("close", () => i.abort());
899
899
  try {
900
- let e = i.authorization ?? (oe(r) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), n = await fetch(r, {
900
+ let e = a.authorization ?? (se(r) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), n = await fetch(r, {
901
901
  redirect: "manual",
902
902
  method: "GET",
903
903
  headers: {
904
904
  accept: "text/event-stream",
905
905
  ...e ? { authorization: Array.isArray(e) ? e[0] : e } : {}
906
906
  },
907
- signal: a.signal
907
+ signal: i.signal
908
908
  });
909
909
  if (!n.ok || !n.body) {
910
910
  t.writeHead(n.status, { "content-type": "text/plain" }), t.end(`upstream ${n.status}`);
@@ -931,23 +931,23 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
931
931
  }
932
932
  return;
933
933
  }
934
- if (a === "/_voltro/inspect/stream") {
935
- let n = ue(i.origin);
936
- if (se()) {
934
+ if (o === "/_voltro/inspect/stream") {
935
+ let n = de(a.origin);
936
+ if (ce()) {
937
937
  t.writeHead(503, {
938
938
  "content-type": "application/json",
939
939
  ...n
940
940
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
941
941
  return;
942
942
  }
943
- let r = P(i);
944
- if (!r.ok) {
943
+ let i = N(a, "GET");
944
+ if (!i.ok) {
945
945
  t.writeHead(401, {
946
946
  "content-type": "application/json",
947
947
  ...n
948
948
  }), t.end(JSON.stringify({
949
949
  error: "unauthorized",
950
- reason: r.reason
950
+ reason: i.reason
951
951
  }));
952
952
  return;
953
953
  }
@@ -958,30 +958,30 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
958
958
  "x-accel-buffering": "no",
959
959
  ...n
960
960
  }), t.flushHeaders(), t.write("retry: 5000\n\n");
961
- for (let e of m.buffered()) t.write(D(e));
962
- let a = m.subscribe((e) => {
963
- t.write(D(e));
964
- }), o = setInterval(() => {
965
- t.write(ee());
966
- }, 15e3), s = () => {
967
- clearInterval(o), a();
961
+ for (let e of g.buffered()) t.write(l(e));
962
+ let o = g.subscribe((e) => {
963
+ t.write(l(e));
964
+ }), s = setInterval(() => {
965
+ t.write(r());
966
+ }, 15e3), c = () => {
967
+ clearInterval(s), o();
968
968
  };
969
- e.on("close", s), t.on("close", s);
969
+ e.on("close", c), t.on("close", c);
970
970
  return;
971
971
  }
972
972
  try {
973
- let e = await Pe(n, i);
974
- if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !a.startsWith("/_voltro/inspect")) {
975
- let t = Date.now() - r;
976
- m.emit("request", {
977
- url: a,
973
+ let e = await Fe(n, a);
974
+ if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
975
+ let t = Date.now() - i;
976
+ g.emit("request", {
977
+ url: o,
978
978
  status: e.status,
979
979
  durationMs: t,
980
980
  renderedBy: e.headers["x-voltro-rendered-by"],
981
981
  cache: e.headers["x-voltro-cache"]
982
982
  });
983
- let n = Ce(a, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
984
- ke.record({
983
+ let n = we(o, W)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
984
+ Ae.record({
985
985
  kind: "request",
986
986
  tag: n,
987
987
  durationMs: t,
@@ -992,71 +992,71 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
992
992
  t.writeHead(500, { "content-type": "text/plain" }), t.end(`internal error: ${e.message}`);
993
993
  }
994
994
  });
995
- await new Promise((e) => Ie.listen(_, "::", e)), Fe = !0, u.mark("ready"), q.info(`listening on http://localhost:${_}`, {
996
- port: _,
997
- distDir: b
998
- }), q.debug("dynamic + ssr/isr routes resolve via SSR loader");
995
+ await new Promise((e) => Le.listen(b, "::", e)), Ie = !0, o.mark("ready"), K.info(`listening on http://localhost:${b}`, {
996
+ port: b,
997
+ distDir: x
998
+ }), K.debug("dynamic + ssr/isr routes resolve via SSR loader");
999
999
  try {
1000
- await x({
1001
- id: M,
1000
+ await w({
1001
+ id: j,
1002
1002
  name: T,
1003
1003
  kind: "web",
1004
- url: `http://localhost:${_}`,
1004
+ url: `http://localhost:${b}`,
1005
1005
  pid: process.pid,
1006
1006
  status: "live",
1007
- logFile: N.path
1007
+ logFile: M.path
1008
1008
  });
1009
- let e = ae(l);
1009
+ let e = oe(a);
1010
1010
  if (e) {
1011
1011
  let n = await t({ dashboardAppPath: e });
1012
- n.status === "launched" ? q.info(`dashboard launched at http://localhost:${n.port}`, { port: n.port }) : n.status === "already-running" && q.debug(`dashboard already running on :${n.port}`, { port: n.port });
1012
+ n.status === "launched" ? K.info(`dashboard launched at http://localhost:${n.port}`, { port: n.port }) : n.status === "already-running" && K.debug(`dashboard already running on :${n.port}`, { port: n.port });
1013
1013
  }
1014
1014
  setInterval(() => {
1015
- x({
1016
- id: M,
1015
+ w({
1016
+ id: j,
1017
1017
  name: T,
1018
1018
  kind: "web",
1019
- url: `http://localhost:${_}`,
1019
+ url: `http://localhost:${b}`,
1020
1020
  pid: process.pid,
1021
1021
  status: "live",
1022
- logFile: N.path
1022
+ logFile: M.path
1023
1023
  }).catch(() => {});
1024
1024
  }, 1e4).unref();
1025
1025
  } catch (e) {
1026
- q.warn("runtime-registry write failed", {}, e);
1026
+ K.warn("runtime-registry write failed", {}, e);
1027
1027
  }
1028
- pe({
1029
- app: d.name ?? "unnamed",
1028
+ me({
1029
+ app: f.name ?? "unnamed",
1030
1030
  kind: "web",
1031
- url: `http://localhost:${_}`,
1032
- bootMs: u.total()
1031
+ url: `http://localhost:${b}`,
1032
+ bootMs: o.total()
1033
1033
  });
1034
- let Le = u.phaseBreakdown();
1035
- q.info(`start: ready in ${u.total()}ms`, {
1036
- bootMs: u.total(),
1037
- ...Le ? { phases: Le } : {}
1034
+ let Re = o.phaseBreakdown();
1035
+ K.info(`start: ready in ${o.total()}ms`, {
1036
+ bootMs: o.total(),
1037
+ ...Re ? { phases: Re } : {}
1038
1038
  });
1039
- let Re = !1, ze = (t) => async () => {
1040
- if (!Re) {
1041
- if (Re = !0, q.info(`received ${t}, shutting down`, { signal: t }), Ie.close(), await Oe.stop(), H) try {
1042
- await H.end();
1039
+ let ze = !1, $ = (e) => async () => {
1040
+ if (!ze) {
1041
+ if (ze = !0, K.info(`received ${e}, shutting down`, { signal: e }), Le.close(), await ke.stop(), V) try {
1042
+ await V.end();
1043
1043
  } catch {}
1044
- await J.close(), await e(M), await N.dispose(), process.exit(0);
1044
+ await q.close(), await y(j), await M.dispose(), process.exit(0);
1045
1045
  }
1046
1046
  };
1047
- process.on("SIGINT", ze("SIGINT")), process.on("SIGTERM", ze("SIGTERM"));
1047
+ process.on("SIGINT", $("SIGINT")), process.on("SIGTERM", $("SIGTERM"));
1048
1048
  let Be = process.ppid;
1049
1049
  if (Be > 1) {
1050
1050
  let e = setInterval(() => {
1051
- (process.ppid !== Be || process.ppid === 1) && (clearInterval(e), ze("SIGTERM")());
1051
+ (process.ppid !== Be || process.ppid === 1) && (clearInterval(e), $("SIGTERM")());
1052
1052
  }, 2e3);
1053
1053
  e.unref();
1054
1054
  }
1055
1055
  return new Promise(() => {});
1056
- }, Oe = async (e) => {
1056
+ }, ke = async (e) => {
1057
1057
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
1058
- let t = await De(L(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1059
- return t.ran ? t.exitCode : (q.error("no web app found at this path"), 1);
1058
+ let t = await Oe(I(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1059
+ return t.ran ? t.exitCode : (K.error("no web app found at this path"), 1);
1060
1060
  };
1061
1061
  //#endregion
1062
- export { Oe as t };
1062
+ export { ke as t };