@jamx-framework/renderer 0.1.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/.turbo/turbo-build.log +4 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/error/boundary.d.ts +36 -0
- package/dist/error/boundary.d.ts.map +1 -0
- package/dist/error/boundary.js +60 -0
- package/dist/error/boundary.js.map +1 -0
- package/dist/error/error-page.d.ts +7 -0
- package/dist/error/error-page.d.ts.map +1 -0
- package/dist/error/error-page.js +132 -0
- package/dist/error/error-page.js.map +1 -0
- package/dist/error/types.d.ts +7 -0
- package/dist/error/types.d.ts.map +1 -0
- package/dist/error/types.js +2 -0
- package/dist/error/types.js.map +1 -0
- package/dist/html/escape.d.ts +19 -0
- package/dist/html/escape.d.ts.map +1 -0
- package/dist/html/escape.js +85 -0
- package/dist/html/escape.js.map +1 -0
- package/dist/html/serializer.d.ts +20 -0
- package/dist/html/serializer.d.ts.map +1 -0
- package/dist/html/serializer.js +132 -0
- package/dist/html/serializer.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx/jsx-runtime.d.ts +213 -0
- package/dist/jsx/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx/jsx-runtime.js +32 -0
- package/dist/jsx/jsx-runtime.js.map +1 -0
- package/dist/pipeline/context.d.ts +44 -0
- package/dist/pipeline/context.d.ts.map +1 -0
- package/dist/pipeline/context.js +2 -0
- package/dist/pipeline/context.js.map +1 -0
- package/dist/pipeline/renderer.d.ts +40 -0
- package/dist/pipeline/renderer.d.ts.map +1 -0
- package/dist/pipeline/renderer.js +95 -0
- package/dist/pipeline/renderer.js.map +1 -0
- package/package.json +38 -0
- package/src/error/boundary.ts +80 -0
- package/src/error/error-page.ts +137 -0
- package/src/error/types.ts +6 -0
- package/src/html/escape.ts +90 -0
- package/src/html/serializer.ts +161 -0
- package/src/index.ts +33 -0
- package/src/jsx/jsx-runtime.ts +247 -0
- package/src/pipeline/context.ts +45 -0
- package/src/pipeline/renderer.ts +138 -0
- package/test/unit/error/boundary.test.ts +78 -0
- package/test/unit/error/error-page.test.ts +63 -0
- package/test/unit/html/escape.test.ts +34 -0
- package/test/unit/html/renderer.test.ts +93 -0
- package/test/unit/html/serializer.test.ts +141 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +4 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { escapeHtml, VOID_ELEMENTS, RAW_TEXT_ELEMENTS, BOOLEAN_ATTRIBUTES, } from "./escape.js";
|
|
2
|
+
import { Fragment } from "../jsx/jsx-runtime.js";
|
|
3
|
+
/**
|
|
4
|
+
* Serializa un árbol JSX a una string HTML.
|
|
5
|
+
*
|
|
6
|
+
* Proceso:
|
|
7
|
+
* 1. Si el nodo es un string/number → escapar y retornar
|
|
8
|
+
* 2. Si el nodo es un componente (función) → llamarlo y serializar el resultado
|
|
9
|
+
* 3. Si el nodo es un elemento HTML → serializar tag + props + children
|
|
10
|
+
* 4. Si el nodo es un Fragment → serializar solo los children
|
|
11
|
+
*/
|
|
12
|
+
export class HtmlSerializer {
|
|
13
|
+
serialize(node) {
|
|
14
|
+
// Nodos primitivos
|
|
15
|
+
if (node === null || node === undefined || node === false)
|
|
16
|
+
return "";
|
|
17
|
+
if (node === true)
|
|
18
|
+
return "";
|
|
19
|
+
if (typeof node === "number")
|
|
20
|
+
return String(node);
|
|
21
|
+
if (typeof node === "string")
|
|
22
|
+
return escapeHtml(node);
|
|
23
|
+
// Arrays
|
|
24
|
+
if (Array.isArray(node)) {
|
|
25
|
+
return node.map((child) => this.serialize(child)).join("");
|
|
26
|
+
}
|
|
27
|
+
// Elemento JSX
|
|
28
|
+
return this.serializeElement(node);
|
|
29
|
+
}
|
|
30
|
+
serializeElement(element) {
|
|
31
|
+
const { type, props } = element;
|
|
32
|
+
// Componente funcional — ejecutar y serializar el resultado
|
|
33
|
+
if (typeof type === "function") {
|
|
34
|
+
return this.serializeComponent(type, props);
|
|
35
|
+
}
|
|
36
|
+
// Fragment — solo los hijos
|
|
37
|
+
if (type === Fragment) {
|
|
38
|
+
return this.serializeChildren(props.children);
|
|
39
|
+
}
|
|
40
|
+
// Elemento HTML
|
|
41
|
+
return this.serializeHtmlElement(type, props);
|
|
42
|
+
}
|
|
43
|
+
serializeComponent(fn, props) {
|
|
44
|
+
try {
|
|
45
|
+
const result = fn(props);
|
|
46
|
+
return this.serialize(result);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
throw new Error(`Error rendering component '${fn.name || "anonymous"}': ${String(err)}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
serializeHtmlElement(tag, props) {
|
|
53
|
+
const { children, ...attrs } = props;
|
|
54
|
+
const attrString = this.serializeAttributes(attrs);
|
|
55
|
+
const openTag = attrString ? `<${tag} ${attrString}>` : `<${tag}>`;
|
|
56
|
+
// Elementos void — no tienen closing tag ni children
|
|
57
|
+
if (VOID_ELEMENTS.has(tag)) {
|
|
58
|
+
return openTag;
|
|
59
|
+
}
|
|
60
|
+
// Elementos con contenido raw (script, style)
|
|
61
|
+
if (RAW_TEXT_ELEMENTS.has(tag)) {
|
|
62
|
+
const rawContent = typeof children === "string" ? children : "";
|
|
63
|
+
return `${openTag}${rawContent}</${tag}>`;
|
|
64
|
+
}
|
|
65
|
+
const childrenHtml = this.serializeChildren(children);
|
|
66
|
+
return `${openTag}${childrenHtml}</${tag}>`;
|
|
67
|
+
}
|
|
68
|
+
serializeAttributes(attrs) {
|
|
69
|
+
const parts = [];
|
|
70
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
71
|
+
// Ignorar atributos internos y undefined/null
|
|
72
|
+
if (key === "key" || value === undefined || value === null)
|
|
73
|
+
continue;
|
|
74
|
+
// className → class
|
|
75
|
+
const attrName = key === "className"
|
|
76
|
+
? "class"
|
|
77
|
+
: key === "htmlFor"
|
|
78
|
+
? "for"
|
|
79
|
+
: key === "tabIndex"
|
|
80
|
+
? "tabindex"
|
|
81
|
+
: camelToKebab(key);
|
|
82
|
+
// Atributos booleanos
|
|
83
|
+
if (BOOLEAN_ATTRIBUTES.has(attrName)) {
|
|
84
|
+
if (value === true)
|
|
85
|
+
parts.push(attrName);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// style como objeto
|
|
89
|
+
if (key === "style" && typeof value === "object" && value !== null) {
|
|
90
|
+
const styleStr = this.serializeStyle(value);
|
|
91
|
+
if (styleStr)
|
|
92
|
+
parts.push(`style="${escapeHtml(styleStr)}"`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// false → omitir el atributo
|
|
96
|
+
if (value === false)
|
|
97
|
+
continue;
|
|
98
|
+
// true → atributo sin valor (no booleano, ej: data-active)
|
|
99
|
+
if (value === true) {
|
|
100
|
+
parts.push(attrName);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
parts.push(`${attrName}="${escapeHtml(value)}"`);
|
|
104
|
+
}
|
|
105
|
+
return parts.join(" ");
|
|
106
|
+
}
|
|
107
|
+
serializeStyle(style) {
|
|
108
|
+
return Object.entries(style)
|
|
109
|
+
.map(([prop, value]) => `${camelToKebab(prop)}: ${value}`)
|
|
110
|
+
.join("; ");
|
|
111
|
+
}
|
|
112
|
+
serializeChildren(children) {
|
|
113
|
+
if (children === undefined || children === null)
|
|
114
|
+
return "";
|
|
115
|
+
if (Array.isArray(children)) {
|
|
116
|
+
return children
|
|
117
|
+
.map((child) => this.serialize(child))
|
|
118
|
+
.join("");
|
|
119
|
+
}
|
|
120
|
+
return this.serialize(children);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ── HELPERS ───────────────────────────────────────────────────────────────
|
|
124
|
+
/**
|
|
125
|
+
* Convierte camelCase a kebab-case para atributos HTML.
|
|
126
|
+
* backgroundColor → background-color
|
|
127
|
+
* dataTestId → data-test-id (los data- ya vienen bien)
|
|
128
|
+
*/
|
|
129
|
+
function camelToKebab(str) {
|
|
130
|
+
return str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/html/serializer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { SSRRenderer } from "./pipeline/renderer.js";
|
|
2
|
+
export { HtmlSerializer } from "./html/serializer.js";
|
|
3
|
+
export { escapeHtml, VOID_ELEMENTS, BOOLEAN_ATTRIBUTES, } from "./html/escape.js";
|
|
4
|
+
export { jsx, jsxs, jsxDEV, Fragment } from "./jsx/jsx-runtime.js";
|
|
5
|
+
export type { JamxNode, JamxElement, ComponentFn, Props, JSX, HtmlAttributes, } from "./jsx/jsx-runtime.js";
|
|
6
|
+
export type { RenderContext, RenderResult, PageHead, } from "./pipeline/context.js";
|
|
7
|
+
export type { PageComponentLike, LayoutComponentLike, } from "./pipeline/renderer.js";
|
|
8
|
+
export { ErrorBoundary } from "./error/boundary.js";
|
|
9
|
+
export { renderErrorPage } from "./error/error-page.js";
|
|
10
|
+
export type { RenderError } from "./error/types.js";
|
|
11
|
+
export type { BoundaryOptions, BoundaryResult } from "./error/boundary.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,UAAU,EACV,aAAa,EACb,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEnE,YAAY,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,KAAK,EACL,GAAG,EACH,cAAc,GACf,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,aAAa,EACb,YAAY,EACZ,QAAQ,GACT,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { SSRRenderer } from "./pipeline/renderer.js";
|
|
2
|
+
export { HtmlSerializer } from "./html/serializer.js";
|
|
3
|
+
export { escapeHtml, VOID_ELEMENTS, BOOLEAN_ATTRIBUTES, } from "./html/escape.js";
|
|
4
|
+
export { jsx, jsxs, jsxDEV, Fragment } from "./jsx/jsx-runtime.js";
|
|
5
|
+
export { ErrorBoundary } from "./error/boundary.js";
|
|
6
|
+
export { renderErrorPage } from "./error/error-page.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,UAAU,EACV,aAAa,EACb,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAsBnE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
export type JamxNode = string | number | boolean | null | undefined | JamxElement | JamxNode[];
|
|
2
|
+
export interface JamxElement {
|
|
3
|
+
type: string | ComponentFn;
|
|
4
|
+
props: Props;
|
|
5
|
+
key: string | null;
|
|
6
|
+
}
|
|
7
|
+
export type Props = Record<string, unknown> & {
|
|
8
|
+
children?: JamxNode | JamxNode[];
|
|
9
|
+
};
|
|
10
|
+
export type ComponentFn = (props: Props) => JamxNode;
|
|
11
|
+
/**
|
|
12
|
+
* Función principal del JSX runtime.
|
|
13
|
+
* TypeScript llama esto cuando encuentra <Tag prop="value" />
|
|
14
|
+
*
|
|
15
|
+
* En lugar de React.createElement, JAMX usa esta función
|
|
16
|
+
* para construir el árbol de nodos que luego serializa a HTML.
|
|
17
|
+
*/
|
|
18
|
+
export declare function jsx(type: string | ComponentFn, props: Props, key?: string): JamxElement;
|
|
19
|
+
/**
|
|
20
|
+
* Versión para elementos con múltiples hijos.
|
|
21
|
+
* TypeScript la usa cuando hay más de un hijo.
|
|
22
|
+
*/
|
|
23
|
+
export declare const jsxs: typeof jsx;
|
|
24
|
+
/**
|
|
25
|
+
* Versión dev con información adicional para debugging.
|
|
26
|
+
* En producción es igual a jsx.
|
|
27
|
+
*/
|
|
28
|
+
export declare const jsxDEV: typeof jsx;
|
|
29
|
+
/**
|
|
30
|
+
* Fragment — permite retornar múltiples elementos sin wrapper.
|
|
31
|
+
* Uso: <> <div/> <div/> </>
|
|
32
|
+
*/
|
|
33
|
+
export declare const Fragment: "jamx.fragment";
|
|
34
|
+
/**
|
|
35
|
+
* Declaraciones de tipos para que TypeScript entienda el JSX de JAMX.
|
|
36
|
+
* Estas interfaces definen qué props acepta cada elemento HTML.
|
|
37
|
+
*/
|
|
38
|
+
export declare namespace JSX {
|
|
39
|
+
type Element = JamxElement;
|
|
40
|
+
interface ElementChildrenAttribute {
|
|
41
|
+
children: JamxNode | JamxNode[];
|
|
42
|
+
}
|
|
43
|
+
interface IntrinsicElements {
|
|
44
|
+
html: HtmlAttributes & {
|
|
45
|
+
lang?: string;
|
|
46
|
+
};
|
|
47
|
+
head: HtmlAttributes;
|
|
48
|
+
body: HtmlAttributes;
|
|
49
|
+
title: HtmlAttributes;
|
|
50
|
+
meta: MetaAttributes;
|
|
51
|
+
link: LinkAttributes;
|
|
52
|
+
script: ScriptAttributes;
|
|
53
|
+
style: HtmlAttributes;
|
|
54
|
+
main: HtmlAttributes;
|
|
55
|
+
header: HtmlAttributes;
|
|
56
|
+
footer: HtmlAttributes;
|
|
57
|
+
nav: HtmlAttributes;
|
|
58
|
+
section: HtmlAttributes;
|
|
59
|
+
article: HtmlAttributes;
|
|
60
|
+
aside: HtmlAttributes;
|
|
61
|
+
h1: HtmlAttributes;
|
|
62
|
+
h2: HtmlAttributes;
|
|
63
|
+
h3: HtmlAttributes;
|
|
64
|
+
h4: HtmlAttributes;
|
|
65
|
+
h5: HtmlAttributes;
|
|
66
|
+
h6: HtmlAttributes;
|
|
67
|
+
p: HtmlAttributes;
|
|
68
|
+
span: HtmlAttributes;
|
|
69
|
+
strong: HtmlAttributes;
|
|
70
|
+
em: HtmlAttributes;
|
|
71
|
+
small: HtmlAttributes;
|
|
72
|
+
code: HtmlAttributes;
|
|
73
|
+
pre: HtmlAttributes;
|
|
74
|
+
ul: HtmlAttributes;
|
|
75
|
+
ol: HtmlAttributes;
|
|
76
|
+
li: HtmlAttributes;
|
|
77
|
+
a: AnchorAttributes;
|
|
78
|
+
button: ButtonAttributes;
|
|
79
|
+
input: InputAttributes;
|
|
80
|
+
textarea: TextareaAttributes;
|
|
81
|
+
select: HtmlAttributes;
|
|
82
|
+
option: HtmlAttributes & {
|
|
83
|
+
value?: string;
|
|
84
|
+
selected?: boolean;
|
|
85
|
+
};
|
|
86
|
+
form: FormAttributes;
|
|
87
|
+
label: HtmlAttributes & {
|
|
88
|
+
for?: string;
|
|
89
|
+
htmlFor?: string;
|
|
90
|
+
};
|
|
91
|
+
img: ImgAttributes;
|
|
92
|
+
video: HtmlAttributes & {
|
|
93
|
+
src?: string;
|
|
94
|
+
controls?: boolean;
|
|
95
|
+
autoplay?: boolean;
|
|
96
|
+
};
|
|
97
|
+
audio: HtmlAttributes & {
|
|
98
|
+
src?: string;
|
|
99
|
+
controls?: boolean;
|
|
100
|
+
};
|
|
101
|
+
canvas: HtmlAttributes & {
|
|
102
|
+
width?: number;
|
|
103
|
+
height?: number;
|
|
104
|
+
};
|
|
105
|
+
div: HtmlAttributes;
|
|
106
|
+
table: HtmlAttributes;
|
|
107
|
+
thead: HtmlAttributes;
|
|
108
|
+
tbody: HtmlAttributes;
|
|
109
|
+
tr: HtmlAttributes;
|
|
110
|
+
th: HtmlAttributes & {
|
|
111
|
+
colSpan?: number;
|
|
112
|
+
rowSpan?: number;
|
|
113
|
+
};
|
|
114
|
+
td: HtmlAttributes & {
|
|
115
|
+
colSpan?: number;
|
|
116
|
+
rowSpan?: number;
|
|
117
|
+
};
|
|
118
|
+
br: HtmlAttributes;
|
|
119
|
+
hr: HtmlAttributes;
|
|
120
|
+
slot: HtmlAttributes & {
|
|
121
|
+
name?: string;
|
|
122
|
+
};
|
|
123
|
+
[tag: string]: HtmlAttributes;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export interface HtmlAttributes {
|
|
127
|
+
id?: string;
|
|
128
|
+
class?: string;
|
|
129
|
+
className?: string;
|
|
130
|
+
style?: string | Record<string, string>;
|
|
131
|
+
children?: JamxNode | JamxNode[];
|
|
132
|
+
[key: `data-${string}`]: string | undefined;
|
|
133
|
+
role?: string;
|
|
134
|
+
"aria-label"?: string;
|
|
135
|
+
"aria-hidden"?: boolean;
|
|
136
|
+
"aria-expanded"?: boolean;
|
|
137
|
+
"aria-disabled"?: boolean;
|
|
138
|
+
"aria-selected"?: boolean;
|
|
139
|
+
"aria-controls"?: string;
|
|
140
|
+
"aria-describedby"?: string;
|
|
141
|
+
tabIndex?: number;
|
|
142
|
+
}
|
|
143
|
+
export interface AnchorAttributes extends HtmlAttributes {
|
|
144
|
+
href?: string;
|
|
145
|
+
target?: "_blank" | "_self" | "_parent" | "_top";
|
|
146
|
+
rel?: string;
|
|
147
|
+
download?: boolean | string;
|
|
148
|
+
}
|
|
149
|
+
export interface ButtonAttributes extends HtmlAttributes {
|
|
150
|
+
type?: "button" | "submit" | "reset";
|
|
151
|
+
disabled?: boolean;
|
|
152
|
+
name?: string;
|
|
153
|
+
value?: string;
|
|
154
|
+
}
|
|
155
|
+
export interface InputAttributes extends HtmlAttributes {
|
|
156
|
+
type?: string;
|
|
157
|
+
name?: string;
|
|
158
|
+
value?: string | number;
|
|
159
|
+
placeholder?: string;
|
|
160
|
+
required?: boolean;
|
|
161
|
+
disabled?: boolean;
|
|
162
|
+
readonly?: boolean;
|
|
163
|
+
checked?: boolean;
|
|
164
|
+
min?: string | number;
|
|
165
|
+
max?: string | number;
|
|
166
|
+
step?: string | number;
|
|
167
|
+
pattern?: string;
|
|
168
|
+
autocomplete?: string;
|
|
169
|
+
}
|
|
170
|
+
export interface TextareaAttributes extends HtmlAttributes {
|
|
171
|
+
name?: string;
|
|
172
|
+
rows?: number;
|
|
173
|
+
cols?: number;
|
|
174
|
+
placeholder?: string;
|
|
175
|
+
required?: boolean;
|
|
176
|
+
disabled?: boolean;
|
|
177
|
+
readonly?: boolean;
|
|
178
|
+
}
|
|
179
|
+
export interface FormAttributes extends HtmlAttributes {
|
|
180
|
+
action?: string;
|
|
181
|
+
method?: "get" | "post";
|
|
182
|
+
enctype?: string;
|
|
183
|
+
}
|
|
184
|
+
export interface ImgAttributes extends HtmlAttributes {
|
|
185
|
+
src?: string;
|
|
186
|
+
alt?: string;
|
|
187
|
+
width?: number | string;
|
|
188
|
+
height?: number | string;
|
|
189
|
+
loading?: "lazy" | "eager";
|
|
190
|
+
}
|
|
191
|
+
export interface MetaAttributes extends HtmlAttributes {
|
|
192
|
+
name?: string;
|
|
193
|
+
content?: string;
|
|
194
|
+
charset?: string;
|
|
195
|
+
httpEquiv?: string;
|
|
196
|
+
property?: string;
|
|
197
|
+
"http-equiv"?: string;
|
|
198
|
+
}
|
|
199
|
+
export interface LinkAttributes extends HtmlAttributes {
|
|
200
|
+
rel?: string;
|
|
201
|
+
href?: string;
|
|
202
|
+
type?: string;
|
|
203
|
+
media?: string;
|
|
204
|
+
as?: string;
|
|
205
|
+
}
|
|
206
|
+
export interface ScriptAttributes extends HtmlAttributes {
|
|
207
|
+
src?: string;
|
|
208
|
+
type?: string;
|
|
209
|
+
async?: boolean;
|
|
210
|
+
defer?: boolean;
|
|
211
|
+
module?: boolean;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=jsx-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime.d.ts","sourceRoot":"","sources":["../../src/jsx/jsx-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// ── TIPOS DEL ÁRBOL JSX ───────────────────────────────────────────────────
|
|
2
|
+
// ── JSX RUNTIME ───────────────────────────────────────────────────────────
|
|
3
|
+
/**
|
|
4
|
+
* Función principal del JSX runtime.
|
|
5
|
+
* TypeScript llama esto cuando encuentra <Tag prop="value" />
|
|
6
|
+
*
|
|
7
|
+
* En lugar de React.createElement, JAMX usa esta función
|
|
8
|
+
* para construir el árbol de nodos que luego serializa a HTML.
|
|
9
|
+
*/
|
|
10
|
+
export function jsx(type, props, key) {
|
|
11
|
+
return {
|
|
12
|
+
type,
|
|
13
|
+
props: props ?? {},
|
|
14
|
+
key: key ?? null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Versión para elementos con múltiples hijos.
|
|
19
|
+
* TypeScript la usa cuando hay más de un hijo.
|
|
20
|
+
*/
|
|
21
|
+
export const jsxs = jsx;
|
|
22
|
+
/**
|
|
23
|
+
* Versión dev con información adicional para debugging.
|
|
24
|
+
* En producción es igual a jsx.
|
|
25
|
+
*/
|
|
26
|
+
export const jsxDEV = jsx;
|
|
27
|
+
/**
|
|
28
|
+
* Fragment — permite retornar múltiples elementos sin wrapper.
|
|
29
|
+
* Uso: <> <div/> <div/> </>
|
|
30
|
+
*/
|
|
31
|
+
export const Fragment = "jamx.fragment";
|
|
32
|
+
//# sourceMappingURL=jsx-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime.js","sourceRoot":"","sources":["../../src/jsx/jsx-runtime.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAuB7E,6EAA6E;AAE7E;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,CACjB,IAA0B,EAC1B,KAAY,EACZ,GAAY;IAEZ,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,KAAK,IAAI,EAAE;QAClB,GAAG,EAAE,GAAG,IAAI,IAAI;KACjB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAC;AAE1B;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAwB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contexto disponible durante el render de una página.
|
|
3
|
+
* Se pasa al componente para que pueda acceder a datos
|
|
4
|
+
* de la request sin importar directamente @jamx-framework/server.
|
|
5
|
+
*/
|
|
6
|
+
export interface RenderContext {
|
|
7
|
+
/** Path de la ruta actual. Ej: /users/123 */
|
|
8
|
+
path: string;
|
|
9
|
+
/** Params de la ruta. Ej: { id: '123' } */
|
|
10
|
+
params: Record<string, string>;
|
|
11
|
+
/** Query string parseado */
|
|
12
|
+
query: Record<string, string | string[]>;
|
|
13
|
+
/** Headers de la request */
|
|
14
|
+
headers: Record<string, string | string[] | undefined>;
|
|
15
|
+
/** Entorno actual */
|
|
16
|
+
env: "development" | "production" | "test";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resultado del render de una página.
|
|
20
|
+
*/
|
|
21
|
+
export interface RenderResult {
|
|
22
|
+
/** HTML completo listo para enviar */
|
|
23
|
+
html: string;
|
|
24
|
+
/** Status HTTP a usar en la response */
|
|
25
|
+
statusCode: number;
|
|
26
|
+
/** Headers adicionales para la response */
|
|
27
|
+
headers: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Metadatos de una página para el <head>.
|
|
31
|
+
*/
|
|
32
|
+
export interface PageHead {
|
|
33
|
+
title?: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
canonical?: string;
|
|
36
|
+
og?: {
|
|
37
|
+
title?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
image?: string;
|
|
40
|
+
type?: string;
|
|
41
|
+
};
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/pipeline/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IACzC,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,qBAAqB;IACrB,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,MAAM,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/pipeline/context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { RenderContext, RenderResult, PageHead } from "./context.js";
|
|
2
|
+
import type { JamxNode } from "../jsx/jsx-runtime.js";
|
|
3
|
+
export interface PageComponentLike {
|
|
4
|
+
render: (ctx: RenderContext) => JamxNode;
|
|
5
|
+
meta?: (ctx: RenderContext) => PageHead;
|
|
6
|
+
layout?: LayoutComponentLike;
|
|
7
|
+
}
|
|
8
|
+
export interface LayoutComponentLike {
|
|
9
|
+
render: (props: {
|
|
10
|
+
children: JamxNode;
|
|
11
|
+
ctx: RenderContext;
|
|
12
|
+
}) => JamxNode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Renderer SSR de JAMX.
|
|
16
|
+
*
|
|
17
|
+
* Convierte un componente de página en un string HTML completo,
|
|
18
|
+
* listo para ser enviado al cliente.
|
|
19
|
+
*
|
|
20
|
+
* Flujo:
|
|
21
|
+
* 1. Llamar page.meta() para obtener los metadatos del <head>
|
|
22
|
+
* 2. Llamar page.render() para obtener el árbol JSX del contenido
|
|
23
|
+
* 3. Si hay layout, envolver el contenido en él
|
|
24
|
+
* 4. Serializar el árbol completo a HTML string
|
|
25
|
+
* 5. Envolver en el documento HTML base
|
|
26
|
+
*/
|
|
27
|
+
export declare class SSRRenderer {
|
|
28
|
+
private readonly serializer;
|
|
29
|
+
constructor();
|
|
30
|
+
/**
|
|
31
|
+
* Renderiza una página completa a HTML.
|
|
32
|
+
*/
|
|
33
|
+
render(page: PageComponentLike, ctx: RenderContext): Promise<RenderResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Construye el documento HTML completo con el <head> y el <body>.
|
|
36
|
+
*/
|
|
37
|
+
private buildDocument;
|
|
38
|
+
private buildMetaTags;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/pipeline/renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,QAAQ,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,QAAQ,CAAC;IACxC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,GAAG,EAAE,aAAa,CAAA;KAAE,KAAK,QAAQ,CAAC;CACzE;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;;IAM5C;;OAEG;IACG,MAAM,CACV,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,YAAY,CAAC;IA2BxB;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,aAAa;CAyBtB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { HtmlSerializer } from "../html/serializer.js";
|
|
2
|
+
/**
|
|
3
|
+
* Renderer SSR de JAMX.
|
|
4
|
+
*
|
|
5
|
+
* Convierte un componente de página en un string HTML completo,
|
|
6
|
+
* listo para ser enviado al cliente.
|
|
7
|
+
*
|
|
8
|
+
* Flujo:
|
|
9
|
+
* 1. Llamar page.meta() para obtener los metadatos del <head>
|
|
10
|
+
* 2. Llamar page.render() para obtener el árbol JSX del contenido
|
|
11
|
+
* 3. Si hay layout, envolver el contenido en él
|
|
12
|
+
* 4. Serializar el árbol completo a HTML string
|
|
13
|
+
* 5. Envolver en el documento HTML base
|
|
14
|
+
*/
|
|
15
|
+
export class SSRRenderer {
|
|
16
|
+
serializer;
|
|
17
|
+
constructor() {
|
|
18
|
+
this.serializer = new HtmlSerializer();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Renderiza una página completa a HTML.
|
|
22
|
+
*/
|
|
23
|
+
async render(page, ctx) {
|
|
24
|
+
// 1. Obtener metadatos
|
|
25
|
+
const head = page.meta?.(ctx) ?? {};
|
|
26
|
+
// 2. Renderizar el contenido de la página
|
|
27
|
+
const contentNode = page.render(ctx);
|
|
28
|
+
// 3. Aplicar layout si existe
|
|
29
|
+
const bodyNode = page.layout
|
|
30
|
+
? page.layout.render({ children: contentNode, ctx })
|
|
31
|
+
: contentNode;
|
|
32
|
+
// 4. Serializar a string
|
|
33
|
+
const bodyHtml = this.serializer.serialize(bodyNode);
|
|
34
|
+
// 5. Construir el documento HTML completo
|
|
35
|
+
const html = this.buildDocument(bodyHtml, head, ctx);
|
|
36
|
+
return {
|
|
37
|
+
html,
|
|
38
|
+
statusCode: 200,
|
|
39
|
+
headers: {
|
|
40
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Construye el documento HTML completo con el <head> y el <body>.
|
|
46
|
+
*/
|
|
47
|
+
buildDocument(bodyHtml, head, ctx) {
|
|
48
|
+
const title = head.title ?? "JAMX App";
|
|
49
|
+
const description = head.description ?? "";
|
|
50
|
+
const isDev = ctx.env === "development";
|
|
51
|
+
const metaTags = this.buildMetaTags(head);
|
|
52
|
+
return `<!DOCTYPE html>
|
|
53
|
+
<html lang="en">
|
|
54
|
+
<head>
|
|
55
|
+
<meta charset="UTF-8" />
|
|
56
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
57
|
+
<title>${escapeTitle(title)}</title>
|
|
58
|
+
${description ? `<meta name="description" content="${escapeAttr(description)}" />` : ""}
|
|
59
|
+
${metaTags}
|
|
60
|
+
<link rel="stylesheet" href="/__jamx/styles.css" />
|
|
61
|
+
</head>
|
|
62
|
+
<body>
|
|
63
|
+
<div id="__jamx_root__" data-route="${escapeAttr(ctx.path)}">${bodyHtml}</div>
|
|
64
|
+
<script type="module" src="/__jamx/client.js"${isDev ? ' data-dev="true"' : ""}></script>
|
|
65
|
+
</body>
|
|
66
|
+
</html>`;
|
|
67
|
+
}
|
|
68
|
+
buildMetaTags(head) {
|
|
69
|
+
const tags = [];
|
|
70
|
+
if (head.og) {
|
|
71
|
+
const og = head.og;
|
|
72
|
+
if (og.title)
|
|
73
|
+
tags.push(`<meta property="og:title" content="${escapeAttr(og.title)}" />`);
|
|
74
|
+
if (og.description)
|
|
75
|
+
tags.push(`<meta property="og:description" content="${escapeAttr(og.description)}" />`);
|
|
76
|
+
if (og.image)
|
|
77
|
+
tags.push(`<meta property="og:image" content="${escapeAttr(og.image)}" />`);
|
|
78
|
+
if (og.type)
|
|
79
|
+
tags.push(`<meta property="og:type" content="${escapeAttr(og.type)}" />`);
|
|
80
|
+
}
|
|
81
|
+
return tags.join("\n ");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// ── HELPERS ───────────────────────────────────────────────────────────────
|
|
85
|
+
function escapeTitle(str) {
|
|
86
|
+
return str.replace(/</g, "<").replace(/>/g, ">");
|
|
87
|
+
}
|
|
88
|
+
function escapeAttr(str) {
|
|
89
|
+
return str
|
|
90
|
+
.replace(/&/g, "&")
|
|
91
|
+
.replace(/"/g, """)
|
|
92
|
+
.replace(/</g, "<")
|
|
93
|
+
.replace(/>/g, ">");
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/pipeline/renderer.ts"],"names":[],"mappings":"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"}
|