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