@withl5e/l5e 0.1.0-alpha.0 → 0.1.1-alpha.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/dist/server.js CHANGED
@@ -1,21 +1,28 @@
1
- import { existsSync as V } from "fs";
2
- import M from "node:fs/promises";
3
- import u from "node:path";
4
- import { pathToFileURL as I } from "node:url";
5
- import W from "request-ip";
6
- import { p as K, c as X, a as Y } from "./index-BIt7MJT9.js";
7
- import { createHash as Z } from "node:crypto";
8
- import { rollup as Q } from "rollup";
9
- const N = /* @__PURE__ */ new Map(), J = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map();
1
+ import { existsSync as z } from "fs";
2
+ import L from "node:fs/promises";
3
+ import l from "node:path";
4
+ import { pathToFileURL as N } from "node:url";
5
+ import K from "request-ip";
6
+ import { p as J, c as Y, a as Z } from "./index-BIt7MJT9.js";
7
+ import { createHash as q } from "node:crypto";
8
+ import { createRequire as Q } from "node:module";
9
+ let D = null;
10
+ function ee() {
11
+ return D || (D = (async () => {
12
+ const e = Q(import.meta.url), t = e.resolve("vite"), n = e.resolve("rollup", { paths: [l.dirname(t)] });
13
+ return await import(N(n).href);
14
+ })()), D;
15
+ }
16
+ const H = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Map(), V = /* @__PURE__ */ new Map();
10
17
  function U(e) {
11
- return Z("sha256").update(e).digest("hex").substring(0, 16);
18
+ return q("sha256").update(e).digest("hex").substring(0, 16);
12
19
  }
13
- async function q(e, t, n) {
20
+ async function te(e, t, n) {
14
21
  if (e.length === 0)
15
22
  return { hash: "", filename: "", content: "" };
16
- const o = [...new Set(e)], f = `scripts:${o.sort().join(",")}`, h = J.get(f);
23
+ const o = [...new Set(e)], f = `scripts:${o.sort().join(",")}`, h = B.get(f);
17
24
  if (h) {
18
- const a = N.get(h);
25
+ const a = H.get(h);
19
26
  if (a)
20
27
  return {
21
28
  hash: a.hash,
@@ -26,30 +33,30 @@ async function q(e, t, n) {
26
33
  let c = null;
27
34
  try {
28
35
  const a = U(o.join(`
29
- `)), g = u.join(t, ".temp-bundle");
30
- await M.mkdir(g, { recursive: !0 }).catch(() => {
31
- }), c = u.join(g, `entry-${a}.js`);
32
- const v = o.map((s, l) => {
33
- const d = s.startsWith("/") ? u.join(n, s.substring(1)) : u.join(n, s);
34
- return `import ${JSON.stringify(d)};`;
36
+ `)), g = l.join(t, ".temp-bundle");
37
+ await L.mkdir(g, { recursive: !0 }).catch(() => {
38
+ }), c = l.join(g, `entry-${a}.js`);
39
+ const v = o.map((s, u) => {
40
+ const y = s.startsWith("/") ? l.join(n, s.substring(1)) : l.join(n, s);
41
+ return `import ${JSON.stringify(y)};`;
35
42
  }).join(`
36
43
  `);
37
- await M.writeFile(c, v, "utf-8"), console.log(`[bundler] Wrote entry file to ${c}`), console.log(`[bundler] Entry content: ${v}`);
38
- const C = {
44
+ await L.writeFile(c, v, "utf-8"), console.log(`[bundler] Wrote entry file to ${c}`), console.log(`[bundler] Entry content: ${v}`);
45
+ const R = {
39
46
  input: c,
40
47
  plugins: [
41
48
  {
42
49
  name: "vendor-path-rewriter",
43
- resolveId(s, l, d) {
50
+ resolveId(s, u, y) {
44
51
  if (s.includes("vendor-") || s.includes("chunk-") || s.includes(".global")) {
45
- if (console.log(`[bundler] Resolving source: ${s}`), u.isAbsolute(s))
46
- return console.log(`[bundler] Resolving absolute path: ${s}`), { id: "/" + u.relative(n, s).replace(/\\/g, "/"), external: !0 };
47
- if (l && s.startsWith(".")) {
52
+ if (console.log(`[bundler] Resolving source: ${s}`), l.isAbsolute(s))
53
+ return console.log(`[bundler] Resolving absolute path: ${s}`), { id: "/" + l.relative(n, s).replace(/\\/g, "/"), external: !0 };
54
+ if (u && s.startsWith(".")) {
48
55
  console.log(
49
- `[bundler] Resolving relative path: ${s} from importer: ${l}`
56
+ `[bundler] Resolving relative path: ${s} from importer: ${u}`
50
57
  );
51
- const y = u.resolve(u.dirname(l), s);
52
- return { id: "/" + u.relative(n, y).replace(/\\/g, "/"), external: !0 };
58
+ const b = l.resolve(l.dirname(u), s);
59
+ return { id: "/" + l.relative(n, b).replace(/\\/g, "/"), external: !0 };
53
60
  } else
54
61
  console.log(`[bundler] Resolving source: ${s}`);
55
62
  }
@@ -57,43 +64,43 @@ async function q(e, t, n) {
57
64
  }
58
65
  }
59
66
  ],
60
- external: (s) => !s.startsWith(".") && !u.isAbsolute(s) ? !0 : (s.includes("vendor-") || s.includes("chunk-") || s.includes(".global"), !1)
61
- }, x = {
67
+ external: (s) => !s.startsWith(".") && !l.isAbsolute(s) ? !0 : (s.includes("vendor-") || s.includes("chunk-") || s.includes(".global"), !1)
68
+ }, S = {
62
69
  format: "es",
63
70
  inlineDynamicImports: !1,
64
71
  entryFileNames: "bundle-[hash].js",
65
72
  chunkFileNames: "bundle-[hash].js"
66
- }, F = await Q(C), { output: S } = await F.generate(x);
67
- await F.close(), S.forEach((s) => {
73
+ }, { rollup: P } = await ee(), C = await P(R), { output: i } = await C.generate(S);
74
+ await C.close(), i.forEach((s) => {
68
75
  if (s.type !== "chunk")
69
76
  return;
70
- const l = {
77
+ const u = {
71
78
  content: s.code || "",
72
79
  hash: U(s.code || ""),
73
80
  filename: s.fileName,
74
81
  mimeType: "application/javascript"
75
82
  };
76
- N.set(s.fileName, l);
83
+ H.set(s.fileName, u);
77
84
  });
78
- const i = S[0];
79
- return i?.type === "chunk" && J.set(f, i.fileName), {
80
- hash: U(S[0]?.code || ""),
81
- filename: S[0]?.fileName || "",
82
- content: S[0]?.code || ""
85
+ const d = i[0];
86
+ return d?.type === "chunk" && B.set(f, d.fileName), {
87
+ hash: U(i[0]?.code || ""),
88
+ filename: i[0]?.fileName || "",
89
+ content: i[0]?.code || ""
83
90
  };
84
91
  } catch (a) {
85
92
  return console.error("[bundler] Error bundling scripts:", a), { hash: "", filename: "", content: "" };
86
93
  } finally {
87
- c && await M.unlink(c).catch(() => {
94
+ c && await L.unlink(c).catch(() => {
88
95
  });
89
96
  }
90
97
  }
91
- async function ee(e, t, n) {
98
+ async function ne(e, t, n) {
92
99
  if (e.length === 0)
93
100
  return { hash: "", filename: "", content: "" };
94
- const o = [...new Set(e)], f = `css:${o.sort().join(",")}`, h = B.get(f);
101
+ const o = [...new Set(e)], f = `css:${o.sort().join(",")}`, h = V.get(f);
95
102
  if (h) {
96
- const c = N.get(h);
103
+ const c = H.get(h);
97
104
  if (c)
98
105
  return {
99
106
  hash: c.hash,
@@ -103,51 +110,51 @@ async function ee(e, t, n) {
103
110
  }
104
111
  try {
105
112
  const c = [];
106
- for (const x of o) {
107
- const F = x.startsWith("/") ? u.join(n, x.substring(1)) : u.join(n, x);
113
+ for (const S of o) {
114
+ const P = S.startsWith("/") ? l.join(n, S.substring(1)) : l.join(n, S);
108
115
  try {
109
- const S = await M.readFile(F, "utf-8");
110
- c.push(`/* ${x} */
111
- ${S}
116
+ const C = await L.readFile(P, "utf-8");
117
+ c.push(`/* ${S} */
118
+ ${C}
112
119
  `);
113
- } catch (S) {
114
- console.warn(`[bundler] Failed to read CSS file: ${x}`, S);
120
+ } catch (C) {
121
+ console.warn(`[bundler] Failed to read CSS file: ${S}`, C);
115
122
  }
116
123
  }
117
124
  const a = c.join(`
118
125
 
119
- `), g = U(a), v = `bundle-${g}.css`, C = {
126
+ `), g = U(a), v = `bundle-${g}.css`, R = {
120
127
  content: a,
121
128
  hash: g,
122
129
  filename: v,
123
130
  mimeType: "text/css"
124
131
  };
125
- return N.set(v, C), B.set(f, v), { hash: g, filename: v, content: a };
132
+ return H.set(v, R), V.set(f, v), { hash: g, filename: v, content: a };
126
133
  } catch (c) {
127
134
  return console.error("[bundler] Error bundling CSS:", c), { hash: "", filename: "", content: "" };
128
135
  }
129
136
  }
130
- function te(e) {
131
- return N.get(e);
137
+ function se(e) {
138
+ return H.get(e);
132
139
  }
133
- function ne(e, t) {
140
+ function oe(e, t) {
134
141
  return e.replace(/<html\b([^>]*)>/i, (n, o) => /\blang\s*=/i.test(o) ? n.replace(/lang\s*=\s*"[^"]*"/i, `lang="${t}"`) : `<html lang="${t}"${o}>`);
135
142
  }
136
- function se(e) {
143
+ function re(e) {
137
144
  return new URL(`${e.protocol}://${e.get("host")}${e.originalUrl}`);
138
145
  }
139
- function z(e, t) {
146
+ function G(e, t) {
140
147
  return `${e.pathname}${e.search}`.replace(t, "") || "/";
141
148
  }
142
- function oe(e) {
149
+ function ie(e) {
143
150
  const t = {
144
151
  method: e.method,
145
- headers: Y(e)
152
+ headers: Z(e)
146
153
  };
147
- return e.method !== "GET" && e.method !== "HEAD" && (t.body = e, t.duplex = "half"), new globalThis.Request(se(e).href, t);
154
+ return e.method !== "GET" && e.method !== "HEAD" && (t.body = e, t.duplex = "half"), new globalThis.Request(re(e).href, t);
148
155
  }
149
- function D(e, t, n, o) {
150
- const f = new URL(t.url), h = z(f, n), c = h.startsWith("/") ? h : `/${h}`, a = {};
156
+ function W(e, t, n, o) {
157
+ const f = new URL(t.url), h = G(f, n), c = h.startsWith("/") ? h : `/${h}`, a = {};
151
158
  return t.headers.forEach((g, v) => {
152
159
  a[v] = g;
153
160
  }), {
@@ -156,18 +163,18 @@ function D(e, t, n, o) {
156
163
  pathname: f.pathname,
157
164
  method: t.method,
158
165
  headers: a,
159
- cookies: K(t.headers.get("cookie") ?? void 0),
166
+ cookies: J(t.headers.get("cookie") ?? void 0),
160
167
  query: Object.fromEntries(f.searchParams.entries()),
161
- ip: W.getClientIp(e) ?? void 0,
168
+ ip: K.getClientIp(e) ?? void 0,
162
169
  locals: o
163
170
  };
164
171
  }
165
- function re(e, t, n) {
172
+ function ae(e, t, n) {
166
173
  return e ? e instanceof globalThis.Request ? e : e instanceof URL ? new globalThis.Request(e.href, t.clone()) : new globalThis.Request(new URL(e, n).href, t.clone()) : t;
167
174
  }
168
- async function ie(e, t, n) {
175
+ async function ce(e, t, n) {
169
176
  t.status(n.status);
170
- const o = ae(n.headers);
177
+ const o = le(n.headers);
171
178
  if (n.headers.forEach((h, c) => {
172
179
  c.toLowerCase() !== "set-cookie" && t.setHeader(c, h);
173
180
  }), o.length > 0 && t.setHeader("Set-Cookie", o), e.method === "HEAD") {
@@ -177,7 +184,7 @@ async function ie(e, t, n) {
177
184
  const f = Buffer.from(await n.arrayBuffer());
178
185
  t.send(f);
179
186
  }
180
- function ae(e) {
187
+ function le(e) {
181
188
  const t = e.getSetCookie;
182
189
  if (typeof t == "function")
183
190
  return t.call(e);
@@ -185,9 +192,9 @@ function ae(e) {
185
192
  if (n?.["set-cookie"])
186
193
  return n["set-cookie"];
187
194
  const o = e.get("set-cookie");
188
- return o ? ce(o) : [];
195
+ return o ? ue(o) : [];
189
196
  }
190
- function ce(e) {
197
+ function ue(e) {
191
198
  const t = [];
192
199
  let n = 0;
193
200
  for (let o = 0; o < e.length; o++) {
@@ -197,7 +204,7 @@ function ce(e) {
197
204
  }
198
205
  return t.push(e.slice(n).trim()), t.filter(Boolean);
199
206
  }
200
- function le(e) {
207
+ function fe(e) {
201
208
  if (!e.rawResponse)
202
209
  return null;
203
210
  const { body: t, contentType: n, statusCode: o, headers: f } = e.rawResponse, h = new Headers(f);
@@ -206,7 +213,7 @@ function le(e) {
206
213
  headers: h
207
214
  });
208
215
  }
209
- async function ue({
216
+ async function he({
210
217
  rendered: e,
211
218
  template: t,
212
219
  manifest: n,
@@ -214,7 +221,7 @@ async function ue({
214
221
  distClientDir: f,
215
222
  isProduction: h
216
223
  }) {
217
- const c = le(e);
224
+ const c = fe(e);
218
225
  if (c)
219
226
  return c;
220
227
  if (e.redirect)
@@ -226,103 +233,103 @@ async function ue({
226
233
  });
227
234
  let a = e.scripts || [], g = e.styles || [];
228
235
  const v = e.islands || [];
229
- let C = e.cacheTags || [];
230
- const x = e.maxAge, F = e.sMaxAge, S = e.swr;
231
- let i = "", s = [], l = "";
236
+ let R = e.cacheTags || [];
237
+ const S = e.maxAge, P = e.sMaxAge, C = e.swr;
238
+ let i = "", d = [], s = "";
232
239
  if (h && n) {
233
- let k = function(r) {
240
+ let j = function(r) {
234
241
  const m = n[r];
235
- return m ? (m.css && m.css.forEach(($) => w.add($)), m.imports && m.imports.forEach(($) => {
236
- const _ = n[$];
242
+ return m ? (m.css && m.css.forEach((x) => w.add(x)), m.imports && m.imports.forEach((x) => {
243
+ const _ = n[x];
237
244
  _?.file && E.add(_.file), _?.css && _.css.forEach((O) => w.add(O)), _?.imports && _.imports.forEach((O) => {
238
- const H = n[O];
239
- H?.file && E.add(H.file), H?.css && H.css.forEach((G) => w.add(G));
245
+ const I = n[O];
246
+ I?.file && E.add(I.file), I?.css && I.css.forEach((X) => w.add(X));
240
247
  });
241
248
  }), { file: m.file }) : { file: null };
242
249
  };
243
250
  a = a.filter((r) => !r.includes(".global.")), g = g.filter((r) => !r.includes(".global."));
244
- const w = /* @__PURE__ */ new Set(), E = /* @__PURE__ */ new Set(), L = [];
251
+ const w = /* @__PURE__ */ new Set(), E = /* @__PURE__ */ new Set(), T = [];
245
252
  for (const r of a) {
246
- const m = r.replace(/^\//, ""), { file: $ } = k(m);
247
- $ && L.push(`/${$}`);
253
+ const m = r.replace(/^\//, ""), { file: x } = j(m);
254
+ x && T.push(`/${x}`);
248
255
  }
249
- const P = [];
256
+ const M = [];
250
257
  for (const r of g) {
251
- const m = r.replace(/^\//, ""), { file: $ } = k(m);
252
- $ && (P.push(`/${$}`), w.add($));
258
+ const m = r.replace(/^\//, ""), { file: x } = j(m);
259
+ x && (M.push(`/${x}`), w.add(x));
253
260
  }
254
- if (L.length > 0) {
255
- const r = await q(L, o, f);
256
- a = r.filename ? [`/${r.filename}`] : L;
261
+ if (T.length > 0) {
262
+ const r = await te(T, o, f);
263
+ a = r.filename ? [`/${r.filename}`] : T;
257
264
  }
258
- if (P.length > 0) {
259
- const r = await ee(P, o, f);
265
+ if (M.length > 0) {
266
+ const r = await ne(M, o, f);
260
267
  r.filename && (g = [`/${r.filename}`]);
261
268
  }
262
269
  const p = n["src/client.global.ts"];
263
270
  if (p && (p.css && p.css.length > 0 && p.css.forEach((r) => {
264
271
  i += `<link rel="stylesheet" crossorigin href="/${r}">`;
265
- }), p.file && s.push(`/${p.file}`)), v.length > 0) {
272
+ }), p.file && d.push(`/${p.file}`)), v.length > 0) {
266
273
  const r = {};
267
274
  for (const m of v) {
268
- const $ = n[m.src];
269
- $?.file && (r[m.key] = `/${$.file}`);
275
+ const x = n[m.src];
276
+ x?.file && (r[m.key] = `/${x.file}`);
270
277
  }
271
- Object.keys(r).length > 0 && (l = `<script>window.__L5E_ISLANDS__=${JSON.stringify(r)}<\/script>`);
278
+ Object.keys(r).length > 0 && (s = `<script>window.__L5E_ISLANDS__=${JSON.stringify(r)}<\/script>`);
272
279
  }
273
280
  g.length > 0 && (i += g.map((r) => `<link rel="stylesheet" crossorigin href="${r}">`).join(""));
274
281
  }
275
- let d = "";
276
- h || (d = g.map((k) => `<link rel="stylesheet" href="${k}">`).join(""));
277
- let y = [...s, ...a];
282
+ let u = "";
283
+ h || (u = g.map((j) => `<link rel="stylesheet" href="${j}">`).join(""));
284
+ let y = [...d, ...a];
278
285
  if (!h) {
279
- const k = u.join(o, "src", "client.global.ts");
280
- if (V(k) && (y = ["/src/client.global.ts", ...y]), v.length > 0) {
286
+ const j = l.join(o, "src", "client.global.ts");
287
+ if (z(j) && (y = ["/src/client.global.ts", ...y]), v.length > 0) {
281
288
  const w = {};
282
289
  for (const E of v)
283
290
  w[E.key] = `/${E.src}`;
284
- l = `<script>window.__L5E_ISLANDS__=${JSON.stringify(w)}<\/script>`;
291
+ s = `<script>window.__L5E_ISLANDS__=${JSON.stringify(w)}<\/script>`;
285
292
  }
286
293
  }
287
- const b = l + y.map((k) => `<script type="module" src="${k}"><\/script>`).join(""), A = e.lang ? ne(t, e.lang) : t, j = e.rawHtml ? e.html || "" : A.replace("<!--app-head-->", (e.head ?? "") + i + d).replace("<!--app-html-->", e.html ?? "").replace("<!--app-scripts-->", b), T = new Headers({
294
+ const b = s + y.map((j) => `<script type="module" src="${j}"><\/script>`).join(""), A = e.lang ? oe(t, e.lang) : t, $ = e.rawHtml ? e.html || "" : A.replace("<!--app-head-->", (e.head ?? "") + i + u).replace("<!--app-html-->", e.html ?? "").replace("<!--app-scripts-->", b), F = new Headers({
288
295
  "Content-Type": "text/html"
289
- }), R = ["public"];
290
- return x !== void 0 && R.push(`max-age=${x}`), F !== void 0 && R.push(`s-maxage=${F}`), S !== void 0 && R.push(`stale-while-revalidate=${S}`), R.length > 1 && h && T.set("Cache-Control", R.join(", ")), process.env.NODE_ENV === "production" && (C = pe(C)), T.set("Cache-Tag", ["global", ...C].join(",")), new globalThis.Response(j, {
296
+ }), k = ["public"];
297
+ return S !== void 0 && k.push(`max-age=${S}`), P !== void 0 && k.push(`s-maxage=${P}`), C !== void 0 && k.push(`stale-while-revalidate=${C}`), k.length > 1 && h && F.set("Cache-Control", k.join(", ")), process.env.NODE_ENV === "production" && (R = ge(R)), F.set("Cache-Tag", ["global", ...R].join(",")), new globalThis.Response($, {
291
298
  status: e.statusCode || 200,
292
- headers: T
299
+ headers: F
293
300
  });
294
301
  }
295
- async function fe(e = {}) {
296
- const t = e.root || process.cwd(), n = e.base || "/", o = process.env.NODE_ENV === "production", f = o ? await M.readFile(u.join(t, "./index.html"), "utf-8") : "", h = (await import("express")).default, c = e.app || h();
302
+ async function de(e = {}) {
303
+ const t = e.root || process.cwd(), n = e.base || "/", o = process.env.NODE_ENV === "production", f = o ? await L.readFile(l.join(t, "./index.html"), "utf-8") : "", h = (await import("express")).default, c = e.app || h();
297
304
  if (e.publicDir) {
298
- const i = u.isAbsolute(e.publicDir) ? e.publicDir : u.join(t, e.publicDir);
299
- V(i) && c.use(h.static(i));
305
+ const i = l.isAbsolute(e.publicDir) ? e.publicDir : l.join(t, e.publicDir);
306
+ z(i) && c.use(h.static(i));
300
307
  }
301
308
  let a;
302
- const g = u.join(t, "./dist/client");
309
+ const g = l.join(t, "./dist/client");
303
310
  if (o) {
304
- const i = (await import("compression")).default, s = (await import("sirv")).default;
305
- c.use(i()), c.use(n, s(g, { extensions: [] })), c.get(
311
+ const i = (await import("compression")).default, d = (await import("sirv")).default;
312
+ c.use(i()), c.use(n, d(g, { extensions: [] })), c.get(
306
313
  `${n === "/" ? "" : n}/bundle-:hash.:ext`,
307
- async (l, d) => {
314
+ async (s, u) => {
308
315
  try {
309
- const { hash: y, ext: b } = l.params, A = `bundle-${y}.${b}`, j = te(A);
310
- if (!j)
311
- return d.status(404).send("Bundled file not found");
312
- d.set({
313
- "Content-Type": j.mimeType,
316
+ const { hash: y, ext: b } = s.params, A = `bundle-${y}.${b}`, $ = se(A);
317
+ if (!$)
318
+ return u.status(404).send("Bundled file not found");
319
+ u.set({
320
+ "Content-Type": $.mimeType,
314
321
  "Cache-Control": "public, max-age=31536000, immutable"
315
- }), d.send(j.content);
322
+ }), u.send($.content);
316
323
  } catch (y) {
317
- console.error("[server] Error serving bundled file:", y), d.status(500).end(y.message);
324
+ console.error("[server] Error serving bundled file:", y), u.status(500).end(y.message);
318
325
  }
319
326
  }
320
327
  );
321
328
  } else {
322
- const { createServer: i } = await import("vite"), s = u.join(t, "vite.config.js");
329
+ const { createServer: i } = await import("vite"), d = l.join(t, "vite.config.js");
323
330
  a = await i({
324
331
  root: t,
325
- configFile: s,
332
+ configFile: d,
326
333
  server: { middlewareMode: !0 },
327
334
  appType: "custom",
328
335
  base: n,
@@ -341,88 +348,88 @@ async function fe(e = {}) {
341
348
  }
342
349
  c.use("/_l5e/action", h.json({ limit: "100kb" }));
343
350
  const v = /^[a-zA-Z]\w+_[0-9a-f]{1,4}$/;
344
- let C = null, x = null;
345
- async function F() {
351
+ let R = null, S = null;
352
+ async function P() {
346
353
  if (!o)
347
354
  return (await a.ssrLoadModule("virtual:l5e-actions")).actionRegistry || {};
348
- if (!C) {
349
- const i = u.join(t, "./dist/server/action-registry.json"), s = await M.readFile(i, "utf-8");
350
- C = JSON.parse(s);
355
+ if (!R) {
356
+ const i = l.join(t, "./dist/server/action-registry.json"), d = await L.readFile(i, "utf-8");
357
+ R = JSON.parse(d);
351
358
  }
352
- return C;
359
+ return R;
353
360
  }
354
- async function S() {
361
+ async function C() {
355
362
  if (!o)
356
363
  return (await a.ssrLoadModule("virtual:l5e-actions")).viewActions || {};
357
- if (!x) {
358
- const i = u.join(t, "./dist/server/entry-server.js");
359
- x = (await import(I(i).href)).viewActions || {};
364
+ if (!S) {
365
+ const i = l.join(t, "./dist/server/entry-server.js");
366
+ S = (await import(N(i).href)).viewActions || {};
360
367
  }
361
- return x;
368
+ return S;
362
369
  }
363
- return c.all("/_l5e/action/:actionKey", async (i, s) => {
370
+ return c.all("/_l5e/action/:actionKey", async (i, d) => {
364
371
  try {
365
- const { actionKey: l } = i.params;
366
- if (!v.test(l))
367
- return s.status(400).send("Invalid action key");
368
- const y = (await F())[l];
372
+ const { actionKey: s } = i.params;
373
+ if (!v.test(s))
374
+ return d.status(400).send("Invalid action key");
375
+ const y = (await P())[s];
369
376
  if (!y)
370
- return s.status(404).send("Action not found");
377
+ return d.status(404).send("Action not found");
371
378
  const { modulePath: b, actionName: A } = y;
372
- let j;
379
+ let $;
373
380
  if (o) {
374
- const r = await S(), m = r[`/src/${b}/actions.tsx`] ? `/src/${b}/actions.tsx` : r[`/src/${b}/actions.ts`] ? `/src/${b}/actions.ts` : null;
381
+ const r = await C(), m = r[`/src/${b}/actions.tsx`] ? `/src/${b}/actions.tsx` : r[`/src/${b}/actions.ts`] ? `/src/${b}/actions.ts` : null;
375
382
  if (!m)
376
- return s.status(404).send("Action module not found");
377
- j = await r[m]();
383
+ return d.status(404).send("Action module not found");
384
+ $ = await r[m]();
378
385
  } else
379
386
  try {
380
- j = await a.ssrLoadModule(`/src/${b}/actions.tsx`);
387
+ $ = await a.ssrLoadModule(`/src/${b}/actions.tsx`);
381
388
  } catch {
382
- j = await a.ssrLoadModule(`/src/${b}/actions.ts`);
389
+ $ = await a.ssrLoadModule(`/src/${b}/actions.ts`);
383
390
  }
384
- if (!Object.prototype.hasOwnProperty.call(j, A))
385
- return s.status(404).send("Action not found");
386
- const T = j[A];
387
- if (!T || !T.handler)
388
- return s.status(404).send("Action not found");
389
- const R = `${i.protocol}://${i.get("host")}${i.originalUrl}`, k = new URL(R), w = {
390
- url: k,
391
+ if (!Object.prototype.hasOwnProperty.call($, A))
392
+ return d.status(404).send("Action not found");
393
+ const F = $[A];
394
+ if (!F || !F.handler)
395
+ return d.status(404).send("Action not found");
396
+ const k = `${i.protocol}://${i.get("host")}${i.originalUrl}`, j = new URL(k), w = {
397
+ url: j,
391
398
  path: i.originalUrl,
392
- pathname: k.pathname,
399
+ pathname: j.pathname,
393
400
  method: i.method,
394
401
  headers: i.headers,
395
- cookies: K(i.headers.cookie),
402
+ cookies: J(i.headers.cookie),
396
403
  query: i.query || {},
397
404
  body: i.body,
398
- ip: W.getClientIp(i)
399
- }, E = u.join(t, "./dist/server/entry-server.js"), { runInRenderContext: L } = await (o ? import(I(E).href) : a.ssrLoadModule("@withl5e/l5e/jsx-runtime")), { renderJsxToHtmlString: P } = await (o ? import(I(E).href) : a.ssrLoadModule("@withl5e/l5e")), p = await L(
405
+ ip: K.getClientIp(i)
406
+ }, E = l.join(t, "./dist/server/entry-server.js"), { runInRenderContext: T } = await (o ? import(N(E).href) : a.ssrLoadModule("@withl5e/l5e/jsx-runtime")), { renderJsxToHtmlString: M } = await (o ? import(N(E).href) : a.ssrLoadModule("@withl5e/l5e")), p = await T(
400
407
  async () => {
401
- const r = await T.handler(w);
402
- return P(r);
408
+ const r = await F.handler(w);
409
+ return M(r);
403
410
  },
404
411
  w,
405
412
  b
406
413
  );
407
- s.set("Content-Type", "text/html").send(p);
408
- } catch (l) {
409
- a?.ssrFixStacktrace?.(l), console.error("[l5e] Action error:", l.stack || l), s.status(500).send("Internal server error");
414
+ d.set("Content-Type", "text/html").send(p);
415
+ } catch (s) {
416
+ a?.ssrFixStacktrace?.(s), console.error("[l5e] Action error:", s.stack || s), d.status(500).send("Internal server error");
410
417
  }
411
- }), c.use(async (i, s) => {
418
+ }), c.use(async (i, d) => {
412
419
  try {
413
- const l = i.originalUrl.replace(n, "");
414
- let d, y, b, A;
420
+ const s = i.originalUrl.replace(n, "");
421
+ let u, y, b, A;
415
422
  if (o) {
416
- d = f;
417
- const p = u.join(t, "./dist/server/entry-server.js"), r = await import(I(p).href);
423
+ u = f;
424
+ const p = l.join(t, "./dist/server/entry-server.js"), r = await import(N(p).href);
418
425
  y = r.render, b = r.loadMiddleware;
419
- const m = await M.readFile(
420
- u.join(t, "./dist/client/.vite/manifest.json"),
426
+ const m = await L.readFile(
427
+ l.join(t, "./dist/client/.vite/manifest.json"),
421
428
  "utf-8"
422
429
  );
423
430
  A = JSON.parse(m);
424
431
  } else {
425
- d = await M.readFile(u.join(t, "./index.html"), "utf-8"), d = await a.transformIndexHtml(l, d), d.includes("@vite/client") || (d = d.replace(
432
+ u = await L.readFile(l.join(t, "./index.html"), "utf-8"), u = await a.transformIndexHtml(s, u), u.includes("@vite/client") || (u = u.replace(
426
433
  "</head>",
427
434
  '<script type="module" src="/@vite/client"><\/script></head>'
428
435
  ));
@@ -431,43 +438,43 @@ async function fe(e = {}) {
431
438
  );
432
439
  y = p.render, b = p.loadMiddleware;
433
440
  }
434
- const j = await b?.(), T = typeof j == "function" ? j : (p, r) => r(), R = {}, k = oe(i), w = X({
435
- request: k,
436
- requestInfo: D(i, k, n, R),
437
- locals: R,
438
- clientAddress: W.getClientIp(i)
441
+ const $ = await b?.(), F = typeof $ == "function" ? $ : (p, r) => r(), k = {}, j = ie(i), w = Y({
442
+ request: j,
443
+ requestInfo: W(i, j, n, k),
444
+ locals: k,
445
+ clientAddress: K.getClientIp(i)
439
446
  }), E = async (p) => {
440
- const r = D(i, p, n, R), m = z(r.url, n), $ = await y(m, r);
441
- return ue({
442
- rendered: $,
443
- template: d,
447
+ const r = W(i, p, n, k), m = G(r.url, n), x = await y(m, r);
448
+ return he({
449
+ rendered: x,
450
+ template: u,
444
451
  manifest: A,
445
452
  root: t,
446
453
  distClientDir: g,
447
454
  isProduction: o
448
455
  });
449
- }, L = async (p) => {
450
- const r = re(p, w.request, w.url);
451
- return w.request = r, w.url = new URL(r.url), w.cookies = K(r.headers.get("cookie") ?? void 0), w.requestInfo = D(i, r, n, R), E(r);
456
+ }, T = async (p) => {
457
+ const r = ae(p, w.request, w.url);
458
+ return w.request = r, w.url = new URL(r.url), w.cookies = J(r.headers.get("cookie") ?? void 0), w.requestInfo = W(i, r, n, k), E(r);
452
459
  };
453
- w.rewrite = (p) => L(p);
454
- const P = await T(w, L);
455
- await ie(i, s, P);
456
- } catch (l) {
457
- a?.ssrFixStacktrace?.(l), console.log(l.stack), s.status(500).end(l.stack);
460
+ w.rewrite = (p) => T(p);
461
+ const M = await F(w, T);
462
+ await ce(i, d, M);
463
+ } catch (s) {
464
+ a?.ssrFixStacktrace?.(s), console.log(s.stack), d.status(500).end(s.stack);
458
465
  }
459
466
  }), { app: c, vite: a };
460
467
  }
461
- async function Se(e = {}) {
468
+ async function ke(e = {}) {
462
469
  const t = e.port || 5173, n = (await import("express")).default, o = n();
463
470
  e.setupApp && (console.log("setupApp"), await e.setupApp(o));
464
- const { app: f } = await fe({ ...e, app: o });
471
+ const { app: f } = await de({ ...e, app: o });
465
472
  f.listen(t, () => {
466
473
  console.log(`Server started at http://localhost:${t}`);
467
474
  });
468
475
  }
469
- const he = 1e3;
470
- function de(e) {
476
+ const pe = 1e3;
477
+ function me(e) {
471
478
  if (e === "global")
472
479
  return "global";
473
480
  let t = 0;
@@ -477,13 +484,13 @@ function de(e) {
477
484
  }
478
485
  return Math.abs(t).toString(36).substring(0, 8);
479
486
  }
480
- function pe(e) {
481
- return (Array.isArray(e) ? e : [...e]).slice(0, he).map(de);
487
+ function ge(e) {
488
+ return (Array.isArray(e) ? e : [...e]).slice(0, pe).map(me);
482
489
  }
483
490
  export {
484
- fe as createServer,
485
- de as hashTag,
486
- pe as optimizeCacheTags,
487
- Se as startServer
491
+ de as createServer,
492
+ me as hashTag,
493
+ ge as optimizeCacheTags,
494
+ ke as startServer
488
495
  };
489
496
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../src/core/bundler.ts","../src/core/server.ts"],"sourcesContent":["/// <reference path=\"./jsx-types.d.ts\" />\nimport { createHash } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { rollup, type OutputOptions, type RollupOptions } from 'rollup';\n\ninterface BundledFile {\n content: string;\n hash: string;\n filename: string;\n mimeType: string;\n}\n\n// Memory map để lưu bundled files\nconst bundledFilesMap = new Map<string, BundledFile>();\n\n// Cache map để deduplicate bundling requests (cacheKey → entry chunk fileName)\nconst bundleCache = new Map<string, string>();\nconst cssCache = new Map<string, string>();\n\n/**\n * Generate hash từ content\n */\nfunction generateHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').substring(0, 16);\n}\n\n/**\n * Bundle JavaScript files từ dist/client thành 1 file\n * Trong production, các file đã được build sẵn trong dist/client\n */\nexport async function bundleScripts(\n scriptPaths: string[],\n rootDir: string,\n distClientDir: string,\n): Promise<{ hash: string; filename: string; content: string }> {\n if (scriptPaths.length === 0) {\n return { hash: '', filename: '', content: '' };\n }\n\n // Dedupe paths (remove duplicates)\n const uniquePaths = [...new Set(scriptPaths)];\n\n // Tạo cache key từ sorted unique paths\n const cacheKey = `scripts:${uniquePaths.sort().join(',')}`;\n\n // Kiểm tra cache - return entry chunk info if already bundled\n const cachedEntryFileName = bundleCache.get(cacheKey);\n if (cachedEntryFileName) {\n const entryFile = bundledFilesMap.get(cachedEntryFileName);\n if (entryFile) {\n return {\n hash: entryFile.hash,\n filename: entryFile.filename,\n content: entryFile.content,\n };\n }\n }\n\n // Temp file path for cleanup\n let entryFile: string | null = null;\n\n try {\n // Sử dụng rollup để bundle nếu cần (resolve imports, etc)\n // Tạo temp entry file\n const hash = generateHash(uniquePaths.join('\\n'));\n const tempDir = path.join(rootDir, '.temp-bundle');\n await fs.mkdir(tempDir, { recursive: true }).catch(() => {});\n\n entryFile = path.join(tempDir, `entry-${hash}.js`);\n // Tạo entry file import tất cả scripts\n const entryContent = uniquePaths\n .map((p, i) => {\n const filePath = p.startsWith('/')\n ? path.join(distClientDir, p.substring(1))\n : path.join(distClientDir, p);\n return `import ${JSON.stringify(filePath)};`;\n })\n .join('\\n');\n\n await fs.writeFile(entryFile, entryContent, 'utf-8');\n console.log(`[bundler] Wrote entry file to ${entryFile}`);\n console.log(`[bundler] Entry content: ${entryContent}`);\n // Rollup config để bundle\n const rollupOptions: RollupOptions = {\n input: entryFile,\n plugins: [\n {\n name: 'vendor-path-rewriter',\n resolveId(source, importer, _options) {\n // Handle vendor/chunk/global files: convert absolute paths to web paths\n // Global files (*.global.*) are already loaded by client.global.ts —\n // re-bundling them would create duplicate module instances (e.g. nanostores)\n if (\n source.includes('vendor-') ||\n source.includes('chunk-') ||\n source.includes('.global')\n ) {\n console.log(`[bundler] Resolving source: ${source}`);\n if (path.isAbsolute(source)) {\n console.log(`[bundler] Resolving absolute path: ${source}`);\n // e.g., C:\\...\\dist\\client\\assets\\vendor-react-XXX.js -> /assets/vendor-react-XXX.js\n const relativePath = path.relative(distClientDir, source);\n const webPath = '/' + relativePath.replace(/\\\\/g, '/');\n return { id: webPath, external: true };\n } else if (importer && source.startsWith('.')) {\n console.log(\n `[bundler] Resolving relative path: ${source} from importer: ${importer}`,\n );\n // Relative path like ./auth.global-BOVr81Z5.js — resolve from importer\n const resolved = path.resolve(path.dirname(importer), source);\n const relativePath = path.relative(distClientDir, resolved);\n const webPath = '/' + relativePath.replace(/\\\\/g, '/');\n return { id: webPath, external: true };\n } else {\n console.log(`[bundler] Resolving source: ${source}`);\n }\n }\n return null; // Let other plugins/external handle\n },\n },\n ],\n external: (id) => {\n // External node_modules\n if (!id.startsWith('.') && !path.isAbsolute(id)) {\n return true;\n }\n\n // Let plugin handle vendor/chunk/global files (don't mark external here)\n if (id.includes('vendor-') || id.includes('chunk-') || id.includes('.global')) {\n return false; // Let plugin's resolveId handle path rewriting\n }\n\n return false;\n },\n };\n\n const outputOptions: OutputOptions = {\n format: 'es',\n inlineDynamicImports: false,\n entryFileNames: 'bundle-[hash].js',\n chunkFileNames: 'bundle-[hash].js',\n };\n\n const bundle = await rollup(rollupOptions);\n const { output } = await bundle.generate(outputOptions);\n await bundle.close();\n\n // Lấy bundled content từ rollup\n\n output.forEach((o) => {\n if (o.type !== 'chunk') {\n return;\n }\n // Lưu vào map với key = fileName\n const bundledFile: BundledFile = {\n content: o.code || '',\n hash: generateHash(o.code || ''),\n filename: o.fileName,\n mimeType: 'application/javascript',\n };\n bundledFilesMap.set(o.fileName, bundledFile);\n });\n\n // Cache entry chunk fileName for deduplication\n const entryChunk = output[0];\n if (entryChunk?.type === 'chunk') {\n bundleCache.set(cacheKey, entryChunk.fileName);\n }\n\n // Return entry chunk info\n return {\n hash: generateHash(output[0]?.code || ''),\n filename: output[0]?.fileName || '',\n content: output[0]?.code || '',\n };\n } catch (error) {\n console.error('[bundler] Error bundling scripts:', error);\n return { hash: '', filename: '', content: '' };\n } finally {\n // Cleanup temp entry file\n if (entryFile) {\n await fs.unlink(entryFile).catch(() => {\n // Ignore cleanup errors\n });\n }\n }\n}\n\n/**\n * Bundle CSS files từ dist/client thành 1 file\n * Trong production, các file đã được build sẵn trong dist/client\n */\nexport async function bundleCss(\n cssPaths: string[],\n rootDir: string,\n distClientDir: string,\n): Promise<{ hash: string; filename: string; content: string }> {\n if (cssPaths.length === 0) {\n return { hash: '', filename: '', content: '' };\n }\n\n // Dedupe paths (remove duplicates)\n const uniquePaths = [...new Set(cssPaths)];\n\n // Tạo cache key từ sorted unique paths\n const cacheKey = `css:${uniquePaths.sort().join(',')}`;\n\n // Kiểm tra cache - return cached file if already bundled\n const cachedFileName = cssCache.get(cacheKey);\n if (cachedFileName) {\n const cachedFile = bundledFilesMap.get(cachedFileName);\n if (cachedFile) {\n return {\n hash: cachedFile.hash,\n filename: cachedFile.filename,\n content: cachedFile.content,\n };\n }\n }\n\n try {\n // Đọc và gộp tất cả CSS files từ dist/client\n const cssContents: string[] = [];\n\n for (const cssPath of uniquePaths) {\n // cssPath có thể là \"/assets/xxx.css\" hoặc từ manifest\n const filePath = cssPath.startsWith('/')\n ? path.join(distClientDir, cssPath.substring(1))\n : path.join(distClientDir, cssPath);\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n cssContents.push(`/* ${cssPath} */\\n${content}\\n`);\n } catch (err) {\n console.warn(`[bundler] Failed to read CSS file: ${cssPath}`, err);\n }\n }\n\n const bundledContent = cssContents.join('\\n\\n');\n const hash = generateHash(bundledContent);\n const filename = `bundle-${hash}.css`;\n\n // Lưu vào map với key = filename\n const bundledFile: BundledFile = {\n content: bundledContent,\n hash,\n filename,\n mimeType: 'text/css',\n };\n bundledFilesMap.set(filename, bundledFile);\n\n // Cache filename for deduplication\n cssCache.set(cacheKey, filename);\n\n return { hash, filename, content: bundledContent };\n } catch (error) {\n console.error('[bundler] Error bundling CSS:', error);\n return { hash: '', filename: '', content: '' };\n }\n}\n\n/**\n * Get bundled file từ map\n */\nexport function getBundledFile(filename: string): BundledFile | undefined {\n return bundledFilesMap.get(filename);\n}\n\n/**\n * Clear bundled files map (useful for testing)\n */\nexport function clearBundledFiles(): void {\n bundledFilesMap.clear();\n}\n","import type { Request as ExpressRequest, Response as ExpressResponse } from 'express';\nimport { existsSync } from 'fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport requestIp from 'request-ip';\nimport type { ViteDevServer } from 'vite';\nimport { createContext, type MiddlewareHandler, type RewritePayload } from '../middleware';\nimport { bundleCss, bundleScripts, getBundledFile } from './bundler';\nimport type { RenderResult, RequestInfo } from './entry-server';\nimport { createHeadersFromExpressRequest, parseCookies } from './request';\n\nexport interface ServerOptions {\n root?: string;\n port?: number;\n base?: string;\n publicDir?: string;\n setupApp?: (app: any) => void | Promise<void>;\n app?: any; // Express\n}\n\nexport interface ServerContext {\n app: any; // Express app\n vite?: ViteDevServer;\n}\n\n/**\n * Apply or replace lang attribute on <html> tag\n */\nfunction applyHtmlLang(template: string, lang: string): string {\n return template.replace(/<html\\b([^>]*)>/i, (match, attrs) => {\n // Check if lang already exists\n if (/\\blang\\s*=/i.test(attrs)) {\n // Replace existing lang value\n return match.replace(/lang\\s*=\\s*\"[^\"]*\"/i, `lang=\"${lang}\"`);\n } else {\n // Add lang attribute\n return `<html lang=\"${lang}\"${attrs}>`;\n }\n });\n}\n\ntype EntryServerModule = {\n render: (url: string, requestInfo?: RequestInfo) => Promise<RenderResult>;\n loadMiddleware?: () => Promise<MiddlewareHandler | undefined>;\n};\n\nfunction getRequestUrl(req: ExpressRequest): URL {\n return new URL(`${req.protocol}://${req.get('host')}${req.originalUrl}`);\n}\n\nfunction getRenderUrl(urlObject: URL, base: string): string {\n const requestPath = `${urlObject.pathname}${urlObject.search}`;\n return requestPath.replace(base, '') || '/';\n}\n\nfunction createWebRequestFromExpress(req: ExpressRequest): globalThis.Request {\n const init: RequestInit & { duplex?: 'half' } = {\n method: req.method,\n headers: createHeadersFromExpressRequest(req),\n };\n\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n init.body = req as unknown as BodyInit;\n init.duplex = 'half';\n }\n\n return new globalThis.Request(getRequestUrl(req).href, init);\n}\n\nfunction createRequestInfo(\n req: ExpressRequest,\n webRequest: globalThis.Request,\n base: string,\n locals: Record<string, unknown>,\n): RequestInfo {\n const urlObject = new URL(webRequest.url);\n const renderUrl = getRenderUrl(urlObject, base);\n const normalizedPath = renderUrl.startsWith('/') ? renderUrl : `/${renderUrl}`;\n const headers: Record<string, string> = {};\n webRequest.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n return {\n url: urlObject,\n path: normalizedPath,\n pathname: urlObject.pathname,\n method: webRequest.method,\n headers,\n cookies: parseCookies(webRequest.headers.get('cookie') ?? undefined),\n query: Object.fromEntries(urlObject.searchParams.entries()),\n ip: requestIp.getClientIp(req) ?? undefined,\n locals,\n };\n}\n\nfunction createRewriteRequest(\n payload: RewritePayload | undefined,\n currentRequest: globalThis.Request,\n currentUrl: URL,\n): globalThis.Request {\n if (!payload) {\n return currentRequest;\n }\n\n if (payload instanceof globalThis.Request) {\n return payload;\n }\n\n if (payload instanceof URL) {\n return new globalThis.Request(payload.href, currentRequest.clone());\n }\n\n return new globalThis.Request(new URL(payload, currentUrl).href, currentRequest.clone());\n}\n\nasync function sendWebResponse(\n req: ExpressRequest,\n res: ExpressResponse,\n response: globalThis.Response,\n): Promise<void> {\n res.status(response.status);\n const setCookieValues = getSetCookieHeaders(response.headers);\n response.headers.forEach((value, key) => {\n if (key.toLowerCase() === 'set-cookie') {\n return;\n }\n res.setHeader(key, value);\n });\n if (setCookieValues.length > 0) {\n res.setHeader('Set-Cookie', setCookieValues);\n }\n\n if (req.method === 'HEAD') {\n res.end();\n return;\n }\n\n const body = Buffer.from(await response.arrayBuffer());\n res.send(body);\n}\n\nfunction getSetCookieHeaders(headers: Headers): string[] {\n const getSetCookie = (headers as Headers & { getSetCookie?: () => string[] }).getSetCookie;\n if (typeof getSetCookie === 'function') {\n return getSetCookie.call(headers);\n }\n\n const raw = (headers as Headers & { raw?: () => Record<string, string[]> }).raw?.();\n if (raw?.['set-cookie']) {\n return raw['set-cookie'];\n }\n\n const value = headers.get('set-cookie');\n return value ? splitSetCookieHeader(value) : [];\n}\n\nfunction splitSetCookieHeader(value: string): string[] {\n const cookies: string[] = [];\n let start = 0;\n\n for (let i = 0; i < value.length; i++) {\n if (value[i] !== ',') continue;\n\n const rest = value.slice(i + 1);\n if (/^\\s*[^=;,]+=/.test(rest)) {\n cookies.push(value.slice(start, i).trim());\n start = i + 1;\n }\n }\n\n cookies.push(value.slice(start).trim());\n return cookies.filter(Boolean);\n}\n\nfunction createRawResponse(rendered: RenderResult): globalThis.Response | null {\n if (!rendered.rawResponse) {\n return null;\n }\n\n const { body, contentType, statusCode, headers } = rendered.rawResponse;\n const responseHeaders = new Headers(headers);\n responseHeaders.set('Content-Type', contentType);\n\n return new globalThis.Response(body as BodyInit, {\n status: statusCode || 200,\n headers: responseHeaders,\n });\n}\n\nasync function createPageResponse({\n rendered,\n template,\n manifest,\n root,\n distClientDir,\n isProduction,\n}: {\n rendered: RenderResult;\n template: string;\n manifest?: Record<string, any>;\n root: string;\n distClientDir: string;\n isProduction: boolean;\n}): Promise<globalThis.Response> {\n const rawResponse = createRawResponse(rendered);\n if (rawResponse) {\n return rawResponse;\n }\n\n if (rendered.redirect) {\n return new globalThis.Response(null, {\n status: rendered.redirect.statusCode,\n headers: {\n Location: rendered.redirect.url,\n },\n });\n }\n\n let scriptSrcList: string[] = rendered.scripts || [];\n let cssSrcList: string[] = rendered.styles || [];\n const islandEntries = rendered.islands || [];\n let cacheTags: string[] = rendered.cacheTags || [];\n const maxAge: number | undefined = rendered.maxAge;\n const sMaxAge: number | undefined = rendered.sMaxAge;\n const swr: number | undefined = rendered.swr;\n\n let extraHead = '';\n let globalScripts: string[] = [];\n let islandRegistryScript = '';\n\n if (isProduction && manifest) {\n scriptSrcList = scriptSrcList.filter((src) => !src.includes('.global.'));\n cssSrcList = cssSrcList.filter((src) => !src.includes('.global.'));\n\n const cssFiles = new Set<string>();\n const preloadFiles = new Set<string>();\n\n function collectFromEntry(entryKey: string): { file: string | null } {\n const entry = manifest![entryKey];\n if (!entry) return { file: null };\n\n if (entry.css) entry.css.forEach((css: string) => cssFiles.add(css));\n if (entry.imports) {\n entry.imports.forEach((importKey: string) => {\n const importedChunk = manifest![importKey];\n if (importedChunk?.file) preloadFiles.add(importedChunk.file);\n if (importedChunk?.css) {\n importedChunk.css.forEach((css: string) => cssFiles.add(css));\n }\n if (importedChunk?.imports) {\n importedChunk.imports.forEach((key: string) => {\n const chunk = manifest![key];\n if (chunk?.file) preloadFiles.add(chunk.file);\n if (chunk?.css) chunk.css.forEach((css: string) => cssFiles.add(css));\n });\n }\n });\n }\n\n return { file: entry.file };\n }\n\n const mappedScripts: string[] = [];\n for (const src of scriptSrcList) {\n const entryKey = src.replace(/^\\//, '');\n const { file } = collectFromEntry(entryKey);\n if (file) mappedScripts.push(`/${file}`);\n }\n\n const mappedCssFiles: string[] = [];\n for (const src of cssSrcList) {\n const entryKey = src.replace(/^\\//, '');\n const { file } = collectFromEntry(entryKey);\n if (file) {\n mappedCssFiles.push(`/${file}`);\n cssFiles.add(file);\n }\n }\n\n if (mappedScripts.length > 0) {\n const bundledScript = await bundleScripts(mappedScripts, root, distClientDir);\n scriptSrcList = bundledScript.filename ? [`/${bundledScript.filename}`] : mappedScripts;\n }\n\n if (mappedCssFiles.length > 0) {\n const bundledCss = await bundleCss(mappedCssFiles, root, distClientDir);\n if (bundledCss.filename) {\n cssSrcList = [`/${bundledCss.filename}`];\n }\n }\n\n const globalEntry = manifest['src/client.global.ts'];\n if (globalEntry) {\n if (globalEntry.css && globalEntry.css.length > 0) {\n globalEntry.css.forEach((cssFile: string) => {\n extraHead += `<link rel=\"stylesheet\" crossorigin href=\"/${cssFile}\">`;\n });\n }\n if (globalEntry.file) {\n globalScripts.push(`/${globalEntry.file}`);\n }\n }\n\n if (islandEntries.length > 0) {\n const islandMap: Record<string, string> = {};\n for (const island of islandEntries) {\n const entry = manifest[island.src];\n if (entry?.file) {\n islandMap[island.key] = `/${entry.file}`;\n }\n }\n if (Object.keys(islandMap).length > 0) {\n islandRegistryScript = `<script>window.__L5E_ISLANDS__=${JSON.stringify(islandMap)}</script>`;\n }\n }\n\n if (cssSrcList.length > 0) {\n extraHead += cssSrcList\n .map((file) => `<link rel=\"stylesheet\" crossorigin href=\"${file}\">`)\n .join('');\n }\n }\n\n let cssHtml = '';\n if (!isProduction) {\n cssHtml = cssSrcList.map((src) => `<link rel=\"stylesheet\" href=\"${src}\">`).join('');\n }\n\n let allScripts = [...globalScripts, ...scriptSrcList];\n\n if (!isProduction) {\n const globalTsPath = path.join(root, 'src', 'client.global.ts');\n if (existsSync(globalTsPath)) {\n allScripts = ['/src/client.global.ts', ...allScripts];\n }\n\n if (islandEntries.length > 0) {\n const islandMap: Record<string, string> = {};\n for (const island of islandEntries) {\n islandMap[island.key] = `/${island.src}`;\n }\n islandRegistryScript = `<script>window.__L5E_ISLANDS__=${JSON.stringify(islandMap)}</script>`;\n }\n }\n\n const scriptsHtml =\n islandRegistryScript +\n allScripts.map((src) => `<script type=\"module\" src=\"${src}\"></script>`).join('');\n\n const templateWithLang = rendered.lang ? applyHtmlLang(template, rendered.lang) : template;\n\n const html = rendered.rawHtml\n ? rendered.html || ''\n : templateWithLang\n .replace(`<!--app-head-->`, (rendered.head ?? '') + extraHead + cssHtml)\n .replace(`<!--app-html-->`, rendered.html ?? '')\n .replace(`<!--app-scripts-->`, scriptsHtml);\n\n const headers = new Headers({\n 'Content-Type': 'text/html',\n });\n\n const cacheControlParts: string[] = ['public'];\n if (maxAge !== undefined) cacheControlParts.push(`max-age=${maxAge}`);\n if (sMaxAge !== undefined) cacheControlParts.push(`s-maxage=${sMaxAge}`);\n if (swr !== undefined) cacheControlParts.push(`stale-while-revalidate=${swr}`);\n\n if (cacheControlParts.length > 1 && isProduction) {\n headers.set('Cache-Control', cacheControlParts.join(', '));\n }\n\n if (process.env.NODE_ENV === 'production') {\n cacheTags = optimizeCacheTags(cacheTags);\n }\n headers.set('Cache-Tag', ['global', ...cacheTags].join(','));\n\n return new globalThis.Response(html, {\n status: rendered.statusCode || 200,\n headers,\n });\n}\n\nexport async function createServer(options: ServerOptions = {}): Promise<ServerContext> {\n const root = options.root || process.cwd();\n const base = options.base || '/';\n const isProduction = process.env.NODE_ENV === 'production';\n\n // Cached production assets\n const templateHtml = isProduction\n ? await fs.readFile(path.join(root, './index.html'), 'utf-8')\n : '';\n\n // Create http server\n // @ts-ignore\n const express = (await import('express')).default;\n const app = options.app || express();\n\n // Serve static files from public directory\n if (options.publicDir) {\n const publicPath = path.isAbsolute(options.publicDir)\n ? options.publicDir\n : path.join(root, options.publicDir);\n\n if (existsSync(publicPath)) {\n app.use(express.static(publicPath));\n }\n }\n\n // Add Vite or respective production middlewares\n let vite: ViteDevServer | undefined;\n const distClientDir = path.join(root, './dist/client');\n\n if (!isProduction) {\n const { createServer } = await import('vite');\n const configFile = path.join(root, 'vite.config.js');\n vite = await createServer({\n root,\n configFile,\n server: { middlewareMode: true },\n appType: 'custom',\n base,\n optimizeDeps: {\n exclude: ['@withl5e/l5e', 'file-type'],\n },\n ssr: {\n resolve: {\n conditions: ['development', 'default'],\n },\n },\n resolve: {\n conditions: ['development', 'default'],\n },\n });\n app.use(vite.middlewares);\n } else {\n // @ts-ignore\n const compression = (await import('compression')).default;\n // @ts-ignore\n const sirv = (await import('sirv')).default;\n app.use(compression());\n app.use(base, sirv(distClientDir, { extensions: [] }));\n\n // Route để serve bundled files từ memory map\n // Đặt route này trước route HTML để catch request trước\n app.get(\n `${base === '/' ? '' : base}/bundle-:hash.:ext`,\n async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const { hash, ext } = req.params;\n const filename = `bundle-${hash}.${ext}`;\n const bundledFile = getBundledFile(filename);\n\n if (!bundledFile) {\n return res.status(404).send('Bundled file not found');\n }\n\n res.set({\n 'Content-Type': bundledFile.mimeType,\n 'Cache-Control': 'public, max-age=31536000, immutable',\n });\n res.send(bundledFile.content);\n } catch (e: any) {\n console.error('[server] Error serving bundled file:', e);\n res.status(500).end(e.message);\n }\n },\n );\n }\n\n // Action routes — JSON body parsing scoped to action endpoints only\n app.use('/_l5e/action', express.json({ limit: '100kb' }));\n\n // Validate action key format: actionName_hexHash\n const ACTION_KEY_RE = /^[a-zA-Z]\\w+_[0-9a-f]{1,4}$/;\n\n // Load action registry and viewActions glob from virtual module (dev) or built bundle (prod)\n let prodActionRegistry: Record<string, { modulePath: string; actionName: string }> | null = null;\n let prodViewActions: Record<string, () => Promise<any>> | null = null;\n\n async function getActionRegistry(): Promise<\n Record<string, { modulePath: string; actionName: string }>\n > {\n if (!isProduction) {\n const mod = await vite!.ssrLoadModule('virtual:l5e-actions');\n return mod.actionRegistry || {};\n }\n if (!prodActionRegistry) {\n const registryPath = path.join(root, './dist/server/action-registry.json');\n const json = await fs.readFile(registryPath, 'utf-8');\n prodActionRegistry = JSON.parse(json);\n }\n return prodActionRegistry!;\n }\n\n async function getViewActions(): Promise<Record<string, () => Promise<any>>> {\n if (!isProduction) {\n const mod = await vite!.ssrLoadModule('virtual:l5e-actions');\n return mod.viewActions || {};\n }\n if (!prodViewActions) {\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const mod = await import(pathToFileURL(entryServerPath).href);\n prodViewActions = mod.viewActions || {};\n }\n return prodViewActions!;\n }\n\n // Action route handler — hashed action keys\n // URL: /_l5e/action/:actionKey (e.g., /_l5e/action/loadMoreComments_a1b2)\n app.all('/_l5e/action/:actionKey', async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const { actionKey } = req.params;\n\n // Validate action key format\n if (!ACTION_KEY_RE.test(actionKey)) {\n return res.status(400).send('Invalid action key');\n }\n\n // Look up action in registry\n const registry = await getActionRegistry();\n const entry = registry[actionKey];\n if (!entry) {\n return res.status(404).send('Action not found');\n }\n\n const { modulePath, actionName } = entry;\n\n // Import action module via viewActions glob (works in both dev and prod)\n let actionModule: any;\n if (!isProduction) {\n try {\n actionModule = await vite!.ssrLoadModule(`/src/${modulePath}/actions.tsx`);\n } catch {\n actionModule = await vite!.ssrLoadModule(`/src/${modulePath}/actions.ts`);\n }\n } else {\n const viewActions = await getViewActions();\n // Find matching glob entry by modulePath\n const globKey = viewActions[`/src/${modulePath}/actions.tsx`]\n ? `/src/${modulePath}/actions.tsx`\n : viewActions[`/src/${modulePath}/actions.ts`]\n ? `/src/${modulePath}/actions.ts`\n : null;\n if (!globKey) {\n return res.status(404).send('Action module not found');\n }\n actionModule = await viewActions[globKey]();\n }\n\n // Look up exported action — use hasOwnProperty to avoid prototype pollution\n if (!Object.prototype.hasOwnProperty.call(actionModule, actionName)) {\n return res.status(404).send('Action not found');\n }\n const action = actionModule[actionName];\n if (!action || !action.handler) {\n return res.status(404).send('Action not found');\n }\n\n // Build RequestInfo (same pattern as HTML handler)\n const fullUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\n const urlObject = new URL(fullUrl);\n\n const requestInfo = {\n url: urlObject,\n path: req.originalUrl,\n pathname: urlObject.pathname,\n method: req.method,\n headers: req.headers,\n cookies: parseCookies(req.headers.cookie as string),\n query: req.query || {},\n body: req.body,\n ip: requestIp.getClientIp(req),\n };\n\n // Import render utilities from entry-server (bundled in SSR build)\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const { runInRenderContext } = await (isProduction\n ? import(pathToFileURL(entryServerPath).href)\n : vite!.ssrLoadModule('@withl5e/l5e/jsx-runtime'));\n const { renderJsxToHtmlString } = await (isProduction\n ? import(pathToFileURL(entryServerPath).href)\n : vite!.ssrLoadModule('@withl5e/l5e'));\n\n // Run action handler in render context (needed for JSX)\n const html = await runInRenderContext(\n async () => {\n const jsx = await action.handler(requestInfo);\n return renderJsxToHtmlString(jsx);\n },\n requestInfo,\n modulePath,\n );\n\n res.set('Content-Type', 'text/html').send(html);\n } catch (e: any) {\n vite?.ssrFixStacktrace?.(e);\n console.error('[l5e] Action error:', e.stack || e);\n res.status(500).send('Internal server error');\n }\n });\n\n // Serve HTML\n app.use(async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const url = req.originalUrl.replace(base, '');\n\n let template: string;\n let render: (url: string, requestInfo?: any) => Promise<any>;\n let loadMiddleware: EntryServerModule['loadMiddleware'];\n let manifest: Record<string, any> | undefined;\n\n if (!isProduction) {\n // Always read fresh template in development\n template = await fs.readFile(path.join(root, './index.html'), 'utf-8');\n template = await vite!.transformIndexHtml(url, template);\n\n // Inject Vite HMR client for hot reload\n if (!template.includes('@vite/client')) {\n template = template.replace(\n '</head>',\n '<script type=\"module\" src=\"/@vite/client\"></script></head>',\n );\n }\n\n const entryServer = (await vite!.ssrLoadModule(\n '@withl5e/l5e/entry-server',\n )) as EntryServerModule;\n render = entryServer.render;\n loadMiddleware = entryServer.loadMiddleware;\n } else {\n template = templateHtml;\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const entryServer = (await import(\n pathToFileURL(entryServerPath).href\n )) as EntryServerModule;\n render = entryServer.render;\n loadMiddleware = entryServer.loadMiddleware;\n // Read manifest to map hashed assets\n const manifestJson = await fs.readFile(\n path.join(root, './dist/client/.vite/manifest.json'),\n 'utf-8',\n );\n manifest = JSON.parse(manifestJson);\n }\n\n const loadedMiddleware = await loadMiddleware?.();\n const handler: MiddlewareHandler =\n typeof loadedMiddleware === 'function' ? loadedMiddleware : (_ctx, next) => next();\n\n const locals: Record<string, unknown> = {};\n const initialRequest = createWebRequestFromExpress(req);\n const context = createContext({\n request: initialRequest,\n requestInfo: createRequestInfo(req, initialRequest, base, locals),\n locals,\n clientAddress: requestIp.getClientIp(req),\n });\n\n const renderResponse = async (webRequest: globalThis.Request) => {\n const nextRequestInfo = createRequestInfo(req, webRequest, base, locals);\n const nextUrl = getRenderUrl(nextRequestInfo.url!, base);\n const nextRendered = await render(nextUrl, nextRequestInfo);\n return createPageResponse({\n rendered: nextRendered,\n template,\n manifest,\n root,\n distClientDir,\n isProduction,\n });\n };\n\n const next = async (payload?: RewritePayload) => {\n const nextRequest = createRewriteRequest(payload, context.request, context.url);\n context.request = nextRequest;\n context.url = new URL(nextRequest.url);\n context.cookies = parseCookies(nextRequest.headers.get('cookie') ?? undefined);\n context.requestInfo = createRequestInfo(req, nextRequest, base, locals);\n return renderResponse(nextRequest);\n };\n\n context.rewrite = (payload: RewritePayload) => next(payload);\n\n const response = await handler(context, next);\n await sendWebResponse(req, res, response);\n } catch (e: any) {\n vite?.ssrFixStacktrace?.(e);\n console.log(e.stack);\n res.status(500).end(e.stack);\n }\n });\n\n return { app, vite };\n}\n\nexport async function startServer(options: ServerOptions = {}): Promise<void> {\n const port = options.port || 5173;\n\n // Create Express app first\n // @ts-ignore\n const express = (await import('express')).default;\n const app = express();\n\n // Call callback if provided to allow custom routes before setting up L5E server\n if (options.setupApp) {\n console.log('setupApp');\n await options.setupApp(app);\n }\n\n const { app: serverApp } = await createServer({ ...options, app });\n\n serverApp.listen(port, () => {\n console.log(`Server started at http://localhost:${port}`);\n });\n}\n\nconst MAX_TAGS = 1000;\n\nexport function hashTag(tag: string): string {\n // global tag is not hashed, better for ci/cd\n if (tag === 'global') {\n return 'global';\n }\n\n let hash = 0;\n for (let i = 0; i < tag.length; i++) {\n const char = tag.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36).substring(0, 8);\n}\n\nexport function optimizeCacheTags(tags: Set<string> | string[]): string[] {\n const _tags = Array.isArray(tags) ? tags : [...tags];\n const result = _tags.slice(0, MAX_TAGS).map(hashTag);\n return result;\n}\n"],"names":["bundledFilesMap","bundleCache","cssCache","generateHash","content","createHash","bundleScripts","scriptPaths","rootDir","distClientDir","uniquePaths","cacheKey","cachedEntryFileName","entryFile","hash","tempDir","path","fs","entryContent","p","i","filePath","rollupOptions","source","importer","_options","resolved","id","outputOptions","bundle","rollup","output","o","bundledFile","entryChunk","error","bundleCss","cssPaths","cachedFileName","cachedFile","cssContents","cssPath","err","bundledContent","filename","getBundledFile","applyHtmlLang","template","lang","match","attrs","getRequestUrl","req","getRenderUrl","urlObject","base","createWebRequestFromExpress","init","createHeadersFromExpressRequest","createRequestInfo","webRequest","locals","renderUrl","normalizedPath","headers","value","key","parseCookies","requestIp","createRewriteRequest","payload","currentRequest","currentUrl","sendWebResponse","res","response","setCookieValues","getSetCookieHeaders","body","getSetCookie","raw","splitSetCookieHeader","cookies","start","rest","createRawResponse","rendered","contentType","statusCode","responseHeaders","createPageResponse","manifest","root","isProduction","rawResponse","scriptSrcList","cssSrcList","islandEntries","cacheTags","maxAge","sMaxAge","swr","extraHead","globalScripts","islandRegistryScript","collectFromEntry","entryKey","entry","css","cssFiles","importKey","importedChunk","preloadFiles","chunk","src","mappedScripts","file","mappedCssFiles","bundledScript","bundledCss","globalEntry","cssFile","islandMap","island","cssHtml","allScripts","globalTsPath","existsSync","scriptsHtml","templateWithLang","html","cacheControlParts","optimizeCacheTags","createServer","options","templateHtml","express","app","publicPath","vite","compression","sirv","ext","e","configFile","ACTION_KEY_RE","prodActionRegistry","prodViewActions","getActionRegistry","registryPath","json","getViewActions","entryServerPath","pathToFileURL","actionKey","modulePath","actionName","actionModule","viewActions","globKey","action","fullUrl","requestInfo","runInRenderContext","renderJsxToHtmlString","jsx","url","render","loadMiddleware","entryServer","manifestJson","loadedMiddleware","handler","_ctx","next","initialRequest","context","createContext","renderResponse","nextRequestInfo","nextUrl","nextRendered","nextRequest","startServer","port","serverApp","MAX_TAGS","hashTag","tag","char","tags"],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../src/core/bundler.ts","../src/core/server.ts"],"sourcesContent":["/// <reference path=\"./jsx-types.d.ts\" />\nimport { createHash } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { OutputOptions, RollupOptions } from 'rollup';\n\nlet rollupModulePromise: Promise<typeof import('rollup')> | null = null;\n\n/**\n * Resolve rollup lazily. We can't `import 'rollup'` directly because when the\n * framework gets bundled into the consumer's SSR output the bare specifier is\n * hoisted to a static import that pnpm doesn't satisfy. Resolve through `vite`\n * instead — vite is a peer dep so it's always installed, and it always ships\n * rollup as a direct dependency.\n */\nfunction loadRollup(): Promise<typeof import('rollup')> {\n if (!rollupModulePromise) {\n rollupModulePromise = (async () => {\n const require = createRequire(import.meta.url);\n const vitePath = require.resolve('vite');\n const rollupPath = require.resolve('rollup', { paths: [path.dirname(vitePath)] });\n return (await import(pathToFileURL(rollupPath).href)) as typeof import('rollup');\n })();\n }\n return rollupModulePromise;\n}\n\ninterface BundledFile {\n content: string;\n hash: string;\n filename: string;\n mimeType: string;\n}\n\n// Memory map để lưu bundled files\nconst bundledFilesMap = new Map<string, BundledFile>();\n\n// Cache map để deduplicate bundling requests (cacheKey → entry chunk fileName)\nconst bundleCache = new Map<string, string>();\nconst cssCache = new Map<string, string>();\n\n/**\n * Generate hash từ content\n */\nfunction generateHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').substring(0, 16);\n}\n\n/**\n * Bundle JavaScript files từ dist/client thành 1 file\n * Trong production, các file đã được build sẵn trong dist/client\n */\nexport async function bundleScripts(\n scriptPaths: string[],\n rootDir: string,\n distClientDir: string,\n): Promise<{ hash: string; filename: string; content: string }> {\n if (scriptPaths.length === 0) {\n return { hash: '', filename: '', content: '' };\n }\n\n // Dedupe paths (remove duplicates)\n const uniquePaths = [...new Set(scriptPaths)];\n\n // Tạo cache key từ sorted unique paths\n const cacheKey = `scripts:${uniquePaths.sort().join(',')}`;\n\n // Kiểm tra cache - return entry chunk info if already bundled\n const cachedEntryFileName = bundleCache.get(cacheKey);\n if (cachedEntryFileName) {\n const entryFile = bundledFilesMap.get(cachedEntryFileName);\n if (entryFile) {\n return {\n hash: entryFile.hash,\n filename: entryFile.filename,\n content: entryFile.content,\n };\n }\n }\n\n // Temp file path for cleanup\n let entryFile: string | null = null;\n\n try {\n // Sử dụng rollup để bundle nếu cần (resolve imports, etc)\n // Tạo temp entry file\n const hash = generateHash(uniquePaths.join('\\n'));\n const tempDir = path.join(rootDir, '.temp-bundle');\n await fs.mkdir(tempDir, { recursive: true }).catch(() => {});\n\n entryFile = path.join(tempDir, `entry-${hash}.js`);\n // Tạo entry file import tất cả scripts\n const entryContent = uniquePaths\n .map((p, i) => {\n const filePath = p.startsWith('/')\n ? path.join(distClientDir, p.substring(1))\n : path.join(distClientDir, p);\n return `import ${JSON.stringify(filePath)};`;\n })\n .join('\\n');\n\n await fs.writeFile(entryFile, entryContent, 'utf-8');\n console.log(`[bundler] Wrote entry file to ${entryFile}`);\n console.log(`[bundler] Entry content: ${entryContent}`);\n // Rollup config để bundle\n const rollupOptions: RollupOptions = {\n input: entryFile,\n plugins: [\n {\n name: 'vendor-path-rewriter',\n resolveId(source, importer, _options) {\n // Handle vendor/chunk/global files: convert absolute paths to web paths\n // Global files (*.global.*) are already loaded by client.global.ts —\n // re-bundling them would create duplicate module instances (e.g. nanostores)\n if (\n source.includes('vendor-') ||\n source.includes('chunk-') ||\n source.includes('.global')\n ) {\n console.log(`[bundler] Resolving source: ${source}`);\n if (path.isAbsolute(source)) {\n console.log(`[bundler] Resolving absolute path: ${source}`);\n // e.g., C:\\...\\dist\\client\\assets\\vendor-react-XXX.js -> /assets/vendor-react-XXX.js\n const relativePath = path.relative(distClientDir, source);\n const webPath = '/' + relativePath.replace(/\\\\/g, '/');\n return { id: webPath, external: true };\n } else if (importer && source.startsWith('.')) {\n console.log(\n `[bundler] Resolving relative path: ${source} from importer: ${importer}`,\n );\n // Relative path like ./auth.global-BOVr81Z5.js — resolve from importer\n const resolved = path.resolve(path.dirname(importer), source);\n const relativePath = path.relative(distClientDir, resolved);\n const webPath = '/' + relativePath.replace(/\\\\/g, '/');\n return { id: webPath, external: true };\n } else {\n console.log(`[bundler] Resolving source: ${source}`);\n }\n }\n return null; // Let other plugins/external handle\n },\n },\n ],\n external: (id) => {\n // External node_modules\n if (!id.startsWith('.') && !path.isAbsolute(id)) {\n return true;\n }\n\n // Let plugin handle vendor/chunk/global files (don't mark external here)\n if (id.includes('vendor-') || id.includes('chunk-') || id.includes('.global')) {\n return false; // Let plugin's resolveId handle path rewriting\n }\n\n return false;\n },\n };\n\n const outputOptions: OutputOptions = {\n format: 'es',\n inlineDynamicImports: false,\n entryFileNames: 'bundle-[hash].js',\n chunkFileNames: 'bundle-[hash].js',\n };\n\n const { rollup } = await loadRollup();\n const bundle = await rollup(rollupOptions);\n const { output } = await bundle.generate(outputOptions);\n await bundle.close();\n\n // Lấy bundled content từ rollup\n\n output.forEach((o) => {\n if (o.type !== 'chunk') {\n return;\n }\n // Lưu vào map với key = fileName\n const bundledFile: BundledFile = {\n content: o.code || '',\n hash: generateHash(o.code || ''),\n filename: o.fileName,\n mimeType: 'application/javascript',\n };\n bundledFilesMap.set(o.fileName, bundledFile);\n });\n\n // Cache entry chunk fileName for deduplication\n const entryChunk = output[0];\n if (entryChunk?.type === 'chunk') {\n bundleCache.set(cacheKey, entryChunk.fileName);\n }\n\n // Return entry chunk info\n return {\n hash: generateHash(output[0]?.code || ''),\n filename: output[0]?.fileName || '',\n content: output[0]?.code || '',\n };\n } catch (error) {\n console.error('[bundler] Error bundling scripts:', error);\n return { hash: '', filename: '', content: '' };\n } finally {\n // Cleanup temp entry file\n if (entryFile) {\n await fs.unlink(entryFile).catch(() => {\n // Ignore cleanup errors\n });\n }\n }\n}\n\n/**\n * Bundle CSS files từ dist/client thành 1 file\n * Trong production, các file đã được build sẵn trong dist/client\n */\nexport async function bundleCss(\n cssPaths: string[],\n rootDir: string,\n distClientDir: string,\n): Promise<{ hash: string; filename: string; content: string }> {\n if (cssPaths.length === 0) {\n return { hash: '', filename: '', content: '' };\n }\n\n // Dedupe paths (remove duplicates)\n const uniquePaths = [...new Set(cssPaths)];\n\n // Tạo cache key từ sorted unique paths\n const cacheKey = `css:${uniquePaths.sort().join(',')}`;\n\n // Kiểm tra cache - return cached file if already bundled\n const cachedFileName = cssCache.get(cacheKey);\n if (cachedFileName) {\n const cachedFile = bundledFilesMap.get(cachedFileName);\n if (cachedFile) {\n return {\n hash: cachedFile.hash,\n filename: cachedFile.filename,\n content: cachedFile.content,\n };\n }\n }\n\n try {\n // Đọc và gộp tất cả CSS files từ dist/client\n const cssContents: string[] = [];\n\n for (const cssPath of uniquePaths) {\n // cssPath có thể là \"/assets/xxx.css\" hoặc từ manifest\n const filePath = cssPath.startsWith('/')\n ? path.join(distClientDir, cssPath.substring(1))\n : path.join(distClientDir, cssPath);\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n cssContents.push(`/* ${cssPath} */\\n${content}\\n`);\n } catch (err) {\n console.warn(`[bundler] Failed to read CSS file: ${cssPath}`, err);\n }\n }\n\n const bundledContent = cssContents.join('\\n\\n');\n const hash = generateHash(bundledContent);\n const filename = `bundle-${hash}.css`;\n\n // Lưu vào map với key = filename\n const bundledFile: BundledFile = {\n content: bundledContent,\n hash,\n filename,\n mimeType: 'text/css',\n };\n bundledFilesMap.set(filename, bundledFile);\n\n // Cache filename for deduplication\n cssCache.set(cacheKey, filename);\n\n return { hash, filename, content: bundledContent };\n } catch (error) {\n console.error('[bundler] Error bundling CSS:', error);\n return { hash: '', filename: '', content: '' };\n }\n}\n\n/**\n * Get bundled file từ map\n */\nexport function getBundledFile(filename: string): BundledFile | undefined {\n return bundledFilesMap.get(filename);\n}\n\n/**\n * Clear bundled files map (useful for testing)\n */\nexport function clearBundledFiles(): void {\n bundledFilesMap.clear();\n}\n","import type { Request as ExpressRequest, Response as ExpressResponse } from 'express';\nimport { existsSync } from 'fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport requestIp from 'request-ip';\nimport type { ViteDevServer } from 'vite';\nimport { createContext, type MiddlewareHandler, type RewritePayload } from '../middleware';\nimport { bundleCss, bundleScripts, getBundledFile } from './bundler';\nimport type { RenderResult, RequestInfo } from './entry-server';\nimport { createHeadersFromExpressRequest, parseCookies } from './request';\n\nexport interface ServerOptions {\n root?: string;\n port?: number;\n base?: string;\n publicDir?: string;\n setupApp?: (app: any) => void | Promise<void>;\n app?: any; // Express\n}\n\nexport interface ServerContext {\n app: any; // Express app\n vite?: ViteDevServer;\n}\n\n/**\n * Apply or replace lang attribute on <html> tag\n */\nfunction applyHtmlLang(template: string, lang: string): string {\n return template.replace(/<html\\b([^>]*)>/i, (match, attrs) => {\n // Check if lang already exists\n if (/\\blang\\s*=/i.test(attrs)) {\n // Replace existing lang value\n return match.replace(/lang\\s*=\\s*\"[^\"]*\"/i, `lang=\"${lang}\"`);\n } else {\n // Add lang attribute\n return `<html lang=\"${lang}\"${attrs}>`;\n }\n });\n}\n\ntype EntryServerModule = {\n render: (url: string, requestInfo?: RequestInfo) => Promise<RenderResult>;\n loadMiddleware?: () => Promise<MiddlewareHandler | undefined>;\n};\n\nfunction getRequestUrl(req: ExpressRequest): URL {\n return new URL(`${req.protocol}://${req.get('host')}${req.originalUrl}`);\n}\n\nfunction getRenderUrl(urlObject: URL, base: string): string {\n const requestPath = `${urlObject.pathname}${urlObject.search}`;\n return requestPath.replace(base, '') || '/';\n}\n\nfunction createWebRequestFromExpress(req: ExpressRequest): globalThis.Request {\n const init: RequestInit & { duplex?: 'half' } = {\n method: req.method,\n headers: createHeadersFromExpressRequest(req),\n };\n\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n init.body = req as unknown as BodyInit;\n init.duplex = 'half';\n }\n\n return new globalThis.Request(getRequestUrl(req).href, init);\n}\n\nfunction createRequestInfo(\n req: ExpressRequest,\n webRequest: globalThis.Request,\n base: string,\n locals: Record<string, unknown>,\n): RequestInfo {\n const urlObject = new URL(webRequest.url);\n const renderUrl = getRenderUrl(urlObject, base);\n const normalizedPath = renderUrl.startsWith('/') ? renderUrl : `/${renderUrl}`;\n const headers: Record<string, string> = {};\n webRequest.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n return {\n url: urlObject,\n path: normalizedPath,\n pathname: urlObject.pathname,\n method: webRequest.method,\n headers,\n cookies: parseCookies(webRequest.headers.get('cookie') ?? undefined),\n query: Object.fromEntries(urlObject.searchParams.entries()),\n ip: requestIp.getClientIp(req) ?? undefined,\n locals,\n };\n}\n\nfunction createRewriteRequest(\n payload: RewritePayload | undefined,\n currentRequest: globalThis.Request,\n currentUrl: URL,\n): globalThis.Request {\n if (!payload) {\n return currentRequest;\n }\n\n if (payload instanceof globalThis.Request) {\n return payload;\n }\n\n if (payload instanceof URL) {\n return new globalThis.Request(payload.href, currentRequest.clone());\n }\n\n return new globalThis.Request(new URL(payload, currentUrl).href, currentRequest.clone());\n}\n\nasync function sendWebResponse(\n req: ExpressRequest,\n res: ExpressResponse,\n response: globalThis.Response,\n): Promise<void> {\n res.status(response.status);\n const setCookieValues = getSetCookieHeaders(response.headers);\n response.headers.forEach((value, key) => {\n if (key.toLowerCase() === 'set-cookie') {\n return;\n }\n res.setHeader(key, value);\n });\n if (setCookieValues.length > 0) {\n res.setHeader('Set-Cookie', setCookieValues);\n }\n\n if (req.method === 'HEAD') {\n res.end();\n return;\n }\n\n const body = Buffer.from(await response.arrayBuffer());\n res.send(body);\n}\n\nfunction getSetCookieHeaders(headers: Headers): string[] {\n const getSetCookie = (headers as Headers & { getSetCookie?: () => string[] }).getSetCookie;\n if (typeof getSetCookie === 'function') {\n return getSetCookie.call(headers);\n }\n\n const raw = (headers as Headers & { raw?: () => Record<string, string[]> }).raw?.();\n if (raw?.['set-cookie']) {\n return raw['set-cookie'];\n }\n\n const value = headers.get('set-cookie');\n return value ? splitSetCookieHeader(value) : [];\n}\n\nfunction splitSetCookieHeader(value: string): string[] {\n const cookies: string[] = [];\n let start = 0;\n\n for (let i = 0; i < value.length; i++) {\n if (value[i] !== ',') continue;\n\n const rest = value.slice(i + 1);\n if (/^\\s*[^=;,]+=/.test(rest)) {\n cookies.push(value.slice(start, i).trim());\n start = i + 1;\n }\n }\n\n cookies.push(value.slice(start).trim());\n return cookies.filter(Boolean);\n}\n\nfunction createRawResponse(rendered: RenderResult): globalThis.Response | null {\n if (!rendered.rawResponse) {\n return null;\n }\n\n const { body, contentType, statusCode, headers } = rendered.rawResponse;\n const responseHeaders = new Headers(headers);\n responseHeaders.set('Content-Type', contentType);\n\n return new globalThis.Response(body as BodyInit, {\n status: statusCode || 200,\n headers: responseHeaders,\n });\n}\n\nasync function createPageResponse({\n rendered,\n template,\n manifest,\n root,\n distClientDir,\n isProduction,\n}: {\n rendered: RenderResult;\n template: string;\n manifest?: Record<string, any>;\n root: string;\n distClientDir: string;\n isProduction: boolean;\n}): Promise<globalThis.Response> {\n const rawResponse = createRawResponse(rendered);\n if (rawResponse) {\n return rawResponse;\n }\n\n if (rendered.redirect) {\n return new globalThis.Response(null, {\n status: rendered.redirect.statusCode,\n headers: {\n Location: rendered.redirect.url,\n },\n });\n }\n\n let scriptSrcList: string[] = rendered.scripts || [];\n let cssSrcList: string[] = rendered.styles || [];\n const islandEntries = rendered.islands || [];\n let cacheTags: string[] = rendered.cacheTags || [];\n const maxAge: number | undefined = rendered.maxAge;\n const sMaxAge: number | undefined = rendered.sMaxAge;\n const swr: number | undefined = rendered.swr;\n\n let extraHead = '';\n let globalScripts: string[] = [];\n let islandRegistryScript = '';\n\n if (isProduction && manifest) {\n scriptSrcList = scriptSrcList.filter((src) => !src.includes('.global.'));\n cssSrcList = cssSrcList.filter((src) => !src.includes('.global.'));\n\n const cssFiles = new Set<string>();\n const preloadFiles = new Set<string>();\n\n function collectFromEntry(entryKey: string): { file: string | null } {\n const entry = manifest![entryKey];\n if (!entry) return { file: null };\n\n if (entry.css) entry.css.forEach((css: string) => cssFiles.add(css));\n if (entry.imports) {\n entry.imports.forEach((importKey: string) => {\n const importedChunk = manifest![importKey];\n if (importedChunk?.file) preloadFiles.add(importedChunk.file);\n if (importedChunk?.css) {\n importedChunk.css.forEach((css: string) => cssFiles.add(css));\n }\n if (importedChunk?.imports) {\n importedChunk.imports.forEach((key: string) => {\n const chunk = manifest![key];\n if (chunk?.file) preloadFiles.add(chunk.file);\n if (chunk?.css) chunk.css.forEach((css: string) => cssFiles.add(css));\n });\n }\n });\n }\n\n return { file: entry.file };\n }\n\n const mappedScripts: string[] = [];\n for (const src of scriptSrcList) {\n const entryKey = src.replace(/^\\//, '');\n const { file } = collectFromEntry(entryKey);\n if (file) mappedScripts.push(`/${file}`);\n }\n\n const mappedCssFiles: string[] = [];\n for (const src of cssSrcList) {\n const entryKey = src.replace(/^\\//, '');\n const { file } = collectFromEntry(entryKey);\n if (file) {\n mappedCssFiles.push(`/${file}`);\n cssFiles.add(file);\n }\n }\n\n if (mappedScripts.length > 0) {\n const bundledScript = await bundleScripts(mappedScripts, root, distClientDir);\n scriptSrcList = bundledScript.filename ? [`/${bundledScript.filename}`] : mappedScripts;\n }\n\n if (mappedCssFiles.length > 0) {\n const bundledCss = await bundleCss(mappedCssFiles, root, distClientDir);\n if (bundledCss.filename) {\n cssSrcList = [`/${bundledCss.filename}`];\n }\n }\n\n const globalEntry = manifest['src/client.global.ts'];\n if (globalEntry) {\n if (globalEntry.css && globalEntry.css.length > 0) {\n globalEntry.css.forEach((cssFile: string) => {\n extraHead += `<link rel=\"stylesheet\" crossorigin href=\"/${cssFile}\">`;\n });\n }\n if (globalEntry.file) {\n globalScripts.push(`/${globalEntry.file}`);\n }\n }\n\n if (islandEntries.length > 0) {\n const islandMap: Record<string, string> = {};\n for (const island of islandEntries) {\n const entry = manifest[island.src];\n if (entry?.file) {\n islandMap[island.key] = `/${entry.file}`;\n }\n }\n if (Object.keys(islandMap).length > 0) {\n islandRegistryScript = `<script>window.__L5E_ISLANDS__=${JSON.stringify(islandMap)}</script>`;\n }\n }\n\n if (cssSrcList.length > 0) {\n extraHead += cssSrcList\n .map((file) => `<link rel=\"stylesheet\" crossorigin href=\"${file}\">`)\n .join('');\n }\n }\n\n let cssHtml = '';\n if (!isProduction) {\n cssHtml = cssSrcList.map((src) => `<link rel=\"stylesheet\" href=\"${src}\">`).join('');\n }\n\n let allScripts = [...globalScripts, ...scriptSrcList];\n\n if (!isProduction) {\n const globalTsPath = path.join(root, 'src', 'client.global.ts');\n if (existsSync(globalTsPath)) {\n allScripts = ['/src/client.global.ts', ...allScripts];\n }\n\n if (islandEntries.length > 0) {\n const islandMap: Record<string, string> = {};\n for (const island of islandEntries) {\n islandMap[island.key] = `/${island.src}`;\n }\n islandRegistryScript = `<script>window.__L5E_ISLANDS__=${JSON.stringify(islandMap)}</script>`;\n }\n }\n\n const scriptsHtml =\n islandRegistryScript +\n allScripts.map((src) => `<script type=\"module\" src=\"${src}\"></script>`).join('');\n\n const templateWithLang = rendered.lang ? applyHtmlLang(template, rendered.lang) : template;\n\n const html = rendered.rawHtml\n ? rendered.html || ''\n : templateWithLang\n .replace(`<!--app-head-->`, (rendered.head ?? '') + extraHead + cssHtml)\n .replace(`<!--app-html-->`, rendered.html ?? '')\n .replace(`<!--app-scripts-->`, scriptsHtml);\n\n const headers = new Headers({\n 'Content-Type': 'text/html',\n });\n\n const cacheControlParts: string[] = ['public'];\n if (maxAge !== undefined) cacheControlParts.push(`max-age=${maxAge}`);\n if (sMaxAge !== undefined) cacheControlParts.push(`s-maxage=${sMaxAge}`);\n if (swr !== undefined) cacheControlParts.push(`stale-while-revalidate=${swr}`);\n\n if (cacheControlParts.length > 1 && isProduction) {\n headers.set('Cache-Control', cacheControlParts.join(', '));\n }\n\n if (process.env.NODE_ENV === 'production') {\n cacheTags = optimizeCacheTags(cacheTags);\n }\n headers.set('Cache-Tag', ['global', ...cacheTags].join(','));\n\n return new globalThis.Response(html, {\n status: rendered.statusCode || 200,\n headers,\n });\n}\n\nexport async function createServer(options: ServerOptions = {}): Promise<ServerContext> {\n const root = options.root || process.cwd();\n const base = options.base || '/';\n const isProduction = process.env.NODE_ENV === 'production';\n\n // Cached production assets\n const templateHtml = isProduction\n ? await fs.readFile(path.join(root, './index.html'), 'utf-8')\n : '';\n\n // Create http server\n // @ts-ignore\n const express = (await import('express')).default;\n const app = options.app || express();\n\n // Serve static files from public directory\n if (options.publicDir) {\n const publicPath = path.isAbsolute(options.publicDir)\n ? options.publicDir\n : path.join(root, options.publicDir);\n\n if (existsSync(publicPath)) {\n app.use(express.static(publicPath));\n }\n }\n\n // Add Vite or respective production middlewares\n let vite: ViteDevServer | undefined;\n const distClientDir = path.join(root, './dist/client');\n\n if (!isProduction) {\n const { createServer } = await import('vite');\n const configFile = path.join(root, 'vite.config.js');\n vite = await createServer({\n root,\n configFile,\n server: { middlewareMode: true },\n appType: 'custom',\n base,\n optimizeDeps: {\n exclude: ['@withl5e/l5e', 'file-type'],\n },\n ssr: {\n resolve: {\n conditions: ['development', 'default'],\n },\n },\n resolve: {\n conditions: ['development', 'default'],\n },\n });\n app.use(vite.middlewares);\n } else {\n // @ts-ignore\n const compression = (await import('compression')).default;\n // @ts-ignore\n const sirv = (await import('sirv')).default;\n app.use(compression());\n app.use(base, sirv(distClientDir, { extensions: [] }));\n\n // Route để serve bundled files từ memory map\n // Đặt route này trước route HTML để catch request trước\n app.get(\n `${base === '/' ? '' : base}/bundle-:hash.:ext`,\n async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const { hash, ext } = req.params;\n const filename = `bundle-${hash}.${ext}`;\n const bundledFile = getBundledFile(filename);\n\n if (!bundledFile) {\n return res.status(404).send('Bundled file not found');\n }\n\n res.set({\n 'Content-Type': bundledFile.mimeType,\n 'Cache-Control': 'public, max-age=31536000, immutable',\n });\n res.send(bundledFile.content);\n } catch (e: any) {\n console.error('[server] Error serving bundled file:', e);\n res.status(500).end(e.message);\n }\n },\n );\n }\n\n // Action routes — JSON body parsing scoped to action endpoints only\n app.use('/_l5e/action', express.json({ limit: '100kb' }));\n\n // Validate action key format: actionName_hexHash\n const ACTION_KEY_RE = /^[a-zA-Z]\\w+_[0-9a-f]{1,4}$/;\n\n // Load action registry and viewActions glob from virtual module (dev) or built bundle (prod)\n let prodActionRegistry: Record<string, { modulePath: string; actionName: string }> | null = null;\n let prodViewActions: Record<string, () => Promise<any>> | null = null;\n\n async function getActionRegistry(): Promise<\n Record<string, { modulePath: string; actionName: string }>\n > {\n if (!isProduction) {\n const mod = await vite!.ssrLoadModule('virtual:l5e-actions');\n return mod.actionRegistry || {};\n }\n if (!prodActionRegistry) {\n const registryPath = path.join(root, './dist/server/action-registry.json');\n const json = await fs.readFile(registryPath, 'utf-8');\n prodActionRegistry = JSON.parse(json);\n }\n return prodActionRegistry!;\n }\n\n async function getViewActions(): Promise<Record<string, () => Promise<any>>> {\n if (!isProduction) {\n const mod = await vite!.ssrLoadModule('virtual:l5e-actions');\n return mod.viewActions || {};\n }\n if (!prodViewActions) {\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const mod = await import(pathToFileURL(entryServerPath).href);\n prodViewActions = mod.viewActions || {};\n }\n return prodViewActions!;\n }\n\n // Action route handler — hashed action keys\n // URL: /_l5e/action/:actionKey (e.g., /_l5e/action/loadMoreComments_a1b2)\n app.all('/_l5e/action/:actionKey', async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const { actionKey } = req.params;\n\n // Validate action key format\n if (!ACTION_KEY_RE.test(actionKey)) {\n return res.status(400).send('Invalid action key');\n }\n\n // Look up action in registry\n const registry = await getActionRegistry();\n const entry = registry[actionKey];\n if (!entry) {\n return res.status(404).send('Action not found');\n }\n\n const { modulePath, actionName } = entry;\n\n // Import action module via viewActions glob (works in both dev and prod)\n let actionModule: any;\n if (!isProduction) {\n try {\n actionModule = await vite!.ssrLoadModule(`/src/${modulePath}/actions.tsx`);\n } catch {\n actionModule = await vite!.ssrLoadModule(`/src/${modulePath}/actions.ts`);\n }\n } else {\n const viewActions = await getViewActions();\n // Find matching glob entry by modulePath\n const globKey = viewActions[`/src/${modulePath}/actions.tsx`]\n ? `/src/${modulePath}/actions.tsx`\n : viewActions[`/src/${modulePath}/actions.ts`]\n ? `/src/${modulePath}/actions.ts`\n : null;\n if (!globKey) {\n return res.status(404).send('Action module not found');\n }\n actionModule = await viewActions[globKey]();\n }\n\n // Look up exported action — use hasOwnProperty to avoid prototype pollution\n if (!Object.prototype.hasOwnProperty.call(actionModule, actionName)) {\n return res.status(404).send('Action not found');\n }\n const action = actionModule[actionName];\n if (!action || !action.handler) {\n return res.status(404).send('Action not found');\n }\n\n // Build RequestInfo (same pattern as HTML handler)\n const fullUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\n const urlObject = new URL(fullUrl);\n\n const requestInfo = {\n url: urlObject,\n path: req.originalUrl,\n pathname: urlObject.pathname,\n method: req.method,\n headers: req.headers,\n cookies: parseCookies(req.headers.cookie as string),\n query: req.query || {},\n body: req.body,\n ip: requestIp.getClientIp(req),\n };\n\n // Import render utilities from entry-server (bundled in SSR build)\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const { runInRenderContext } = await (isProduction\n ? import(pathToFileURL(entryServerPath).href)\n : vite!.ssrLoadModule('@withl5e/l5e/jsx-runtime'));\n const { renderJsxToHtmlString } = await (isProduction\n ? import(pathToFileURL(entryServerPath).href)\n : vite!.ssrLoadModule('@withl5e/l5e'));\n\n // Run action handler in render context (needed for JSX)\n const html = await runInRenderContext(\n async () => {\n const jsx = await action.handler(requestInfo);\n return renderJsxToHtmlString(jsx);\n },\n requestInfo,\n modulePath,\n );\n\n res.set('Content-Type', 'text/html').send(html);\n } catch (e: any) {\n vite?.ssrFixStacktrace?.(e);\n console.error('[l5e] Action error:', e.stack || e);\n res.status(500).send('Internal server error');\n }\n });\n\n // Serve HTML\n app.use(async (req: ExpressRequest, res: ExpressResponse) => {\n try {\n const url = req.originalUrl.replace(base, '');\n\n let template: string;\n let render: (url: string, requestInfo?: any) => Promise<any>;\n let loadMiddleware: EntryServerModule['loadMiddleware'];\n let manifest: Record<string, any> | undefined;\n\n if (!isProduction) {\n // Always read fresh template in development\n template = await fs.readFile(path.join(root, './index.html'), 'utf-8');\n template = await vite!.transformIndexHtml(url, template);\n\n // Inject Vite HMR client for hot reload\n if (!template.includes('@vite/client')) {\n template = template.replace(\n '</head>',\n '<script type=\"module\" src=\"/@vite/client\"></script></head>',\n );\n }\n\n const entryServer = (await vite!.ssrLoadModule(\n '@withl5e/l5e/entry-server',\n )) as EntryServerModule;\n render = entryServer.render;\n loadMiddleware = entryServer.loadMiddleware;\n } else {\n template = templateHtml;\n const entryServerPath = path.join(root, './dist/server/entry-server.js');\n const entryServer = (await import(\n pathToFileURL(entryServerPath).href\n )) as EntryServerModule;\n render = entryServer.render;\n loadMiddleware = entryServer.loadMiddleware;\n // Read manifest to map hashed assets\n const manifestJson = await fs.readFile(\n path.join(root, './dist/client/.vite/manifest.json'),\n 'utf-8',\n );\n manifest = JSON.parse(manifestJson);\n }\n\n const loadedMiddleware = await loadMiddleware?.();\n const handler: MiddlewareHandler =\n typeof loadedMiddleware === 'function' ? loadedMiddleware : (_ctx, next) => next();\n\n const locals: Record<string, unknown> = {};\n const initialRequest = createWebRequestFromExpress(req);\n const context = createContext({\n request: initialRequest,\n requestInfo: createRequestInfo(req, initialRequest, base, locals),\n locals,\n clientAddress: requestIp.getClientIp(req),\n });\n\n const renderResponse = async (webRequest: globalThis.Request) => {\n const nextRequestInfo = createRequestInfo(req, webRequest, base, locals);\n const nextUrl = getRenderUrl(nextRequestInfo.url!, base);\n const nextRendered = await render(nextUrl, nextRequestInfo);\n return createPageResponse({\n rendered: nextRendered,\n template,\n manifest,\n root,\n distClientDir,\n isProduction,\n });\n };\n\n const next = async (payload?: RewritePayload) => {\n const nextRequest = createRewriteRequest(payload, context.request, context.url);\n context.request = nextRequest;\n context.url = new URL(nextRequest.url);\n context.cookies = parseCookies(nextRequest.headers.get('cookie') ?? undefined);\n context.requestInfo = createRequestInfo(req, nextRequest, base, locals);\n return renderResponse(nextRequest);\n };\n\n context.rewrite = (payload: RewritePayload) => next(payload);\n\n const response = await handler(context, next);\n await sendWebResponse(req, res, response);\n } catch (e: any) {\n vite?.ssrFixStacktrace?.(e);\n console.log(e.stack);\n res.status(500).end(e.stack);\n }\n });\n\n return { app, vite };\n}\n\nexport async function startServer(options: ServerOptions = {}): Promise<void> {\n const port = options.port || 5173;\n\n // Create Express app first\n // @ts-ignore\n const express = (await import('express')).default;\n const app = express();\n\n // Call callback if provided to allow custom routes before setting up L5E server\n if (options.setupApp) {\n console.log('setupApp');\n await options.setupApp(app);\n }\n\n const { app: serverApp } = await createServer({ ...options, app });\n\n serverApp.listen(port, () => {\n console.log(`Server started at http://localhost:${port}`);\n });\n}\n\nconst MAX_TAGS = 1000;\n\nexport function hashTag(tag: string): string {\n // global tag is not hashed, better for ci/cd\n if (tag === 'global') {\n return 'global';\n }\n\n let hash = 0;\n for (let i = 0; i < tag.length; i++) {\n const char = tag.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36).substring(0, 8);\n}\n\nexport function optimizeCacheTags(tags: Set<string> | string[]): string[] {\n const _tags = Array.isArray(tags) ? tags : [...tags];\n const result = _tags.slice(0, MAX_TAGS).map(hashTag);\n return result;\n}\n"],"names":["rollupModulePromise","loadRollup","require","createRequire","vitePath","rollupPath","path","pathToFileURL","bundledFilesMap","bundleCache","cssCache","generateHash","content","createHash","bundleScripts","scriptPaths","rootDir","distClientDir","uniquePaths","cacheKey","cachedEntryFileName","entryFile","hash","tempDir","fs","entryContent","p","i","filePath","rollupOptions","source","importer","_options","resolved","id","outputOptions","rollup","bundle","output","o","bundledFile","entryChunk","error","bundleCss","cssPaths","cachedFileName","cachedFile","cssContents","cssPath","err","bundledContent","filename","getBundledFile","applyHtmlLang","template","lang","match","attrs","getRequestUrl","req","getRenderUrl","urlObject","base","createWebRequestFromExpress","init","createHeadersFromExpressRequest","createRequestInfo","webRequest","locals","renderUrl","normalizedPath","headers","value","key","parseCookies","requestIp","createRewriteRequest","payload","currentRequest","currentUrl","sendWebResponse","res","response","setCookieValues","getSetCookieHeaders","body","getSetCookie","raw","splitSetCookieHeader","cookies","start","rest","createRawResponse","rendered","contentType","statusCode","responseHeaders","createPageResponse","manifest","root","isProduction","rawResponse","scriptSrcList","cssSrcList","islandEntries","cacheTags","maxAge","sMaxAge","swr","extraHead","globalScripts","islandRegistryScript","collectFromEntry","entryKey","entry","css","cssFiles","importKey","importedChunk","preloadFiles","chunk","src","mappedScripts","file","mappedCssFiles","bundledScript","bundledCss","globalEntry","cssFile","islandMap","island","cssHtml","allScripts","globalTsPath","existsSync","scriptsHtml","templateWithLang","html","cacheControlParts","optimizeCacheTags","createServer","options","templateHtml","express","app","publicPath","vite","compression","sirv","ext","e","configFile","ACTION_KEY_RE","prodActionRegistry","prodViewActions","getActionRegistry","registryPath","json","getViewActions","entryServerPath","actionKey","modulePath","actionName","actionModule","viewActions","globKey","action","fullUrl","requestInfo","runInRenderContext","renderJsxToHtmlString","jsx","url","render","loadMiddleware","entryServer","manifestJson","loadedMiddleware","handler","_ctx","next","initialRequest","context","createContext","renderResponse","nextRequestInfo","nextUrl","nextRendered","nextRequest","startServer","port","serverApp","MAX_TAGS","hashTag","tag","char","tags"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withl5e/l5e",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.1-alpha.0",
4
4
  "description": "HTML-first SSR MPA framework with loaders, middleware, islands, actions, swap, SEO and cache controls.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,8 +1,31 @@
1
1
  /// <reference path="./jsx-types.d.ts" />
2
2
  import { createHash } from 'node:crypto';
3
3
  import fs from 'node:fs/promises';
4
+ import { createRequire } from 'node:module';
4
5
  import path from 'node:path';
5
- import { rollup, type OutputOptions, type RollupOptions } from 'rollup';
6
+ import { pathToFileURL } from 'node:url';
7
+ import type { OutputOptions, RollupOptions } from 'rollup';
8
+
9
+ let rollupModulePromise: Promise<typeof import('rollup')> | null = null;
10
+
11
+ /**
12
+ * Resolve rollup lazily. We can't `import 'rollup'` directly because when the
13
+ * framework gets bundled into the consumer's SSR output the bare specifier is
14
+ * hoisted to a static import that pnpm doesn't satisfy. Resolve through `vite`
15
+ * instead — vite is a peer dep so it's always installed, and it always ships
16
+ * rollup as a direct dependency.
17
+ */
18
+ function loadRollup(): Promise<typeof import('rollup')> {
19
+ if (!rollupModulePromise) {
20
+ rollupModulePromise = (async () => {
21
+ const require = createRequire(import.meta.url);
22
+ const vitePath = require.resolve('vite');
23
+ const rollupPath = require.resolve('rollup', { paths: [path.dirname(vitePath)] });
24
+ return (await import(pathToFileURL(rollupPath).href)) as typeof import('rollup');
25
+ })();
26
+ }
27
+ return rollupModulePromise;
28
+ }
6
29
 
7
30
  interface BundledFile {
8
31
  content: string;
@@ -142,6 +165,7 @@ export async function bundleScripts(
142
165
  chunkFileNames: 'bundle-[hash].js',
143
166
  };
144
167
 
168
+ const { rollup } = await loadRollup();
145
169
  const bundle = await rollup(rollupOptions);
146
170
  const { output } = await bundle.generate(outputOptions);
147
171
  await bundle.close();