@voltro/cli 0.39.1 → 0.40.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.
- package/CHANGELOG.md +158 -0
- package/dist/agentsMd-Bu_XQgVf.js +2 -0
- package/dist/{agentsMd-7zI2h5l9.js → agentsMd-D6yD7IQv.js} +31 -14
- package/dist/apiBuild-BIyGkym8.js +2 -0
- package/dist/{apiBuild-D9FB13_2.js → apiBuild-C8xBEYbL.js} +2 -2
- package/dist/bin.js +1 -1
- package/dist/{build-DORV5mLM.js → build-CkhFGnKA.js} +168 -165
- package/dist/{checkCommand-Bf6oMao4.js → checkCommand-BcXJa2IS.js} +2 -2
- package/dist/{checkCommand-D9qK_gtA.js → checkCommand-QbHshOac.js} +1 -1
- package/dist/{cloudCmd-C42gaO8s.js → cloudCmd-F4YJeqM3.js} +1 -1
- package/dist/{codegenCommand-CxOyKmc1.js → codegenCommand-DF2OJh3O.js} +2 -2
- package/dist/{codemodRunner-D-jTyvWo.js → codemodRunner-BcOvi4A2.js} +103 -0
- package/dist/{commands-D6aW_6AR.js → commands-7Z7-HOE3.js} +30 -30
- package/dist/{dashboardCommand-CwTZh-XZ.js → dashboardCommand-CUycH6dR.js} +5 -5
- package/dist/{dataCommand-Cc9RiLQZ.js → dataCommand-By78lscK.js} +1 -1
- package/dist/{dev-CjJAasDs.js → dev-D8JSKlBM.js} +1 -1
- package/dist/{dev-3mgc8c-H.js → dev-Dh1NuYx1.js} +1569 -1569
- package/dist/{doctorCommand-oLuzc-aC.js → doctorCommand-C-8-Z9D6.js} +36 -36
- package/dist/doctorCommand-FhQ7EVYL.js +2 -0
- package/dist/{dormancyCommand-Bxe4WtHU.js → dormancyCommand-A79Odglm.js} +1 -1
- package/dist/{embeddingsCommand-CyNQkFIc.js → embeddingsCommand-CoiyHfkY.js} +1 -1
- package/dist/{envCommand-CAkSgBbh.js → envCommand-B6d0s-jZ.js} +8 -8
- package/dist/{evolveCommand-CWhBoe_P.js → evolveCommand-BC5a9lxX.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-CTo8Jnhq.js → infoCommand-ZqSVzJZ4.js} +1 -1
- package/dist/{metaCommands-DUYR--Ts.js → metaCommands-CfRLra0s.js} +1 -1
- package/dist/{projectScaffold-BEhhHjPr.js → projectScaffold-BIl97_E6.js} +1 -1
- package/dist/{projectScaffold-BvhLOrLq.js → projectScaffold-mIX_DpSe.js} +1 -1
- package/dist/{runtimeTrace-gNXeLf6H.js → runtimeTrace-BslKJjDY.js} +1 -1
- package/dist/{sdkgen-C8zz10-X.js → sdkgen-DQ8uEmmn.js} +1 -1
- package/dist/serveCommand-BmvEQCMS.js +2 -0
- package/dist/{serveCommand-BpK8-m1N.js → serveCommand-Dqb9Ku1-.js} +656 -656
- package/dist/serveEntry.js +1 -1
- package/dist/{start-BNuTWdRd.js → start-BA7txHhY.js} +1 -1
- package/dist/{start-ft_KzFTd.js → start-dkNYKtgQ.js} +342 -318
- package/dist/startEntry.js +1 -1
- package/dist/updateCommand-BauSVxPp.js +2 -0
- package/dist/{updateCommand-CHBmCB17.js → updateCommand-eoGpZr3E.js} +1 -1
- package/dist/webDev-CBbKs4dZ.js +2 -0
- package/dist/{webDev-CTpSY-e_.js → webDev-bybjZA0o.js} +240 -186
- package/dist/{webhooksCommand-EccPZQZ4.js → webhooksCommand-DubZWNOx.js} +1 -1
- package/package.json +29 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/data.md +43 -0
- package/templates/agent-docs/routing.md +40 -0
- package/templates/agent-docs/whats-new.md +132 -26
- package/templates/apps/api-ai/package.json +7 -7
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +10 -10
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-durable/tests/orders.place.test.ts +17 -4
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-versioning/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/changelog/src/pages/[slug]/page.test.tsx +8 -1
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +9 -9
- package/templates/apps/frontend-auth/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-cms/package.json +9 -9
- package/templates/apps/frontend-collab/package.json +10 -10
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +7 -7
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +8 -8
- package/templates/apps/frontend-saas/package.json +8 -8
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/templates/apps/frontend-status/package.json +8 -8
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/agentsMd-BFCXh2gl.js +0 -2
- package/dist/apiBuild-BmR_bIxN.js +0 -2
- package/dist/doctorCommand-Cghssndo.js +0 -2
- package/dist/serveCommand-CW-goXvh.js +0 -2
- package/dist/updateCommand-6FMU2klq.js +0 -2
- package/dist/webDev-id3I5PvG.js +0 -2
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { i as e, t } from "./nodeEnvironment-cGFAj1J8.js";
|
|
2
2
|
import { r as n } from "./appPort-B_HpJ_ck.js";
|
|
3
|
-
import { A as r, B as i, C as a, D as o, E as s,
|
|
4
|
-
import { o as
|
|
5
|
-
import { A as
|
|
6
|
-
import { a as
|
|
7
|
-
import { i as
|
|
8
|
-
import { n as
|
|
9
|
-
import { t as
|
|
10
|
-
import { t as
|
|
11
|
-
import { dirname as
|
|
12
|
-
import { promises as
|
|
13
|
-
import { fileURLToPath as
|
|
14
|
-
import { createLogger as
|
|
15
|
-
import { snapshotMetricsSync as
|
|
16
|
-
import { createServer as
|
|
3
|
+
import { A as r, B as i, C as a, D as o, E as s, F as c, G as l, K as u, L as d, M as f, N as p, O as m, P as h, Q as g, R as _, S as v, T as y, U as ee, W as b, Z as x, a as S, b as C, d as w, dt as T, f as E, i as te, j as D, k as ne, mt as O, n as re, q as ie, s as ae, w as oe, x as k, y as se } from "./webDev-bybjZA0o.js";
|
|
4
|
+
import { o as A, t as j } from "./connectionConfig-Bk9IC7D0.js";
|
|
5
|
+
import { A as M, D as N, a as ce, h as le, j as ue, k as P } from "./inspect-B7U7Cl_Z.js";
|
|
6
|
+
import { a as de, c as F, d as fe, f as I, l as pe, p as me, u as he } from "./renderModeScan-D7J1B7Kw.js";
|
|
7
|
+
import { i as ge, n as _e, r as ve, t as ye } from "./runtimeRegistry-DMeKfTHP.js";
|
|
8
|
+
import { n as be } from "./logFileSink-B4uP8pvf.js";
|
|
9
|
+
import { t as xe } from "./inspectMetrics-CfdKLh6t.js";
|
|
10
|
+
import { t as Se } from "./bootTiming-BdyP9nYw.js";
|
|
11
|
+
import { dirname as L, extname as R, join as z, resolve as B } from "node:path";
|
|
12
|
+
import { promises as V } from "node:fs";
|
|
13
|
+
import { fileURLToPath as Ce, pathToFileURL as we } from "node:url";
|
|
14
|
+
import { createLogger as H, printReadyBlock as Te } from "@voltro/logger";
|
|
15
|
+
import { snapshotMetricsSync as Ee } from "@voltro/runtime";
|
|
16
|
+
import { createServer as De } from "node:http";
|
|
17
17
|
//#region src/isrCdcInvalidator.ts
|
|
18
|
-
var
|
|
18
|
+
var U = H({ scope: "voltro:start:cdc" }), W = (e) => (t) => {
|
|
19
19
|
let n = 0;
|
|
20
20
|
for (let [r, i] of e.tableSubscriptionsByPattern) {
|
|
21
21
|
if (!i.includes(t)) continue;
|
|
@@ -26,17 +26,17 @@ var V = B({ scope: "voltro:start:cdc" }), H = (e) => (t) => {
|
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
28
|
return n;
|
|
29
|
-
},
|
|
30
|
-
let t = e.channel ?? "framework_changes", n =
|
|
29
|
+
}, G = () => j() ? A() : null, Oe = (e) => {
|
|
30
|
+
let t = e.channel ?? "framework_changes", n = W(e), r = null, i = null;
|
|
31
31
|
return {
|
|
32
32
|
start: async () => {
|
|
33
33
|
if (e.tableSubscriptionsByPattern.size === 0) {
|
|
34
|
-
|
|
34
|
+
U.debug("skipped — no pages declare cacheInvalidatesOn");
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
let a =
|
|
37
|
+
let a = G();
|
|
38
38
|
if (!a) {
|
|
39
|
-
|
|
39
|
+
U.warn(`${e.tableSubscriptionsByPattern.size} route(s) declare \`cacheInvalidatesOn\` and will NOT be invalidated live — no database is configured for this web process. Set DB_URL (or DB_HOST / PG_HOST) so the CDC listener can connect; until then those routes go stale until their \`revalidate\` window expires.`, { routes: [...e.tableSubscriptionsByPattern.keys()] });
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
r = new (await (import("pg"))).default.Client(a), await r.connect(), i = (e) => {
|
|
@@ -45,16 +45,16 @@ var V = B({ scope: "voltro:start:cdc" }), H = (e) => (t) => {
|
|
|
45
45
|
try {
|
|
46
46
|
r = JSON.parse(e.payload);
|
|
47
47
|
} catch (e) {
|
|
48
|
-
|
|
48
|
+
U.warn("bad CDC payload", {}, e);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
let i = n(r.table);
|
|
52
|
-
i > 0 &&
|
|
52
|
+
i > 0 && U.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
|
|
53
53
|
op: r.op,
|
|
54
54
|
table: r.table,
|
|
55
55
|
dropped: i
|
|
56
56
|
});
|
|
57
|
-
}, r.on("notification", i), await r.query(`LISTEN ${t}`),
|
|
57
|
+
}, r.on("notification", i), await r.query(`LISTEN ${t}`), U.info(`LISTEN ${t}`, {
|
|
58
58
|
channel: t,
|
|
59
59
|
..."connectionString" in a ? { target: a.connectionString.replace(/\/\/[^@/]*@/, "//") } : {
|
|
60
60
|
host: a.host,
|
|
@@ -72,7 +72,7 @@ var V = B({ scope: "voltro:start:cdc" }), H = (e) => (t) => {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
-
},
|
|
75
|
+
}, K = H({ scope: "voltro:start:isr-cache" }), q = "voltro_isr_cache", ke = (e) => `
|
|
76
76
|
CREATE TABLE IF NOT EXISTS ${e} (
|
|
77
77
|
cache_key TEXT PRIMARY KEY,
|
|
78
78
|
html TEXT NOT NULL,
|
|
@@ -83,9 +83,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
|
|
|
83
83
|
stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
|
|
84
84
|
);
|
|
85
85
|
CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
86
|
-
`,
|
|
87
|
-
let t = e.tableName ??
|
|
88
|
-
i || (i = !0, await n.query(
|
|
86
|
+
`, Ae = (e) => {
|
|
87
|
+
let t = e.tableName ?? q, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
|
|
88
|
+
i || (i = !0, await n.query(ke(t)));
|
|
89
89
|
})().then(async () => {
|
|
90
90
|
let e = await n.query(`SELECT * FROM ${t}`);
|
|
91
91
|
for (let t of e.rows) r.set(t.cache_key, {
|
|
@@ -97,10 +97,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
97
97
|
staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
|
|
98
98
|
});
|
|
99
99
|
}).catch((e) => {
|
|
100
|
-
|
|
100
|
+
K.warn("postgres bootstrap failed", {}, e);
|
|
101
101
|
}), o = (e, t) => {
|
|
102
102
|
a.then(() => n.query(e, t)).catch((e) => {
|
|
103
|
-
|
|
103
|
+
K.warn("postgres write failed", {}, e);
|
|
104
104
|
});
|
|
105
105
|
};
|
|
106
106
|
return {
|
|
@@ -145,14 +145,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
145
145
|
return Array.from(r.entries());
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
|
-
},
|
|
148
|
+
}, J = H({ scope: "voltro:start" }), je = await (async () => {
|
|
149
149
|
try {
|
|
150
|
-
let e =
|
|
150
|
+
let e = z(L(Ce(import.meta.url)), "..", "package.json"), t = await V.readFile(e, "utf8");
|
|
151
151
|
return JSON.parse(t).version ?? "0.0.0";
|
|
152
152
|
} catch {
|
|
153
153
|
return "0.0.0";
|
|
154
154
|
}
|
|
155
|
-
})(),
|
|
155
|
+
})(), Y = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", X = (e) => e instanceof Error && e._voltroControl === "not-found", Z = {
|
|
156
156
|
".html": "text/html; charset=utf-8",
|
|
157
157
|
".js": "application/javascript",
|
|
158
158
|
".mjs": "application/javascript",
|
|
@@ -170,13 +170,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
170
170
|
".woff": "font/woff",
|
|
171
171
|
".woff2": "font/woff2",
|
|
172
172
|
".txt": "text/plain; charset=utf-8"
|
|
173
|
-
},
|
|
173
|
+
}, Me = (e) => Z[R(e).toLowerCase()] ?? "application/octet-stream", Ne = (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) => {
|
|
174
174
|
try {
|
|
175
|
-
return await
|
|
175
|
+
return await V.stat(e), !0;
|
|
176
176
|
} catch {
|
|
177
177
|
return !1;
|
|
178
178
|
}
|
|
179
|
-
},
|
|
179
|
+
}, Pe = (e) => {
|
|
180
180
|
let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
|
|
181
181
|
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, "\\$&"));
|
|
182
182
|
let a = i.join("/");
|
|
@@ -185,8 +185,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
185
185
|
paramNames: t,
|
|
186
186
|
priority: n
|
|
187
187
|
};
|
|
188
|
-
},
|
|
189
|
-
let { regex: t, paramNames: n, priority: r } =
|
|
188
|
+
}, Fe = (e) => e.map((e) => {
|
|
189
|
+
let { regex: t, paramNames: n, priority: r } = Pe(e.pattern);
|
|
190
190
|
return {
|
|
191
191
|
pattern: e.pattern,
|
|
192
192
|
file: e.file,
|
|
@@ -195,7 +195,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
195
195
|
paramNames: n,
|
|
196
196
|
priority: r
|
|
197
197
|
};
|
|
198
|
-
}).slice().sort((e, t) => e.priority - t.priority),
|
|
198
|
+
}).slice().sort((e, t) => e.priority - t.priority), Ie = (e, t) => {
|
|
199
199
|
for (let n of t) {
|
|
200
200
|
let t = n.regex.exec(e);
|
|
201
201
|
if (!t) continue;
|
|
@@ -207,12 +207,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
return null;
|
|
210
|
-
},
|
|
211
|
-
let { provider: t, route: n, params: i, pathname: c, dirs: l, shellTemplate: u, requestHeaders: d, requestUrl:
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
}, Le = async (e) => {
|
|
211
|
+
let { provider: t, route: n, params: i, pathname: c, dirs: l, shellTemplate: u, requestHeaders: d, requestUrl: g = "", apiOrigin: _, apiName: ee } = e, { search: b } = h(g), x = await a(e.middleware, {
|
|
212
|
+
pathname: c,
|
|
213
|
+
search: b,
|
|
214
|
+
headers: d,
|
|
215
|
+
cookies: v(d.cookie)
|
|
216
|
+
}), C = te(_, x.headers.cookie, {
|
|
217
|
+
apiName: ee,
|
|
218
|
+
headers: x.headers
|
|
219
|
+
}), w = await t.getPage(n.pattern, n.file), T = F(w, n.file), E = T === "spa" && ae(l, n.dirChain).some((e) => e.hasLayout);
|
|
220
|
+
if (T !== "ssr" && T !== "isr" && !E) return null;
|
|
221
|
+
let ne = ae(l, n.dirChain), O = {}, re = null, ie, oe = new AbortController();
|
|
214
222
|
try {
|
|
215
|
-
(await t.getHelpers()).beginStoreSeeds(), {chain:
|
|
223
|
+
(await t.getHelpers()).beginStoreSeeds(), {chain: ie, segmentLoaderData: O} = await S({
|
|
216
224
|
entries: ne,
|
|
217
225
|
loadLayout: (e) => t.getLayout(e.dir),
|
|
218
226
|
loadError: (e) => t.getError(e.dir),
|
|
@@ -220,87 +228,92 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
220
228
|
ctx: {
|
|
221
229
|
params: i,
|
|
222
230
|
pathname: c,
|
|
223
|
-
search:
|
|
231
|
+
search: b,
|
|
224
232
|
signal: oe.signal,
|
|
225
233
|
headers: d,
|
|
226
|
-
query:
|
|
234
|
+
query: C,
|
|
227
235
|
isServer: !0
|
|
228
236
|
}
|
|
229
|
-
}), typeof
|
|
237
|
+
}), typeof w.loader == "function" && !E && (re = await w.loader({
|
|
230
238
|
params: i,
|
|
231
239
|
pathname: c,
|
|
232
|
-
search:
|
|
240
|
+
search: b,
|
|
233
241
|
signal: oe.signal,
|
|
234
242
|
headers: d,
|
|
235
|
-
query:
|
|
243
|
+
query: C,
|
|
236
244
|
isServer: !0
|
|
237
245
|
}));
|
|
238
246
|
} catch (e) {
|
|
239
|
-
if (
|
|
247
|
+
if (Y(e)) return {
|
|
240
248
|
control: "redirect",
|
|
241
249
|
status: e.status,
|
|
242
|
-
location: e.location
|
|
250
|
+
location: e.location,
|
|
251
|
+
setCookies: x.setCookies
|
|
252
|
+
};
|
|
253
|
+
if (X(e)) return {
|
|
254
|
+
control: "not-found",
|
|
255
|
+
setCookies: x.setCookies
|
|
243
256
|
};
|
|
244
|
-
if (q(e)) return { control: "not-found" };
|
|
245
257
|
throw e;
|
|
246
258
|
}
|
|
247
|
-
let
|
|
248
|
-
|
|
249
|
-
pageMod:
|
|
259
|
+
let k = await t.getHelpers();
|
|
260
|
+
E || await y({
|
|
261
|
+
pageMod: w,
|
|
250
262
|
params: i,
|
|
251
|
-
query:
|
|
252
|
-
apiName:
|
|
253
|
-
seed:
|
|
254
|
-
seedFailure:
|
|
255
|
-
onError: ({ tag: e, apiName: t }, n) =>
|
|
263
|
+
query: C,
|
|
264
|
+
apiName: ee,
|
|
265
|
+
seed: k.seedPreloadedSubscription,
|
|
266
|
+
seedFailure: k.seedPreloadedSubscriptionFailure,
|
|
267
|
+
onError: ({ tag: e, apiName: t }, n) => J.warn("preload seed failed", {
|
|
256
268
|
tag: e,
|
|
257
269
|
apiName: t,
|
|
258
270
|
pathname: c
|
|
259
271
|
}, n)
|
|
260
272
|
});
|
|
261
|
-
let
|
|
273
|
+
let se = {
|
|
262
274
|
pattern: n.pattern,
|
|
263
|
-
Component:
|
|
264
|
-
meta:
|
|
265
|
-
loader:
|
|
266
|
-
ErrorBoundary:
|
|
267
|
-
Pending:
|
|
268
|
-
renderMode:
|
|
269
|
-
chain:
|
|
270
|
-
},
|
|
271
|
-
cookies:
|
|
275
|
+
Component: w.default,
|
|
276
|
+
meta: w.meta,
|
|
277
|
+
loader: w.loader,
|
|
278
|
+
ErrorBoundary: w.ErrorBoundary,
|
|
279
|
+
Pending: w.Pending,
|
|
280
|
+
renderMode: T,
|
|
281
|
+
chain: ie
|
|
282
|
+
}, A = {
|
|
283
|
+
cookies: k.parseCookieHeader(d.cookie),
|
|
272
284
|
headers: d,
|
|
273
|
-
url:
|
|
274
|
-
},
|
|
275
|
-
if (
|
|
276
|
-
let e =
|
|
277
|
-
helpers:
|
|
285
|
+
url: g
|
|
286
|
+
}, j = k.i18n?.resolve(d.cookie, d["accept-language"]), M = w.interactive ?? "full";
|
|
287
|
+
if (E) {
|
|
288
|
+
let e = D({
|
|
289
|
+
helpers: k,
|
|
278
290
|
page: n.pattern,
|
|
279
|
-
interactive:
|
|
291
|
+
interactive: M,
|
|
280
292
|
delivery: "stream",
|
|
281
293
|
renderInput: {
|
|
282
|
-
descriptor:
|
|
294
|
+
descriptor: se,
|
|
283
295
|
params: i,
|
|
284
296
|
pathname: c,
|
|
285
|
-
search:
|
|
286
|
-
segmentLoaderData:
|
|
287
|
-
requestContext:
|
|
288
|
-
...
|
|
289
|
-
outerWrap:
|
|
290
|
-
locale:
|
|
297
|
+
search: b,
|
|
298
|
+
segmentLoaderData: O,
|
|
299
|
+
requestContext: A,
|
|
300
|
+
...j ? {
|
|
301
|
+
outerWrap: j.outerWrap,
|
|
302
|
+
locale: j.locale
|
|
291
303
|
} : {}
|
|
292
304
|
}
|
|
293
|
-
}), t =
|
|
294
|
-
helpers:
|
|
305
|
+
}), t = j?.locale ?? A.cookies["voltro:locale"] ?? "en", r = (t) => p({
|
|
306
|
+
helpers: k,
|
|
295
307
|
prepared: e,
|
|
296
308
|
meta: t,
|
|
297
|
-
interactive:
|
|
309
|
+
interactive: M
|
|
298
310
|
});
|
|
299
311
|
if (e.hasDeferred) {
|
|
300
|
-
let n =
|
|
312
|
+
let n = o({ shell: u });
|
|
301
313
|
return {
|
|
302
314
|
renderMode: "spa",
|
|
303
|
-
|
|
315
|
+
setCookies: x.setCookies,
|
|
316
|
+
stream: (i) => m({
|
|
304
317
|
res: i,
|
|
305
318
|
shell: n,
|
|
306
319
|
htmlLang: t,
|
|
@@ -309,58 +322,60 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
309
322
|
"x-voltro-rendered-by": "spa"
|
|
310
323
|
},
|
|
311
324
|
headInjection: r,
|
|
312
|
-
render: (t) =>
|
|
325
|
+
render: (t) => k.renderPageToStream({
|
|
313
326
|
...e.renderInput,
|
|
314
327
|
...t
|
|
315
328
|
}),
|
|
316
329
|
onShellError: (e) => {
|
|
317
|
-
|
|
330
|
+
J.error("spa layout shell render failed", { pathname: c }, e), i.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), i.end("server error");
|
|
318
331
|
}
|
|
319
332
|
})
|
|
320
333
|
};
|
|
321
334
|
}
|
|
322
|
-
let
|
|
323
|
-
helpers:
|
|
335
|
+
let a = f({
|
|
336
|
+
helpers: k,
|
|
324
337
|
prepared: e
|
|
325
338
|
});
|
|
326
339
|
return {
|
|
327
|
-
html:
|
|
340
|
+
html: s(u.replace("<div id=\"root\"></div>", `<div id="root">${a.body}</div>`), r(a.meta)).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${t}"`),
|
|
328
341
|
renderMode: "spa",
|
|
329
|
-
revalidateMs: null
|
|
342
|
+
revalidateMs: null,
|
|
343
|
+
setCookies: x.setCookies
|
|
330
344
|
};
|
|
331
345
|
}
|
|
332
|
-
let
|
|
333
|
-
helpers:
|
|
346
|
+
let N = r({
|
|
347
|
+
helpers: k,
|
|
334
348
|
page: n.pattern,
|
|
335
349
|
pathname: c,
|
|
336
|
-
renderMode:
|
|
337
|
-
interactive:
|
|
338
|
-
loaderData:
|
|
339
|
-
segmentLoaderData:
|
|
340
|
-
pageLoaderRan: typeof
|
|
341
|
-
}),
|
|
342
|
-
descriptor:
|
|
350
|
+
renderMode: T,
|
|
351
|
+
interactive: M,
|
|
352
|
+
loaderData: re,
|
|
353
|
+
segmentLoaderData: O,
|
|
354
|
+
pageLoaderRan: typeof w.loader == "function"
|
|
355
|
+
}), ce = {
|
|
356
|
+
descriptor: se,
|
|
343
357
|
params: i,
|
|
344
358
|
pathname: c,
|
|
345
|
-
search:
|
|
346
|
-
loaderData:
|
|
347
|
-
segmentLoaderData:
|
|
348
|
-
requestContext:
|
|
349
|
-
...
|
|
350
|
-
outerWrap:
|
|
351
|
-
locale:
|
|
359
|
+
search: b,
|
|
360
|
+
loaderData: N.loaderData,
|
|
361
|
+
segmentLoaderData: N.segmentLoaderData,
|
|
362
|
+
requestContext: A,
|
|
363
|
+
...j ? {
|
|
364
|
+
outerWrap: j.outerWrap,
|
|
365
|
+
locale: j.locale
|
|
352
366
|
} : {}
|
|
353
|
-
},
|
|
354
|
-
|
|
355
|
-
`<meta name="voltro-interactive" content="${
|
|
356
|
-
...
|
|
357
|
-
|
|
367
|
+
}, le = (e) => [
|
|
368
|
+
k.renderMetaToHtml(e),
|
|
369
|
+
`<meta name="voltro-interactive" content="${M}" />`,
|
|
370
|
+
...N.hasDeferred ? [k.renderDeferredRegistryScript()] : [],
|
|
371
|
+
k.renderRouterStateScript(N.stateInput)
|
|
358
372
|
].filter((e) => e.length > 0).join("\n ");
|
|
359
|
-
if (
|
|
360
|
-
let e =
|
|
373
|
+
if (T === "ssr" && M === "full" && e.buffered !== !0) {
|
|
374
|
+
let e = j?.locale ?? A.cookies["voltro:locale"] ?? "en", t = o({ shell: u });
|
|
361
375
|
return {
|
|
362
376
|
renderMode: "ssr",
|
|
363
|
-
|
|
377
|
+
setCookies: x.setCookies,
|
|
378
|
+
stream: (n) => m({
|
|
364
379
|
res: n,
|
|
365
380
|
shell: t,
|
|
366
381
|
htmlLang: e,
|
|
@@ -368,27 +383,28 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
368
383
|
"content-type": "text/html; charset=utf-8",
|
|
369
384
|
"x-voltro-rendered-by": "ssr"
|
|
370
385
|
},
|
|
371
|
-
headInjection:
|
|
372
|
-
render: (e) =>
|
|
373
|
-
...
|
|
386
|
+
headInjection: le,
|
|
387
|
+
render: (e) => k.renderPageToStream({
|
|
388
|
+
...ce,
|
|
374
389
|
...e
|
|
375
390
|
}),
|
|
376
391
|
onShellError: (e) => {
|
|
377
|
-
|
|
392
|
+
J.error("ssr shell render failed", { pathname: c }, e), n.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), n.end("server error");
|
|
378
393
|
}
|
|
379
394
|
})
|
|
380
395
|
};
|
|
381
396
|
}
|
|
382
|
-
let { html:
|
|
383
|
-
|
|
384
|
-
let
|
|
397
|
+
let { html: ue, meta: P } = k.renderPageToHtml(ce), de = le(P), fe = j?.locale ?? A.cookies["voltro:locale"] ?? "en", I = s(u.replace("<div id=\"root\"></div>", `<div id="root">${ue}</div>`), de).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${fe}"`);
|
|
398
|
+
M === "none" && (I = Ne(I));
|
|
399
|
+
let pe = T === "isr" ? me(w.revalidate) : null;
|
|
385
400
|
return {
|
|
386
|
-
html:
|
|
387
|
-
renderMode:
|
|
388
|
-
revalidateMs:
|
|
401
|
+
html: I,
|
|
402
|
+
renderMode: T,
|
|
403
|
+
revalidateMs: pe,
|
|
404
|
+
setCookies: x.setCookies
|
|
389
405
|
};
|
|
390
|
-
},
|
|
391
|
-
let t = await import(
|
|
406
|
+
}, $ = (e) => e === "" ? "/" : e, Re = async (e) => {
|
|
407
|
+
let t = await import(we(e).href);
|
|
392
408
|
return {
|
|
393
409
|
kind: "bundle",
|
|
394
410
|
getPageMeta: () => t.pageMeta,
|
|
@@ -398,18 +414,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
398
414
|
return typeof r == "function" ? await r() : r;
|
|
399
415
|
},
|
|
400
416
|
async getLayout(e) {
|
|
401
|
-
let n = t.layouts[
|
|
402
|
-
if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${
|
|
417
|
+
let n = t.layouts[$(e)];
|
|
418
|
+
if (!n) throw Error(`[voltro start] ssr bundle missing layout for dir ${$(e)}`);
|
|
403
419
|
return typeof n == "function" ? await n() : n;
|
|
404
420
|
},
|
|
405
421
|
async getError(e) {
|
|
406
|
-
let n = t.errors[
|
|
407
|
-
if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${
|
|
422
|
+
let n = t.errors[$(e)];
|
|
423
|
+
if (!n) throw Error(`[voltro start] ssr bundle missing error for dir ${$(e)}`);
|
|
408
424
|
return typeof n == "function" ? await n() : n;
|
|
409
425
|
},
|
|
410
426
|
async getPending(e) {
|
|
411
|
-
let n = t.pendings[
|
|
412
|
-
if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${
|
|
427
|
+
let n = t.pendings[$(e)];
|
|
428
|
+
if (!n) throw Error(`[voltro start] ssr bundle missing pending for dir ${$(e)}`);
|
|
413
429
|
return typeof n == "function" ? await n() : n;
|
|
414
430
|
},
|
|
415
431
|
async getHelpers() {
|
|
@@ -417,8 +433,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
417
433
|
},
|
|
418
434
|
async close() {}
|
|
419
435
|
};
|
|
420
|
-
},
|
|
421
|
-
let n = await
|
|
436
|
+
}, ze = async (e, t) => {
|
|
437
|
+
let n = await O("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
|
|
422
438
|
root: t,
|
|
423
439
|
envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
|
|
424
440
|
plugins: [r(), i()],
|
|
@@ -435,10 +451,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
435
451
|
},
|
|
436
452
|
appType: "custom",
|
|
437
453
|
logLevel: "warn"
|
|
438
|
-
}), o =
|
|
439
|
-
limit:
|
|
440
|
-
onColdStart: (e) =>
|
|
441
|
-
onColdEnd: (e, { durationMs: t, failed: n }) =>
|
|
454
|
+
}), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c = x({
|
|
455
|
+
limit: g(),
|
|
456
|
+
onColdStart: (e) => J.debug("ssr cold-compile start", { id: e }),
|
|
457
|
+
onColdEnd: (e, { durationMs: t, failed: n }) => J.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
|
|
442
458
|
id: e,
|
|
443
459
|
ms: t,
|
|
444
460
|
...n ? { failed: !0 } : {}
|
|
@@ -447,16 +463,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
447
463
|
return {
|
|
448
464
|
kind: "middleware",
|
|
449
465
|
async getPage(e, t) {
|
|
450
|
-
return l(
|
|
466
|
+
return l(z(o, t));
|
|
451
467
|
},
|
|
452
468
|
async getLayout(e) {
|
|
453
|
-
return l(
|
|
469
|
+
return l(z(s(e), "layout.tsx"));
|
|
454
470
|
},
|
|
455
471
|
async getError(e) {
|
|
456
|
-
return l(
|
|
472
|
+
return l(z(s(e), "error.tsx"));
|
|
457
473
|
},
|
|
458
474
|
async getPending(e) {
|
|
459
|
-
return l(
|
|
475
|
+
return l(z(s(e), "loading.tsx"));
|
|
460
476
|
},
|
|
461
477
|
async getHelpers() {
|
|
462
478
|
return await l("@voltro/web/ssr");
|
|
@@ -465,99 +481,101 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
465
481
|
await a.close();
|
|
466
482
|
}
|
|
467
483
|
};
|
|
468
|
-
},
|
|
469
|
-
let r =
|
|
484
|
+
}, Be = async (t) => {
|
|
485
|
+
let r = Se(), a = await w(t);
|
|
470
486
|
if (!a) return {
|
|
471
487
|
ran: !1,
|
|
472
488
|
exitCode: 0
|
|
473
489
|
};
|
|
474
|
-
if (a.type !== "web") return
|
|
490
|
+
if (a.type !== "web") return J.error("only web apps are supported by `voltro start`"), {
|
|
475
491
|
ran: !0,
|
|
476
492
|
exitCode: 1
|
|
477
493
|
};
|
|
478
|
-
let { resolved: o } = await
|
|
494
|
+
let { resolved: o } = await T({
|
|
479
495
|
rawEnv: a.env,
|
|
480
496
|
appType: "web",
|
|
481
497
|
root: t,
|
|
482
|
-
log:
|
|
498
|
+
log: J,
|
|
483
499
|
generateTypes: !1
|
|
484
500
|
}), s = o.publicValues;
|
|
485
501
|
r.mark("config");
|
|
486
|
-
let
|
|
487
|
-
|
|
488
|
-
let
|
|
502
|
+
let f = u();
|
|
503
|
+
ee(f), J.info("booting voltro start", { app: a.name ?? "(unnamed)" });
|
|
504
|
+
let p = n({
|
|
489
505
|
kind: "web",
|
|
490
506
|
configPort: a.port,
|
|
491
507
|
env: process.env,
|
|
492
|
-
dashboardPin: process.env[
|
|
508
|
+
dashboardPin: process.env[c] === "1"
|
|
493
509
|
});
|
|
494
|
-
for (let e of
|
|
495
|
-
let m =
|
|
496
|
-
if (!await
|
|
510
|
+
for (let e of p.warnings) J.warn(e);
|
|
511
|
+
let m = p.port, h = z(t, ".framework"), g = z(h, "dist"), v = z(g, "index.html");
|
|
512
|
+
if (!await Q(v)) return J.error("no built dist found — run `voltro build` first", { distDir: g }), {
|
|
497
513
|
ran: !0,
|
|
498
514
|
exitCode: 1
|
|
499
515
|
};
|
|
500
|
-
let
|
|
501
|
-
await
|
|
502
|
-
id:
|
|
503
|
-
name:
|
|
516
|
+
let y = a.name ?? "unnamed", x = ye("web", y, m), S = be(y);
|
|
517
|
+
await ge({
|
|
518
|
+
id: x,
|
|
519
|
+
name: y,
|
|
504
520
|
kind: "web",
|
|
505
521
|
url: `http://localhost:${m}`,
|
|
506
522
|
pid: process.pid,
|
|
507
523
|
status: "booting",
|
|
508
|
-
logFile:
|
|
524
|
+
logFile: S.path
|
|
509
525
|
}).catch(() => {});
|
|
510
|
-
let
|
|
511
|
-
|
|
512
|
-
|
|
526
|
+
let te = z(g, "_voltro", "shell.html"), D = await Q(te) ? await V.readFile(te, "utf8") : await V.readFile(v, "utf8"), O = await E(t, a), F = re(O[0]), me = O[0]?.name, L = await k(t);
|
|
527
|
+
L !== void 0 && J.info("middleware.ts loaded — renews credentials before each SSR render");
|
|
528
|
+
let R, B = null, Ce = process.env.SSR_CACHE === "postgres";
|
|
529
|
+
if (Ce && j()) B = new (await (import("pg"))).default.Client(A()), await B.connect(), R = Ae({ client: B }), J.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
|
|
530
|
+
else if (Ce) {
|
|
513
531
|
let t = "SSR_CACHE=postgres, but nothing in the environment names a database (looked for DB_URL, DB_PRIMARY_URL, DB_DIRECT_URL, DB_MIGRATE_URL, DB_HOST, PG_HOST).";
|
|
514
|
-
if (e()) throw
|
|
515
|
-
|
|
516
|
-
} else
|
|
517
|
-
await
|
|
518
|
-
let
|
|
532
|
+
if (e()) throw J.fatal(`${t} Refusing to fall back to the per-process memory cache: it is not shared between instances and does not survive a restart, so the pages this process serves would differ from its replicas' with nothing to indicate it.`), Error("[voltro start] SSR_CACHE=postgres with no database configured");
|
|
533
|
+
R = I(), J.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
|
|
534
|
+
} else R = I(), J.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
|
|
535
|
+
await C(t, a, O, s);
|
|
536
|
+
let we = z(t, "src", "pages"), { pages: H, dirs: U } = await se(we), W = Fe(H);
|
|
519
537
|
r.mark("scan");
|
|
520
|
-
let
|
|
521
|
-
if (!
|
|
522
|
-
let
|
|
523
|
-
|
|
524
|
-
kind:
|
|
525
|
-
...
|
|
538
|
+
let G = z(g, "server", "ssrEntry.js"), K = await Q(G);
|
|
539
|
+
if (!K && process.env.NODE_ENV === "production") throw J.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${G} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${G}`);
|
|
540
|
+
let q = K ? await Re(G) : await ze(t, h);
|
|
541
|
+
J.info(`ssr loader: ${q.kind}`, {
|
|
542
|
+
kind: q.kind,
|
|
543
|
+
...q.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
|
|
526
544
|
}), r.mark("provider");
|
|
527
|
-
let
|
|
528
|
-
for (let e of
|
|
529
|
-
let t =
|
|
545
|
+
let ke = q.getPageMeta?.(), Y = /* @__PURE__ */ new Map(), X = 0;
|
|
546
|
+
for (let e of H) {
|
|
547
|
+
let t = ke?.[e.pattern];
|
|
530
548
|
if (t) {
|
|
531
|
-
|
|
549
|
+
Y.set(e.pattern, t);
|
|
532
550
|
continue;
|
|
533
551
|
}
|
|
534
552
|
try {
|
|
535
|
-
let t = await
|
|
536
|
-
|
|
553
|
+
let t = await q.getPage(e.pattern, e.file);
|
|
554
|
+
Y.set(e.pattern, de(t, e.file)), X++;
|
|
537
555
|
} catch (t) {
|
|
538
|
-
|
|
556
|
+
J.warn("failed to load page metadata", { pattern: e.pattern }, t);
|
|
539
557
|
}
|
|
540
558
|
}
|
|
541
|
-
|
|
542
|
-
count:
|
|
543
|
-
fromManifest:
|
|
544
|
-
fromModules:
|
|
559
|
+
J.info(`registered ${Y.size} route(s)`, {
|
|
560
|
+
count: Y.size,
|
|
561
|
+
fromManifest: Y.size - X,
|
|
562
|
+
fromModules: X
|
|
545
563
|
}), r.mark("routes");
|
|
546
|
-
let
|
|
547
|
-
for (let e of
|
|
548
|
-
|
|
549
|
-
let
|
|
550
|
-
for (let [e, t] of
|
|
551
|
-
let
|
|
552
|
-
for (let e of
|
|
553
|
-
let $ =
|
|
554
|
-
cache:
|
|
555
|
-
tableSubscriptionsByPattern:
|
|
556
|
-
regexByPattern:
|
|
564
|
+
let Z = /* @__PURE__ */ new Set();
|
|
565
|
+
for (let e of W) Y.get(e.pattern)?.renderMode === "spa" && ae(U, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
|
|
566
|
+
Z.size > 0 && J.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
|
|
567
|
+
let Ne = /* @__PURE__ */ new Map();
|
|
568
|
+
for (let [e, t] of Y) t.cacheInvalidatesOn.length > 0 && Ne.set(e, t.cacheInvalidatesOn);
|
|
569
|
+
let Pe = /* @__PURE__ */ new Map();
|
|
570
|
+
for (let e of W) Pe.set(e.pattern, e.regex);
|
|
571
|
+
let $ = Oe({
|
|
572
|
+
cache: R,
|
|
573
|
+
tableSubscriptionsByPattern: Ne,
|
|
574
|
+
regexByPattern: Pe
|
|
557
575
|
});
|
|
558
576
|
await $.start(), r.mark("cdc");
|
|
559
|
-
let
|
|
560
|
-
let t =
|
|
577
|
+
let Be = xe(), Ve = H.map((e) => {
|
|
578
|
+
let t = Y.get(e.pattern);
|
|
561
579
|
return {
|
|
562
580
|
pattern: e.pattern,
|
|
563
581
|
file: e.file,
|
|
@@ -572,17 +590,17 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
572
590
|
hasMeta: t?.hasMeta ?? !1,
|
|
573
591
|
hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
|
|
574
592
|
};
|
|
575
|
-
}),
|
|
593
|
+
}), He = U.map((e) => ({
|
|
576
594
|
dir: e.dir,
|
|
577
595
|
hasLayout: e.hasLayout,
|
|
578
596
|
hasError: e.hasError,
|
|
579
597
|
hasPending: e.hasPending,
|
|
580
598
|
hasNotFound: e.hasNotFound
|
|
581
|
-
})),
|
|
599
|
+
})), Ue = B ? "postgres" : "memory", We = {
|
|
582
600
|
kind: "web",
|
|
583
601
|
meta: {
|
|
584
602
|
name: a.name ?? "(unnamed)",
|
|
585
|
-
voltroVersion:
|
|
603
|
+
voltroVersion: je,
|
|
586
604
|
port: m,
|
|
587
605
|
mode: "start",
|
|
588
606
|
apis: Object.entries(a.apis ?? {}).map(([e, t]) => {
|
|
@@ -593,10 +611,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
593
611
|
return t.url !== void 0 && (n.url = t.url), n;
|
|
594
612
|
})
|
|
595
613
|
},
|
|
596
|
-
routes:
|
|
597
|
-
dirs:
|
|
614
|
+
routes: Ve,
|
|
615
|
+
dirs: He,
|
|
598
616
|
cache: () => {
|
|
599
|
-
let e = Date.now(), t =
|
|
617
|
+
let e = Date.now(), t = R.snapshot().map(([t, n]) => ({
|
|
600
618
|
key: t,
|
|
601
619
|
renderedAt: n.renderedAt,
|
|
602
620
|
expiresAt: n.expiresAt,
|
|
@@ -607,16 +625,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
607
625
|
staleWhileRevalidateMs: n.staleWhileRevalidateMs
|
|
608
626
|
}));
|
|
609
627
|
return {
|
|
610
|
-
backend:
|
|
611
|
-
size:
|
|
628
|
+
backend: Ue,
|
|
629
|
+
size: R.size(),
|
|
612
630
|
entries: t
|
|
613
631
|
};
|
|
614
632
|
},
|
|
615
|
-
metrics: () =>
|
|
616
|
-
},
|
|
633
|
+
metrics: () => Ee()
|
|
634
|
+
}, Ge = async (e, n) => {
|
|
617
635
|
let r = e.split("?")[0] ?? "/";
|
|
618
636
|
if (a.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
|
|
619
|
-
let e = await
|
|
637
|
+
let e = await _e();
|
|
620
638
|
return {
|
|
621
639
|
status: 200,
|
|
622
640
|
headers: { "content-type": "application/json; charset=utf-8" },
|
|
@@ -659,18 +677,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
659
677
|
};
|
|
660
678
|
}
|
|
661
679
|
if (r === "/_voltro/inspect/logs") {
|
|
662
|
-
let t =
|
|
680
|
+
let t = i(e, b(), n);
|
|
663
681
|
return {
|
|
664
682
|
status: t.status,
|
|
665
683
|
headers: {
|
|
666
684
|
"content-type": t.contentType,
|
|
667
|
-
...
|
|
685
|
+
...N(n.origin)
|
|
668
686
|
},
|
|
669
687
|
body: t.body
|
|
670
688
|
};
|
|
671
689
|
}
|
|
672
690
|
if (r !== "/_voltro/inspect/stream") {
|
|
673
|
-
let t =
|
|
691
|
+
let t = le(e, We, n);
|
|
674
692
|
if (t !== null) return {
|
|
675
693
|
status: t.status,
|
|
676
694
|
headers: {
|
|
@@ -680,36 +698,36 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
680
698
|
body: t.body
|
|
681
699
|
};
|
|
682
700
|
}
|
|
683
|
-
let o =
|
|
684
|
-
if (!c && await
|
|
701
|
+
let o = Ie(r, W), s = o ? Y.get(o.route.pattern)?.renderMode : void 0, c = s === "ssr" || s === "isr" || (o ? Z.has(o.route.pattern) : !1), l = r === "/" ? z(g, "index.html") : z(g, r.replace(/^\//, ""), "index.html");
|
|
702
|
+
if (!c && await Q(l)) return {
|
|
685
703
|
status: 200,
|
|
686
704
|
headers: { "content-type": "text/html; charset=utf-8" },
|
|
687
|
-
body: await
|
|
705
|
+
body: await V.readFile(l)
|
|
688
706
|
};
|
|
689
707
|
if (/\.[a-z0-9]+$/i.test(r)) {
|
|
690
|
-
let e =
|
|
691
|
-
if (await
|
|
692
|
-
let t = await
|
|
708
|
+
let e = z(g, r.replace(/^\//, ""));
|
|
709
|
+
if (await Q(e)) {
|
|
710
|
+
let t = await V.readFile(e);
|
|
693
711
|
return {
|
|
694
712
|
status: 200,
|
|
695
|
-
headers: { "content-type":
|
|
713
|
+
headers: { "content-type": Me(e) },
|
|
696
714
|
body: t
|
|
697
715
|
};
|
|
698
716
|
}
|
|
699
717
|
}
|
|
700
|
-
let
|
|
701
|
-
if (!
|
|
718
|
+
let u = Ie(r, W);
|
|
719
|
+
if (!u) return {
|
|
702
720
|
status: 404,
|
|
703
721
|
headers: { "content-type": "text/plain" },
|
|
704
722
|
body: "not found"
|
|
705
723
|
};
|
|
706
|
-
let
|
|
707
|
-
...
|
|
708
|
-
...
|
|
709
|
-
}), _ =
|
|
710
|
-
if (_ &&
|
|
724
|
+
let d = Y.get(u.route.pattern), p = n["x-tenant"] ?? "anonymous", m = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, h = pe(r, {
|
|
725
|
+
...d?.tenantAware ? { tenant: p } : {},
|
|
726
|
+
...m ? { locale: m } : {}
|
|
727
|
+
}), _ = R.get(h), v = Date.now();
|
|
728
|
+
if (_ && he(_, v)) return f.emit("cache", {
|
|
711
729
|
kind: "HIT",
|
|
712
|
-
key:
|
|
730
|
+
key: h,
|
|
713
731
|
ageMs: v - _.renderedAt
|
|
714
732
|
}), {
|
|
715
733
|
status: 200,
|
|
@@ -717,34 +735,35 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
717
735
|
"content-type": "text/html; charset=utf-8",
|
|
718
736
|
"x-voltro-rendered-by": "isr",
|
|
719
737
|
"x-voltro-cache": "HIT",
|
|
720
|
-
"x-voltro-cache-key":
|
|
738
|
+
"x-voltro-cache-key": h,
|
|
721
739
|
"x-voltro-cache-age-ms": String(v - _.renderedAt)
|
|
722
740
|
},
|
|
723
741
|
body: _.html
|
|
724
742
|
};
|
|
725
|
-
if (_ &&
|
|
743
|
+
if (_ && fe(_, v)) return f.emit("cache", {
|
|
726
744
|
kind: "STALE",
|
|
727
|
-
key:
|
|
745
|
+
key: h,
|
|
728
746
|
ageMs: v - _.renderedAt
|
|
729
747
|
}), (async () => {
|
|
730
748
|
try {
|
|
731
|
-
let i = await
|
|
732
|
-
provider:
|
|
749
|
+
let i = await Le({
|
|
750
|
+
provider: q,
|
|
733
751
|
root: t,
|
|
734
|
-
route:
|
|
735
|
-
params:
|
|
752
|
+
route: u.route,
|
|
753
|
+
params: u.params,
|
|
736
754
|
pathname: r,
|
|
737
|
-
dirs:
|
|
738
|
-
shellTemplate:
|
|
755
|
+
dirs: U,
|
|
756
|
+
shellTemplate: D,
|
|
739
757
|
requestHeaders: n,
|
|
740
|
-
apiOrigin:
|
|
741
|
-
apiName:
|
|
758
|
+
apiOrigin: F,
|
|
759
|
+
apiName: me,
|
|
760
|
+
middleware: L,
|
|
742
761
|
requestUrl: e,
|
|
743
762
|
buffered: !0
|
|
744
763
|
});
|
|
745
764
|
if (i && "html" in i && i.renderMode === "isr" && i.revalidateMs !== null) {
|
|
746
|
-
let e =
|
|
747
|
-
|
|
765
|
+
let e = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
|
|
766
|
+
R.set(h, {
|
|
748
767
|
html: i.html,
|
|
749
768
|
renderedAt: t,
|
|
750
769
|
expiresAt: t + i.revalidateMs,
|
|
@@ -754,7 +773,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
754
773
|
});
|
|
755
774
|
}
|
|
756
775
|
} catch (e) {
|
|
757
|
-
|
|
776
|
+
J.warn("background SWR refresh failed", { url: r }, e);
|
|
758
777
|
}
|
|
759
778
|
})(), {
|
|
760
779
|
status: 200,
|
|
@@ -762,23 +781,24 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
762
781
|
"content-type": "text/html; charset=utf-8",
|
|
763
782
|
"x-voltro-rendered-by": "isr",
|
|
764
783
|
"x-voltro-cache": "STALE",
|
|
765
|
-
"x-voltro-cache-key":
|
|
784
|
+
"x-voltro-cache-key": h,
|
|
766
785
|
"x-voltro-cache-age-ms": String(v - _.renderedAt)
|
|
767
786
|
},
|
|
768
787
|
body: _.html
|
|
769
788
|
};
|
|
770
789
|
try {
|
|
771
|
-
let i = await
|
|
772
|
-
provider:
|
|
790
|
+
let i = await Le({
|
|
791
|
+
provider: q,
|
|
773
792
|
root: t,
|
|
774
|
-
route:
|
|
775
|
-
params:
|
|
793
|
+
route: u.route,
|
|
794
|
+
params: u.params,
|
|
776
795
|
pathname: r,
|
|
777
|
-
dirs:
|
|
778
|
-
shellTemplate:
|
|
796
|
+
dirs: U,
|
|
797
|
+
shellTemplate: D,
|
|
779
798
|
requestHeaders: n,
|
|
780
|
-
apiOrigin:
|
|
781
|
-
apiName:
|
|
799
|
+
apiOrigin: F,
|
|
800
|
+
apiName: me,
|
|
801
|
+
middleware: L,
|
|
782
802
|
requestUrl: e
|
|
783
803
|
});
|
|
784
804
|
if (!i) return {
|
|
@@ -787,59 +807,63 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
787
807
|
"content-type": "text/html; charset=utf-8",
|
|
788
808
|
"x-voltro-rendered-by": "spa-fallback"
|
|
789
809
|
},
|
|
790
|
-
body:
|
|
810
|
+
body: D
|
|
811
|
+
};
|
|
812
|
+
let a = i.setCookies ?? [], o = (e) => a.length === 0 ? e : {
|
|
813
|
+
...e,
|
|
814
|
+
"set-cookie": a.map(oe)
|
|
791
815
|
};
|
|
792
816
|
if ("stream" in i) return {
|
|
793
817
|
status: 200,
|
|
794
|
-
headers: { "x-voltro-rendered-by": i.renderMode },
|
|
818
|
+
headers: o({ "x-voltro-rendered-by": i.renderMode }),
|
|
795
819
|
body: "",
|
|
796
820
|
stream: i.stream
|
|
797
821
|
};
|
|
798
822
|
if ("control" in i) return i.control === "redirect" ? {
|
|
799
823
|
status: i.status,
|
|
800
|
-
headers: {
|
|
824
|
+
headers: o({
|
|
801
825
|
location: i.location,
|
|
802
826
|
"x-voltro-rendered-by": "loader-redirect"
|
|
803
|
-
},
|
|
827
|
+
}),
|
|
804
828
|
body: ""
|
|
805
829
|
} : {
|
|
806
830
|
status: 404,
|
|
807
|
-
headers: {
|
|
831
|
+
headers: o({
|
|
808
832
|
"content-type": "text/plain; charset=utf-8",
|
|
809
833
|
"x-voltro-rendered-by": "loader-not-found"
|
|
810
|
-
},
|
|
834
|
+
}),
|
|
811
835
|
body: "not found"
|
|
812
836
|
};
|
|
813
|
-
let
|
|
837
|
+
let s = o({
|
|
814
838
|
"content-type": "text/html; charset=utf-8",
|
|
815
839
|
"x-voltro-rendered-by": i.renderMode
|
|
816
|
-
};
|
|
840
|
+
});
|
|
817
841
|
if (i.renderMode === "isr" && i.revalidateMs !== null) {
|
|
818
|
-
let e = Date.now(), t =
|
|
819
|
-
|
|
842
|
+
let e = Date.now(), t = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0;
|
|
843
|
+
R.set(h, {
|
|
820
844
|
html: i.html,
|
|
821
845
|
renderedAt: e,
|
|
822
846
|
expiresAt: e + i.revalidateMs,
|
|
823
847
|
servableUntil: e + i.revalidateMs + t,
|
|
824
848
|
revalidateMs: i.revalidateMs,
|
|
825
849
|
staleWhileRevalidateMs: t
|
|
826
|
-
}),
|
|
850
|
+
}), s["x-voltro-cache"] = "MISS", s["x-voltro-cache-key"] = h, s["x-voltro-cache-revalidate-ms"] = String(i.revalidateMs), t > 0 && (s["x-voltro-cache-swr-ms"] = String(t)), f.emit("cache", {
|
|
827
851
|
kind: "MISS",
|
|
828
|
-
key:
|
|
852
|
+
key: h,
|
|
829
853
|
revalidateMs: i.revalidateMs,
|
|
830
854
|
swrMs: t
|
|
831
855
|
});
|
|
832
|
-
} else i.renderMode === "isr" && (
|
|
856
|
+
} else i.renderMode === "isr" && (s["x-voltro-cache"] = "BYPASS", f.emit("cache", {
|
|
833
857
|
kind: "BYPASS",
|
|
834
|
-
key:
|
|
858
|
+
key: h
|
|
835
859
|
}));
|
|
836
860
|
return {
|
|
837
861
|
status: 200,
|
|
838
|
-
headers:
|
|
862
|
+
headers: s,
|
|
839
863
|
body: i.html
|
|
840
864
|
};
|
|
841
865
|
} catch (e) {
|
|
842
|
-
return
|
|
866
|
+
return J.error("render error", { url: r }, e), ne(e) ? {
|
|
843
867
|
status: 500,
|
|
844
868
|
headers: {
|
|
845
869
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -852,7 +876,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
852
876
|
body: "server error"
|
|
853
877
|
};
|
|
854
878
|
}
|
|
855
|
-
},
|
|
879
|
+
}, Ke = !1, qe = De(async (e, t) => {
|
|
856
880
|
let n = e.url ?? "/", r = Date.now(), i = {};
|
|
857
881
|
for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
|
|
858
882
|
let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
|
|
@@ -864,15 +888,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
864
888
|
return;
|
|
865
889
|
}
|
|
866
890
|
if (o === "/internal/readiness") {
|
|
867
|
-
let e =
|
|
891
|
+
let e = Ke ? 200 : 503;
|
|
868
892
|
t.writeHead(e, {
|
|
869
893
|
"content-type": "text/plain",
|
|
870
894
|
"cache-control": "no-store"
|
|
871
|
-
}), t.end(
|
|
895
|
+
}), t.end(Ke ? "ready" : "not-ready");
|
|
872
896
|
return;
|
|
873
897
|
}
|
|
874
898
|
if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
|
|
875
|
-
let e =
|
|
899
|
+
let e = N(i.origin);
|
|
876
900
|
t.writeHead(204, e), t.end();
|
|
877
901
|
return;
|
|
878
902
|
}
|
|
@@ -882,13 +906,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
882
906
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
883
907
|
return;
|
|
884
908
|
}
|
|
885
|
-
if (!
|
|
909
|
+
if (!P(r)) {
|
|
886
910
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
887
911
|
return;
|
|
888
912
|
}
|
|
889
913
|
try {
|
|
890
914
|
let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
|
|
891
|
-
a ? n.authorization = Array.isArray(a) ? a[0] : a :
|
|
915
|
+
a ? n.authorization = Array.isArray(a) ? a[0] : a : ue(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
|
|
892
916
|
let o;
|
|
893
917
|
if (s && s !== "GET" && s !== "HEAD") {
|
|
894
918
|
let t = [];
|
|
@@ -918,14 +942,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
918
942
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
919
943
|
return;
|
|
920
944
|
}
|
|
921
|
-
if (!
|
|
945
|
+
if (!P(r)) {
|
|
922
946
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
923
947
|
return;
|
|
924
948
|
}
|
|
925
949
|
let a = new AbortController();
|
|
926
950
|
e.on("close", () => a.abort()), t.on("close", () => a.abort());
|
|
927
951
|
try {
|
|
928
|
-
let e = i.authorization ?? (
|
|
952
|
+
let e = i.authorization ?? (ue(r) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), n = await fetch(r, {
|
|
929
953
|
redirect: "manual",
|
|
930
954
|
method: "GET",
|
|
931
955
|
headers: {
|
|
@@ -960,15 +984,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
960
984
|
return;
|
|
961
985
|
}
|
|
962
986
|
if (o === "/_voltro/inspect/stream") {
|
|
963
|
-
let n =
|
|
964
|
-
if (
|
|
987
|
+
let n = N(i.origin);
|
|
988
|
+
if (M()) {
|
|
965
989
|
t.writeHead(503, {
|
|
966
990
|
"content-type": "application/json",
|
|
967
991
|
...n
|
|
968
992
|
}), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
|
|
969
993
|
return;
|
|
970
994
|
}
|
|
971
|
-
let r =
|
|
995
|
+
let r = ce(i, "GET");
|
|
972
996
|
if (!r.ok) {
|
|
973
997
|
t.writeHead(401, {
|
|
974
998
|
"content-type": "application/json",
|
|
@@ -986,11 +1010,11 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
986
1010
|
"x-accel-buffering": "no",
|
|
987
1011
|
...n
|
|
988
1012
|
}), t.flushHeaders(), t.write("retry: 5000\n\n");
|
|
989
|
-
for (let e of
|
|
990
|
-
let a =
|
|
991
|
-
t.write(
|
|
1013
|
+
for (let e of f.buffered()) t.write(l(e));
|
|
1014
|
+
let a = f.subscribe((e) => {
|
|
1015
|
+
t.write(l(e));
|
|
992
1016
|
}), o = setInterval(() => {
|
|
993
|
-
t.write(
|
|
1017
|
+
t.write(ie());
|
|
994
1018
|
}, 15e3), s = () => {
|
|
995
1019
|
clearInterval(o), a();
|
|
996
1020
|
};
|
|
@@ -998,18 +1022,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
998
1022
|
return;
|
|
999
1023
|
}
|
|
1000
1024
|
try {
|
|
1001
|
-
let e = await
|
|
1025
|
+
let e = await Ge(n, i);
|
|
1002
1026
|
if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
|
|
1003
1027
|
let t = Date.now() - r;
|
|
1004
|
-
|
|
1028
|
+
f.emit("request", {
|
|
1005
1029
|
url: o,
|
|
1006
1030
|
status: e.status,
|
|
1007
1031
|
durationMs: t,
|
|
1008
1032
|
renderedBy: e.headers["x-voltro-rendered-by"],
|
|
1009
1033
|
cache: e.headers["x-voltro-cache"]
|
|
1010
1034
|
});
|
|
1011
|
-
let n =
|
|
1012
|
-
|
|
1035
|
+
let n = Ie(o, W)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
|
|
1036
|
+
Be.record({
|
|
1013
1037
|
kind: "request",
|
|
1014
1038
|
tag: n,
|
|
1015
1039
|
durationMs: t,
|
|
@@ -1020,71 +1044,71 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1020
1044
|
t.writeHead(500, { "content-type": "text/plain" }), t.end(`internal error: ${e.message}`);
|
|
1021
1045
|
}
|
|
1022
1046
|
});
|
|
1023
|
-
await new Promise((e) =>
|
|
1047
|
+
await new Promise((e) => qe.listen(m, "::", e)), Ke = !0, r.mark("ready"), J.info(`listening on http://localhost:${m}`, {
|
|
1024
1048
|
port: m,
|
|
1025
|
-
distDir:
|
|
1026
|
-
}),
|
|
1049
|
+
distDir: g
|
|
1050
|
+
}), J.debug("dynamic + ssr/isr routes resolve via SSR loader");
|
|
1027
1051
|
try {
|
|
1028
|
-
await
|
|
1029
|
-
id:
|
|
1030
|
-
name:
|
|
1052
|
+
await ge({
|
|
1053
|
+
id: x,
|
|
1054
|
+
name: y,
|
|
1031
1055
|
kind: "web",
|
|
1032
1056
|
url: `http://localhost:${m}`,
|
|
1033
1057
|
pid: process.pid,
|
|
1034
1058
|
status: "live",
|
|
1035
|
-
logFile:
|
|
1059
|
+
logFile: S.path
|
|
1036
1060
|
});
|
|
1037
|
-
let e =
|
|
1061
|
+
let e = _(t);
|
|
1038
1062
|
if (e) {
|
|
1039
1063
|
let t = await d({ dashboardAppPath: e });
|
|
1040
|
-
t.status === "launched" ?
|
|
1064
|
+
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 });
|
|
1041
1065
|
}
|
|
1042
1066
|
setInterval(() => {
|
|
1043
|
-
|
|
1044
|
-
id:
|
|
1045
|
-
name:
|
|
1067
|
+
ge({
|
|
1068
|
+
id: x,
|
|
1069
|
+
name: y,
|
|
1046
1070
|
kind: "web",
|
|
1047
1071
|
url: `http://localhost:${m}`,
|
|
1048
1072
|
pid: process.pid,
|
|
1049
1073
|
status: "live",
|
|
1050
|
-
logFile:
|
|
1074
|
+
logFile: S.path
|
|
1051
1075
|
}).catch(() => {});
|
|
1052
1076
|
}, 1e4).unref();
|
|
1053
1077
|
} catch (e) {
|
|
1054
|
-
|
|
1078
|
+
J.warn("runtime-registry write failed", {}, e);
|
|
1055
1079
|
}
|
|
1056
|
-
|
|
1080
|
+
Te({
|
|
1057
1081
|
app: a.name ?? "unnamed",
|
|
1058
1082
|
kind: "web",
|
|
1059
1083
|
url: `http://localhost:${m}`,
|
|
1060
1084
|
bootMs: r.total()
|
|
1061
1085
|
});
|
|
1062
|
-
let
|
|
1063
|
-
|
|
1086
|
+
let Je = r.phaseBreakdown();
|
|
1087
|
+
J.info(`start: ready in ${r.total()}ms`, {
|
|
1064
1088
|
bootMs: r.total(),
|
|
1065
|
-
...
|
|
1089
|
+
...Je ? { phases: Je } : {}
|
|
1066
1090
|
});
|
|
1067
|
-
let
|
|
1068
|
-
if (!
|
|
1069
|
-
if (
|
|
1070
|
-
await
|
|
1091
|
+
let Ye = !1, Xe = (e) => async () => {
|
|
1092
|
+
if (!Ye) {
|
|
1093
|
+
if (Ye = !0, J.info(`received ${e}, shutting down`, { signal: e }), qe.close(), await $.stop(), B) try {
|
|
1094
|
+
await B.end();
|
|
1071
1095
|
} catch {}
|
|
1072
|
-
await
|
|
1096
|
+
await q.close(), await ve(x), await S.dispose(), process.exit(0);
|
|
1073
1097
|
}
|
|
1074
1098
|
};
|
|
1075
|
-
process.on("SIGINT",
|
|
1076
|
-
let
|
|
1077
|
-
if (
|
|
1099
|
+
process.on("SIGINT", Xe("SIGINT")), process.on("SIGTERM", Xe("SIGTERM"));
|
|
1100
|
+
let Ze = process.ppid;
|
|
1101
|
+
if (Ze > 1) {
|
|
1078
1102
|
let e = setInterval(() => {
|
|
1079
|
-
(process.ppid !==
|
|
1103
|
+
(process.ppid !== Ze || process.ppid === 1) && (clearInterval(e), Xe("SIGTERM")());
|
|
1080
1104
|
}, 2e3);
|
|
1081
1105
|
e.unref();
|
|
1082
1106
|
}
|
|
1083
1107
|
return new Promise(() => {});
|
|
1084
|
-
},
|
|
1108
|
+
}, Ve = async (e) => {
|
|
1085
1109
|
t("start");
|
|
1086
|
-
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await
|
|
1087
|
-
return r.ran ? r.exitCode : (
|
|
1110
|
+
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await Be(B(n));
|
|
1111
|
+
return r.ran ? r.exitCode : (J.error("no web app found at this path"), 1);
|
|
1088
1112
|
};
|
|
1089
1113
|
//#endregion
|
|
1090
|
-
export {
|
|
1114
|
+
export { Be as n, Ve as t };
|