@withl5e/l5e 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/entry-server.js +175 -10
  2. package/dist/entry-server.js.map +1 -1
  3. package/dist/{generateMetadata-DLMaI0EO.js → generateMetadata-CIFVlViV.js} +4 -4
  4. package/dist/{generateMetadata-DLMaI0EO.js.map → generateMetadata-CIFVlViV.js.map} +1 -1
  5. package/dist/index-BlfNBupp.js +318 -0
  6. package/dist/index-BlfNBupp.js.map +1 -0
  7. package/dist/index.js +37 -36
  8. package/dist/index.js.map +1 -1
  9. package/dist/island/runtime.js +9 -8
  10. package/dist/island/runtime.js.map +1 -1
  11. package/dist/island.js +36 -23
  12. package/dist/island.js.map +1 -1
  13. package/dist/{jsx-runtime-DVQ9eOji.js → jsx-runtime-Bokflh8Q.js} +68 -55
  14. package/dist/jsx-runtime-Bokflh8Q.js.map +1 -0
  15. package/dist/jsx-runtime.js +12 -10
  16. package/dist/middleware.js +3 -5
  17. package/dist/render-DTXfJu0d.js +202 -0
  18. package/dist/render-DTXfJu0d.js.map +1 -0
  19. package/dist/seo.js +2 -2
  20. package/dist/server.js +250 -244
  21. package/dist/server.js.map +1 -1
  22. package/dist/vite-plugin.js +110 -108
  23. package/dist/vite-plugin.js.map +1 -1
  24. package/package.json +20 -1
  25. package/src/core/entry-server.ts +83 -8
  26. package/src/core/index.ts +0 -2
  27. package/src/core/jsx-runtime.ts +33 -0
  28. package/src/core/render.ts +36 -0
  29. package/src/core/request.ts +11 -10
  30. package/src/core/server.ts +23 -9
  31. package/src/core/vite-plugin.ts +25 -0
  32. package/src/island/ClientIsland.ts +36 -1
  33. package/src/island/runtime.ts +10 -3
  34. package/src/island/types.ts +1 -0
  35. package/src/middleware/index.ts +0 -48
  36. package/dist/entry-server-DJzzhCmz.js +0 -224
  37. package/dist/entry-server-DJzzhCmz.js.map +0 -1
  38. package/dist/index-BIt7MJT9.js +0 -163
  39. package/dist/index-BIt7MJT9.js.map +0 -1
  40. package/dist/jsx-runtime-DVQ9eOji.js.map +0 -1
@@ -72,54 +72,6 @@ export function createContext({
72
72
  return context;
73
73
  }
74
74
 
75
- export function isLocalsSerializable(value: unknown): boolean {
76
- const stack: unknown[] = [value];
77
-
78
- while (stack.length > 0) {
79
- const current = stack.pop();
80
- const type = typeof current;
81
-
82
- if (current === null || type === 'string' || type === 'number' || type === 'boolean') {
83
- continue;
84
- }
85
-
86
- if (Array.isArray(current)) {
87
- stack.push(...current);
88
- continue;
89
- }
90
-
91
- if (type === 'object' && isPlainObject(current)) {
92
- stack.push(...Object.values(current as Record<string, unknown>));
93
- continue;
94
- }
95
-
96
- return false;
97
- }
98
-
99
- return true;
100
- }
101
-
102
- function isPlainObject(value: unknown): value is object {
103
- if (typeof value !== 'object' || value === null) return false;
104
-
105
- const proto = Object.getPrototypeOf(value);
106
- if (proto === null) return true;
107
-
108
- let baseProto = proto;
109
- while (Object.getPrototypeOf(baseProto) !== null) {
110
- baseProto = Object.getPrototypeOf(baseProto);
111
- }
112
-
113
- return proto === baseProto;
114
- }
115
-
116
- export function trySerializeLocals(value: unknown): string {
117
- if (isLocalsSerializable(value)) {
118
- return JSON.stringify(value);
119
- }
120
- throw new Error("The passed value can't be serialized.");
121
- }
122
-
123
75
  function stringifyRewritePayload(payload: RewritePayload, currentUrl: URL): string {
124
76
  if (payload instanceof Request) {
125
77
  return payload.url;
@@ -1,224 +0,0 @@
1
- import { M as K } from "./generateMetadata-DLMaI0EO.js";
2
- import { N as U, I as M, R as W, H as Y, S as z } from "./exceptions-CHPz01DJ.js";
3
- import { R as Q, b as v, o as X, s as V, p as H, l as R, k as h, i as Z, a as q, H as tt, d as O, e as D, h as et, g as at, f as _ } from "./jsx-runtime-DVQ9eOji.js";
4
- import { viewLoaders as j, viewComponents as m } from "virtual:l5e-views";
5
- import rt from "virtual:l5e-route";
6
- import { globalLoader as L } from "virtual:l5e-global-loader";
7
- import "virtual:l5e-middleware";
8
- console.log("render.ts");
9
- const st = /* @__PURE__ */ new Set([
10
- "area",
11
- "base",
12
- "br",
13
- "col",
14
- "embed",
15
- "hr",
16
- "img",
17
- "input",
18
- "link",
19
- "meta",
20
- "param",
21
- "source",
22
- "track",
23
- "wbr"
24
- ]);
25
- function J(t) {
26
- return t ? typeof t == "string" ? t : Array.isArray(t) ? t.map(J).filter(Boolean).join(" ") : typeof t == "object" ? Object.keys(t).filter((s) => t[s]).join(" ") : "" : "";
27
- }
28
- function y(t) {
29
- return t.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll(`
30
- `, "&#10;").trim();
31
- }
32
- function N(t) {
33
- return t.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll(`
34
- `, "<br/>");
35
- }
36
- function ot(t) {
37
- if (!t) return "";
38
- let s = "";
39
- if (t.classList !== void 0 && (s = J(t.classList)), t.class) {
40
- const a = typeof t.class == "string" ? t.class : "";
41
- s = s ? `${s} ${a}`.trim() : a;
42
- }
43
- const r = Object.entries(t).filter(
44
- ([a]) => a !== "children" && a !== "classList" && a !== "setHtml" && a !== "setText" && a !== "class" && a !== "key" && a !== "cacheTag"
45
- ).map(([a, n]) => {
46
- if (n === !1 || n === null || n === void 0) return "";
47
- if (n === !0) return a;
48
- if (typeof n == "function") {
49
- const i = n();
50
- return `${a}="${y(i?.toString() || "")}"`;
51
- }
52
- return `${a}="${y(n?.toString() || "")}"`;
53
- }).filter(Boolean);
54
- return s && r.push(`class="${y(s)}"`), r.join(" ");
55
- }
56
- function w(t) {
57
- if (t === null || typeof t == "boolean" || t === void 0) return "";
58
- if (t && typeof t == "object" && t[Q])
59
- return t.content || "";
60
- if (t && typeof t == "object" && "htmlContent" in t)
61
- return t.htmlContent;
62
- if (typeof t == "string") return N(t.toString());
63
- if (typeof t == "number") return t.toString();
64
- if (Array.isArray(t))
65
- return t.map((o) => w(o)).join("");
66
- const { type: s, props: r, children: a } = t;
67
- if (r?.cacheTag && v(r.cacheTag), typeof s == "function") {
68
- const o = s({ ...r || {}, children: a });
69
- return o && typeof o == "object" && "string" in o ? o.string : w(o);
70
- }
71
- const n = ot(r);
72
- if (st.has(s.toLowerCase()))
73
- return `<${s}${n ? " " + n : ""} />`;
74
- let c = "";
75
- return r?.setHtml !== void 0 ? c = r.setHtml?.toString() || "" : r?.setText !== void 0 ? c = N(r.setText?.toString() || "") : c = a.map((o) => w(o)).join(""), `<${s}${n ? " " + n : ""}>${c}</${s}>`;
76
- }
77
- function f(t) {
78
- return t && typeof t == "object" && "string" in t ? t.string : w(t);
79
- }
80
- function ht(t) {
81
- return t && typeof t == "object" && "string" in t ? t : {
82
- string: w(t)
83
- };
84
- }
85
- async function P(t, s) {
86
- const r = "_error", a = `/src/views/${r}/index.tsx`;
87
- V(r);
88
- const n = m[a] ? await m[a]() : null;
89
- if (n?.default) {
90
- const i = {
91
- statusCode: t.statusCode,
92
- message: t.message,
93
- data: t.data
94
- }, c = n.default, o = f(h(c, i)), b = O(), E = D(), g = _(), S = g.length > 0 ? g.map((l) => f(l)).join(`
95
- `) : void 0;
96
- return {
97
- html: o,
98
- scripts: b.map((l) => l.path),
99
- styles: E.map((l) => l.path),
100
- head: S,
101
- lang: s,
102
- statusCode: t.statusCode
103
- };
104
- } else {
105
- const i = h("div", {}, `${t.statusCode} - ${t.message}`);
106
- return {
107
- html: f(i),
108
- statusCode: t.statusCode
109
- };
110
- }
111
- }
112
- async function mt(t, s = {}) {
113
- return X(async () => {
114
- try {
115
- const r = await rt(s);
116
- if (!r)
117
- throw new U("Page not found", {
118
- path: s.path,
119
- pathname: s.pathname,
120
- url: s.url?.href
121
- });
122
- const a = typeof r == "string" ? r : r.view;
123
- s.params = typeof r == "string" ? {} : r.params ?? {}, V(a);
124
- let n = {}, i;
125
- const c = "/src/global-loader.ts", o = L[c] ? await L[c]() : null;
126
- if (o?.loader)
127
- if (o.shouldIgnore?.(a) || !1)
128
- console.info(`Global loader ignored for view: ${a}`);
129
- else {
130
- const p = await o.loader(s);
131
- n = p.props || {}, i = p.lang, p.cacheTags && v(p.cacheTags);
132
- }
133
- let b = {}, E, g, S, l = !1;
134
- const x = `/src/views/${a}/loader.ts`, d = j[x] ? await j[x]() : null;
135
- if (d?.loader) {
136
- const e = await d.loader(s);
137
- if (e.rawResponse)
138
- return {
139
- rawResponse: e.rawResponse,
140
- statusCode: e.rawResponse.statusCode || 200
141
- };
142
- b = e.props || {}, E = e.maxAge, g = e.sMaxAge, S = e.swr, l = e.rawHtml || !1, e.cacheTags && v(e.cacheTags), e.lang && (i = e.lang);
143
- } else
144
- console.info(`No loader for view: ${a}`);
145
- const u = { ...n, ...b };
146
- if (o?.generateMetadata) {
147
- const e = o.generateMetadata(s, u);
148
- e && H(e);
149
- }
150
- if (d?.generateMetadata) {
151
- const e = d.generateMetadata(s, u);
152
- e && H(e);
153
- }
154
- if (o?.generateSchema) {
155
- const e = o.generateSchema(s, u);
156
- e && R(e);
157
- }
158
- if (d?.generateSchema) {
159
- const e = d.generateSchema(s, u);
160
- e && R(e);
161
- }
162
- const C = `/src/views/${a}/index.tsx`, A = (m[C] ? await m[C]() : null)?.default;
163
- if (!A)
164
- throw console.error(`View component not found: ${a}`), process.env.NODE_ENV !== "production" ? new M(`View component not found: "${a}"`, {
165
- viewName: a,
166
- expectedPath: C,
167
- availableViews: Object.keys(m),
168
- hint: `Make sure the view component exists at ${C} and exports a default component`,
169
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
170
- }) : new M("Internal Server Error");
171
- f(h(K, {})), Z().forEach((e) => {
172
- const p = JSON.stringify(e);
173
- q({
174
- priority: tt.SEO,
175
- children: h("script", {
176
- type: "application/ld+json",
177
- setHtml: p
178
- })
179
- });
180
- });
181
- const B = f(h(A, u)), I = O(), F = D(), T = et(), k = at(), $ = _(), G = $.length > 0 ? $.map((e) => f(e)).join(`
182
- `) : void 0;
183
- return {
184
- html: B,
185
- scripts: I.map((e) => e.path),
186
- styles: F.map((e) => e.path),
187
- islands: T.length > 0 ? T : void 0,
188
- head: G,
189
- lang: i,
190
- maxAge: E,
191
- sMaxAge: g,
192
- swr: S,
193
- cacheTags: k,
194
- rawHtml: l
195
- };
196
- } catch (r) {
197
- if (r instanceof W)
198
- return {
199
- html: "",
200
- redirect: {
201
- url: r.url,
202
- statusCode: r.statusCode
203
- }
204
- };
205
- if (r instanceof Y)
206
- return await P(r);
207
- console.error("Failed to render:", r);
208
- const a = new z(r.message || "Internal Server Error", {
209
- originalError: r.name,
210
- stack: r.stack,
211
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
212
- });
213
- return await P(a);
214
- }
215
- }, s);
216
- }
217
- export {
218
- y as a,
219
- f as b,
220
- ht as c,
221
- N as e,
222
- mt as r
223
- };
224
- //# sourceMappingURL=entry-server-DJzzhCmz.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry-server-DJzzhCmz.js","sources":["../src/core/render.ts","../src/core/entry-server.ts"],"sourcesContent":["import { RAW_HTML_MARKER } from './const';\nimport {\n addCacheTag,\n type HtmlContentObject,\n type JSXChild,\n type JSXNode,\n type RenderedNode,\n} from './jsx-runtime';\n\nif (true) {\n console.log('render.ts');\n}\n\nconst VOID_ELEMENTS = new Set<string>([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\nfunction classList(input: unknown): string {\n if (!input) return '';\n if (typeof input === 'string') return input;\n if (Array.isArray(input)) {\n return input.map(classList).filter(Boolean).join(' ');\n }\n if (typeof input === 'object') {\n return Object.keys(input as Record<string, boolean>)\n .filter((key) => (input as Record<string, boolean>)[key])\n .join(' ');\n }\n return '';\n}\n\nexport function escapeProp(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\\n', '&#10;')\n .trim();\n}\n\nexport function escapeHTML(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\\n', '<br/>');\n}\n\nfunction renderAttributes(props?: Record<string, any>): string {\n if (!props) return '';\n\n let classValue = '';\n if (props.classList !== undefined) {\n classValue = classList(props.classList);\n }\n if (props.class) {\n const existingClass = typeof props.class === 'string' ? props.class : '';\n classValue = classValue ? `${classValue} ${existingClass}`.trim() : existingClass;\n }\n\n const attrs = Object.entries(props)\n .filter(\n ([key]) =>\n key !== 'children' &&\n key !== 'classList' &&\n key !== 'setHtml' &&\n key !== 'setText' &&\n key !== 'class' &&\n key !== 'key' &&\n key !== 'cacheTag',\n )\n .map(([key, value]) => {\n // HTML standard behavior with function execution support\n if (value === false || value === null || value === undefined) return '';\n if (value === true) return key;\n\n // Execute function props and get result (new feature)\n if (typeof value === 'function') {\n const result = value();\n return `${key}=\"${escapeProp(result?.toString() || '')}\"`;\n }\n\n return `${key}=\"${escapeProp(value?.toString() || '')}\"`;\n })\n .filter(Boolean) as string[];\n\n if (classValue) {\n attrs.push(`class=\"${escapeProp(classValue)}\"`);\n }\n\n return attrs.join(' ');\n}\n\nfunction renderJsxToHtmlStringInternal(element: JSXChild): string {\n // HTML standard: skip boolean, null, undefined children\n if (element === null || typeof element === 'boolean' || element === undefined) return '';\n\n if (element && typeof element === 'object' && (element as any)[RAW_HTML_MARKER]) {\n return (element as any).content || '';\n }\n\n // Support htmlContent object (new feature)\n if (element && typeof element === 'object' && 'htmlContent' in element) {\n return (element as HtmlContentObject).htmlContent;\n }\n\n if (typeof element === 'string') return escapeHTML(element.toString());\n if (typeof element === 'number') return element.toString();\n\n if (Array.isArray(element)) {\n return (element as JSXChild[]).map((el) => renderJsxToHtmlStringInternal(el)).join('');\n }\n\n const { type, props, children } = element as JSXNode;\n\n // Collect cache tags from props\n if (props?.cacheTag) {\n addCacheTag(props.cacheTag);\n }\n\n if (typeof type === 'function') {\n const componentResult = (type as any)({ ...(props || {}), children });\n // Check if component returned a RenderedNode\n if (componentResult && typeof componentResult === 'object' && 'string' in componentResult) {\n return (componentResult as RenderedNode).string;\n }\n return renderJsxToHtmlStringInternal(componentResult as JSXChild);\n }\n\n const attrs = renderAttributes(props);\n const isVoidElement = VOID_ELEMENTS.has((type as string).toLowerCase());\n\n if (isVoidElement) {\n return `<${type}${attrs ? ' ' + attrs : ''} />`;\n }\n\n let childrenHtml = '';\n if (props?.setHtml !== undefined) {\n childrenHtml = props.setHtml?.toString() || '';\n } else if (props?.setText !== undefined) {\n childrenHtml = escapeHTML(props.setText?.toString() || '');\n } else {\n childrenHtml = (children as JSXChild[]).map((el) => renderJsxToHtmlStringInternal(el)).join('');\n }\n\n return `<${type}${attrs ? ' ' + attrs : ''}>${childrenHtml}</${type}>`;\n}\n\nexport function renderJsxToHtmlString(element: JSXChild | RenderedNode): string {\n // If already a RenderedNode, return its string\n if (element && typeof element === 'object' && 'string' in element) {\n return (element as RenderedNode).string;\n }\n return renderJsxToHtmlStringInternal(element as JSXChild);\n}\n\nexport function renderToRenderedNode(element: JSXChild | RenderedNode): RenderedNode {\n // If already a RenderedNode, return as is\n if (element && typeof element === 'object' && 'string' in element) {\n return element as RenderedNode;\n }\n return {\n string: renderJsxToHtmlStringInternal(element as JSXChild),\n };\n}\n","/// <reference path=\"./jsx-types.d.ts\" />\nimport { MetadataRenderer } from '../seo/generateMetadata';\nimport type { Metadata } from '../seo/types';\nimport {\n HttpException,\n InternalServerErrorException,\n NotFoundException,\n RedirectException,\n ServiceUnavailableException,\n} from './exceptions';\nimport { HEAD_PRIORITY } from './head-priority';\nimport {\n addCacheTag,\n getCacheTags,\n getClientJsEntries,\n getCssEntries,\n getHeadContent,\n getIslandEntries,\n getSchemas,\n jsxFactory as h,\n Head,\n pushMetadata,\n pushSchema,\n runInRenderContext,\n setViewName,\n} from './jsx-runtime';\nimport { renderJsxToHtmlString } from './render';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { viewComponents, viewLoaders } from 'virtual:l5e-views';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport routeHandler from 'virtual:l5e-route';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { globalLoader } from 'virtual:l5e-global-loader';\n// @ts-ignore - Virtual modules provided by Vite plugin\nexport { loadMiddleware } from 'virtual:l5e-middleware';\n\nexport interface RawResponse {\n body: string | Buffer;\n contentType: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderResult {\n html?: string;\n scripts?: string[];\n styles?: string[];\n islands?: Array<{ key: string; src: string; name: string }>;\n head?: string;\n lang?: string;\n statusCode?: number;\n maxAge?: number;\n sMaxAge?: number;\n swr?: number;\n cacheTags?: string[];\n redirect?: { url: string; statusCode: number };\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport interface RequestInfo {\n url?: URL;\n path?: string;\n pathname?: string;\n method?: string;\n headers?: Record<string, any>;\n cookies?: Record<string, string>;\n query?: Record<string, any>;\n ip?: string;\n locals?: Record<string, unknown>;\n params?: Record<string, any>;\n}\n\nexport type RouteResult =\n | string\n | null\n | { view: string; params?: Record<string, any> };\n\n// SchemaMarkup type - có thể là single schema hoặc array of schemas\n// Sử dụng any để tương thích với schema-dts types từ frontend\nexport type SchemaMarkup = any | Array<any>;\n\nexport interface LoaderResult {\n props?: Record<string, any>;\n lang?: string;\n maxAge?: number;\n sMaxAge?: number;\n swr?: number;\n cacheTags?: string[] | Record<string, boolean>;\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport type LoaderFunction = (requestInfo: RequestInfo) => Promise<LoaderResult>;\n\nexport type GenerateMetadataFunction = (requestInfo: RequestInfo, props: any) => Metadata | null;\n\nexport type GenerateSchemaFunction = (requestInfo: RequestInfo, props: any) => SchemaMarkup | null;\n\nexport interface GlobalLoaderModule {\n loader: LoaderFunction;\n generateMetadata?: GenerateMetadataFunction;\n generateSchema?: GenerateSchemaFunction;\n shouldIgnore?: (viewName: string) => boolean;\n}\n\n/**\n * Helper function to render error view\n */\nasync function renderErrorView(err: HttpException, lang?: string): Promise<RenderResult> {\n const errorViewName = `_error`;\n const errorComponentPath = `/src/views/${errorViewName}/index.tsx`;\n\n // Set error view name in context\n setViewName(errorViewName);\n\n // Try to load error view\n const errorComponentModule = viewComponents[errorComponentPath]\n ? await viewComponents[errorComponentPath]()\n : null;\n\n if (errorComponentModule?.default) {\n // Render error view with exception data\n const errorProps = {\n statusCode: err.statusCode,\n message: err.message,\n data: err.data,\n };\n\n const Component = errorComponentModule.default;\n const htmlBody = renderJsxToHtmlString(h(Component, errorProps));\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const headContent = getHeadContent();\n\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n head: headHtml,\n lang,\n statusCode: err.statusCode,\n };\n } else {\n // No error view found, render default error message\n const html = h('div', {}, `${err.statusCode} - ${err.message}`);\n return {\n html: renderJsxToHtmlString(html),\n statusCode: err.statusCode,\n };\n }\n}\n\nexport async function render(url: string, requestInfo: RequestInfo = {}): Promise<RenderResult> {\n return runInRenderContext(async () => {\n try {\n // Step 1: Call route handler to get view name\n const rawRouteResult: RouteResult = await routeHandler(requestInfo);\n\n if (!rawRouteResult) {\n // Throw NotFoundException to render error_404 view\n throw new NotFoundException('Page not found', {\n path: requestInfo.path,\n pathname: requestInfo.pathname,\n url: requestInfo.url?.href,\n });\n }\n\n const viewName =\n typeof rawRouteResult === 'string' ? rawRouteResult : rawRouteResult.view;\n requestInfo.params =\n typeof rawRouteResult === 'string' ? {} : (rawRouteResult.params ?? {});\n\n // Set view name in render context\n setViewName(viewName);\n\n // Step 2: Load global loader (optional)\n let globalProps: Record<string, any> = {};\n let lang: string | undefined;\n\n // Try to load global loader\n const globalLoaderPathTs = '/src/global-loader.ts';\n\n const globalLoaderModule: GlobalLoaderModule | null = globalLoader[globalLoaderPathTs]\n ? await globalLoader[globalLoaderPathTs]()\n : null;\n\n // Run global loader if exists and not ignored\n if (globalLoaderModule?.loader) {\n const shouldIgnore = globalLoaderModule.shouldIgnore?.(viewName) || false;\n\n if (!shouldIgnore) {\n const globalLoaderResult = await globalLoaderModule.loader(requestInfo);\n\n globalProps = globalLoaderResult.props || {};\n lang = globalLoaderResult.lang; // Extract lang from global loader\n\n if (globalLoaderResult.cacheTags) {\n addCacheTag(globalLoaderResult.cacheTags);\n }\n\n // generateMetadata và generateSchema sẽ được gọi sau khi có props\n } else {\n console.info(`Global loader ignored for view: ${viewName}`);\n }\n }\n\n // Step 3: Dynamic import view loader (optional)\n let viewProps: Record<string, any> = {};\n let maxAge: number | undefined;\n let sMaxAge: number | undefined;\n let swr: number | undefined;\n let rawHtml: boolean = false;\n const loaderPathTs = `/src/views/${viewName}/loader.ts`;\n\n // Try TypeScript loader formats only\n const loaderModule = viewLoaders[loaderPathTs] ? await viewLoaders[loaderPathTs]() : null;\n\n if (loaderModule?.loader) {\n const loaderResult = await loaderModule.loader(requestInfo);\n\n // Check if loader returns raw response\n if (loaderResult.rawResponse) {\n return {\n rawResponse: loaderResult.rawResponse,\n statusCode: loaderResult.rawResponse.statusCode || 200,\n };\n }\n\n viewProps = loaderResult.props || {};\n maxAge = loaderResult.maxAge;\n sMaxAge = loaderResult.sMaxAge;\n swr = loaderResult.swr;\n rawHtml = loaderResult.rawHtml || false;\n\n if (loaderResult.cacheTags) {\n addCacheTag(loaderResult.cacheTags);\n }\n\n // View loader lang overrides global loader lang\n if (loaderResult.lang) {\n lang = loaderResult.lang;\n }\n } else {\n console.info(`No loader for view: ${viewName}`);\n }\n\n // Merge props: global props first, then view props (view can override)\n const props = { ...globalProps, ...viewProps };\n\n // Step 3.5: Generate metadata và schema từ generateMetadata và generateSchema functions\n // Global generateMetadata (parent metadata)\n if (globalLoaderModule?.generateMetadata) {\n const globalMetadata = globalLoaderModule.generateMetadata(requestInfo, props);\n if (globalMetadata) {\n pushMetadata(globalMetadata);\n }\n }\n\n // View generateMetadata (child metadata, sẽ merge với parent)\n if (loaderModule?.generateMetadata) {\n const viewMetadata = loaderModule.generateMetadata(requestInfo, props);\n if (viewMetadata) {\n pushMetadata(viewMetadata);\n }\n }\n\n // Global generateSchema (base schemas)\n if (globalLoaderModule?.generateSchema) {\n const globalSchema = globalLoaderModule.generateSchema(requestInfo, props);\n if (globalSchema) {\n pushSchema(globalSchema);\n }\n }\n\n // View generateSchema (view-specific schemas)\n if (loaderModule?.generateSchema) {\n const viewSchema = loaderModule.generateSchema(requestInfo, props);\n if (viewSchema) {\n pushSchema(viewSchema);\n }\n }\n\n // Step 4: Dynamic import component (required)\n const componentPathTsx = `/src/views/${viewName}/index.tsx`;\n\n const componentModule = viewComponents[componentPathTsx]\n ? await viewComponents[componentPathTsx]()\n : null;\n\n const Component = componentModule?.default;\n\n if (!Component) {\n console.error(`View component not found: ${viewName}`);\n\n // Check if in development or production mode\n const isDevelopment = process.env.NODE_ENV !== 'production';\n\n if (isDevelopment) {\n // Development: provide detailed error information\n throw new InternalServerErrorException(`View component not found: \"${viewName}\"`, {\n viewName,\n expectedPath: componentPathTsx,\n availableViews: Object.keys(viewComponents),\n hint: `Make sure the view component exists at ${componentPathTsx} and exports a default component`,\n timestamp: new Date().toISOString(),\n });\n } else {\n // Production: simple error message\n throw new InternalServerErrorException('Internal Server Error');\n }\n }\n\n // Auto-render MetadataRenderer trước khi render component\n // MetadataRenderer sẽ push metadata vào headRegistry thông qua Head component\n renderJsxToHtmlString(h(MetadataRenderer, {}));\n\n // Auto-render schemas vào headRegistry\n const schemas = getSchemas();\n schemas.forEach((schema) => {\n const schemaJson = JSON.stringify(schema);\n // Push schema vào headRegistry thông qua Head component\n // Head component chỉ push vào registry, không cần renderJsxToHtmlString\n Head({\n priority: HEAD_PRIORITY.SEO,\n children: h('script', {\n type: 'application/ld+json',\n setHtml: schemaJson,\n }),\n });\n });\n\n // Render component (có thể có Head components khác)\n const htmlBody = renderJsxToHtmlString(h(Component, props));\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const islandEntries = getIslandEntries();\n const cacheTags = getCacheTags();\n const headContent = getHeadContent();\n\n // Render head content to HTML string\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n islands: islandEntries.length > 0 ? islandEntries : undefined,\n head: headHtml,\n lang,\n maxAge,\n sMaxAge,\n swr,\n cacheTags,\n rawHtml,\n };\n } catch (err: any) {\n // Handle RedirectException\n if (err instanceof RedirectException) {\n return {\n html: '',\n redirect: {\n url: err.url,\n statusCode: err.statusCode,\n },\n };\n }\n\n // Handle HttpException\n if (err instanceof HttpException) {\n return await renderErrorView(err);\n }\n\n // For other errors, convert to ServiceUnavailableException\n console.error(`Failed to render:`, err);\n const serviceError = new ServiceUnavailableException(err.message || 'Internal Server Error', {\n originalError: err.name,\n stack: err.stack,\n timestamp: new Date().toISOString(),\n });\n return await renderErrorView(serviceError);\n }\n }, requestInfo);\n}\n"],"names":["VOID_ELEMENTS","classList","input","key","escapeProp","value","escapeHTML","renderAttributes","props","classValue","existingClass","attrs","result","renderJsxToHtmlStringInternal","element","RAW_HTML_MARKER","el","type","children","addCacheTag","componentResult","childrenHtml","renderJsxToHtmlString","renderToRenderedNode","renderErrorView","err","lang","errorViewName","errorComponentPath","setViewName","errorComponentModule","viewComponents","errorProps","Component","htmlBody","h","clientEntries","getClientJsEntries","cssEntries","getCssEntries","headContent","getHeadContent","headHtml","content","entry","html","render","url","requestInfo","runInRenderContext","rawRouteResult","routeHandler","NotFoundException","viewName","globalProps","globalLoaderPathTs","globalLoaderModule","globalLoader","globalLoaderResult","viewProps","maxAge","sMaxAge","swr","rawHtml","loaderPathTs","loaderModule","viewLoaders","loaderResult","globalMetadata","pushMetadata","viewMetadata","globalSchema","pushSchema","viewSchema","componentPathTsx","InternalServerErrorException","MetadataRenderer","getSchemas","schema","schemaJson","Head","HEAD_PRIORITY","islandEntries","getIslandEntries","cacheTags","getCacheTags","RedirectException","HttpException","serviceError","ServiceUnavailableException"],"mappings":"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"}
@@ -1,163 +0,0 @@
1
- function f(e) {
2
- return e ? e.split(";").reduce(
3
- (t, r) => {
4
- const [n, ...s] = r.split("=");
5
- return n && s.length > 0 && (t[n.trim()] = decodeURIComponent(s.join("=").trim())), t;
6
- },
7
- {}
8
- ) : {};
9
- }
10
- function b(e) {
11
- const t = new Headers();
12
- return Object.entries(e.headers).forEach(([r, n]) => {
13
- if (n !== void 0) {
14
- if (Array.isArray(n)) {
15
- n.forEach((s) => t.append(r, s));
16
- return;
17
- }
18
- t.set(r, n);
19
- }
20
- }), t;
21
- }
22
- function g(e) {
23
- return e;
24
- }
25
- function R(...e) {
26
- const t = e.filter(Boolean), r = t.length;
27
- return r ? (n, s) => {
28
- let i;
29
- return o(0, n);
30
- function o(a, u) {
31
- const h = t[a];
32
- return h(u, async (c) => a < r - 1 ? (c && (i = c, l(u, c)), o(a + 1, u)) : s(c ?? i));
33
- }
34
- } : (n, s) => s();
35
- }
36
- function l(e, t) {
37
- let r;
38
- t instanceof Request ? r = t : t instanceof URL ? r = new Request(t.href, e.request.clone()) : r = new Request(new URL(t, e.url).href, e.request.clone());
39
- const n = e.url, s = new URL(r.url), i = f(r.headers.get("cookie") ?? void 0);
40
- if (e.request = r, e.url = s, e.cookies = i, e.requestInfo) {
41
- const o = {};
42
- r.headers.forEach((a, u) => {
43
- o[u] = a;
44
- }), e.requestInfo = {
45
- ...e.requestInfo,
46
- url: s,
47
- path: p(s, n, e.requestInfo.path),
48
- pathname: s.pathname,
49
- method: r.method,
50
- headers: o,
51
- cookies: i,
52
- query: Object.fromEntries(s.searchParams.entries())
53
- };
54
- }
55
- }
56
- function p(e, t, r) {
57
- const n = `${e.pathname}${e.search}` || "/";
58
- if (!r)
59
- return n;
60
- const s = r.split("?")[0] || "/";
61
- if (s === t.pathname || !t.pathname.endsWith(s))
62
- return n;
63
- const i = t.pathname.slice(
64
- 0,
65
- t.pathname.length - s.length
66
- );
67
- if (!i || !e.pathname.startsWith(i))
68
- return n;
69
- const o = e.pathname.slice(i.length) || "/";
70
- return `${o.startsWith("/") ? o : `/${o}`}${e.search}`;
71
- }
72
- function P({
73
- request: e,
74
- requestInfo: t,
75
- locals: r = {},
76
- clientAddress: n
77
- }) {
78
- const s = {
79
- cookies: f(e.headers.get("cookie") ?? void 0),
80
- request: e,
81
- requestInfo: t,
82
- url: new URL(e.url),
83
- redirect(i, o = 302) {
84
- return new Response(null, {
85
- status: o,
86
- headers: {
87
- Location: i.toString()
88
- }
89
- });
90
- },
91
- rewrite(i) {
92
- return Promise.resolve(new Response(null));
93
- },
94
- get clientAddress() {
95
- if (n)
96
- return n;
97
- throw new Error("clientAddress is not available for this request.");
98
- }
99
- };
100
- return Object.defineProperty(s, "locals", {
101
- enumerable: !0,
102
- get() {
103
- if (typeof r != "object" || r === null || Array.isArray(r))
104
- throw new Error("Middleware locals must be a plain object.");
105
- return r;
106
- },
107
- set() {
108
- throw new Error("Middleware locals cannot be reassigned. Mutate its properties instead.");
109
- }
110
- }), s.rewrite = (i) => Promise.resolve(
111
- new Response(null, {
112
- status: 307,
113
- headers: {
114
- "X-L5E-Rewrite": w(i, s.url)
115
- }
116
- })
117
- ), s;
118
- }
119
- function d(e) {
120
- const t = [e];
121
- for (; t.length > 0; ) {
122
- const r = t.pop(), n = typeof r;
123
- if (!(r === null || n === "string" || n === "number" || n === "boolean")) {
124
- if (Array.isArray(r)) {
125
- t.push(...r);
126
- continue;
127
- }
128
- if (n === "object" && m(r)) {
129
- t.push(...Object.values(r));
130
- continue;
131
- }
132
- return !1;
133
- }
134
- }
135
- return !0;
136
- }
137
- function m(e) {
138
- if (typeof e != "object" || e === null) return !1;
139
- const t = Object.getPrototypeOf(e);
140
- if (t === null) return !0;
141
- let r = t;
142
- for (; Object.getPrototypeOf(r) !== null; )
143
- r = Object.getPrototypeOf(r);
144
- return t === r;
145
- }
146
- function q(e) {
147
- if (d(e))
148
- return JSON.stringify(e);
149
- throw new Error("The passed value can't be serialized.");
150
- }
151
- function w(e, t) {
152
- return e instanceof Request ? e.url : e instanceof URL ? e.href : new URL(e, t).href;
153
- }
154
- export {
155
- b as a,
156
- P as c,
157
- g as d,
158
- d as i,
159
- f as p,
160
- R as s,
161
- q as t
162
- };
163
- //# sourceMappingURL=index-BIt7MJT9.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-BIt7MJT9.js","sources":["../src/core/request.ts","../src/middleware/defineMiddleware.ts","../src/middleware/sequence.ts","../src/middleware/index.ts"],"sourcesContent":["import type { Request } from 'express';\n\nexport function parseCookies(cookieHeader?: string): Record<string, string> {\n if (!cookieHeader) return {};\n\n return cookieHeader.split(';').reduce(\n (cookies, cookie) => {\n const [name, ...rest] = cookie.split('=');\n if (name && rest.length > 0) {\n cookies[name.trim()] = decodeURIComponent(rest.join('=').trim());\n }\n return cookies;\n },\n {} as Record<string, string>,\n );\n}\n\nexport function createHeadersFromExpressRequest(req: Request): Headers {\n const headers = new Headers();\n\n Object.entries(req.headers).forEach(([key, value]) => {\n if (value === undefined) return;\n if (Array.isArray(value)) {\n value.forEach((item) => headers.append(key, item));\n return;\n }\n headers.set(key, value);\n });\n\n return headers;\n}\n","import type { MiddlewareHandler } from './types';\n\nexport function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler {\n return fn;\n}\n","import { parseCookies } from '../core/request';\nimport { defineMiddleware } from './defineMiddleware';\nimport type { MiddlewareContext, MiddlewareHandler, RewritePayload } from './types';\n\n// From SvelteKit via Astro: compose middleware handlers in declaration order.\nexport function sequence(...handlers: Array<MiddlewareHandler | false | null | undefined>) {\n const filtered = handlers.filter(Boolean) as MiddlewareHandler[];\n const length = filtered.length;\n\n if (!length) {\n return defineMiddleware((_context, next) => {\n return next();\n });\n }\n\n return defineMiddleware((context, next) => {\n let carriedPayload: RewritePayload | undefined;\n return applyHandle(0, context);\n\n function applyHandle(\n i: number,\n handleContext: MiddlewareContext,\n ): Promise<Response> | Response {\n const handle = filtered[i];\n\n return handle(handleContext, async (payload?: RewritePayload) => {\n if (i < length - 1) {\n if (payload) {\n carriedPayload = payload;\n updateContextForRewrite(handleContext, payload);\n }\n return applyHandle(i + 1, handleContext);\n }\n\n return next(payload ?? carriedPayload);\n });\n }\n });\n}\n\nfunction updateContextForRewrite(context: MiddlewareContext, payload: RewritePayload): void {\n let request: Request;\n\n if (payload instanceof Request) {\n request = payload;\n } else if (payload instanceof URL) {\n request = new Request(payload.href, context.request.clone());\n } else {\n request = new Request(new URL(payload, context.url).href, context.request.clone());\n }\n\n const previousUrl = context.url;\n const nextUrl = new URL(request.url);\n const nextCookies = parseCookies(request.headers.get('cookie') ?? undefined);\n context.request = request;\n context.url = nextUrl;\n context.cookies = nextCookies;\n\n if (context.requestInfo) {\n const headers: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n context.requestInfo = {\n ...context.requestInfo,\n url: nextUrl,\n path: getRequestInfoPath(nextUrl, previousUrl, context.requestInfo.path),\n pathname: nextUrl.pathname,\n method: request.method,\n headers,\n cookies: nextCookies,\n query: Object.fromEntries(nextUrl.searchParams.entries()),\n };\n }\n}\n\nfunction getRequestInfoPath(nextUrl: URL, previousUrl: URL, previousPath?: string): string {\n const nextPath = `${nextUrl.pathname}${nextUrl.search}` || '/';\n if (!previousPath) {\n return nextPath;\n }\n\n const previousPathname = previousPath.split('?')[0] || '/';\n if (\n previousPathname === previousUrl.pathname ||\n !previousUrl.pathname.endsWith(previousPathname)\n ) {\n return nextPath;\n }\n\n const basePathname = previousUrl.pathname.slice(\n 0,\n previousUrl.pathname.length - previousPathname.length,\n );\n if (!basePathname || !nextUrl.pathname.startsWith(basePathname)) {\n return nextPath;\n }\n\n const strippedPathname = nextUrl.pathname.slice(basePathname.length) || '/';\n const normalizedPathname = strippedPathname.startsWith('/')\n ? strippedPathname\n : `/${strippedPathname}`;\n return `${normalizedPathname}${nextUrl.search}`;\n}\n","import { parseCookies } from '../core/request';\nimport { defineMiddleware } from './defineMiddleware';\nimport { sequence } from './sequence';\nimport type { CreateContext, MiddlewareContext, RewritePayload } from './types';\n\nexport type {\n CreateContext,\n MiddlewareContext,\n MiddlewareHandler,\n MiddlewareNext,\n RewritePayload,\n} from './types';\n\nexport { defineMiddleware, sequence };\n\nexport function createContext({\n request,\n requestInfo,\n locals = {},\n clientAddress,\n}: CreateContext): MiddlewareContext {\n const context = {\n cookies: parseCookies(request.headers.get('cookie') ?? undefined),\n request,\n requestInfo,\n url: new URL(request.url),\n redirect(path: string | URL, status = 302) {\n return new Response(null, {\n status,\n headers: {\n Location: path.toString(),\n },\n });\n },\n rewrite(payload: RewritePayload) {\n return Promise.resolve(new Response(null));\n },\n get clientAddress() {\n if (clientAddress) {\n return clientAddress;\n }\n throw new Error('clientAddress is not available for this request.');\n },\n } as Omit<MiddlewareContext, 'locals'> & {\n locals: Record<string, unknown>;\n };\n\n Object.defineProperty(context, 'locals', {\n enumerable: true,\n get() {\n if (typeof locals !== 'object' || locals === null || Array.isArray(locals)) {\n throw new Error('Middleware locals must be a plain object.');\n }\n return locals;\n },\n set() {\n throw new Error('Middleware locals cannot be reassigned. Mutate its properties instead.');\n },\n });\n\n context.rewrite = (payload: RewritePayload) => {\n return Promise.resolve(\n new Response(null, {\n status: 307,\n headers: {\n 'X-L5E-Rewrite': stringifyRewritePayload(payload, context.url),\n },\n }),\n );\n };\n\n return context;\n}\n\nexport function isLocalsSerializable(value: unknown): boolean {\n const stack: unknown[] = [value];\n\n while (stack.length > 0) {\n const current = stack.pop();\n const type = typeof current;\n\n if (current === null || type === 'string' || type === 'number' || type === 'boolean') {\n continue;\n }\n\n if (Array.isArray(current)) {\n stack.push(...current);\n continue;\n }\n\n if (type === 'object' && isPlainObject(current)) {\n stack.push(...Object.values(current as Record<string, unknown>));\n continue;\n }\n\n return false;\n }\n\n return true;\n}\n\nfunction isPlainObject(value: unknown): value is object {\n if (typeof value !== 'object' || value === null) return false;\n\n const proto = Object.getPrototypeOf(value);\n if (proto === null) return true;\n\n let baseProto = proto;\n while (Object.getPrototypeOf(baseProto) !== null) {\n baseProto = Object.getPrototypeOf(baseProto);\n }\n\n return proto === baseProto;\n}\n\nexport function trySerializeLocals(value: unknown): string {\n if (isLocalsSerializable(value)) {\n return JSON.stringify(value);\n }\n throw new Error(\"The passed value can't be serialized.\");\n}\n\nfunction stringifyRewritePayload(payload: RewritePayload, currentUrl: URL): string {\n if (payload instanceof Request) {\n return payload.url;\n }\n\n if (payload instanceof URL) {\n return payload.href;\n }\n\n return new URL(payload, currentUrl).href;\n}\n"],"names":["parseCookies","cookieHeader","cookies","cookie","name","rest","createHeadersFromExpressRequest","req","headers","key","value","item","defineMiddleware","fn","sequence","handlers","filtered","length","context","next","carriedPayload","applyHandle","i","handleContext","handle","payload","updateContextForRewrite","_context","request","previousUrl","nextUrl","nextCookies","getRequestInfoPath","previousPath","nextPath","previousPathname","basePathname","strippedPathname","createContext","requestInfo","locals","clientAddress","path","status","stringifyRewritePayload","isLocalsSerializable","stack","current","type","isPlainObject","proto","baseProto","trySerializeLocals","currentUrl"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsx-runtime-DVQ9eOji.js","sources":["../src/core/head-priority.ts","../src/seo/mergeMetadata.ts","../src/core/const.ts","../src/core/jsx-runtime.ts"],"sourcesContent":["/**\n * Priority constants for Head component rendering order\n * Lower numbers render first (higher priority)\n */\nexport const HEAD_PRIORITY = {\n CRITICAL: 0, // charset, viewport - must be first\n HIGH: 10, // title, description, canonical\n MEDIUM: 50, // meta tags, robots\n SEO: 80, // OpenGraph, Twitter\n LOW: 100, // Custom head elements\n SCRIPTS: 200, // Scripts\n STYLES: 300, // Styles\n} as const;\n\nexport type HeadPriority = (typeof HEAD_PRIORITY)[keyof typeof HEAD_PRIORITY] | number;\n","import type { Metadata } from './types';\n\n/**\n * Merges parent and child metadata objects\n * Follows Next.js shallow merge pattern with deep merge for nested objects\n *\n * @param parent - Parent metadata (from layout/global loader)\n * @param child - Child metadata (from page/view loader)\n * @returns Merged metadata object\n */\nexport function mergeMetadata(\n parent: Metadata | null | undefined,\n child: Metadata | null | undefined,\n): Metadata {\n // If no parent, return child (or empty object)\n if (!parent) {\n return child || {};\n }\n\n // If no child, return parent\n if (!child) {\n return parent;\n }\n\n // Shallow merge base properties (child overrides parent)\n const merged: Metadata = {\n ...parent,\n ...child,\n };\n\n // Deep merge for nested objects\n // OpenGraph: merge nested properties\n if (child.openGraph || parent.openGraph) {\n if (child.openGraph && parent.openGraph) {\n merged.openGraph = {\n ...parent.openGraph,\n ...child.openGraph,\n // Deep merge for nested arrays/objects in openGraph\n images: child.openGraph.images ?? parent.openGraph.images,\n videos: child.openGraph.videos ?? parent.openGraph.videos,\n audio: child.openGraph.audio ?? parent.openGraph.audio,\n alternateLocale: child.openGraph.alternateLocale ?? parent.openGraph.alternateLocale,\n authors: child.openGraph.authors ?? parent.openGraph.authors,\n tags: child.openGraph.tags ?? parent.openGraph.tags,\n };\n } else {\n merged.openGraph = child.openGraph || parent.openGraph;\n }\n }\n\n // Twitter: merge nested properties\n if (child.twitter || parent.twitter) {\n if (child.twitter && parent.twitter) {\n merged.twitter = {\n ...parent.twitter,\n ...child.twitter,\n // Deep merge for nested objects\n images: child.twitter.images ?? parent.twitter.images,\n app: child.twitter.app\n ? {\n ...parent.twitter.app,\n ...child.twitter.app,\n id: {\n ...parent.twitter.app?.id,\n ...child.twitter.app.id,\n },\n url: {\n ...parent.twitter.app?.url,\n ...child.twitter.app.url,\n },\n }\n : parent.twitter.app,\n };\n } else {\n merged.twitter = child.twitter || parent.twitter;\n }\n }\n\n // Icons: merge nested properties\n if (child.icons || parent.icons) {\n if (child.icons && parent.icons) {\n merged.icons = {\n icon: child.icons.icon ?? parent.icons.icon,\n shortcut: child.icons.shortcut ?? parent.icons.shortcut,\n apple: child.icons.apple ?? parent.icons.apple,\n other: child.icons.other ?? parent.icons.other,\n };\n } else {\n merged.icons = child.icons || parent.icons;\n }\n }\n\n // Verification: merge nested properties\n if (child.verification || parent.verification) {\n if (child.verification && parent.verification) {\n merged.verification = {\n ...parent.verification,\n ...child.verification,\n // Deep merge for other verification tags\n other: child.verification.other\n ? {\n ...parent.verification.other,\n ...child.verification.other,\n }\n : parent.verification.other,\n me: child.verification.me ?? parent.verification.me,\n };\n } else {\n merged.verification = child.verification || parent.verification;\n }\n }\n\n // AppLinks: merge nested properties\n if (child.appLinks || parent.appLinks) {\n if (child.appLinks && parent.appLinks) {\n merged.appLinks = {\n ios: child.appLinks.ios\n ? {\n ...parent.appLinks.ios,\n ...child.appLinks.ios,\n }\n : parent.appLinks.ios,\n android: child.appLinks.android\n ? {\n ...parent.appLinks.android,\n ...child.appLinks.android,\n }\n : parent.appLinks.android,\n web: child.appLinks.web\n ? {\n ...parent.appLinks.web,\n ...child.appLinks.web,\n }\n : parent.appLinks.web,\n };\n } else {\n merged.appLinks = child.appLinks || parent.appLinks;\n }\n }\n\n // FormatDetection: merge nested properties\n if (child.formatDetection || parent.formatDetection) {\n if (child.formatDetection && parent.formatDetection) {\n merged.formatDetection = {\n ...parent.formatDetection,\n ...child.formatDetection,\n };\n } else {\n merged.formatDetection = child.formatDetection || parent.formatDetection;\n }\n }\n\n // Viewport: merge if both are objects\n if (child.viewport && parent.viewport) {\n if (typeof child.viewport === 'object' && typeof parent.viewport === 'object') {\n merged.viewport = {\n ...parent.viewport,\n ...child.viewport,\n } as Metadata['viewport'];\n } else {\n // If either is string, child overrides\n merged.viewport = child.viewport;\n }\n }\n\n // Robots: merge if both are objects\n if (child.robots && parent.robots) {\n if (typeof child.robots === 'object' && typeof parent.robots === 'object') {\n merged.robots = {\n ...parent.robots,\n ...child.robots,\n } as Metadata['robots'];\n } else {\n // If either is string, child overrides\n merged.robots = child.robots;\n }\n }\n\n // Array fields: child overrides parent (shallow merge behavior)\n // These are already handled by spread operator above\n // But we explicitly handle them for clarity:\n merged.keywords = child.keywords ?? parent.keywords;\n merged.themeColor = child.themeColor ?? parent.themeColor;\n merged.archives = child.archives ?? parent.archives;\n merged.assets = child.assets ?? parent.assets;\n\n // Other: merge objects\n if (child.other || parent.other) {\n if (child.other && parent.other) {\n merged.other = {\n ...parent.other,\n ...child.other,\n };\n } else {\n merged.other = child.other || parent.other;\n }\n }\n\n return merged;\n}\n","// Marker object để đánh dấu raw HTML không escape\nexport const RAW_HTML_MARKER = Symbol('rawHtml');\n","import { mergeMetadata } from '../seo/mergeMetadata';\nimport type { Metadata } from '../seo/types';\nimport { RAW_HTML_MARKER } from './const';\nimport { RequestInfo } from './entry-server';\nimport { HEAD_PRIORITY, type HeadPriority } from './head-priority';\n\nexport type JSXChild =\n | string\n | number\n | boolean\n | null\n | undefined\n | JSXNode\n | JSXChild[]\n | RawHtmlObject\n | HtmlContentObject;\n\nexport type RawHtmlObject = {\n [RAW_HTML_MARKER]: true;\n content: string;\n};\n\nexport type HtmlContentObject = {\n htmlContent: string;\n};\n\nexport type RenderedNode = {\n string: string;\n};\n\nexport type JSXNode = {\n type: string | ((props: any) => JSXChild);\n props: Record<string, any>;\n children: JSXChild[];\n};\n\nexport function jsxFactory(type: any, props: any, ...children: any): JSXNode {\n return { type, props: props || {}, children: children.flat() };\n}\n\nexport function Fragment({\n children,\n ...props\n}: { children?: JSXChild; setHtml?: unknown } & Record<string, any>): JSXChild {\n // Hỗ trợ setHtml cho Fragment\n if (props.setHtml !== undefined) {\n // Trả về object đặc biệt để không bị escape\n return { [RAW_HTML_MARKER]: true, content: props.setHtml?.toString() || '' };\n }\n return children;\n}\n\n// AsyncLocalStorage for render context (request-level)\nimport { AsyncLocalStorage } from 'async_hooks';\n\ninterface HeadEntry {\n content: JSXChild;\n priority: number; // Số càng nhỏ, render càng sớm\n source?: string; // Để debug (ví dụ: 'layout', 'page', 'seo')\n}\n\ninterface IslandEntry {\n key: string; // \"Counter_a3f2\" — registry key\n src: string; // \"src/views/.../Counter.tsx\" — manifest-compatible path\n name: string; // \"Counter\" — export name\n}\n\ninterface RenderContext {\n clientJsRegistry: Array<{ path: string; from: string }>;\n cssRegistry: Array<{ path: string; from: string }>;\n islandRegistry: IslandEntry[];\n cacheTags: Set<string>;\n headRegistry: HeadEntry[]; // Thay vì JSXChild[]\n metadataStack: Metadata[]; // Stack để track metadata hierarchy\n schemaRegistry: Array<Record<string, any>>; // Schema.org structured data từ loaders\n request: RequestInfo;\n viewName?: string; // View name from route handler\n}\n\nconst renderStore = new AsyncLocalStorage<RenderContext>();\n\n// Create context for each request\nfunction createRequestContext(requestInfo: RequestInfo): RenderContext {\n return {\n clientJsRegistry: [],\n cssRegistry: [],\n islandRegistry: [],\n cacheTags: new Set(),\n headRegistry: [],\n metadataStack: [],\n schemaRegistry: [],\n request: requestInfo,\n };\n}\n\nexport function useClientJs(path: string): string {\n if (typeof path === 'string' && path.length > 0) {\n const renderContext = renderStore.getStore();\n if (renderContext) {\n renderContext.clientJsRegistry.push({ path, from: 'Unknown' });\n }\n }\n return '';\n}\n\nexport function registerIsland(key: string, src: string, name: string): void {\n const renderContext = renderStore.getStore();\n if (renderContext) {\n // Dedupe by key\n if (!renderContext.islandRegistry.some((e) => e.key === key)) {\n renderContext.islandRegistry.push({ key, src, name });\n }\n }\n}\n\nexport function getIslandEntries(): IslandEntry[] {\n const context = renderStore.getStore();\n if (!context) return [];\n return context.islandRegistry.slice();\n}\n\nexport function useCss(path: string): string {\n if (typeof path === 'string' && path.length > 0) {\n const renderContext = renderStore.getStore();\n if (renderContext) {\n renderContext.cssRegistry.push({ path, from: 'Unknown' });\n }\n }\n return '';\n}\n\n// Wrapper to run render in async context\nexport function runInRenderContext<T>(\n renderFn: () => T | Promise<T>,\n requestInfo: RequestInfo,\n viewName?: string,\n): Promise<T> {\n const context = createRequestContext(requestInfo);\n if (viewName) {\n context.viewName = viewName;\n }\n return renderStore.run(context, () => Promise.resolve(renderFn()));\n}\n\n// Set view name in current render context\nexport function setViewName(viewName: string): void {\n const context = renderStore.getStore();\n if (context) {\n context.viewName = viewName;\n }\n}\n\n// Get entries from current context\nexport function getClientJsEntries(): Array<{ path: string; from: string }> {\n const context = renderStore.getStore();\n if (!context) return [];\n return context.clientJsRegistry.slice();\n}\n\n// Get cache tags from current context\nexport function getCacheTags(): string[] {\n const context = renderStore.getStore();\n if (!context) return [];\n return Array.from(context.cacheTags);\n}\n\n// Add cache tags to current context\nexport function addCacheTag(tag: string | string[] | Record<string, boolean>): void {\n const context = renderStore.getStore();\n if (!context) return;\n\n if (Array.isArray(tag)) {\n tag.forEach((t) => {\n if (typeof t === 'string' && t.trim()) {\n context.cacheTags.add(t.trim());\n }\n });\n } else if (typeof tag === 'string' && tag.trim()) {\n context.cacheTags.add(tag.trim());\n } else if (typeof tag === 'object' && tag !== null) {\n Object.entries(tag).forEach(([key, value]) => {\n if (value && typeof key === 'string' && key.trim()) {\n context.cacheTags.add(key.trim());\n }\n });\n }\n}\n\n// Get CSS entries from current context\nexport function getCssEntries(): Array<{ path: string; from: string }> {\n const context = renderStore.getStore();\n if (!context) return [];\n return context.cssRegistry.slice();\n}\n\n// Head component to collect head elements with priority support\nexport function Head({\n children,\n priority = HEAD_PRIORITY.LOW, // Default priority\n}: {\n children?: JSXChild;\n priority?: HeadPriority;\n}): null {\n const renderContext = renderStore.getStore();\n if (renderContext && children) {\n renderContext.headRegistry.push({\n content: children,\n priority: typeof priority === 'number' ? priority : HEAD_PRIORITY.LOW,\n source: 'manual',\n });\n\n // Sort theo priority sau mỗi lần push để đảm bảo thứ tự đúng\n renderContext.headRegistry.sort((a, b) => a.priority - b.priority);\n }\n return null;\n}\n\n// Get head content from current context (already sorted by priority)\nexport function getHeadContent(): JSXChild[] {\n const context = renderStore.getStore();\n if (!context) return [];\n // Đã được sort trong Head component, chỉ cần map để lấy content\n return context.headRegistry.map((entry) => entry.content);\n}\n\n// Push metadata to stack (for hierarchical metadata support)\nexport function pushMetadata(metadata: Metadata): void {\n const context = renderStore.getStore();\n if (context && metadata) {\n context.metadataStack.push(metadata);\n }\n}\n\n// Resolve and merge all metadata from stack (root → leaf)\nexport function resolveMetadata(): Metadata | null {\n const context = renderStore.getStore();\n if (!context || context.metadataStack.length === 0) {\n return null;\n }\n\n // Merge from root → leaf (reduce left to right)\n return context.metadataStack.reduce(\n (acc, current) => mergeMetadata(acc, current),\n null as Metadata | null,\n );\n}\n\n// Push schema to registry (for schema markup from loaders)\n// Accepts schema-dts types (WithContext<T> or array of schemas)\nexport function pushSchema(schema: any | Array<any>): void {\n const context = renderStore.getStore();\n if (!context) return;\n\n if (Array.isArray(schema)) {\n context.schemaRegistry.push(...schema);\n } else {\n context.schemaRegistry.push(schema);\n }\n}\n\n// Get all schemas from registry\nexport function getSchemas(): Array<Record<string, any>> {\n const context = renderStore.getStore();\n if (!context) return [];\n return context.schemaRegistry.slice();\n}\n\n// Hook to get render request context\nexport function useRequest() {\n const context = renderStore.getStore();\n\n if (!context) {\n throw new Error('useRequest called outside of render context');\n }\n\n return {\n request: context.request,\n view: context.viewName,\n locals: (context.request.locals ?? {}) as Record<string, unknown>,\n params: (context.request.params ?? {}) as Record<string, any>,\n\n // Add cache tags\n addCacheTag: (tag: string | string[] | Record<string, boolean>) => {\n addCacheTag(tag);\n },\n\n // Get all cache tags\n getCacheTags: () => {\n return Array.from(context.cacheTags);\n },\n };\n}\n\n/**\n * Checks if a value is a valid JSX element (JSXNode)\n * Similar to React.isValidElement\n */\nexport function isValidElement(value: any): value is JSXNode {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'type' in value &&\n 'props' in value &&\n 'children' in value &&\n (typeof value.type === 'string' || typeof value.type === 'function')\n );\n}\n\n/**\n * Clones a JSX element with new props and/or children\n * Similar to React.cloneElement\n */\nexport function cloneElement(\n element: JSXNode,\n props?: Record<string, any>,\n ...children: JSXChild[]\n): JSXNode {\n const newProps = { ...element.props, ...props };\n const newChildren = children.length > 0 ? children.flat() : element.children;\n\n return {\n type: element.type,\n props: newProps,\n children: newChildren,\n };\n}\n"],"names":["HEAD_PRIORITY","mergeMetadata","parent","child","merged","RAW_HTML_MARKER","jsxFactory","type","props","children","Fragment","renderStore","AsyncLocalStorage","createRequestContext","requestInfo","useClientJs","path","renderContext","registerIsland","key","src","name","e","getIslandEntries","context","useCss","runInRenderContext","renderFn","viewName","setViewName","getClientJsEntries","getCacheTags","addCacheTag","tag","t","value","getCssEntries","Head","priority","a","b","getHeadContent","entry","pushMetadata","metadata","resolveMetadata","acc","current","pushSchema","schema","getSchemas","useRequest","isValidElement","cloneElement","element","newProps","newChildren"],"mappings":"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"}