vue-ssr-lite 0.2.11 → 0.2.12

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.
@@ -0,0 +1,716 @@
1
+ import { createServer as ce } from "node:http";
2
+ import { stat as J, readFile as te } from "node:fs/promises";
3
+ import { resolve as z, sep as X, extname as re } from "node:path";
4
+ import { s as le, q as W, u as de, t as ue, i as he, p as me, l as fe, g as pe } from "./SsrHtmlRuntime-BJUxjM2F.mjs";
5
+ import { c as ge, j as ye, r as we } from "./SsrApplicationRuntime-CKjoPpvD.mjs";
6
+ import { renderToString as ve } from "@vue/server-renderer";
7
+ import { c as Se } from "./SsrDiagnosticsRuntime-B5VbSgsA.mjs";
8
+ import { c as oe } from "./SsrSerialization-DeKozeIm.mjs";
9
+ const N = () => globalThis.performance?.now?.() ?? Date.now(), Q = (e) => new TextEncoder().encode(e).byteLength, Y = (e, r, o, s) => {
10
+ for (const l of s) {
11
+ const d = { requestId: r, applicationId: o, code: l.code };
12
+ e?.warn ? e.warn(`ssr.diagnostic.${l.code}`, d) : console.warn(`[vue-ssr-lite] ${l.message}`, d);
13
+ }
14
+ }, be = async (e, r, o = {}) => {
15
+ const s = N(), l = Math.max(1, Math.floor(o.maxResolutionPasses ?? 4)), d = o.resolutionDeadlineMs ?? 0, v = o.diagnostics ?? process.env.NODE_ENV !== "production", x = ye(!0);
16
+ let M = s, p = s, g = s, C, i, y = "", t = "", n = 0, w;
17
+ const a = async () => {
18
+ if (!i) return;
19
+ const h = i;
20
+ i = void 0;
21
+ try {
22
+ await e.cleanup?.(h.context);
23
+ } catch (b) {
24
+ console.error("[vue-ssr-lite] application cleanup failed", b);
25
+ }
26
+ try {
27
+ h.hydration.dispose();
28
+ } catch (b) {
29
+ console.error("[vue-ssr-lite] hydration cleanup failed", b);
30
+ }
31
+ };
32
+ try {
33
+ let h = !1;
34
+ for (let S = 0; S < l && !h; S += 1) {
35
+ if (n = S + 1, x.beginPass(S), i = await ge(e, {
36
+ server: !0,
37
+ request: r,
38
+ resumeState: S === 0 ? void 0 : C,
39
+ resolution: x
40
+ }), S === 0 && (M = N()), i.router) {
41
+ const u = new URL(r.url);
42
+ await i.router.push(`${u.pathname}${u.search}${u.hash}`), await i.router.isReady(), i.router.currentRoute.value.matched.length === 0 && (i.context.response.statusCode = 404);
43
+ }
44
+ S === 0 && (p = N());
45
+ const T = {};
46
+ y = await ve(i.app, T), t = T.teleports?.body ?? "", g = N();
47
+ const R = x.pendingWork(), A = x.additionalPassRequested(), $ = S === l - 1;
48
+ if (R.length === 0 && !A || $) {
49
+ h = !0, $ && (R.length > 0 || A) && Y(o.logger, r.requestId, e.id, [
50
+ {
51
+ code: "resolution-pass-limit",
52
+ message: `Resolution did not settle within ${l} render passes; serializing the last render.`
53
+ }
54
+ ]);
55
+ break;
56
+ }
57
+ await x.drain(d, r.signal), C = i.hydration.collect(), await a();
58
+ }
59
+ if (!i) throw new Error("SSR render produced no application instance.");
60
+ const b = await e.resolveHead?.(i.context) ?? i.context.head.value;
61
+ v && Y(
62
+ o.logger,
63
+ r.requestId,
64
+ e.id,
65
+ Se({
66
+ html: y,
67
+ route: i.router?.currentRoute.value ?? null,
68
+ requestUrl: r.url,
69
+ applicationId: e.id
70
+ })
71
+ );
72
+ const D = {
73
+ version: 1,
74
+ applicationId: e.id,
75
+ publicConfig: r.publicConfig,
76
+ domain: r.domain,
77
+ application: i.context.state,
78
+ plugins: i.hydration.collect()
79
+ }, f = Q(oe(D)), c = N();
80
+ return {
81
+ html: y,
82
+ teleports: t,
83
+ head: b,
84
+ response: i.context.response,
85
+ hydrationState: D,
86
+ metrics: {
87
+ requestId: r.requestId,
88
+ applicationId: e.id,
89
+ contextDurationMs: M - s,
90
+ routeDurationMs: p - M,
91
+ renderDurationMs: g - p,
92
+ totalDurationMs: c - s,
93
+ htmlBytes: Q(y),
94
+ stateBytes: f,
95
+ renderPasses: n
96
+ }
97
+ };
98
+ } catch (h) {
99
+ throw w = h, h;
100
+ } finally {
101
+ let h;
102
+ if (i) {
103
+ try {
104
+ await e.cleanup?.(i.context);
105
+ } catch (b) {
106
+ h = b, console.error("[vue-ssr-lite] application cleanup failed", b);
107
+ }
108
+ try {
109
+ i.hydration.dispose();
110
+ } catch (b) {
111
+ console.error("[vue-ssr-lite] hydration cleanup failed", b), h || (h = b);
112
+ }
113
+ }
114
+ if (x.dispose(), !w && h) throw h;
115
+ }
116
+ }, xe = {
117
+ ".css": "text/css; charset=utf-8",
118
+ ".gif": "image/gif",
119
+ ".html": "text/html; charset=utf-8",
120
+ ".ico": "image/x-icon",
121
+ ".jpeg": "image/jpeg",
122
+ ".jpg": "image/jpeg",
123
+ ".js": "text/javascript; charset=utf-8",
124
+ ".json": "application/json; charset=utf-8",
125
+ ".map": "application/json; charset=utf-8",
126
+ ".png": "image/png",
127
+ ".svg": "image/svg+xml",
128
+ ".txt": "text/plain; charset=utf-8",
129
+ ".webp": "image/webp",
130
+ ".woff": "font/woff",
131
+ ".woff2": "font/woff2",
132
+ ".xml": "application/xml; charset=utf-8"
133
+ }, Re = async (e, r, o) => {
134
+ try {
135
+ const s = decodeURIComponent(r).replace(/^\/+/, "");
136
+ if (!s || o.includes(s)) return null;
137
+ const l = z(e, s), d = e.endsWith(X) ? e : `${e}${X}`;
138
+ return !l.startsWith(d) || !(await J(l)).isFile() ? null : {
139
+ statusCode: 200,
140
+ body: await te(l),
141
+ headers: {
142
+ "content-type": xe[re(l)] || "application/octet-stream",
143
+ "cache-control": r.startsWith("/assets/") ? "public, max-age=31536000, immutable" : "public, max-age=3600"
144
+ }
145
+ };
146
+ } catch {
147
+ return null;
148
+ }
149
+ }, Ee = (e) => typeof e == "string" ? new TextEncoder().encode(e).byteLength : e?.byteLength ?? 0, Z = (e) => ({
150
+ statusCode: e.statusCode,
151
+ body: e.body instanceof Uint8Array ? e.body.slice() : e.body,
152
+ headers: e.headers ? { ...e.headers } : void 0
153
+ }), _e = (e = {}) => {
154
+ const r = Number(e.maxEntries ?? 500), o = Number(e.maxBytes ?? 32 * 1024 * 1024), s = Number.isFinite(r) ? Math.max(1, Math.floor(r)) : 500, l = Number.isFinite(o) ? Math.max(1, Math.floor(o)) : 32 * 1024 * 1024, d = /* @__PURE__ */ new Map();
155
+ let v = 0;
156
+ const x = (p) => {
157
+ const g = d.get(p);
158
+ return g ? (d.delete(p), v -= g.size, !0) : !1;
159
+ }, M = () => {
160
+ const p = Date.now();
161
+ for (const [g, C] of d)
162
+ C.expiresAt <= p && x(g);
163
+ for (; d.size > s || v > l; ) {
164
+ const g = d.keys().next().value;
165
+ if (!g) break;
166
+ x(g);
167
+ }
168
+ };
169
+ return {
170
+ get(p) {
171
+ const g = d.get(p);
172
+ return g ? g.expiresAt <= Date.now() ? (x(p), null) : (d.delete(p), d.set(p, g), Z(g.response)) : null;
173
+ },
174
+ set(p, g, C) {
175
+ const i = Number(C.ttlMs);
176
+ if (!Number.isFinite(i) || i <= 0) return;
177
+ x(p);
178
+ const y = Z(g), t = Ee(y.body);
179
+ t > l || (d.set(p, {
180
+ response: y,
181
+ expiresAt: Date.now() + i,
182
+ size: t,
183
+ tags: new Set(C.tags ?? [])
184
+ }), v += t, M());
185
+ },
186
+ invalidate(p = {}) {
187
+ const g = new Set(p.keys ?? []), C = new Set(p.tags ?? []);
188
+ let i = 0;
189
+ for (const [y, t] of d)
190
+ (!g.size && !C.size || g.has(y) || [...C].some((w) => t.tags.has(w))) && x(y) && (i += 1);
191
+ return i;
192
+ }
193
+ };
194
+ }, Ce = async (e, r, o) => {
195
+ if (!o || r.method !== "GET" || r.cookie || !Number.isFinite(o.ttlMs) || o.ttlMs <= 0)
196
+ return null;
197
+ const s = o.vary ? await o.vary(r) : "";
198
+ return s == null ? null : JSON.stringify([
199
+ "vue-ssr-lite:v1",
200
+ e,
201
+ r.host,
202
+ r.pathname,
203
+ r.search,
204
+ s
205
+ ]);
206
+ }, Pe = (e, r, o) => {
207
+ const s = Object.entries(e.headers ?? {}), l = String(
208
+ s.find(([v]) => v.toLowerCase() === "cache-control")?.[1] || ""
209
+ ).toLowerCase();
210
+ return e.statusCode === 200 && typeof e.body == "string" && !s.some(([v]) => v.toLowerCase() === "set-cookie") && !l.includes("private") && !l.includes("no-store") && (o.shouldCache?.(e, r) ?? !0);
211
+ };
212
+ class se extends Error {
213
+ constructor() {
214
+ super("SSR request timed out."), this.name = "SsrRequestTimeoutError";
215
+ }
216
+ }
217
+ const Me = (e) => {
218
+ const r = e ?? 4173;
219
+ if (!Number.isInteger(r) || r < 0 || r > 65535)
220
+ throw new Error("SSR server port must be an integer between 0 and 65535.");
221
+ return r;
222
+ }, Ie = (e) => e === "0.0.0.0" || e === "::" || e === "::1" ? "localhost" : e, De = (e, r, o) => {
223
+ const s = `http://${Ie(e)}:${r}/`;
224
+ console.log(
225
+ [
226
+ "",
227
+ "✓ Server Ready",
228
+ "",
229
+ ` ➜ Local: ${s}`,
230
+ ` ➜ Role: ${o}`,
231
+ ""
232
+ ].join(`
233
+ `)
234
+ );
235
+ }, q = async (e, r) => {
236
+ const o = await pe(e, {
237
+ development: !r.production,
238
+ root: r.root,
239
+ importModule: r.vite ? async (s) => await r.vite.ssrLoadModule(s) : void 0
240
+ });
241
+ for (const s of o.applications) {
242
+ const l = !s.roles?.length || !o.server.role || s.roles.includes(o.server.role);
243
+ if (s.kind === "ssr" && l && !s.application)
244
+ throw new Error(
245
+ `SSR application "${s.id}" requires an ssr application definition.`
246
+ );
247
+ }
248
+ return o;
249
+ }, $e = (e, r, o, s) => {
250
+ const d = `<script type="application/json" id="vue-ssr-lite-domain">${oe({
251
+ version: 1,
252
+ applicationId: r,
253
+ domain: o,
254
+ publicConfig: s
255
+ })}<\/script>`;
256
+ return e.includes("</body>") ? e.replace(/<\/body>/i, ` ${d}
257
+ </body>`) : `${e}
258
+ ${d}`;
259
+ }, F = {
260
+ "referrer-policy": "strict-origin-when-cross-origin",
261
+ "x-content-type-options": "nosniff",
262
+ "x-frame-options": "SAMEORIGIN"
263
+ }, U = (e, r) => {
264
+ if (e.method !== "GET" && e.method !== "HEAD") return !1;
265
+ if (e.headers["sec-fetch-mode"] === "navigate") return !0;
266
+ const o = String(e.headers.accept || "");
267
+ return o.includes("text/html") ? !0 : (!o || o === "*/*") && !re(r);
268
+ }, ke = (e, r, o = "") => r.end(e.method === "HEAD" ? "" : o), I = (e, r, o) => {
269
+ r.writeHead(o.statusCode, o.headers ?? {}), ke(e, r, o.body ?? "");
270
+ }, j = (e, r, o, s) => I(e, r, {
271
+ statusCode: o,
272
+ body: JSON.stringify(s),
273
+ headers: {
274
+ "content-type": "application/json; charset=utf-8",
275
+ "cache-control": "no-store"
276
+ }
277
+ }), ee = async (e, r, o) => {
278
+ if (!Number.isFinite(r) || r <= 0) return e;
279
+ let s;
280
+ const l = new Promise((d, v) => {
281
+ s = setTimeout(() => {
282
+ o.abort(), v(new se());
283
+ }, r);
284
+ });
285
+ try {
286
+ return await Promise.race([e, l]);
287
+ } finally {
288
+ s && clearTimeout(s);
289
+ }
290
+ }, Te = (e) => e.headers, Ae = (e, r, o) => new Promise((s, l) => {
291
+ e.middlewares(r, o, (d) => {
292
+ d ? l(d) : s();
293
+ });
294
+ }), Be = async (e) => {
295
+ let r = !1;
296
+ const o = await q(await e.loadRuntime(), e), s = o.server, l = s.host || "0.0.0.0", d = Me(s.port), v = z(
297
+ s.root || e.root,
298
+ s.clientOutDir || "dist/client"
299
+ );
300
+ let x = o, M = null;
301
+ const p = () => e.production ? Promise.resolve(o) : M || (M = (async () => {
302
+ try {
303
+ const t = await q(await e.loadRuntime(), e);
304
+ return x = t, t;
305
+ } catch (t) {
306
+ return s.logger?.error?.("ssr.runtime.reload.failed", {
307
+ error: t instanceof Error ? t.message : "Unknown error"
308
+ }), x;
309
+ } finally {
310
+ M = null;
311
+ }
312
+ })(), M), g = async (t, n, w) => {
313
+ const a = t.server.root || e.root, h = await te(
314
+ z(e.production ? v : a, n),
315
+ "utf8"
316
+ );
317
+ if (e.production || !e.vite) return h;
318
+ const b = `/${n.replaceAll("\\", "/").replace(/^\/+/, "")}`;
319
+ return e.vite.transformIndexHtml(b, h, w);
320
+ }, C = async (t) => {
321
+ const n = t.server.root || e.root, w = t.applications.filter(
322
+ (a) => !a.roles?.length || !t.server.role || a.roles.includes(t.server.role)
323
+ );
324
+ await Promise.all(
325
+ w.map(async (a) => {
326
+ if (!(await J(
327
+ z(
328
+ e.production ? v : n,
329
+ a.template
330
+ )
331
+ )).isFile())
332
+ throw new Error(`SSR client entry is missing: ${a.template}`);
333
+ })
334
+ ), await Promise.all((t.readiness ?? []).map((a) => a.run()));
335
+ }, i = o.applications.filter(
336
+ (t) => !t.roles?.length || !o.server.role || t.roles.includes(o.server.role)
337
+ );
338
+ await Promise.all(
339
+ i.map(async (t) => {
340
+ const n = o.server.root || e.root;
341
+ if (!(await J(
342
+ z(
343
+ e.production ? v : n,
344
+ t.template
345
+ )
346
+ )).isFile())
347
+ throw new Error(`Missing client entry: ${t.template}`);
348
+ })
349
+ );
350
+ const y = ce(async (t, n) => {
351
+ const w = Date.now();
352
+ let a = "/", h = "unknown", b;
353
+ const D = new AbortController();
354
+ t.once("aborted", () => D.abort()), n.once("close", () => {
355
+ n.writableEnded || D.abort();
356
+ });
357
+ try {
358
+ const f = await p(), c = f.server, S = new URL(t.url || "/", "http://internal");
359
+ a = S.pathname;
360
+ const T = c.healthPath || "/healthz", R = c.readinessPath || "/readyz";
361
+ if (a === T)
362
+ return j(t, n, 200, {
363
+ status: "ok",
364
+ service: f.name,
365
+ role: c.role || "default",
366
+ timestamp: new Date(w).toISOString()
367
+ });
368
+ if (a === R) {
369
+ if (r)
370
+ return j(t, n, 503, {
371
+ status: "error",
372
+ service: f.name,
373
+ message: "Server is shutting down."
374
+ });
375
+ try {
376
+ return await C(f), j(t, n, 200, {
377
+ status: "ok",
378
+ service: f.name,
379
+ role: c.role || "default"
380
+ });
381
+ } catch {
382
+ return j(t, n, 503, {
383
+ status: "error",
384
+ service: f.name,
385
+ message: "A required dependency is unavailable."
386
+ });
387
+ }
388
+ }
389
+ const A = le(
390
+ t.headers["x-forwarded-host"],
391
+ t.headers.host,
392
+ c.trustProxy
393
+ );
394
+ if (!A)
395
+ return I(t, n, {
396
+ statusCode: 400,
397
+ body: U(t, a) ? W("Invalid request", "The Host header is invalid.") : JSON.stringify({ status: "error", message: "Invalid Host header." }),
398
+ headers: {
399
+ "content-type": U(t, a) ? "text/html; charset=utf-8" : "application/json; charset=utf-8",
400
+ "cache-control": "no-store",
401
+ ...F
402
+ }
403
+ });
404
+ const $ = de(
405
+ f.applications,
406
+ A,
407
+ f.defaultApplicationId
408
+ );
409
+ if (!$)
410
+ return j(t, n, 421, {
411
+ status: "error",
412
+ service: f.name,
413
+ message: "No application serves this host."
414
+ });
415
+ const u = $.entry;
416
+ if (h = u.id, c.logger?.debug?.("ssr.host_resolved", {
417
+ entryId: u.id,
418
+ category: $.category,
419
+ specificity: $.specificity,
420
+ matchedPattern: $.matchedPattern,
421
+ hostname: $.normalizedHostname,
422
+ role: c.role || "default"
423
+ }), u.roles?.length && c.role && !u.roles.includes(c.role)) {
424
+ const m = `Runtime role does not serve application "${u.id}".`;
425
+ return I(t, n, {
426
+ statusCode: 421,
427
+ body: U(t, a) ? W("Misdirected request", m) : JSON.stringify({ status: "error", message: m }),
428
+ headers: {
429
+ "content-type": U(t, a) ? "text/html; charset=utf-8" : "application/json; charset=utf-8",
430
+ "cache-control": "no-store",
431
+ ...F
432
+ }
433
+ });
434
+ }
435
+ const G = ue(
436
+ t.headers["x-forwarded-proto"],
437
+ t.socket.encrypted ? "https" : "http",
438
+ c.trustProxy
439
+ ), K = we(
440
+ A,
441
+ u,
442
+ f.development
443
+ ), ne = he(
444
+ t.headers.cookie,
445
+ u.cookieAllowlist,
446
+ u.cookieDenylist
447
+ ), P = {
448
+ requestId: String(t.headers["x-request-id"] || "").trim() || `${w.toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
449
+ url: new URL(
450
+ `${S.pathname}${S.search}`,
451
+ `${G}://${A}`
452
+ ).href,
453
+ host: A,
454
+ protocol: G,
455
+ method: t.method || "GET",
456
+ headers: Te(t),
457
+ cookie: ne,
458
+ publicConfig: u.publicConfig,
459
+ domain: K,
460
+ signal: D.signal,
461
+ pathname: a,
462
+ search: S.search,
463
+ entryId: u.id
464
+ };
465
+ b = P;
466
+ const ae = {
467
+ signal: D.signal,
468
+ logger: c.logger
469
+ };
470
+ for (const m of u.endpoints) {
471
+ if (!m.match(P)) continue;
472
+ const k = await ee(
473
+ Promise.resolve(m.handle(P, ae)),
474
+ c.requestTimeoutMs ?? 15e3,
475
+ D
476
+ );
477
+ if (k) return I(t, n, k);
478
+ }
479
+ if (e.production) {
480
+ const m = await Re(
481
+ v,
482
+ a,
483
+ f.applications.map(({ template: k }) => k)
484
+ );
485
+ if (m) return I(t, n, m);
486
+ } else if (e.vite && (a.startsWith("/src/") || a.startsWith("/@") || a.includes(".") || a === "/__vite_ping") && (await Ae(e.vite, t, n), n.writableEnded))
487
+ return;
488
+ if (!U(t, a))
489
+ return j(t, n, 404, {
490
+ status: "error",
491
+ service: f.name,
492
+ message: "Resource not found."
493
+ });
494
+ const H = u.kind === "ssr" ? u.responseCache : void 0;
495
+ let L = null;
496
+ try {
497
+ L = await Ce(
498
+ u.id,
499
+ P,
500
+ H
501
+ );
502
+ } catch (m) {
503
+ c.logger?.warn?.("ssr.cache.key.failed", {
504
+ entryId: u.id,
505
+ requestId: P.requestId,
506
+ error: m instanceof Error ? m.message : "Unknown cache error"
507
+ });
508
+ }
509
+ if (H && L)
510
+ try {
511
+ const m = await H.store.get(L);
512
+ if (m)
513
+ return I(t, n, {
514
+ ...m,
515
+ headers: {
516
+ ...m.headers,
517
+ "server-timing": 'cache;desc="hit"'
518
+ }
519
+ });
520
+ } catch (m) {
521
+ c.logger?.warn?.("ssr.cache.read.failed", {
522
+ entryId: u.id,
523
+ requestId: P.requestId,
524
+ error: m instanceof Error ? m.message : "Unknown cache error"
525
+ });
526
+ }
527
+ let O = await g(f, u.template, t.url || "/");
528
+ if (u.kind === "spa")
529
+ return I(t, n, {
530
+ statusCode: 200,
531
+ body: $e(
532
+ O,
533
+ u.id,
534
+ K,
535
+ u.publicConfig
536
+ ),
537
+ headers: {
538
+ "content-type": "text/html; charset=utf-8",
539
+ "cache-control": u.cacheControl || "private, no-store",
540
+ vary: "Host, X-Forwarded-Host",
541
+ ...F
542
+ }
543
+ });
544
+ const _ = u.application;
545
+ O = me(
546
+ O,
547
+ u.mountSelector || _.mountSelector || "#app"
548
+ );
549
+ const V = c.requestTimeoutMs ?? 15e3, E = await ee(
550
+ be(_, P, {
551
+ maxResolutionPasses: c.maxResolutionPasses,
552
+ resolutionDeadlineMs: c.resolutionDeadlineMs ?? V,
553
+ diagnostics: c.diagnostics ?? !e.production,
554
+ logger: c.logger
555
+ }),
556
+ V,
557
+ D
558
+ );
559
+ if (E.response.redirect) {
560
+ const m = E.response.redirect, k = new URL(m.location, P.url);
561
+ if (k.protocol !== "http:" && k.protocol !== "https:")
562
+ throw new Error("SSR redirects must use HTTP or HTTPS.");
563
+ if (!m.allowExternal && k.origin !== new URL(P.url).origin)
564
+ throw new Error("Cross-origin redirect requires allowExternal: true.");
565
+ return I(t, n, {
566
+ statusCode: m.statusCode ?? 302,
567
+ headers: {
568
+ location: k.href,
569
+ "cache-control": "no-store"
570
+ }
571
+ });
572
+ }
573
+ const ie = fe(O, {
574
+ applicationId: _.id,
575
+ html: E.html,
576
+ teleports: E.teleports,
577
+ head: E.head,
578
+ state: E.hydrationState
579
+ });
580
+ c.onMetrics?.(E.metrics), c.logger?.info?.("ssr.render.complete", E.metrics);
581
+ const B = {
582
+ statusCode: E.response.statusCode,
583
+ body: ie,
584
+ headers: {
585
+ "content-type": "text/html; charset=utf-8",
586
+ "cache-control": u.cacheControl || "private, no-store",
587
+ vary: "Host, X-Forwarded-Host",
588
+ "server-timing": [
589
+ `context;dur=${E.metrics.contextDurationMs.toFixed(1)}`,
590
+ `route;dur=${E.metrics.routeDurationMs.toFixed(1)}`,
591
+ `render;dur=${E.metrics.renderDurationMs.toFixed(1)}`
592
+ ].join(", "),
593
+ ...E.response.headers,
594
+ ...F
595
+ }
596
+ };
597
+ if (H && L && Pe(B, P, H))
598
+ try {
599
+ await H.store.set(L, B, {
600
+ ttlMs: H.ttlMs,
601
+ tags: await H.tags?.(P)
602
+ });
603
+ } catch (m) {
604
+ c.logger?.warn?.("ssr.cache.write.failed", {
605
+ entryId: u.id,
606
+ requestId: P.requestId,
607
+ error: m instanceof Error ? m.message : "Unknown cache error"
608
+ });
609
+ }
610
+ return I(t, n, B);
611
+ } catch (f) {
612
+ e.vite?.ssrFixStacktrace(f);
613
+ const c = await p().catch(() => o);
614
+ if (c.server.logger?.error?.("ssr.request.failed", {
615
+ entryId: h,
616
+ pathname: a,
617
+ error: f instanceof Error ? f.message : "Unknown error"
618
+ }), n.writableEnded) return;
619
+ if (n.headersSent) return n.destroy();
620
+ const S = f instanceof se, T = S ? 504 : 500;
621
+ if (c.server.renderError)
622
+ try {
623
+ const R = await c.server.renderError({
624
+ error: f,
625
+ kind: S ? "timeout" : "internal",
626
+ production: e.production,
627
+ request: b,
628
+ entryId: h === "unknown" ? void 0 : h
629
+ });
630
+ if (R)
631
+ return I(t, n, {
632
+ ...R,
633
+ statusCode: R.statusCode >= 400 ? R.statusCode : T,
634
+ headers: {
635
+ ...R.headers,
636
+ "cache-control": "no-store",
637
+ ...F
638
+ }
639
+ });
640
+ } catch (R) {
641
+ c.server.logger?.error?.("ssr.error-renderer.failed", {
642
+ entryId: h,
643
+ error: R instanceof Error ? R.message : "Unknown error renderer failure"
644
+ });
645
+ }
646
+ return U(t, a) ? I(t, n, {
647
+ statusCode: T,
648
+ body: W(
649
+ S ? "Request timed out" : "Application unavailable",
650
+ e.production ? "The application could not render this page. Please try again." : f instanceof Error ? f.message : "Unknown rendering failure."
651
+ ),
652
+ headers: {
653
+ "content-type": "text/html; charset=utf-8",
654
+ "cache-control": "no-store",
655
+ ...F
656
+ }
657
+ }) : j(t, n, T, {
658
+ status: "error",
659
+ service: c.name
660
+ });
661
+ }
662
+ });
663
+ return {
664
+ nodeServer: y,
665
+ address: () => {
666
+ const t = y.address();
667
+ return {
668
+ host: typeof t == "object" && t ? t.address : l,
669
+ port: typeof t == "object" && t ? t.port : d
670
+ };
671
+ },
672
+ listen: () => new Promise((t, n) => {
673
+ const w = (a) => n(a);
674
+ y.once("error", w), y.listen(d, l, () => {
675
+ y.off("error", w), De(
676
+ l,
677
+ d,
678
+ s.role || "default"
679
+ ), t();
680
+ });
681
+ }),
682
+ close: async () => {
683
+ if (r) return;
684
+ r = !0;
685
+ const t = s.shutdownTimeoutMs ?? 1e4;
686
+ let n;
687
+ try {
688
+ await Promise.race([
689
+ Promise.all([
690
+ new Promise((w, a) => {
691
+ y.close(
692
+ (h) => h ? a(h) : w()
693
+ );
694
+ }),
695
+ e.vite?.close()
696
+ ]),
697
+ new Promise((w, a) => {
698
+ n = setTimeout(() => {
699
+ y.closeAllConnections?.(), a(new Error("SSR server graceful shutdown timed out."));
700
+ }, t);
701
+ })
702
+ ]);
703
+ } finally {
704
+ n && clearTimeout(n);
705
+ }
706
+ }
707
+ };
708
+ };
709
+ export {
710
+ _e as a,
711
+ Re as b,
712
+ Be as c,
713
+ Ce as d,
714
+ Pe as i,
715
+ be as r
716
+ };