@estjs/server 0.0.15-beta.14 → 0.0.15-beta.17
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.cjs.js +2 -1
- package/dist/server.cjs.js.map +1 -1
- package/dist/server.d.cts +166 -26
- package/dist/server.d.ts +166 -26
- package/dist/server.dev.cjs.js +401 -0
- package/dist/server.dev.cjs.js.map +1 -0
- package/dist/server.dev.esm.js +368 -0
- package/dist/server.dev.esm.js.map +1 -0
- package/dist/server.esm.js +2 -1
- package/dist/server.esm.js.map +1 -1
- package/package.json +4 -3
package/dist/server.d.ts
CHANGED
|
@@ -1,50 +1,109 @@
|
|
|
1
1
|
import { ComponentProps, ComponentFn } from '@estjs/template';
|
|
2
|
+
export { getHydrationKey, resetHydrationKey } from '@estjs/template';
|
|
2
3
|
export { escapeHTML } from '@estjs/shared';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
* SSR rendering context.
|
|
7
|
+
|
|
8
|
+
*/
|
|
9
|
+
interface SSRContext {
|
|
10
|
+
/**
|
|
11
|
+
* Map of teleport target → concatenated HTML string. The caller is
|
|
12
|
+
* responsible for inlining each entry into the final document
|
|
13
|
+
* (e.g. by replacing a placeholder in a shell template).
|
|
14
|
+
*/
|
|
15
|
+
teleports: Record<string, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Free-form key/value bag for user-defined per-render metadata
|
|
18
|
+
* (e.g. collected `<head>` tags, status codes, response headers).
|
|
19
|
+
*/
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create an empty SSR context with all collection slots initialised.
|
|
9
24
|
*/
|
|
10
|
-
declare function
|
|
25
|
+
declare function createSSRContext(): SSRContext;
|
|
26
|
+
/**
|
|
27
|
+
* Get the current SSR context, if any. Returns `null` when called outside of
|
|
28
|
+
* a `renderToString` invocation, or when the caller did not pass a context.
|
|
29
|
+
*/
|
|
30
|
+
declare function getSSRContext(): SSRContext | null;
|
|
31
|
+
|
|
11
32
|
/**
|
|
12
|
-
* Render
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
33
|
+
* Render a component to HTML string.
|
|
34
|
+
*
|
|
35
|
+
* Each invocation runs inside its own root scope so that `provide()` calls
|
|
36
|
+
* stay isolated between independent `renderToString` calls.
|
|
37
|
+
*
|
|
38
|
+
* @param component - The component to render.
|
|
39
|
+
* @param props - The props to pass to the component.
|
|
40
|
+
* @param context - Optional {@link SSRContext} that collects out-of-tree
|
|
41
|
+
* render output (currently: `Portal`/`Teleport` content). The same context
|
|
42
|
+
* is visible to nested `createSSGComponent` calls; the caller integrates
|
|
43
|
+
* `context.teleports[selector]` into the final document.
|
|
44
|
+
* @returns {string} The rendered HTML string.
|
|
45
|
+
*/
|
|
46
|
+
declare function renderToString<P extends ComponentProps = ComponentProps>(component: ComponentFn<P>, props?: P | ComponentProps, context?: SSRContext | null): string;
|
|
47
|
+
/**
|
|
48
|
+
* Render template with components (used by babel plugin in SSG mode).
|
|
49
|
+
*
|
|
50
|
+
* @param templates - The template fragments.
|
|
51
|
+
* @param hydrationKey - The hydration key.
|
|
52
|
+
* @param components - The rendered component strings.
|
|
53
|
+
* @returns {string} The rendered HTML string.
|
|
17
54
|
*/
|
|
18
55
|
declare function render(templates: string[], hydrationKey: string, ...components: string[]): string;
|
|
19
56
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
57
|
+
* Async variant of {@link renderToString}. Awaits component results so that
|
|
58
|
+
* `async` components and promise-returning expressions can participate in SSR.
|
|
59
|
+
*
|
|
60
|
+
* The awaited value is passed through the same {@link convertToString}
|
|
61
|
+
* pipeline as the synchronous path, which itself transparently awaits any
|
|
62
|
+
* nested promises (arrays of promises, promise-returning thunks, etc.).
|
|
63
|
+
*/
|
|
64
|
+
declare function renderToStringAsync<P extends ComponentProps = ComponentProps>(component: ComponentFn<P>, props?: P | ComponentProps, context?: SSRContext | null): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Create a SSG component (renders component to string).
|
|
67
|
+
*
|
|
68
|
+
* The component executes inside a child scope that inherits from the current
|
|
69
|
+
* active scope, so `inject()` calls can resolve values from ancestor
|
|
70
|
+
* `provide()` calls, and `provide()` inside the component is scoped to it.
|
|
71
|
+
*
|
|
72
|
+
* @param component - The component to create.
|
|
73
|
+
* @param props - The props to pass to the component.
|
|
74
|
+
* @returns {string} The rendered component as a string.
|
|
24
75
|
*/
|
|
25
76
|
declare function createSSGComponent<P extends ComponentProps = ComponentProps>(component: ComponentFn<P>, props?: P | ComponentProps): string;
|
|
26
77
|
|
|
27
78
|
/**
|
|
28
|
-
* Convert content to string for SSR output
|
|
79
|
+
* Convert content to string for SSR output.
|
|
29
80
|
*
|
|
30
|
-
* @param content -
|
|
31
|
-
* @param isSvg -
|
|
32
|
-
* @returns
|
|
81
|
+
* @param content - The content to convert.
|
|
82
|
+
* @param isSvg - Whether the content is SVG.
|
|
83
|
+
* @returns {string} The content as a string.
|
|
33
84
|
*/
|
|
34
85
|
declare function convertToString(content: unknown, isSvg?: boolean): string;
|
|
35
86
|
/**
|
|
36
|
-
*
|
|
87
|
+
* Convert child-expression content to escaped text for SSR output.
|
|
37
88
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
|
|
89
|
+
* JSX expression children have text semantics, so primitives must be escaped
|
|
90
|
+
* before interpolation into the surrounding HTML template.
|
|
91
|
+
*/
|
|
92
|
+
declare function convertTextChildToString(content: unknown): string;
|
|
93
|
+
/**
|
|
94
|
+
* Add hydration attributes to HTML content.
|
|
95
|
+
*
|
|
96
|
+
* @param htmlContent - The html content.
|
|
97
|
+
* @param hydrationId - The hydration id.
|
|
98
|
+
* @returns {string} The html content with hydration attributes.
|
|
41
99
|
*/
|
|
42
100
|
declare function addAttributes(htmlContent: string, hydrationId: string): string;
|
|
43
101
|
|
|
44
102
|
/**
|
|
45
103
|
* Normalize component properties
|
|
46
104
|
*
|
|
47
|
-
* Special handling for class and style attributes, converting them to normalized format
|
|
105
|
+
* Special handling for class and style attributes, converting them to normalized format.
|
|
106
|
+
* Returns a new object when normalization is needed, preserving the original.
|
|
48
107
|
*
|
|
49
108
|
* @param props - Original component properties
|
|
50
109
|
* @returns Normalized component properties
|
|
@@ -61,9 +120,90 @@ declare function normalizeProps(props: Record<string, any> | null): Record<strin
|
|
|
61
120
|
*
|
|
62
121
|
* @param attrName - Attribute name
|
|
63
122
|
* @param attrValue - Attribute value
|
|
64
|
-
* @param hydrationId - Hydration ID (for client-side reuse)
|
|
65
123
|
* @returns Formatted HTML attribute string
|
|
66
124
|
*/
|
|
67
|
-
declare function setSSGAttr(attrName: string, attrValue: any
|
|
125
|
+
declare function setSSGAttr(attrName: string, attrValue: any): string;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Render a single attribute as an HTML attribute string.
|
|
129
|
+
*
|
|
130
|
+
* @param name - The name of the attribute.
|
|
131
|
+
* @param value - The value of the attribute.
|
|
132
|
+
* @returns {string} The rendered attribute string (e.g., ` name="value"`).
|
|
133
|
+
*/
|
|
134
|
+
declare function ssrAttr(name: string, value: unknown): string;
|
|
135
|
+
/**
|
|
136
|
+
* Render a `class` attribute as an HTML attribute string.
|
|
137
|
+
*
|
|
138
|
+
* @param value - The class value (string, object, or array).
|
|
139
|
+
* @returns {string} The rendered class attribute string.
|
|
140
|
+
*/
|
|
141
|
+
declare function ssrClass(value: unknown): string;
|
|
142
|
+
/**
|
|
143
|
+
* Render a `style` attribute as an HTML attribute string.
|
|
144
|
+
*
|
|
145
|
+
* @param value - The style value (string or object).
|
|
146
|
+
* @returns {string} The rendered style attribute string.
|
|
147
|
+
*/
|
|
148
|
+
declare function ssrStyle(value: unknown): string;
|
|
149
|
+
/**
|
|
150
|
+
* Render a spread of props as HTML attribute strings.
|
|
151
|
+
* Skips event handlers and special keys.
|
|
152
|
+
*
|
|
153
|
+
* @param props - The props object to spread.
|
|
154
|
+
* @returns {string} The rendered attribute strings.
|
|
155
|
+
*/
|
|
156
|
+
declare function ssrSpread(props: Record<string, unknown>): string;
|
|
157
|
+
|
|
158
|
+
interface SSRComponentProps {
|
|
159
|
+
children?: unknown;
|
|
160
|
+
[key: string]: unknown;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* SSR Fragment — returns children converted to a string.
|
|
164
|
+
*/
|
|
165
|
+
declare function Fragment(props: SSRComponentProps): string;
|
|
166
|
+
interface SSRPortalProps extends SSRComponentProps {
|
|
167
|
+
/**
|
|
168
|
+
* Teleport target — only CSS selector strings are meaningful on the server.
|
|
169
|
+
* Element references are silently inlined (they have no server-side meaning).
|
|
170
|
+
*/
|
|
171
|
+
target?: string;
|
|
172
|
+
/**
|
|
173
|
+
* When truthy, children render inline instead of being teleported.
|
|
174
|
+
* The babel plugin resolves reactive getters before reaching the component,
|
|
175
|
+
* so only a plain boolean is needed on the server.
|
|
176
|
+
*/
|
|
177
|
+
disabled?: boolean | (() => boolean);
|
|
178
|
+
}
|
|
179
|
+
declare const TELEPORT_CALLSITE_ANCHOR = "<!--teleport-anchor-->";
|
|
180
|
+
declare const TELEPORT_BLOCK_START = "<!--teleport-start-->";
|
|
181
|
+
declare const TELEPORT_BLOCK_END = "<!--teleport-end-->";
|
|
182
|
+
/**
|
|
183
|
+
* SSR Portal — collects teleported content into `ctx.teleports[target]`.
|
|
184
|
+
*
|
|
185
|
+
* Emits `<!--teleport-anchor-->` at the call site and wraps children with
|
|
186
|
+
* `<!--teleport-start-->...<!--teleport-end-->` in the target buffer.
|
|
187
|
+
* Disabled / no-target / no-context falls back to inline rendering.
|
|
188
|
+
*/
|
|
189
|
+
declare function Portal(props: SSRPortalProps): string;
|
|
190
|
+
/**
|
|
191
|
+
* SSR Suspense — renders children when available, otherwise the fallback slot.
|
|
192
|
+
*/
|
|
193
|
+
declare function Suspense(props: SSRComponentProps & {
|
|
194
|
+
fallback?: unknown;
|
|
195
|
+
}): string;
|
|
196
|
+
interface SSRForProps<T> {
|
|
197
|
+
each: T[] | {
|
|
198
|
+
value: T[];
|
|
199
|
+
} | (() => T[]);
|
|
200
|
+
children: (item: T, index: number) => unknown;
|
|
201
|
+
key?: (item: T, index: number) => unknown;
|
|
202
|
+
fallback?: unknown;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* SSR For — maps each item through the render function and joins the output.
|
|
206
|
+
*/
|
|
207
|
+
declare function For<T>(props: SSRForProps<T>): string;
|
|
68
208
|
|
|
69
|
-
export { addAttributes, convertToString, createSSGComponent, normalizeProps, render, renderToString, setSSGAttr };
|
|
209
|
+
export { For, Fragment, Portal, type SSRComponentProps, type SSRContext, type SSRForProps, type SSRPortalProps, Suspense, TELEPORT_BLOCK_END, TELEPORT_BLOCK_START, TELEPORT_CALLSITE_ANCHOR, addAttributes, convertTextChildToString, convertToString, createSSGComponent, createSSRContext, getSSRContext, normalizeProps, render, renderToString, renderToStringAsync, setSSGAttr, ssrAttr, ssrClass, ssrSpread, ssrStyle };
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var shared = require('@estjs/shared');
|
|
4
|
+
var template = require('@estjs/template');
|
|
5
|
+
var internal = require('@estjs/template/internal');
|
|
6
|
+
var async_hooks = require('async_hooks');
|
|
7
|
+
var signals = require('@estjs/signals');
|
|
8
|
+
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
13
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {}))
|
|
16
|
+
if (__hasOwnProp.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
if (__getOwnPropSymbols)
|
|
19
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
+
if (__propIsEnum.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
25
|
+
var __async = (__this, __arguments, generator) => {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
var fulfilled = (value) => {
|
|
28
|
+
try {
|
|
29
|
+
step(generator.next(value));
|
|
30
|
+
} catch (e) {
|
|
31
|
+
reject(e);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var rejected = (value) => {
|
|
35
|
+
try {
|
|
36
|
+
step(generator.throw(value));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
reject(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
42
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
function createSSRContext() {
|
|
46
|
+
return {
|
|
47
|
+
teleports: /* @__PURE__ */ Object.create(null)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
var store = new async_hooks.AsyncLocalStorage();
|
|
51
|
+
function getSSRContext() {
|
|
52
|
+
var _a;
|
|
53
|
+
return (_a = store.getStore()) != null ? _a : null;
|
|
54
|
+
}
|
|
55
|
+
function runWithSSRContext(ctx, fn) {
|
|
56
|
+
return store.run(ctx, fn);
|
|
57
|
+
}
|
|
58
|
+
function convertToString(content, isSvg = false) {
|
|
59
|
+
if (shared.isNil(content)) {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
if (shared.isString(content)) {
|
|
63
|
+
return content;
|
|
64
|
+
}
|
|
65
|
+
if (shared.isArray(content)) {
|
|
66
|
+
return content.map((item) => convertToString(item, isSvg)).join("");
|
|
67
|
+
}
|
|
68
|
+
if (shared.isFunction(content)) {
|
|
69
|
+
return convertToString(content(), isSvg);
|
|
70
|
+
}
|
|
71
|
+
return String(content);
|
|
72
|
+
}
|
|
73
|
+
function convertTextChildToString(content) {
|
|
74
|
+
if (content === false || shared.isNil(content)) {
|
|
75
|
+
return "";
|
|
76
|
+
}
|
|
77
|
+
if (shared.isString(content)) {
|
|
78
|
+
return shared.escapeHTML(content);
|
|
79
|
+
}
|
|
80
|
+
if (shared.isArray(content)) {
|
|
81
|
+
return content.map((item) => convertTextChildToString(item)).join("");
|
|
82
|
+
}
|
|
83
|
+
if (shared.isFunction(content)) {
|
|
84
|
+
return convertTextChildToString(content());
|
|
85
|
+
}
|
|
86
|
+
return shared.escapeHTML(String(content));
|
|
87
|
+
}
|
|
88
|
+
var HYDRATION_REWRITE_REGEX = /data-idx="(\d+)"|<!--(\d+)-->/g;
|
|
89
|
+
function injectRootHydrationAttribute(htmlContent, hydrationId) {
|
|
90
|
+
const tagStart = htmlContent.indexOf("<");
|
|
91
|
+
if (tagStart === -1) {
|
|
92
|
+
return htmlContent;
|
|
93
|
+
}
|
|
94
|
+
let quote;
|
|
95
|
+
for (let i = tagStart + 1; i < htmlContent.length; i++) {
|
|
96
|
+
const char = htmlContent[i];
|
|
97
|
+
if (quote) {
|
|
98
|
+
if (char === quote) {
|
|
99
|
+
quote = void 0;
|
|
100
|
+
}
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (char === '"' || char === "'") {
|
|
104
|
+
quote = char;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (char === ">") {
|
|
108
|
+
let insertAt = i;
|
|
109
|
+
for (let j = i - 1; j > tagStart; j--) {
|
|
110
|
+
const prev = htmlContent[j];
|
|
111
|
+
if (prev === " " || prev === "\n" || prev === " " || prev === "\r") {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (prev === "/") {
|
|
115
|
+
insertAt = j;
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
return `${htmlContent.slice(0, insertAt)} data-hk="${hydrationId}"${htmlContent.slice(insertAt)}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return htmlContent;
|
|
123
|
+
}
|
|
124
|
+
function addAttributes(htmlContent, hydrationId) {
|
|
125
|
+
return injectRootHydrationAttribute(htmlContent, hydrationId).replaceAll(
|
|
126
|
+
HYDRATION_REWRITE_REGEX,
|
|
127
|
+
(_match, dataIdx, commentBody) => dataIdx !== void 0 ? `data-idx="${hydrationId}-${dataIdx}"` : `<!--${hydrationId}-${commentBody}-->`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/render.ts
|
|
132
|
+
function runInFreshScope(fn, parent = internal.getActiveScope()) {
|
|
133
|
+
const scope = internal.createScope(parent);
|
|
134
|
+
try {
|
|
135
|
+
return internal.runWithScope(scope, fn);
|
|
136
|
+
} finally {
|
|
137
|
+
internal.disposeScope(scope);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function renderToString(component, props = {}, context = null) {
|
|
141
|
+
if (!shared.isFunction(component)) {
|
|
142
|
+
shared.error("Component must be a function");
|
|
143
|
+
return "";
|
|
144
|
+
}
|
|
145
|
+
template.resetHydrationKey();
|
|
146
|
+
const result = runWithSSRContext(
|
|
147
|
+
context,
|
|
148
|
+
() => runInFreshScope(() => component(props), null)
|
|
149
|
+
);
|
|
150
|
+
if (shared.isPromise(result)) {
|
|
151
|
+
shared.error("renderToString received a Promise \u2014 use renderToStringAsync for async components.");
|
|
152
|
+
}
|
|
153
|
+
return convertToString(result);
|
|
154
|
+
}
|
|
155
|
+
function render(templates, hydrationKey, ...components) {
|
|
156
|
+
const templateLen = templates.length;
|
|
157
|
+
const componentLen = components.length;
|
|
158
|
+
let content = "";
|
|
159
|
+
for (let i = 0; i < templateLen; i++) {
|
|
160
|
+
content += templates[i];
|
|
161
|
+
if (i < componentLen && components[i]) {
|
|
162
|
+
content += convertToString(components[i]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return addAttributes(content, hydrationKey);
|
|
166
|
+
}
|
|
167
|
+
function renderToStringAsync(_0) {
|
|
168
|
+
return __async(this, arguments, function* (component, props = {}, context = null) {
|
|
169
|
+
if (!shared.isFunction(component)) {
|
|
170
|
+
shared.error("Component must be a function");
|
|
171
|
+
return "";
|
|
172
|
+
}
|
|
173
|
+
template.resetHydrationKey();
|
|
174
|
+
const scope = internal.createScope(null);
|
|
175
|
+
try {
|
|
176
|
+
return yield runWithSSRContext(context, () => __async(null, null, function* () {
|
|
177
|
+
let result = internal.runWithScope(scope, () => component(props));
|
|
178
|
+
if (shared.isPromise(result)) {
|
|
179
|
+
result = yield result;
|
|
180
|
+
}
|
|
181
|
+
return convertToStringAsync(result);
|
|
182
|
+
}));
|
|
183
|
+
} finally {
|
|
184
|
+
internal.disposeScope(scope);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function convertToStringAsync(content) {
|
|
189
|
+
return __async(this, null, function* () {
|
|
190
|
+
if (shared.isPromise(content)) {
|
|
191
|
+
return convertToStringAsync(yield content);
|
|
192
|
+
}
|
|
193
|
+
if (Array.isArray(content)) {
|
|
194
|
+
const parts = yield Promise.all(content.map((c) => convertToStringAsync(c)));
|
|
195
|
+
return parts.join("");
|
|
196
|
+
}
|
|
197
|
+
if (shared.isFunction(content)) {
|
|
198
|
+
return convertToStringAsync(content());
|
|
199
|
+
}
|
|
200
|
+
return convertToString(content);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function createSSGComponent(component, props = {}) {
|
|
204
|
+
if (!shared.isFunction(component)) {
|
|
205
|
+
shared.error("createSSGComponent: Component is not a function");
|
|
206
|
+
return "";
|
|
207
|
+
}
|
|
208
|
+
const result = runInFreshScope(() => component(props));
|
|
209
|
+
return convertToString(result);
|
|
210
|
+
}
|
|
211
|
+
function normalizeProps(props) {
|
|
212
|
+
if (!props) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const { class: className, style } = props;
|
|
216
|
+
const needsClassNorm = className && !shared.isString(className);
|
|
217
|
+
const needsStyleNorm = !!style;
|
|
218
|
+
if (!needsClassNorm && !needsStyleNorm) {
|
|
219
|
+
return props;
|
|
220
|
+
}
|
|
221
|
+
const result = __spreadValues({}, props);
|
|
222
|
+
if (needsClassNorm) {
|
|
223
|
+
result.class = shared.normalizeClassName(className);
|
|
224
|
+
}
|
|
225
|
+
if (needsStyleNorm) {
|
|
226
|
+
result.style = shared.normalizeStyle(style);
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
function setSSGAttr(attrName, attrValue) {
|
|
231
|
+
if (signals.isSignal(attrValue) || signals.isComputed(attrValue)) {
|
|
232
|
+
return setSSGAttr(attrName, attrValue.value);
|
|
233
|
+
}
|
|
234
|
+
if (!attrValue && attrValue !== 0) {
|
|
235
|
+
return "";
|
|
236
|
+
}
|
|
237
|
+
if (attrName === "style") {
|
|
238
|
+
const normalizedStyle = shared.normalizeStyle(attrValue);
|
|
239
|
+
if (!normalizedStyle) {
|
|
240
|
+
return "";
|
|
241
|
+
}
|
|
242
|
+
if (shared.isString(normalizedStyle)) {
|
|
243
|
+
return ` style="${normalizedStyle}"`;
|
|
244
|
+
}
|
|
245
|
+
return ` style="${shared.styleToString(normalizedStyle)}"`;
|
|
246
|
+
}
|
|
247
|
+
if (attrName === "class") {
|
|
248
|
+
const normalizedClassName = shared.normalizeClassName(attrValue);
|
|
249
|
+
return normalizedClassName ? ` class="${normalizedClassName}"` : "";
|
|
250
|
+
}
|
|
251
|
+
if (attrName.startsWith("on")) {
|
|
252
|
+
return "";
|
|
253
|
+
}
|
|
254
|
+
if (attrValue === true) {
|
|
255
|
+
return ` ${attrName}`;
|
|
256
|
+
}
|
|
257
|
+
return ` ${attrName}="${shared.escapeHTML(String(attrValue))}"`;
|
|
258
|
+
}
|
|
259
|
+
function ssrAttr(name, value) {
|
|
260
|
+
if (shared.isNil(value) || value === false) return "";
|
|
261
|
+
if (value === true) return ` ${name}`;
|
|
262
|
+
return ` ${name}="${shared.escapeHTML(String(value))}"`;
|
|
263
|
+
}
|
|
264
|
+
function ssrClass(value) {
|
|
265
|
+
const normalized = normalizeClassSSR(value);
|
|
266
|
+
if (!normalized) return "";
|
|
267
|
+
return ` class="${shared.escapeHTML(normalized)}"`;
|
|
268
|
+
}
|
|
269
|
+
function ssrStyle(value) {
|
|
270
|
+
if (shared.isNil(value)) return "";
|
|
271
|
+
if (shared.isString(value)) return value ? ` style="${shared.escapeHTML(value)}"` : "";
|
|
272
|
+
if (shared.isObject(value)) {
|
|
273
|
+
const obj = value;
|
|
274
|
+
const parts = [];
|
|
275
|
+
for (const key in obj) {
|
|
276
|
+
const v = obj[key];
|
|
277
|
+
if (v != null && v !== false) {
|
|
278
|
+
const prop = key.startsWith("--") ? key : camelToKebab(key);
|
|
279
|
+
parts.push(`${prop}:${shared.escapeHTML(String(v))}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!parts.length) return "";
|
|
283
|
+
return ` style="${parts.join(";")}"`;
|
|
284
|
+
}
|
|
285
|
+
return "";
|
|
286
|
+
}
|
|
287
|
+
function ssrSpread(props) {
|
|
288
|
+
if (!props || !shared.isObject(props)) return "";
|
|
289
|
+
let out = "";
|
|
290
|
+
for (const key in props) {
|
|
291
|
+
if (key === "children" || key === "ref" || key.startsWith("on")) continue;
|
|
292
|
+
if (key === "class" || key === "className") {
|
|
293
|
+
out += ssrClass(props[key]);
|
|
294
|
+
} else if (key === "style") {
|
|
295
|
+
out += ssrStyle(props[key]);
|
|
296
|
+
} else {
|
|
297
|
+
out += ssrAttr(key, props[key]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return out;
|
|
301
|
+
}
|
|
302
|
+
function normalizeClassSSR(value) {
|
|
303
|
+
if (shared.isNil(value) || value === false) return "";
|
|
304
|
+
if (shared.isString(value)) return value;
|
|
305
|
+
if (shared.isArray(value)) {
|
|
306
|
+
return value.map(normalizeClassSSR).filter(Boolean).join(" ");
|
|
307
|
+
}
|
|
308
|
+
if (shared.isObject(value)) {
|
|
309
|
+
const obj = value;
|
|
310
|
+
return Object.keys(obj).filter((k) => Boolean(obj[k])).join(" ");
|
|
311
|
+
}
|
|
312
|
+
return String(value);
|
|
313
|
+
}
|
|
314
|
+
var UPPER_RE = /[A-Z]/g;
|
|
315
|
+
function camelToKebab(str) {
|
|
316
|
+
return str.replaceAll(UPPER_RE, (m) => `-${m.toLowerCase()}`);
|
|
317
|
+
}
|
|
318
|
+
function Fragment(props) {
|
|
319
|
+
return convertToString(props.children);
|
|
320
|
+
}
|
|
321
|
+
var TELEPORT_CALLSITE_ANCHOR = "<!--teleport-anchor-->";
|
|
322
|
+
var TELEPORT_BLOCK_START = "<!--teleport-start-->";
|
|
323
|
+
var TELEPORT_BLOCK_END = "<!--teleport-end-->";
|
|
324
|
+
function Portal(props) {
|
|
325
|
+
var _a;
|
|
326
|
+
const { target, children } = props;
|
|
327
|
+
const rendered = convertToString(children);
|
|
328
|
+
const disabled = shared.isFunction(props.disabled) ? !!props.disabled() : !!props.disabled;
|
|
329
|
+
if (disabled || !target) return rendered;
|
|
330
|
+
const ctx = getSSRContext();
|
|
331
|
+
if (!ctx) return rendered;
|
|
332
|
+
if (!shared.isString(target)) {
|
|
333
|
+
{
|
|
334
|
+
shared.warn("[Portal] SSR only supports string selector targets; rendering inline.");
|
|
335
|
+
}
|
|
336
|
+
return rendered;
|
|
337
|
+
}
|
|
338
|
+
ctx.teleports[target] = ((_a = ctx.teleports[target]) != null ? _a : "") + TELEPORT_BLOCK_START + rendered + TELEPORT_BLOCK_END;
|
|
339
|
+
return TELEPORT_CALLSITE_ANCHOR;
|
|
340
|
+
}
|
|
341
|
+
function Suspense(props) {
|
|
342
|
+
const { children, fallback } = props;
|
|
343
|
+
return shared.isNil(children) ? convertToString(fallback) : convertToString(children);
|
|
344
|
+
}
|
|
345
|
+
function resolveList(input) {
|
|
346
|
+
var _a, _b;
|
|
347
|
+
if (shared.isNil(input)) return [];
|
|
348
|
+
if (shared.isObject(input) && "value" in input) {
|
|
349
|
+
return (_a = input.value) != null ? _a : [];
|
|
350
|
+
}
|
|
351
|
+
if (shared.isFunction(input)) {
|
|
352
|
+
return (_b = input()) != null ? _b : [];
|
|
353
|
+
}
|
|
354
|
+
return input;
|
|
355
|
+
}
|
|
356
|
+
function For(props) {
|
|
357
|
+
const list = resolveList(props.each);
|
|
358
|
+
if (list.length === 0) {
|
|
359
|
+
return convertToString(props.fallback);
|
|
360
|
+
}
|
|
361
|
+
const render2 = props.children;
|
|
362
|
+
if (!shared.isFunction(render2)) return "";
|
|
363
|
+
return list.map((item, i) => convertToString(render2(item, i))).join("");
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
Object.defineProperty(exports, "escapeHTML", {
|
|
367
|
+
enumerable: true,
|
|
368
|
+
get: function () { return shared.escapeHTML; }
|
|
369
|
+
});
|
|
370
|
+
Object.defineProperty(exports, "getHydrationKey", {
|
|
371
|
+
enumerable: true,
|
|
372
|
+
get: function () { return template.getHydrationKey; }
|
|
373
|
+
});
|
|
374
|
+
Object.defineProperty(exports, "resetHydrationKey", {
|
|
375
|
+
enumerable: true,
|
|
376
|
+
get: function () { return template.resetHydrationKey; }
|
|
377
|
+
});
|
|
378
|
+
exports.For = For;
|
|
379
|
+
exports.Fragment = Fragment;
|
|
380
|
+
exports.Portal = Portal;
|
|
381
|
+
exports.Suspense = Suspense;
|
|
382
|
+
exports.TELEPORT_BLOCK_END = TELEPORT_BLOCK_END;
|
|
383
|
+
exports.TELEPORT_BLOCK_START = TELEPORT_BLOCK_START;
|
|
384
|
+
exports.TELEPORT_CALLSITE_ANCHOR = TELEPORT_CALLSITE_ANCHOR;
|
|
385
|
+
exports.addAttributes = addAttributes;
|
|
386
|
+
exports.convertTextChildToString = convertTextChildToString;
|
|
387
|
+
exports.convertToString = convertToString;
|
|
388
|
+
exports.createSSGComponent = createSSGComponent;
|
|
389
|
+
exports.createSSRContext = createSSRContext;
|
|
390
|
+
exports.getSSRContext = getSSRContext;
|
|
391
|
+
exports.normalizeProps = normalizeProps;
|
|
392
|
+
exports.render = render;
|
|
393
|
+
exports.renderToString = renderToString;
|
|
394
|
+
exports.renderToStringAsync = renderToStringAsync;
|
|
395
|
+
exports.setSSGAttr = setSSGAttr;
|
|
396
|
+
exports.ssrAttr = ssrAttr;
|
|
397
|
+
exports.ssrClass = ssrClass;
|
|
398
|
+
exports.ssrSpread = ssrSpread;
|
|
399
|
+
exports.ssrStyle = ssrStyle;
|
|
400
|
+
//# sourceMappingURL=server.dev.cjs.js.map
|
|
401
|
+
//# sourceMappingURL=server.dev.cjs.js.map
|