@voltro/cli 0.9.0 → 0.10.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 (59) hide show
  1. package/CHANGELOG.md +310 -7
  2. package/dist/apiBuild-BbR1nYcE.js +2 -0
  3. package/dist/{apiBuild-eInHm_bJ.js → apiBuild-DTLPSlt9.js} +8 -8
  4. package/dist/bin.js +2 -2
  5. package/dist/{commands-Cxs97AFp.js → commands-B0QT8dUY.js} +1948 -1599
  6. package/dist/dev-BJvbwjSz.js +2 -0
  7. package/dist/{dev-63Ehpw2p.js → dev-CK9fbuAM.js} +1408 -1342
  8. package/dist/index.js +1 -1
  9. package/dist/{inspectMetrics-DVCKKSPk.js → inspectMetrics-BeMjgt8x.js} +1018 -827
  10. package/dist/inspectState.d.ts +6 -2
  11. package/dist/{serveCommand-Cq7BhtpB.js → serveCommand-YR3mKjvf.js} +367 -384
  12. package/dist/serveEntry.js +3 -3
  13. package/dist/{start-CYe-7ueh.js → start-C_M4fGS2.js} +331 -309
  14. package/dist/startEntry.js +2 -2
  15. package/package.json +17 -17
  16. package/templates/agent-docs/cli.md +45 -17
  17. package/templates/agent-docs/data.md +109 -1
  18. package/templates/agent-docs/database/seedsdialects.md +20 -4
  19. package/templates/agent-docs/routing.md +52 -13
  20. package/templates/agent-docs/scheduling.md +32 -0
  21. package/templates/apps/api-ai/package.json +7 -7
  22. package/templates/apps/api-auth/package.json +8 -8
  23. package/templates/apps/api-backend/package.json +7 -7
  24. package/templates/apps/api-backend-deactivation/package.json +7 -7
  25. package/templates/apps/api-backend-mail/package.json +8 -8
  26. package/templates/apps/api-backend-mariadb/package.json +9 -9
  27. package/templates/apps/api-backend-storage/package.json +8 -8
  28. package/templates/apps/api-data-advanced/package.json +8 -8
  29. package/templates/apps/api-durable/package.json +8 -8
  30. package/templates/apps/api-durable/schedules/nightlyReport.cron.tsx +5 -0
  31. package/templates/apps/api-durable/subscribers/orderChanges.subscribe.ts +8 -2
  32. package/templates/apps/api-feature-flags/package.json +9 -9
  33. package/templates/apps/api-governance/package.json +8 -8
  34. package/templates/apps/api-kv/package.json +8 -8
  35. package/templates/apps/api-moderation/package.json +8 -8
  36. package/templates/apps/api-observability/package.json +8 -8
  37. package/templates/apps/api-ratelimit/package.json +8 -8
  38. package/templates/apps/api-rbac/package.json +8 -8
  39. package/templates/apps/api-rest/package.json +7 -7
  40. package/templates/apps/api-saas/package.json +11 -11
  41. package/templates/apps/api-search/package.json +8 -8
  42. package/templates/apps/api-versioning/package.json +8 -8
  43. package/templates/apps/api-webhooks/package.json +8 -8
  44. package/templates/apps/changelog/package.json +6 -6
  45. package/templates/apps/edge-functions/package.json +2 -2
  46. package/templates/apps/frontend-admin/package.json +8 -8
  47. package/templates/apps/frontend-app/package.json +8 -8
  48. package/templates/apps/frontend-blank/package.json +7 -7
  49. package/templates/apps/frontend-contact/package.json +7 -7
  50. package/templates/apps/frontend-dashboard/package.json +7 -7
  51. package/templates/apps/frontend-docs/package.json +7 -7
  52. package/templates/apps/frontend-i18n/package.json +6 -6
  53. package/templates/apps/frontend-landing/package.json +7 -7
  54. package/templates/apps/frontend-spa/package.json +7 -7
  55. package/templates/apps/frontend-ssr/package.json +7 -7
  56. package/templates/apps/frontend-ssr-api/package.json +8 -8
  57. package/templates/apps/frontend-static-blog/package.json +6 -6
  58. package/dist/apiBuild-Ba4njm9m.js +0 -2
  59. package/dist/dev-CXsR8Zgo.js +0 -2
@@ -1,22 +1,12 @@
1
- import { A as e, D as t, E as n, G as r, H as i, K as a, M as o, N as s, O as c, P as l, S as u, St as d, Tt as f, U as p, W as m, Y as h, _ as g, a as _, bt as v, c as y, f as ee, g as b, h as x, ht as S, i as C, j as te, k as w, m as ne, mt as T, o as E, p as D, r as O, rt as k, s as re, t as ie, v as A, w as ae, x as oe, xt as j, z as M } from "./inspectMetrics-DVCKKSPk.js";
2
- import { dirname as N, extname as P, join as F, resolve as I } from "node:path";
3
- import { fileURLToPath as L, pathToFileURL as R } from "node:url";
4
- import { createLogger as z, printReadyBlock as se } from "@voltro/logger";
5
- import { promises as B } from "node:fs";
6
- import { snapshotMetricsSync as ce } from "@voltro/runtime";
7
- import { createServer as le } from "node:http";
8
- //#region src/routeMeta.ts
9
- var V = (e) => typeof e.renderMode == "string" ? e.renderMode : e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static"), ue = (e) => ({
10
- renderMode: V(e),
11
- tenantAware: e.tenantAware === !0,
12
- revalidateMs: l(e.revalidate),
13
- staleWhileRevalidateMs: l(e.staleWhileRevalidate) ?? 0,
14
- cacheInvalidatesOn: Array.isArray(e.cacheInvalidatesOn) ? e.cacheInvalidatesOn : [],
15
- interactive: e.interactive ?? "full",
16
- hasLoader: typeof e.loader == "function",
17
- hasMeta: e.meta != null,
18
- hasGetStaticPaths: typeof e.getStaticPaths == "function"
19
- }), H = z({ scope: "voltro:start:cdc" }), U = (e) => (t) => {
1
+ import { A as e, At as t, B as n, C as r, Ct as i, Dt as a, E as o, Et as s, H as c, I as l, K as u, Mt as d, O as f, Ot as p, U as m, V as h, _ as g, _t as _, a as v, b as y, c as b, dt as x, et as S, f as C, ft as w, g as T, h as E, i as ee, j as D, jt as O, k, kt as A, m as j, o as M, p as te, r as ne, s as re, t as ie, v as N, vt as P, w as ae, y as F, yt as I, z as oe } from "./inspectMetrics-BeMjgt8x.js";
2
+ import { dirname as L, extname as R, join as z, resolve as se } from "node:path";
3
+ import { fileURLToPath as ce, pathToFileURL as B } from "node:url";
4
+ import { createLogger as V, printReadyBlock as le } from "@voltro/logger";
5
+ import { promises as H } from "node:fs";
6
+ import { snapshotMetricsSync as ue } from "@voltro/runtime";
7
+ import { createServer as de } from "node:http";
8
+ //#region src/isrCdcInvalidator.ts
9
+ var U = V({ scope: "voltro:start:cdc" }), W = (e) => (t) => {
20
10
  let n = 0;
21
11
  for (let [r, i] of e.tableSubscriptionsByPattern) {
22
12
  if (!i.includes(t)) continue;
@@ -27,23 +17,23 @@ var V = (e) => typeof e.renderMode == "string" ? e.renderMode : e.dynamic === "f
27
17
  }));
28
18
  }
29
19
  return n;
30
- }, W = () => !process.env.PG_HOST && !process.env.PG_DATABASE ? null : {
20
+ }, G = () => !process.env.PG_HOST && !process.env.PG_DATABASE ? null : {
31
21
  host: process.env.PG_HOST ?? "localhost",
32
22
  port: Number(process.env.PG_PORT ?? 5432),
33
23
  user: process.env.PG_USER ?? "app",
34
24
  password: process.env.PG_PASSWORD ?? "app",
35
25
  database: process.env.PG_DATABASE ?? "app"
36
- }, de = (e) => {
37
- let t = e.channel ?? "framework_changes", n = U(e), r = null, i = null;
26
+ }, fe = (e) => {
27
+ let t = e.channel ?? "framework_changes", n = W(e), r = null, i = null;
38
28
  return {
39
29
  start: async () => {
40
- let a = W();
30
+ let a = G();
41
31
  if (!a) {
42
- H.debug("skipped — no PG_* env vars set");
32
+ U.debug("skipped — no PG_* env vars set");
43
33
  return;
44
34
  }
45
35
  if (e.tableSubscriptionsByPattern.size === 0) {
46
- H.debug("skipped — no pages declare cacheInvalidatesOn");
36
+ U.debug("skipped — no pages declare cacheInvalidatesOn");
47
37
  return;
48
38
  }
49
39
  r = new (await (import("pg"))).default.Client(a), await r.connect(), i = (e) => {
@@ -52,16 +42,16 @@ var V = (e) => typeof e.renderMode == "string" ? e.renderMode : e.dynamic === "f
52
42
  try {
53
43
  r = JSON.parse(e.payload);
54
44
  } catch (e) {
55
- H.warn("bad CDC payload", {}, e);
45
+ U.warn("bad CDC payload", {}, e);
56
46
  return;
57
47
  }
58
48
  let i = n(r.table);
59
- i > 0 && H.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
49
+ i > 0 && U.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
60
50
  op: r.op,
61
51
  table: r.table,
62
52
  dropped: i
63
53
  });
64
- }, r.on("notification", i), await r.query(`LISTEN ${t}`), H.info(`LISTEN ${t}`, {
54
+ }, r.on("notification", i), await r.query(`LISTEN ${t}`), U.info(`LISTEN ${t}`, {
65
55
  channel: t,
66
56
  host: a.host,
67
57
  port: a.port,
@@ -77,7 +67,7 @@ var V = (e) => typeof e.renderMode == "string" ? e.renderMode : e.dynamic === "f
77
67
  }
78
68
  }
79
69
  };
80
- }, G = z({ scope: "voltro:start:isr-cache" }), K = "voltro_isr_cache", q = (e) => `
70
+ }, K = V({ scope: "voltro:start:isr-cache" }), pe = "voltro_isr_cache", q = (e) => `
81
71
  CREATE TABLE IF NOT EXISTS ${e} (
82
72
  cache_key TEXT PRIMARY KEY,
83
73
  html TEXT NOT NULL,
@@ -88,8 +78,8 @@ CREATE TABLE IF NOT EXISTS ${e} (
88
78
  stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
89
79
  );
90
80
  CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
91
- `, fe = (e) => {
92
- let t = e.tableName ?? K, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
81
+ `, me = (e) => {
82
+ let t = e.tableName ?? pe, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
93
83
  i || (i = !0, await n.query(q(t)));
94
84
  })().then(async () => {
95
85
  let e = await n.query(`SELECT * FROM ${t}`);
@@ -102,10 +92,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
102
92
  staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
103
93
  });
104
94
  }).catch((e) => {
105
- G.warn("postgres bootstrap failed", {}, e);
95
+ K.warn("postgres bootstrap failed", {}, e);
106
96
  }), o = (e, t) => {
107
97
  a.then(() => n.query(e, t)).catch((e) => {
108
- G.warn("postgres write failed", {}, e);
98
+ K.warn("postgres write failed", {}, e);
109
99
  });
110
100
  };
111
101
  return {
@@ -150,14 +140,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
150
140
  return Array.from(r.entries());
151
141
  }
152
142
  };
153
- }, J = z({ scope: "voltro:start" }), pe = await (async () => {
143
+ }, J = V({ scope: "voltro:start" }), he = await (async () => {
154
144
  try {
155
- let e = F(N(L(import.meta.url)), "..", "package.json"), t = await B.readFile(e, "utf8");
145
+ let e = z(L(ce(import.meta.url)), "..", "package.json"), t = await H.readFile(e, "utf8");
156
146
  return JSON.parse(t).version ?? "0.0.0";
157
147
  } catch {
158
148
  return "0.0.0";
159
149
  }
160
- })(), me = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", Y = (e) => e instanceof Error && e._voltroControl === "not-found", he = {
150
+ })(), ge = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", Y = (e) => e instanceof Error && e._voltroControl === "not-found", X = {
161
151
  ".html": "text/html; charset=utf-8",
162
152
  ".js": "application/javascript",
163
153
  ".mjs": "application/javascript",
@@ -175,13 +165,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
175
165
  ".woff": "font/woff",
176
166
  ".woff2": "font/woff2",
177
167
  ".txt": "text/plain; charset=utf-8"
178
- }, ge = (e) => he[P(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) => {
168
+ }, _e = (e) => X[R(e).toLowerCase()] ?? "application/octet-stream", Z = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), Q = async (e) => {
179
169
  try {
180
- return await B.stat(e), !0;
170
+ return await H.stat(e), !0;
181
171
  } catch {
182
172
  return !1;
183
173
  }
184
- }, Q = (e) => {
174
+ }, ve = (e) => {
185
175
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
186
176
  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, "\\$&"));
187
177
  let a = i.join("/");
@@ -190,8 +180,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
190
180
  paramNames: t,
191
181
  priority: n
192
182
  };
193
- }, _e = (e) => e.map((e) => {
194
- let { regex: t, paramNames: n, priority: r } = Q(e.pattern);
183
+ }, ye = (e) => e.map((e) => {
184
+ let { regex: t, paramNames: n, priority: r } = ve(e.pattern);
195
185
  return {
196
186
  pattern: e.pattern,
197
187
  file: e.file,
@@ -200,7 +190,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
200
190
  paramNames: n,
201
191
  priority: r
202
192
  };
203
- }).slice().sort((e, t) => e.priority - t.priority), ve = (e, t) => {
193
+ }).slice().sort((e, t) => e.priority - t.priority), be = (e, t) => {
204
194
  for (let n of t) {
205
195
  let t = n.regex.exec(e);
206
196
  if (!t) continue;
@@ -212,12 +202,12 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
212
202
  };
213
203
  }
214
204
  return null;
215
- }, ye = async (e) => {
216
- let { provider: t, route: n, params: r, pathname: i, dirs: a, shellTemplate: o, requestHeaders: s, requestUrl: c = "", apiOrigin: u } = e, d = C(u, s.cookie), f = await t.getPage(n.pattern, n.file), p = V(f), m = p === "spa" && E(a, n.dirChain).some((e) => e.hasLayout);
205
+ }, xe = async (e) => {
206
+ let { provider: t, route: n, params: r, pathname: i, dirs: a, shellTemplate: o, requestHeaders: c, requestUrl: l = "", apiOrigin: u } = e, d = ee(u, c.cookie), f = await t.getPage(n.pattern, n.file), p = s(f, n.file), m = p === "spa" && M(a, n.dirChain).some((e) => e.hasLayout);
217
207
  if (p !== "ssr" && p !== "isr" && !m) return null;
218
- let h = E(a, n.dirChain), v = {}, y = null, ee, b = new AbortController();
208
+ let h = M(a, n.dirChain), _ = {}, b = null, x, S = new AbortController();
219
209
  try {
220
- ({chain: ee, segmentLoaderData: v} = await _({
210
+ ({chain: x, segmentLoaderData: _} = await v({
221
211
  entries: h,
222
212
  loadLayout: (e) => t.getLayout(e.dir),
223
213
  loadError: (e) => t.getError(e.dir),
@@ -225,19 +215,19 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
225
215
  ctx: {
226
216
  params: r,
227
217
  pathname: i,
228
- signal: b.signal,
229
- headers: s,
218
+ signal: S.signal,
219
+ headers: c,
230
220
  query: d
231
221
  }
232
- })), typeof f.loader == "function" && !m && (y = await f.loader({
222
+ })), typeof f.loader == "function" && !m && (b = await f.loader({
233
223
  params: r,
234
224
  pathname: i,
235
- signal: b.signal,
236
- headers: s,
225
+ signal: S.signal,
226
+ headers: c,
237
227
  query: d
238
228
  }));
239
229
  } catch (e) {
240
- if (me(e)) return {
230
+ if (ge(e)) return {
241
231
  control: "redirect",
242
232
  status: e.status,
243
233
  location: e.location
@@ -245,7 +235,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
245
235
  if (Y(e)) return { control: "not-found" };
246
236
  throw e;
247
237
  }
248
- let S = await t.getHelpers(), te = {
238
+ let C = await t.getHelpers(), w = {
249
239
  pattern: n.pattern,
250
240
  Component: f.default,
251
241
  meta: f.meta,
@@ -253,67 +243,99 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
253
243
  ErrorBoundary: f.ErrorBoundary,
254
244
  Pending: f.Pending,
255
245
  renderMode: p,
256
- chain: ee
257
- }, w = {
258
- cookies: S.parseCookieHeader(s.cookie),
259
- headers: s,
260
- url: c
261
- }, T = S.i18n?.resolve(s.cookie, s["accept-language"]), D = f.interactive ?? "full";
246
+ chain: x
247
+ }, T = {
248
+ cookies: C.parseCookieHeader(c.cookie),
249
+ headers: c,
250
+ url: l
251
+ }, D = C.i18n?.resolve(c.cookie, c["accept-language"]), k = f.interactive ?? "full";
262
252
  if (m) {
263
- let e = A({
264
- helpers: S,
253
+ let e = N({
254
+ helpers: C,
255
+ page: n.pattern,
256
+ interactive: k,
257
+ delivery: "stream",
265
258
  renderInput: {
266
- descriptor: te,
259
+ descriptor: w,
267
260
  params: r,
268
261
  pathname: i,
269
- segmentLoaderData: v,
270
- requestContext: w,
271
- ...T ? {
272
- outerWrap: T.outerWrap,
273
- locale: T.locale
262
+ segmentLoaderData: _,
263
+ requestContext: T,
264
+ ...D ? {
265
+ outerWrap: D.outerWrap,
266
+ locale: D.locale
274
267
  } : {}
275
268
  }
276
- }), t = [
277
- S.renderMetaToHtml(e.meta),
278
- `<meta name="voltro-interactive" content="${D}" />`,
279
- e.stateScript
280
- ].filter((e) => e.length > 0).join("\n "), n = T?.locale ?? w.cookies["voltro:lang"] ?? "en";
269
+ }), t = D?.locale ?? T.cookies["voltro:lang"] ?? "en", a = (t) => y({
270
+ helpers: C,
271
+ prepared: e,
272
+ meta: t,
273
+ interactive: k
274
+ });
275
+ if (e.hasDeferred) {
276
+ let n = j({ shell: o });
277
+ return {
278
+ renderMode: "spa",
279
+ stream: (r) => E({
280
+ res: r,
281
+ shell: n,
282
+ htmlLang: t,
283
+ headers: {
284
+ "content-type": "text/html; charset=utf-8",
285
+ "x-voltro-rendered-by": "spa"
286
+ },
287
+ headInjection: a,
288
+ render: (t) => C.renderPageToStream({
289
+ ...e.renderInput,
290
+ ...t
291
+ }),
292
+ onShellError: (e) => {
293
+ J.error("spa layout shell render failed", { pathname: i }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
294
+ }
295
+ })
296
+ };
297
+ }
298
+ let s = F({
299
+ helpers: C,
300
+ prepared: e
301
+ });
281
302
  return {
282
- html: o.replace("<div id=\"root\"></div>", `<div id="root">${e.body}</div>`).replace("</head>", ` ${t}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${n}"`),
303
+ 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}"`),
283
304
  renderMode: "spa",
284
305
  revalidateMs: null
285
306
  };
286
307
  }
287
- let O = g({
288
- helpers: S,
308
+ let A = g({
309
+ helpers: C,
289
310
  page: n.pattern,
311
+ pathname: i,
290
312
  renderMode: p,
291
- interactive: D,
292
- loaderData: y,
293
- segmentLoaderData: v,
313
+ interactive: k,
314
+ loaderData: b,
315
+ segmentLoaderData: _,
294
316
  pageLoaderRan: typeof f.loader == "function"
295
- }), k = {
296
- descriptor: te,
317
+ }), te = {
318
+ descriptor: w,
297
319
  params: r,
298
320
  pathname: i,
299
- loaderData: O.loaderData,
300
- segmentLoaderData: O.segmentLoaderData,
301
- requestContext: w,
302
- ...T ? {
303
- outerWrap: T.outerWrap,
304
- locale: T.locale
321
+ loaderData: A.loaderData,
322
+ segmentLoaderData: A.segmentLoaderData,
323
+ requestContext: T,
324
+ ...D ? {
325
+ outerWrap: D.outerWrap,
326
+ locale: D.locale
305
327
  } : {}
306
- }, re = (e) => [
307
- S.renderMetaToHtml(e),
308
- `<meta name="voltro-interactive" content="${D}" />`,
309
- ...O.hasDeferred ? [S.renderDeferredRegistryScript()] : [],
310
- S.renderRouterStateScript(O.stateInput)
328
+ }, ne = (e) => [
329
+ C.renderMetaToHtml(e),
330
+ `<meta name="voltro-interactive" content="${k}" />`,
331
+ ...A.hasDeferred ? [C.renderDeferredRegistryScript()] : [],
332
+ C.renderRouterStateScript(A.stateInput)
311
333
  ].filter((e) => e.length > 0).join("\n ");
312
- if (p === "ssr" && D === "full" && e.buffered !== !0) {
313
- let e = T?.locale ?? w.cookies["voltro:lang"] ?? "en", t = ne({ shell: o });
334
+ if (p === "ssr" && k === "full" && e.buffered !== !0) {
335
+ let e = D?.locale ?? T.cookies["voltro:lang"] ?? "en", t = j({ shell: o });
314
336
  return {
315
337
  renderMode: "ssr",
316
- stream: (n) => x({
338
+ stream: (n) => E({
317
339
  res: n,
318
340
  shell: t,
319
341
  htmlLang: e,
@@ -321,9 +343,9 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
321
343
  "content-type": "text/html; charset=utf-8",
322
344
  "x-voltro-rendered-by": "ssr"
323
345
  },
324
- headInjection: re,
325
- render: (e) => S.renderPageToStream({
326
- ...k,
346
+ headInjection: ne,
347
+ render: (e) => C.renderPageToStream({
348
+ ...te,
327
349
  ...e
328
350
  }),
329
351
  onShellError: (e) => {
@@ -332,16 +354,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
332
354
  })
333
355
  };
334
356
  }
335
- let { html: ie, meta: ae } = S.renderPageToHtml(k), oe = re(ae), j = T?.locale ?? w.cookies["voltro:lang"] ?? "en", M = o.replace("<div id=\"root\"></div>", `<div id="root">${ie}</div>`).replace("</head>", ` ${oe}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${j}"`);
336
- D === "none" && (M = X(M));
337
- let N = p === "isr" ? l(f.revalidate) : null;
357
+ let { html: re, meta: ie } = C.renderPageToHtml(te), P = ne(ie), ae = D?.locale ?? T.cookies["voltro:lang"] ?? "en", I = o.replace("<div id=\"root\"></div>", `<div id="root">${re}</div>`).replace("</head>", ` ${P}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${ae}"`);
358
+ k === "none" && (I = Z(I));
359
+ let oe = p === "isr" ? O(f.revalidate) : null;
338
360
  return {
339
- html: M,
361
+ html: I,
340
362
  renderMode: p,
341
- revalidateMs: N
363
+ revalidateMs: oe
342
364
  };
343
- }, $ = (e) => e === "" ? "/" : e, be = async (e) => {
344
- let t = await import(R(e).href);
365
+ }, $ = (e) => e === "" ? "/" : e, Se = async (e) => {
366
+ let t = await import(B(e).href);
345
367
  return {
346
368
  kind: "bundle",
347
369
  getPageMeta: () => t.pageMeta,
@@ -370,8 +392,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
370
392
  },
371
393
  async close() {}
372
394
  };
373
- }, xe = async (e, t) => {
374
- let n = await f("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
395
+ }, Ce = async (e, t) => {
396
+ let n = await d("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
375
397
  root: t,
376
398
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
377
399
  plugins: [r(), i()],
@@ -383,20 +405,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
383
405
  },
384
406
  appType: "custom",
385
407
  logLevel: "warn"
386
- }), o = F(e, "src", "pages"), s = (e) => e === "" ? o : F(o, e), c = v({ limit: j() }), l = (e) => c.load(e, async () => await a.ssrLoadModule(e));
408
+ }), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c = _({ limit: P() }), l = (e) => c.load(e, async () => await a.ssrLoadModule(e));
387
409
  return {
388
410
  kind: "middleware",
389
411
  async getPage(e, t) {
390
- return l(F(o, t));
412
+ return l(z(o, t));
391
413
  },
392
414
  async getLayout(e) {
393
- return l(F(s(e), "layout.tsx"));
415
+ return l(z(s(e), "layout.tsx"));
394
416
  },
395
417
  async getError(e) {
396
- return l(F(s(e), "error.tsx"));
418
+ return l(z(s(e), "error.tsx"));
397
419
  },
398
420
  async getPending(e) {
399
- return l(F(s(e), "loading.tsx"));
421
+ return l(z(s(e), "loading.tsx"));
400
422
  },
401
423
  async getHelpers() {
402
424
  return await l("@voltro/web/ssr");
@@ -405,95 +427,95 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
405
427
  await a.close();
406
428
  }
407
429
  };
408
- }, Se = async (l) => {
409
- let f = await re(l);
410
- if (!f) return {
430
+ }, we = async (s) => {
431
+ let d = await re(s);
432
+ if (!d) return {
411
433
  ran: !1,
412
434
  exitCode: 0
413
435
  };
414
- if (f.type !== "web") return J.error("only web apps are supported by `voltro start`"), {
436
+ if (d.type !== "web") return J.error("only web apps are supported by `voltro start`"), {
415
437
  ran: !0,
416
438
  exitCode: 1
417
439
  };
418
- let { resolved: g } = await d({
419
- rawEnv: f.env,
440
+ let { resolved: g } = await I({
441
+ rawEnv: d.env,
420
442
  appType: "web",
421
- root: l,
443
+ root: s,
422
444
  log: J,
423
445
  generateTypes: !1
424
- }), _ = g.publicValues, v = Date.now(), x = r();
425
- i(x), J.info("booting voltro start", { app: f.name ?? "(unnamed)" });
426
- let C = (() => {
446
+ }), _ = g.publicValues, v = Date.now(), y = c();
447
+ oe(y), J.info("booting voltro start", { app: d.name ?? "(unnamed)" });
448
+ let E = (() => {
427
449
  if (process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT) return Number(process.env.VOLTRO_DASHBOARD_PORT);
428
450
  if (process.env.PORT) {
429
451
  let e = Number(process.env.PORT);
430
452
  if (Number.isFinite(e) && e > 0) return e;
431
453
  }
432
- return f.port ?? 5173;
433
- })(), ne = F(l, ".framework"), A = F(ne, "dist"), j = F(A, "index.html");
434
- if (!await Z(j)) return J.error("no built dist found — run `voltro build` first", { distDir: A }), {
454
+ return d.port ?? 5173;
455
+ })(), ee = z(s, ".framework"), O = z(ee, "dist"), j = z(O, "index.html");
456
+ if (!await Q(j)) return J.error("no built dist found — run `voltro build` first", { distDir: O }), {
435
457
  ran: !0,
436
458
  exitCode: 1
437
459
  };
438
- let N = f.name ?? "unnamed", P = n("web", N, C), I = ae(N);
439
- await w({
460
+ let N = d.name ?? "unnamed", P = f("web", N, E), F = o(N);
461
+ await D({
440
462
  id: P,
441
463
  name: N,
442
464
  kind: "web",
443
- url: `http://localhost:${C}`,
465
+ url: `http://localhost:${E}`,
444
466
  pid: process.pid,
445
467
  status: "booting",
446
- logFile: I.path
468
+ logFile: F.path
447
469
  }).catch(() => {});
448
- let L = F(A, "_voltro", "shell.html"), R = await Z(L) ? await B.readFile(L, "utf8") : await B.readFile(j, "utf8"), z = await y(l, f), V = O(z[0]), H, U = null;
449
- process.env.SSR_CACHE === "postgres" && process.env.PG_HOST ? (U = new (await (import("pg"))).default.Client({
470
+ let L = z(O, "_voltro", "shell.html"), R = await Q(L) ? await H.readFile(L, "utf8") : await H.readFile(j, "utf8"), se = await b(s, d), ce = ne(se[0]), B, V = null;
471
+ process.env.SSR_CACHE === "postgres" && process.env.PG_HOST ? (V = new (await (import("pg"))).default.Client({
450
472
  host: process.env.PG_HOST,
451
473
  port: Number(process.env.PG_PORT ?? 5432),
452
474
  user: process.env.PG_USER ?? "app",
453
475
  password: process.env.PG_PASSWORD ?? "app",
454
476
  database: process.env.PG_DATABASE ?? "app"
455
- }), await U.connect(), H = fe({ client: U }), J.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (H = s(), J.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await D(l, f, z, _);
456
- let { pages: W, dirs: G } = await ee(F(l, "src", "pages")), K = _e(W), q = F(A, "server", "ssrEntry.js"), me = await Z(q);
457
- if (!me && process.env.NODE_ENV === "production") throw J.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}`);
458
- let Y = me ? await be(q) : await xe(l, ne);
459
- J.info(`ssr loader: ${Y.kind}`, {
460
- kind: Y.kind,
461
- ...Y.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
477
+ }), await V.connect(), B = me({ client: V }), J.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (B = t(), J.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await te(s, d, se, _);
478
+ let { pages: U, dirs: W } = await C(z(s, "src", "pages")), G = ye(U), K = z(O, "server", "ssrEntry.js"), pe = await Q(K);
479
+ if (!pe && process.env.NODE_ENV === "production") throw J.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}`);
480
+ let q = pe ? await Se(K) : await Ce(s, ee);
481
+ J.info(`ssr loader: ${q.kind}`, {
482
+ kind: q.kind,
483
+ ...q.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
462
484
  });
463
- let he = Y.getPageMeta?.(), X = /* @__PURE__ */ new Map(), Q = 0;
464
- for (let e of W) {
465
- let t = he?.[e.pattern];
485
+ let ge = q.getPageMeta?.(), Y = /* @__PURE__ */ new Map(), X = 0;
486
+ for (let e of U) {
487
+ let t = ge?.[e.pattern];
466
488
  if (t) {
467
- X.set(e.pattern, t);
489
+ Y.set(e.pattern, t);
468
490
  continue;
469
491
  }
470
492
  try {
471
- let t = await Y.getPage(e.pattern, e.file);
472
- X.set(e.pattern, ue(t)), Q++;
493
+ let t = await q.getPage(e.pattern, e.file);
494
+ Y.set(e.pattern, i(t, e.file)), X++;
473
495
  } catch (t) {
474
496
  J.warn("failed to load page metadata", { pattern: e.pattern }, t);
475
497
  }
476
498
  }
477
- J.info(`registered ${X.size} route(s)`, {
478
- count: X.size,
479
- fromManifest: X.size - Q,
480
- fromModules: Q
499
+ J.info(`registered ${Y.size} route(s)`, {
500
+ count: Y.size,
501
+ fromManifest: Y.size - X,
502
+ fromModules: X
481
503
  });
482
- let $ = /* @__PURE__ */ new Set();
483
- for (let e of K) X.get(e.pattern)?.renderMode === "spa" && E(G, e.dirChain).some((e) => e.hasLayout) && $.add(e.pattern);
484
- $.size > 0 && J.info(`${$.size} spa route(s) render an SSR layout shell`, { patterns: [...$] });
485
- let Se = /* @__PURE__ */ new Map();
486
- for (let [e, t] of X) t.cacheInvalidatesOn.length > 0 && Se.set(e, t.cacheInvalidatesOn);
487
- let Ce = /* @__PURE__ */ new Map();
488
- for (let e of K) Ce.set(e.pattern, e.regex);
489
- let we = de({
490
- cache: H,
491
- tableSubscriptionsByPattern: Se,
492
- regexByPattern: Ce
504
+ let Z = /* @__PURE__ */ new Set();
505
+ for (let e of G) Y.get(e.pattern)?.renderMode === "spa" && M(W, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
506
+ Z.size > 0 && J.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
507
+ let ve = /* @__PURE__ */ new Map();
508
+ for (let [e, t] of Y) t.cacheInvalidatesOn.length > 0 && ve.set(e, t.cacheInvalidatesOn);
509
+ let $ = /* @__PURE__ */ new Map();
510
+ for (let e of G) $.set(e.pattern, e.regex);
511
+ let we = fe({
512
+ cache: B,
513
+ tableSubscriptionsByPattern: ve,
514
+ regexByPattern: $
493
515
  });
494
516
  await we.start();
495
- let Te = ie(), Ee = W.map((e) => {
496
- let t = X.get(e.pattern);
517
+ let Te = ie(), Ee = U.map((e) => {
518
+ let t = Y.get(e.pattern);
497
519
  return {
498
520
  pattern: e.pattern,
499
521
  file: e.file,
@@ -508,20 +530,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
508
530
  hasMeta: t?.hasMeta ?? !1,
509
531
  hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
510
532
  };
511
- }), De = G.map((e) => ({
533
+ }), De = W.map((e) => ({
512
534
  dir: e.dir,
513
535
  hasLayout: e.hasLayout,
514
536
  hasError: e.hasError,
515
537
  hasPending: e.hasPending,
516
538
  hasNotFound: e.hasNotFound
517
- })), Oe = U ? "postgres" : "memory", ke = {
539
+ })), Oe = V ? "postgres" : "memory", ke = {
518
540
  kind: "web",
519
541
  meta: {
520
- name: f.name ?? "(unnamed)",
521
- voltroVersion: pe,
522
- port: C,
542
+ name: d.name ?? "(unnamed)",
543
+ voltroVersion: he,
544
+ port: E,
523
545
  mode: "start",
524
- apis: Object.entries(f.apis ?? {}).map(([e, t]) => {
546
+ apis: Object.entries(d.apis ?? {}).map(([e, t]) => {
525
547
  let n = {
526
548
  name: e,
527
549
  package: t.package
@@ -532,7 +554,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
532
554
  routes: Ee,
533
555
  dirs: De,
534
556
  cache: () => {
535
- let e = Date.now(), t = H.snapshot().map(([t, n]) => ({
557
+ let e = Date.now(), t = B.snapshot().map(([t, n]) => ({
536
558
  key: t,
537
559
  renderedAt: n.renderedAt,
538
560
  expiresAt: n.expiresAt,
@@ -544,15 +566,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
544
566
  }));
545
567
  return {
546
568
  backend: Oe,
547
- size: H.size(),
569
+ size: B.size(),
548
570
  entries: t
549
571
  };
550
572
  },
551
- metrics: () => ce()
552
- }, Ae = async (n, r) => {
553
- let i = n.split("?")[0] ?? "/";
554
- if (f.name === "voltroDashboard" && i === "/api/dashboard/registry") try {
555
- let e = await t();
573
+ metrics: () => ue()
574
+ }, Ae = async (e, t) => {
575
+ let r = e.split("?")[0] ?? "/";
576
+ if (d.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
577
+ let e = await k();
556
578
  return {
557
579
  status: 200,
558
580
  headers: { "content-type": "application/json; charset=utf-8" },
@@ -565,7 +587,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
565
587
  body: `registry read error: ${e.message}`
566
588
  };
567
589
  }
568
- if (f.name === "voltroDashboard" && i === "/api/dashboard/config") {
590
+ if (d.name === "voltroDashboard" && r === "/api/dashboard/config") {
569
591
  let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
570
592
  if (e && e.trim().length > 0) {
571
593
  let n;
@@ -594,56 +616,56 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
594
616
  body: JSON.stringify({ apps: t })
595
617
  };
596
618
  }
597
- if (i === "/_voltro/inspect/logs") {
598
- let e = M(n, p());
619
+ if (r === "/_voltro/inspect/logs") {
620
+ let t = l(e, n());
599
621
  return {
600
- status: e.status,
601
- headers: { "content-type": e.contentType },
602
- body: e.body
622
+ status: t.status,
623
+ headers: { "content-type": t.contentType },
624
+ body: t.body
603
625
  };
604
626
  }
605
- if (i !== "/_voltro/inspect/stream") {
606
- let e = k(n, ke, r);
607
- if (e !== null) return {
608
- status: e.status,
627
+ if (r !== "/_voltro/inspect/stream") {
628
+ let n = S(e, ke, t);
629
+ if (n !== null) return {
630
+ status: n.status,
609
631
  headers: {
610
- "content-type": e.contentType,
611
- ...e.headers ?? {}
632
+ "content-type": n.contentType,
633
+ ...n.headers ?? {}
612
634
  },
613
- body: e.body
635
+ body: n.body
614
636
  };
615
637
  }
616
- let a = ve(i, K), s = a ? X.get(a.route.pattern)?.renderMode : void 0, c = s === "ssr" || s === "isr" || (a ? $.has(a.route.pattern) : !1), u = i === "/" ? F(A, "index.html") : F(A, i.replace(/^\//, ""), "index.html");
617
- if (!c && await Z(u)) return {
638
+ let i = be(r, G), o = i ? Y.get(i.route.pattern)?.renderMode : void 0, c = o === "ssr" || o === "isr" || (i ? Z.has(i.route.pattern) : !1), u = r === "/" ? z(O, "index.html") : z(O, r.replace(/^\//, ""), "index.html");
639
+ if (!c && await Q(u)) return {
618
640
  status: 200,
619
641
  headers: { "content-type": "text/html; charset=utf-8" },
620
- body: await B.readFile(u)
642
+ body: await H.readFile(u)
621
643
  };
622
- if (/\.[a-z0-9]+$/i.test(i)) {
623
- let e = F(A, i.replace(/^\//, ""));
624
- if (await Z(e)) {
625
- let t = await B.readFile(e);
644
+ if (/\.[a-z0-9]+$/i.test(r)) {
645
+ let e = z(O, r.replace(/^\//, ""));
646
+ if (await Q(e)) {
647
+ let t = await H.readFile(e);
626
648
  return {
627
649
  status: 200,
628
- headers: { "content-type": ge(e) },
650
+ headers: { "content-type": _e(e) },
629
651
  body: t
630
652
  };
631
653
  }
632
654
  }
633
- let d = ve(i, K);
634
- if (!d) return {
655
+ let f = be(r, G);
656
+ if (!f) return {
635
657
  status: 404,
636
658
  headers: { "content-type": "text/plain" },
637
659
  body: "not found"
638
660
  };
639
- let m = X.get(d.route.pattern), h = r["x-tenant"] ?? "anonymous", g = (await Y.getHelpers()).i18n?.resolve(r.cookie, r["accept-language"])?.locale, _ = e(i, {
661
+ let m = Y.get(f.route.pattern), h = t["x-tenant"] ?? "anonymous", g = (await q.getHelpers()).i18n?.resolve(t.cookie, t["accept-language"])?.locale, _ = a(r, {
640
662
  ...m?.tenantAware ? { tenant: h } : {},
641
663
  ...g ? { locale: g } : {}
642
- }), v = H.get(_), y = Date.now();
643
- if (v && te(v, y)) return x.emit("cache", {
664
+ }), v = B.get(_), b = Date.now();
665
+ if (v && p(v, b)) return y.emit("cache", {
644
666
  kind: "HIT",
645
667
  key: _,
646
- ageMs: y - v.renderedAt
668
+ ageMs: b - v.renderedAt
647
669
  }), {
648
670
  status: 200,
649
671
  headers: {
@@ -651,42 +673,42 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
651
673
  "x-voltro-rendered-by": "isr",
652
674
  "x-voltro-cache": "HIT",
653
675
  "x-voltro-cache-key": _,
654
- "x-voltro-cache-age-ms": String(y - v.renderedAt)
676
+ "x-voltro-cache-age-ms": String(b - v.renderedAt)
655
677
  },
656
678
  body: v.html
657
679
  };
658
- if (v && o(v, y)) return x.emit("cache", {
680
+ if (v && A(v, b)) return y.emit("cache", {
659
681
  kind: "STALE",
660
682
  key: _,
661
- ageMs: y - v.renderedAt
683
+ ageMs: b - v.renderedAt
662
684
  }), (async () => {
663
685
  try {
664
- let e = await ye({
665
- provider: Y,
666
- root: l,
667
- route: d.route,
668
- params: d.params,
669
- pathname: i,
670
- dirs: G,
686
+ let n = await xe({
687
+ provider: q,
688
+ root: s,
689
+ route: f.route,
690
+ params: f.params,
691
+ pathname: r,
692
+ dirs: W,
671
693
  shellTemplate: R,
672
- requestHeaders: r,
673
- apiOrigin: V,
674
- requestUrl: n,
694
+ requestHeaders: t,
695
+ apiOrigin: ce,
696
+ requestUrl: e,
675
697
  buffered: !0
676
698
  });
677
- if (e && "html" in e && e.renderMode === "isr" && e.revalidateMs !== null) {
678
- let t = X.get(d.route.pattern)?.staleWhileRevalidateMs ?? 0, n = Date.now();
679
- H.set(_, {
680
- html: e.html,
681
- renderedAt: n,
682
- expiresAt: n + e.revalidateMs,
683
- servableUntil: n + e.revalidateMs + t,
684
- revalidateMs: e.revalidateMs,
685
- staleWhileRevalidateMs: t
699
+ if (n && "html" in n && n.renderMode === "isr" && n.revalidateMs !== null) {
700
+ let e = Y.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
701
+ B.set(_, {
702
+ html: n.html,
703
+ renderedAt: t,
704
+ expiresAt: t + n.revalidateMs,
705
+ servableUntil: t + n.revalidateMs + e,
706
+ revalidateMs: n.revalidateMs,
707
+ staleWhileRevalidateMs: e
686
708
  });
687
709
  }
688
710
  } catch (e) {
689
- J.warn("background SWR refresh failed", { url: i }, e);
711
+ J.warn("background SWR refresh failed", { url: r }, e);
690
712
  }
691
713
  })(), {
692
714
  status: 200,
@@ -695,24 +717,24 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
695
717
  "x-voltro-rendered-by": "isr",
696
718
  "x-voltro-cache": "STALE",
697
719
  "x-voltro-cache-key": _,
698
- "x-voltro-cache-age-ms": String(y - v.renderedAt)
720
+ "x-voltro-cache-age-ms": String(b - v.renderedAt)
699
721
  },
700
722
  body: v.html
701
723
  };
702
724
  try {
703
- let e = await ye({
704
- provider: Y,
705
- root: l,
706
- route: d.route,
707
- params: d.params,
708
- pathname: i,
709
- dirs: G,
725
+ let n = await xe({
726
+ provider: q,
727
+ root: s,
728
+ route: f.route,
729
+ params: f.params,
730
+ pathname: r,
731
+ dirs: W,
710
732
  shellTemplate: R,
711
- requestHeaders: r,
712
- apiOrigin: V,
713
- requestUrl: n
733
+ requestHeaders: t,
734
+ apiOrigin: ce,
735
+ requestUrl: e
714
736
  });
715
- if (!e) return {
737
+ if (!n) return {
716
738
  status: 200,
717
739
  headers: {
718
740
  "content-type": "text/html; charset=utf-8",
@@ -720,16 +742,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
720
742
  },
721
743
  body: R
722
744
  };
723
- if ("stream" in e) return {
745
+ if ("stream" in n) return {
724
746
  status: 200,
725
- headers: { "x-voltro-rendered-by": "ssr" },
747
+ headers: { "x-voltro-rendered-by": n.renderMode },
726
748
  body: "",
727
- stream: e.stream
749
+ stream: n.stream
728
750
  };
729
- if ("control" in e) return e.control === "redirect" ? {
730
- status: e.status,
751
+ if ("control" in n) return n.control === "redirect" ? {
752
+ status: n.status,
731
753
  headers: {
732
- location: e.location,
754
+ location: n.location,
733
755
  "x-voltro-rendered-by": "loader-redirect"
734
756
  },
735
757
  body: ""
@@ -741,36 +763,36 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
741
763
  },
742
764
  body: "not found"
743
765
  };
744
- let t = {
766
+ let i = {
745
767
  "content-type": "text/html; charset=utf-8",
746
- "x-voltro-rendered-by": e.renderMode
768
+ "x-voltro-rendered-by": n.renderMode
747
769
  };
748
- if (e.renderMode === "isr" && e.revalidateMs !== null) {
749
- let n = Date.now(), r = X.get(d.route.pattern)?.staleWhileRevalidateMs ?? 0;
750
- H.set(_, {
751
- html: e.html,
752
- renderedAt: n,
753
- expiresAt: n + e.revalidateMs,
754
- servableUntil: n + e.revalidateMs + r,
755
- revalidateMs: e.revalidateMs,
756
- staleWhileRevalidateMs: r
757
- }), t["x-voltro-cache"] = "MISS", t["x-voltro-cache-key"] = _, t["x-voltro-cache-revalidate-ms"] = String(e.revalidateMs), r > 0 && (t["x-voltro-cache-swr-ms"] = String(r)), x.emit("cache", {
770
+ if (n.renderMode === "isr" && n.revalidateMs !== null) {
771
+ let e = Date.now(), t = Y.get(f.route.pattern)?.staleWhileRevalidateMs ?? 0;
772
+ B.set(_, {
773
+ html: n.html,
774
+ renderedAt: e,
775
+ expiresAt: e + n.revalidateMs,
776
+ servableUntil: e + n.revalidateMs + t,
777
+ revalidateMs: n.revalidateMs,
778
+ staleWhileRevalidateMs: t
779
+ }), i["x-voltro-cache"] = "MISS", i["x-voltro-cache-key"] = _, i["x-voltro-cache-revalidate-ms"] = String(n.revalidateMs), t > 0 && (i["x-voltro-cache-swr-ms"] = String(t)), y.emit("cache", {
758
780
  kind: "MISS",
759
781
  key: _,
760
- revalidateMs: e.revalidateMs,
761
- swrMs: r
782
+ revalidateMs: n.revalidateMs,
783
+ swrMs: t
762
784
  });
763
- } else e.renderMode === "isr" && (t["x-voltro-cache"] = "BYPASS", x.emit("cache", {
785
+ } else n.renderMode === "isr" && (i["x-voltro-cache"] = "BYPASS", y.emit("cache", {
764
786
  kind: "BYPASS",
765
787
  key: _
766
788
  }));
767
789
  return {
768
790
  status: 200,
769
- headers: t,
770
- body: e.html
791
+ headers: i,
792
+ body: n.html
771
793
  };
772
794
  } catch (e) {
773
- return J.error("render error", { url: i }, e), b(e) ? {
795
+ return J.error("render error", { url: r }, e), T(e) ? {
774
796
  status: 500,
775
797
  headers: {
776
798
  "content-type": "text/plain; charset=utf-8",
@@ -783,18 +805,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
783
805
  body: "server error"
784
806
  };
785
807
  }
786
- }, je = !1, Me = le(async (e, t) => {
808
+ }, je = !1, Me = de(async (e, t) => {
787
809
  let n = e.url ?? "/", r = Date.now(), i = {};
788
810
  for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
789
- let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
790
- if (o === "/internal/liveness") {
811
+ let a = n.split("?")[0] ?? "/", o = (e.method ?? "GET").toUpperCase();
812
+ if (a === "/internal/liveness") {
791
813
  t.writeHead(200, {
792
814
  "content-type": "text/plain",
793
815
  "cache-control": "no-store"
794
816
  }), t.end("ok");
795
817
  return;
796
818
  }
797
- if (o === "/internal/readiness") {
819
+ if (a === "/internal/readiness") {
798
820
  let e = je ? 200 : 503;
799
821
  t.writeHead(e, {
800
822
  "content-type": "text/plain",
@@ -802,12 +824,12 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
802
824
  }), t.end(je ? "ready" : "not-ready");
803
825
  return;
804
826
  }
805
- if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
806
- let e = T(i.origin);
827
+ if (o === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
828
+ let e = x(i.origin);
807
829
  t.writeHead(204, e), t.end();
808
830
  return;
809
831
  }
810
- if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
832
+ if (d.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
811
833
  let r = new URL(n, "http://x").searchParams.get("target");
812
834
  if (!r) {
813
835
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
@@ -816,18 +838,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
816
838
  try {
817
839
  let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
818
840
  a && (n.authorization = Array.isArray(a) ? a[0] : a);
819
- let o;
820
- if (s && s !== "GET" && s !== "HEAD") {
841
+ let s;
842
+ if (o && o !== "GET" && o !== "HEAD") {
821
843
  let t = [];
822
844
  for await (let n of e) t.push(n);
823
- o = Buffer.concat(t);
845
+ s = Buffer.concat(t);
824
846
  let r = i["content-type"];
825
847
  r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
826
848
  }
827
849
  let c = await fetch(r, {
828
- method: s,
850
+ method: o,
829
851
  headers: n,
830
- ...o ? { body: new Uint8Array(o.buffer, o.byteOffset, o.byteLength) } : {}
852
+ ...s ? { body: new Uint8Array(s.buffer, s.byteOffset, s.byteLength) } : {}
831
853
  }), l = Buffer.from(await c.arrayBuffer());
832
854
  t.writeHead(c.status, {
833
855
  "content-type": c.headers.get("content-type") ?? "application/octet-stream",
@@ -838,7 +860,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
838
860
  }
839
861
  return;
840
862
  }
841
- if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
863
+ if (d.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
842
864
  let r = new URL(n, "http://x").searchParams.get("target");
843
865
  if (!r) {
844
866
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
@@ -880,16 +902,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
880
902
  }
881
903
  return;
882
904
  }
883
- if (o === "/_voltro/inspect/stream") {
884
- let n = T(i.origin);
885
- if (S()) {
905
+ if (a === "/_voltro/inspect/stream") {
906
+ let n = x(i.origin);
907
+ if (w()) {
886
908
  t.writeHead(503, {
887
909
  "content-type": "application/json",
888
910
  ...n
889
911
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
890
912
  return;
891
913
  }
892
- let r = h(i);
914
+ let r = u(i);
893
915
  if (!r.ok) {
894
916
  t.writeHead(401, {
895
917
  "content-type": "application/json",
@@ -907,29 +929,29 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
907
929
  "x-accel-buffering": "no",
908
930
  ...n
909
931
  }), t.flushHeaders(), t.write("retry: 5000\n\n");
910
- for (let e of x.buffered()) t.write(m(e));
911
- let o = x.subscribe((e) => {
912
- t.write(m(e));
913
- }), s = setInterval(() => {
914
- t.write(a());
915
- }, 15e3), c = () => {
916
- clearInterval(s), o();
932
+ for (let e of y.buffered()) t.write(h(e));
933
+ let a = y.subscribe((e) => {
934
+ t.write(h(e));
935
+ }), o = setInterval(() => {
936
+ t.write(m());
937
+ }, 15e3), s = () => {
938
+ clearInterval(o), a();
917
939
  };
918
- e.on("close", c), t.on("close", c);
940
+ e.on("close", s), t.on("close", s);
919
941
  return;
920
942
  }
921
943
  try {
922
944
  let e = await Ae(n, i);
923
- if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
945
+ if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !a.startsWith("/_voltro/inspect")) {
924
946
  let t = Date.now() - r;
925
- x.emit("request", {
926
- url: o,
947
+ y.emit("request", {
948
+ url: a,
927
949
  status: e.status,
928
950
  durationMs: t,
929
951
  renderedBy: e.headers["x-voltro-rendered-by"],
930
952
  cache: e.headers["x-voltro-cache"]
931
953
  });
932
- let n = ve(o, K)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
954
+ let n = be(a, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
933
955
  Te.record({
934
956
  kind: "request",
935
957
  tag: n,
@@ -941,51 +963,51 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
941
963
  t.writeHead(500, { "content-type": "text/plain" }), t.end(`internal error: ${e.message}`);
942
964
  }
943
965
  });
944
- await new Promise((e) => Me.listen(C, "::", e)), je = !0, J.info(`listening on http://localhost:${C}`, {
945
- port: C,
946
- distDir: A
966
+ await new Promise((e) => Me.listen(E, "::", e)), je = !0, J.info(`listening on http://localhost:${E}`, {
967
+ port: E,
968
+ distDir: O
947
969
  }), J.debug("dynamic + ssr/isr routes resolve via SSR loader");
948
970
  try {
949
- await w({
971
+ await D({
950
972
  id: P,
951
973
  name: N,
952
974
  kind: "web",
953
- url: `http://localhost:${C}`,
975
+ url: `http://localhost:${E}`,
954
976
  pid: process.pid,
955
977
  status: "live",
956
- logFile: I.path
978
+ logFile: F.path
957
979
  });
958
- let e = u(l);
980
+ let e = ae(s);
959
981
  if (e) {
960
- let t = await oe({ dashboardAppPath: e });
982
+ let t = await r({ dashboardAppPath: e });
961
983
  t.status === "launched" ? J.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && J.debug(`dashboard already running on :${t.port}`, { port: t.port });
962
984
  }
963
985
  setInterval(() => {
964
- w({
986
+ D({
965
987
  id: P,
966
988
  name: N,
967
989
  kind: "web",
968
- url: `http://localhost:${C}`,
990
+ url: `http://localhost:${E}`,
969
991
  pid: process.pid,
970
992
  status: "live",
971
- logFile: I.path
993
+ logFile: F.path
972
994
  }).catch(() => {});
973
995
  }, 1e4).unref();
974
996
  } catch (e) {
975
997
  J.warn("runtime-registry write failed", {}, e);
976
998
  }
977
- se({
978
- app: f.name ?? "unnamed",
999
+ le({
1000
+ app: d.name ?? "unnamed",
979
1001
  kind: "web",
980
- url: `http://localhost:${C}`,
1002
+ url: `http://localhost:${E}`,
981
1003
  bootMs: Date.now() - v
982
1004
  });
983
- let Ne = !1, Pe = (e) => async () => {
1005
+ let Ne = !1, Pe = (t) => async () => {
984
1006
  if (!Ne) {
985
- if (Ne = !0, J.info(`received ${e}, shutting down`, { signal: e }), Me.close(), await we.stop(), U) try {
986
- await U.end();
1007
+ if (Ne = !0, J.info(`received ${t}, shutting down`, { signal: t }), Me.close(), await we.stop(), V) try {
1008
+ await V.end();
987
1009
  } catch {}
988
- await Y.close(), await c(P), await I.dispose(), process.exit(0);
1010
+ await q.close(), await e(P), await F.dispose(), process.exit(0);
989
1011
  }
990
1012
  };
991
1013
  process.on("SIGINT", Pe("SIGINT")), process.on("SIGTERM", Pe("SIGTERM"));
@@ -997,10 +1019,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
997
1019
  e.unref();
998
1020
  }
999
1021
  return new Promise(() => {});
1000
- }, Ce = async (e) => {
1022
+ }, Te = async (e) => {
1001
1023
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
1002
- let t = await Se(I(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1024
+ let t = await we(se(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1003
1025
  return t.ran ? t.exitCode : (J.error("no web app found at this path"), 1);
1004
1026
  };
1005
1027
  //#endregion
1006
- export { ue as n, Ce as t };
1028
+ export { Te as t };