@zeus-js/runtime-ssr 0.1.0-canary.20260805.97.1.fa5d9cef

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,393 @@
1
+ /**
2
+ * runtime-ssr v0.1.0-canary.20260805.97.1.fa5d9cef
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ Object.defineProperties(exports, {
7
+ __esModule: { value: true },
8
+ [Symbol.toStringTag]: { value: "Module" }
9
+ });
10
+ let _zeus_js_signal = require("@zeus-js/signal");
11
+ //#region packages/core/runtime-ssr/src/serialize.ts
12
+ const SSR_FRAGMENT = Symbol.for("zeus.ssr.fragment");
13
+ const RAW_TEXT_END_TAG = {
14
+ script: /<\/script(?=[\t\n\f\r />]|$)/gi,
15
+ style: /<\/style(?=[\t\n\f\r />]|$)/gi
16
+ };
17
+ const RAW_TEXT_ESCAPE = {
18
+ script: "\\u003C",
19
+ style: "\\3C "
20
+ };
21
+ function createSSRFragment(html) {
22
+ return Object.freeze({
23
+ [SSR_FRAGMENT]: true,
24
+ html
25
+ });
26
+ }
27
+ function isSSRFragment(value) {
28
+ return typeof value === "object" && value !== null && value[SSR_FRAGMENT] === true;
29
+ }
30
+ function escapeHTMLText(value) {
31
+ return value.replace(/[&<>]/g, (character) => TEXT_ESCAPE[character]);
32
+ }
33
+ function escapeHTMLAttribute(value) {
34
+ return value.replace(/[&"<>]/g, (character) => ATTRIBUTE_ESCAPE[character]);
35
+ }
36
+ function assertSyncSSRValue(value) {
37
+ if (!isPromiseLike(value)) return;
38
+ Promise.resolve(value).catch(() => {});
39
+ throw new TypeError("renderToString() does not support async render values.");
40
+ }
41
+ const TEXT_ESCAPE = {
42
+ "&": "&amp;",
43
+ "<": "&lt;",
44
+ ">": "&gt;"
45
+ };
46
+ const ATTRIBUTE_ESCAPE = {
47
+ "&": "&amp;",
48
+ "\"": "&quot;",
49
+ "<": "&lt;",
50
+ ">": "&gt;"
51
+ };
52
+ function serializeSSRNode(value) {
53
+ assertSyncSSRValue(value);
54
+ if (isSSRFragment(value)) return value.html;
55
+ if (Array.isArray(value)) {
56
+ let html = "";
57
+ for (const child of value) html += serializeSSRNode(child);
58
+ return html;
59
+ }
60
+ if (value == null || typeof value === "boolean") return "";
61
+ if (typeof value === "string") return escapeHTMLText(value);
62
+ if (typeof value === "number") return String(value);
63
+ throw new TypeError("renderToString() received an unsupported SSR value.");
64
+ }
65
+ function serializeSSRRawText(value, tag) {
66
+ return escapeSSRRawText(serializeSSRRawTextValue(value, tag), tag);
67
+ }
68
+ function serializeSSRRawTextValue(value, tag) {
69
+ assertSyncSSRValue(value);
70
+ if (isSSRFragment(value)) throw new TypeError(`renderToString() does not support serialized fragments inside <${tag}> raw text.`);
71
+ if (Array.isArray(value)) {
72
+ let text = "";
73
+ for (const child of value) text += serializeSSRRawTextValue(child, tag);
74
+ return text;
75
+ }
76
+ if (value == null || typeof value === "boolean") return "";
77
+ if (typeof value === "string") return value;
78
+ if (typeof value === "number") return String(value);
79
+ throw new TypeError("renderToString() received an unsupported SSR value.");
80
+ }
81
+ function escapeSSRRawText(value, tag) {
82
+ if (tag === "script") return escapeSSRScriptText(value);
83
+ return value.replace(RAW_TEXT_END_TAG[tag], (match) => `${RAW_TEXT_ESCAPE[tag]}${match.slice(1)}`);
84
+ }
85
+ function escapeSSRScriptText(value) {
86
+ let escaped = false;
87
+ let result = "";
88
+ for (let index = 0; index < value.length;) {
89
+ if (matchesRawTextTag(value, index, "script", true)) {
90
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 8)}`;
91
+ index += 8;
92
+ continue;
93
+ }
94
+ if (!escaped && value.startsWith("<!--", index)) {
95
+ result += "<!--";
96
+ escaped = true;
97
+ index += 4;
98
+ continue;
99
+ }
100
+ if (escaped && value.startsWith("-->", index)) {
101
+ result += "-->";
102
+ escaped = false;
103
+ index += 3;
104
+ continue;
105
+ }
106
+ if (escaped && matchesRawTextTag(value, index, "script", false)) {
107
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 7)}`;
108
+ index += 7;
109
+ continue;
110
+ }
111
+ result += value[index];
112
+ index++;
113
+ }
114
+ return result;
115
+ }
116
+ function matchesRawTextTag(value, index, tag, closing) {
117
+ const prefix = `${closing ? "</" : "<"}${tag}`;
118
+ if (value.slice(index, index + prefix.length).toLowerCase() !== prefix) return false;
119
+ const delimiter = value[index + prefix.length];
120
+ return delimiter === void 0 || /[\t\n\f\r />]/.test(delimiter);
121
+ }
122
+ function isPromiseLike(value) {
123
+ return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
124
+ }
125
+ //#endregion
126
+ //#region packages/core/runtime-ssr/src/render.ts
127
+ function renderToString(input) {
128
+ if (typeof input !== "function") throw new TypeError("renderToString() expects a synchronous render function.");
129
+ return (0, _zeus_js_signal.createRoot)((dispose) => {
130
+ try {
131
+ return serializeSSRNode(input());
132
+ } finally {
133
+ dispose();
134
+ }
135
+ });
136
+ }
137
+ //#endregion
138
+ //#region packages/core/runtime-ssr/src/text.ts
139
+ function ssrStatic(html) {
140
+ return createSSRFragment(html);
141
+ }
142
+ function ssrText(value) {
143
+ return createSSRFragment(serializeSSRNode(value));
144
+ }
145
+ //#endregion
146
+ //#region packages/core/runtime-ssr/src/property.ts
147
+ const SSR_PROPERTY = Symbol.for("zeus.ssr.property");
148
+ const BOOLEAN_PROPERTY_ELEMENTS = {
149
+ checked: /* @__PURE__ */ new Set(["input"]),
150
+ disabled: /* @__PURE__ */ new Set([
151
+ "button",
152
+ "fieldset",
153
+ "input",
154
+ "optgroup",
155
+ "option",
156
+ "select",
157
+ "textarea"
158
+ ]),
159
+ multiple: /* @__PURE__ */ new Set(["input", "select"]),
160
+ readOnly: /* @__PURE__ */ new Set(["input", "textarea"]),
161
+ selected: /* @__PURE__ */ new Set(["option"])
162
+ };
163
+ const VALUE_PROPERTY_ELEMENTS = /* @__PURE__ */ new Set([
164
+ "button",
165
+ "input",
166
+ "option"
167
+ ]);
168
+ const SUPPORTED_PROPERTY_NAMES = /* @__PURE__ */ new Set([
169
+ ...Object.keys(BOOLEAN_PROPERTY_ELEMENTS),
170
+ "htmlFor",
171
+ "tabIndex",
172
+ "value"
173
+ ]);
174
+ function createSSRProperty(name, value) {
175
+ assertSyncSSRValue(value);
176
+ if (!SUPPORTED_PROPERTY_NAMES.has(name)) throw new TypeError(`SSR cannot serialize property "${name}".`);
177
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") return null;
178
+ return {
179
+ [SSR_PROPERTY]: true,
180
+ name,
181
+ propertyValue: value,
182
+ value: value === true ? true : String(value)
183
+ };
184
+ }
185
+ function resolveSSRElementProperties(tag, entries, children) {
186
+ const attributes = [];
187
+ const properties = [];
188
+ for (const entry of entries) {
189
+ assertSyncSSRValue(entry);
190
+ if (!entry) continue;
191
+ assertSyncSSRValue(entry.value);
192
+ if (isSSRProperty(entry)) properties.push(entry);
193
+ else attributes.push(entry);
194
+ }
195
+ let resolvedChildren = children;
196
+ for (const property of properties) {
197
+ const serialization = getSSRPropertySerialization(tag, property.name);
198
+ if (!serialization) throw new TypeError(`SSR cannot serialize property "${property.name}" on <${tag}>.`);
199
+ if (serialization.kind === "text-content") {
200
+ removeAttribute(attributes, "value");
201
+ resolvedChildren = normalizeTextareaValue(property.propertyValue);
202
+ continue;
203
+ }
204
+ removeAttribute(attributes, serialization.name);
205
+ if (serialization.kind === "boolean-attribute") {
206
+ if (Boolean(property.propertyValue)) attributes.push({
207
+ name: serialization.name,
208
+ value: true
209
+ });
210
+ continue;
211
+ }
212
+ attributes.push({
213
+ name: serialization.name,
214
+ value: property.name === "tabIndex" ? normalizeTabIndex(property.propertyValue) : String(property.propertyValue)
215
+ });
216
+ }
217
+ return {
218
+ attributes,
219
+ children: resolvedChildren
220
+ };
221
+ }
222
+ function getSSRPropertySerialization(tag, name) {
223
+ const normalizedTag = tag.toLowerCase();
224
+ if (name === "tabIndex") return {
225
+ kind: "string-attribute",
226
+ name: "tabindex"
227
+ };
228
+ if (name === "htmlFor") return normalizedTag === "label" ? {
229
+ kind: "string-attribute",
230
+ name: "for"
231
+ } : void 0;
232
+ if (name === "value") {
233
+ if (normalizedTag === "textarea") return { kind: "text-content" };
234
+ return VALUE_PROPERTY_ELEMENTS.has(normalizedTag) ? {
235
+ kind: "string-attribute",
236
+ name: "value"
237
+ } : void 0;
238
+ }
239
+ if (!BOOLEAN_PROPERTY_ELEMENTS[name]?.has(normalizedTag)) return void 0;
240
+ return {
241
+ kind: "boolean-attribute",
242
+ name: name === "readOnly" ? "readonly" : name
243
+ };
244
+ }
245
+ function isSSRProperty(attribute) {
246
+ return attribute[SSR_PROPERTY] === true;
247
+ }
248
+ function removeAttribute(attributes, name) {
249
+ const normalizedName = name.toLowerCase();
250
+ for (let index = attributes.length - 1; index >= 0; index--) if (attributes[index].name.toLowerCase() === normalizedName) attributes.splice(index, 1);
251
+ }
252
+ function normalizeTabIndex(value) {
253
+ const number = Number(value);
254
+ return String(Number.isFinite(number) ? Math.trunc(number) : 0);
255
+ }
256
+ function normalizeTextareaValue(value) {
257
+ const normalized = String(value).replace(/\r\n?/g, "\n");
258
+ return normalized.startsWith("\n") ? `\n${normalized}` : normalized;
259
+ }
260
+ //#endregion
261
+ //#region packages/core/runtime-ssr/src/element.ts
262
+ const VOID_ELEMENTS = /* @__PURE__ */ new Set([
263
+ "area",
264
+ "base",
265
+ "br",
266
+ "col",
267
+ "embed",
268
+ "hr",
269
+ "img",
270
+ "input",
271
+ "link",
272
+ "meta",
273
+ "param",
274
+ "source",
275
+ "track",
276
+ "wbr"
277
+ ]);
278
+ function ssrElement(tag, attributes = [], children = null, isVoid = VOID_ELEMENTS.has(tag.toLowerCase())) {
279
+ const resolved = resolveSSRElementProperties(tag, attributes, children);
280
+ const opening = `<${tag}${serializeAttributes(resolved.attributes)}>`;
281
+ if (isVoid) return createSSRFragment(opening);
282
+ const normalizedTag = tag.toLowerCase();
283
+ return createSSRFragment(`${opening}${normalizedTag === "script" || normalizedTag === "style" ? serializeSSRRawText(resolved.children, normalizedTag) : serializeSSRNode(resolved.children)}</${tag}>`);
284
+ }
285
+ function ssrAttr(name, value) {
286
+ assertSyncSSRValue(value);
287
+ const normalizedName = normalizeAttributeName(name);
288
+ if (normalizedName === "class") {
289
+ const normalized = normalizeClass(value);
290
+ return normalized ? createSSRAttribute("class", normalized) : null;
291
+ }
292
+ if (normalizedName === "style") return createStyleAttribute(value);
293
+ if (value == null || value === false) return null;
294
+ return createSSRAttribute(normalizedName, value === true ? true : String(value));
295
+ }
296
+ function createStyleAttribute(value) {
297
+ assertSyncSSRValue(value);
298
+ if (value == null) return null;
299
+ if (typeof value === "string") return createSSRAttribute("style", value);
300
+ const declarations = [];
301
+ for (const [key, declarationValue] of Object.entries(value)) {
302
+ assertSyncSSRValue(declarationValue);
303
+ if (declarationValue == null) continue;
304
+ declarations.push(`${normalizeStyleName(key)}:${normalizeStyleValue(key, declarationValue)}`);
305
+ }
306
+ return declarations.length ? createSSRAttribute("style", declarations.join(";")) : null;
307
+ }
308
+ function ssrProp(name, value) {
309
+ return createSSRProperty(name, value);
310
+ }
311
+ function createSSRAttribute(name, value) {
312
+ return {
313
+ name,
314
+ value
315
+ };
316
+ }
317
+ function serializeAttributes(attributes) {
318
+ let html = "";
319
+ for (const attribute of attributes) {
320
+ assertSyncSSRValue(attribute);
321
+ if (!attribute) continue;
322
+ assertSyncSSRValue(attribute.value);
323
+ html += ` ${attribute.name}`;
324
+ if (attribute.value !== true) html += `="${escapeHTMLAttribute(attribute.value)}"`;
325
+ }
326
+ return html;
327
+ }
328
+ function normalizeAttributeName(name) {
329
+ return name === "className" ? "class" : name;
330
+ }
331
+ function normalizeClass(value) {
332
+ assertSyncSSRValue(value);
333
+ if (!value) return "";
334
+ if (typeof value === "string") return value;
335
+ if (Array.isArray(value)) return value.map(normalizeClass).filter(Boolean).join(" ");
336
+ const tokens = value;
337
+ return Object.keys(tokens).filter((key) => {
338
+ assertSyncSSRValue(tokens[key]);
339
+ return tokens[key];
340
+ }).join(" ");
341
+ }
342
+ function normalizeStyleName(name) {
343
+ if (name.startsWith("--")) return name;
344
+ return name.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`);
345
+ }
346
+ function normalizeStyleValue(name, value) {
347
+ if (typeof value === "number" && value !== 0 && !name.startsWith("--") && !UNITLESS_STYLES.has(name)) return `${value}px`;
348
+ return String(value);
349
+ }
350
+ const UNITLESS_STYLES = /* @__PURE__ */ new Set([
351
+ "opacity",
352
+ "zIndex",
353
+ "fontWeight",
354
+ "lineHeight",
355
+ "flex",
356
+ "flexGrow",
357
+ "flexShrink",
358
+ "order"
359
+ ]);
360
+ //#endregion
361
+ //#region packages/core/runtime-ssr/src/component.ts
362
+ function ssrComponent(component, props) {
363
+ return component(props);
364
+ }
365
+ //#endregion
366
+ //#region packages/core/runtime-ssr/src/controlFlow.ts
367
+ function ssrShow(when, children, fallback) {
368
+ return resolve(when) ? resolve(children) : resolve(fallback) ?? null;
369
+ }
370
+ function Show(props) {
371
+ return resolve(props.when ? props.children : props.fallback) ?? null;
372
+ }
373
+ function ssrFor(each, render) {
374
+ return resolve(each)?.map((item, index) => render(item, index)) ?? null;
375
+ }
376
+ function For(props) {
377
+ return ssrFor(props.each, props.children);
378
+ }
379
+ function resolve(value) {
380
+ return typeof value === "function" ? value() : value;
381
+ }
382
+ //#endregion
383
+ exports.For = For;
384
+ exports.Show = Show;
385
+ exports.renderToString = renderToString;
386
+ exports.ssrAttr = ssrAttr;
387
+ exports.ssrComponent = ssrComponent;
388
+ exports.ssrElement = ssrElement;
389
+ exports.ssrFor = ssrFor;
390
+ exports.ssrProp = ssrProp;
391
+ exports.ssrShow = ssrShow;
392
+ exports.ssrStatic = ssrStatic;
393
+ exports.ssrText = ssrText;
@@ -0,0 +1,46 @@
1
+ export type SSRPrimitive = string | number | boolean | null | undefined;
2
+ declare const SSR_FRAGMENT: unique symbol;
3
+ export interface SSRFragment {
4
+ readonly [SSR_FRAGMENT]: true;
5
+ readonly html: string;
6
+ }
7
+ export type SSRNode = SSRPrimitive | SSRFragment | readonly SSRNode[];
8
+ export type SSRComponent<P extends Record<string, unknown> = Record<string, unknown>> = (props: P) => SSRNode;
9
+ export interface SSRAttribute {
10
+ readonly name: string;
11
+ readonly value: string | true;
12
+ }
13
+ export type SSRAttributeValue = string | number | boolean | null | undefined;
14
+ export type SSRAttributeEntry = SSRAttribute | null | undefined | false;
15
+ export type SSRClassValue = string | null | undefined | false | Readonly<Record<string, boolean | null | undefined>> | readonly SSRClassValue[];
16
+ export type SSRStyleValue = string | null | undefined | Readonly<Record<string, string | number | null | undefined>>;
17
+ export type SSRRenderInput = () => SSRNode;
18
+
19
+ export declare function renderToString(input: SSRRenderInput): string;
20
+
21
+ export declare function ssrStatic(html: string): SSRFragment;
22
+ export declare function ssrText(value: SSRNode): SSRFragment;
23
+
24
+ export declare function ssrElement(tag: string, attributes?: readonly SSRAttributeEntry[], children?: SSRNode, isVoid?: boolean): SSRFragment;
25
+ export declare function ssrAttr(name: string, value: SSRAttributeValue | SSRClassValue | SSRStyleValue): SSRAttributeEntry;
26
+ export declare function ssrProp(name: string, value: unknown): SSRAttributeEntry;
27
+
28
+ export declare function ssrComponent<P extends Record<string, unknown>, R extends SSRNode>(component: (props: P) => R, props: P): R;
29
+
30
+ export type SSRResolvable<T> = T | (() => T);
31
+ export interface ShowProps {
32
+ when: unknown;
33
+ fallback?: SSRResolvable<SSRNode>;
34
+ children?: SSRResolvable<SSRNode>;
35
+ }
36
+ export declare function ssrShow(when: SSRResolvable<unknown>, children: SSRResolvable<SSRNode>, fallback?: SSRResolvable<SSRNode>): SSRNode;
37
+ export declare function Show(props: ShowProps): SSRNode;
38
+ export interface ForProps<T, K = unknown> {
39
+ each: readonly T[] | null | undefined;
40
+ by?: (item: T, index: number) => K;
41
+ children: (item: T, index: number) => SSRNode;
42
+ }
43
+ export declare function ssrFor<T>(each: SSRResolvable<readonly T[] | null | undefined>, render: (item: T, index: number) => SSRNode): SSRNode;
44
+ export declare function For<T, K = unknown>(props: ForProps<T, K>): SSRNode;
45
+
46
+
@@ -0,0 +1,379 @@
1
+ /**
2
+ * runtime-ssr v0.1.0-canary.20260805.97.1.fa5d9cef
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ import { createRoot } from "@zeus-js/signal";
7
+ //#region packages/core/runtime-ssr/src/serialize.ts
8
+ const SSR_FRAGMENT = Symbol.for("zeus.ssr.fragment");
9
+ const RAW_TEXT_END_TAG = {
10
+ script: /<\/script(?=[\t\n\f\r />]|$)/gi,
11
+ style: /<\/style(?=[\t\n\f\r />]|$)/gi
12
+ };
13
+ const RAW_TEXT_ESCAPE = {
14
+ script: "\\u003C",
15
+ style: "\\3C "
16
+ };
17
+ function createSSRFragment(html) {
18
+ return Object.freeze({
19
+ [SSR_FRAGMENT]: true,
20
+ html
21
+ });
22
+ }
23
+ function isSSRFragment(value) {
24
+ return typeof value === "object" && value !== null && value[SSR_FRAGMENT] === true;
25
+ }
26
+ function escapeHTMLText(value) {
27
+ return value.replace(/[&<>]/g, (character) => TEXT_ESCAPE[character]);
28
+ }
29
+ function escapeHTMLAttribute(value) {
30
+ return value.replace(/[&"<>]/g, (character) => ATTRIBUTE_ESCAPE[character]);
31
+ }
32
+ function assertSyncSSRValue(value) {
33
+ if (!isPromiseLike(value)) return;
34
+ Promise.resolve(value).catch(() => {});
35
+ throw new TypeError("renderToString() does not support async render values.");
36
+ }
37
+ const TEXT_ESCAPE = {
38
+ "&": "&amp;",
39
+ "<": "&lt;",
40
+ ">": "&gt;"
41
+ };
42
+ const ATTRIBUTE_ESCAPE = {
43
+ "&": "&amp;",
44
+ "\"": "&quot;",
45
+ "<": "&lt;",
46
+ ">": "&gt;"
47
+ };
48
+ function serializeSSRNode(value) {
49
+ assertSyncSSRValue(value);
50
+ if (isSSRFragment(value)) return value.html;
51
+ if (Array.isArray(value)) {
52
+ let html = "";
53
+ for (const child of value) html += serializeSSRNode(child);
54
+ return html;
55
+ }
56
+ if (value == null || typeof value === "boolean") return "";
57
+ if (typeof value === "string") return escapeHTMLText(value);
58
+ if (typeof value === "number") return String(value);
59
+ throw new TypeError("renderToString() received an unsupported SSR value.");
60
+ }
61
+ function serializeSSRRawText(value, tag) {
62
+ return escapeSSRRawText(serializeSSRRawTextValue(value, tag), tag);
63
+ }
64
+ function serializeSSRRawTextValue(value, tag) {
65
+ assertSyncSSRValue(value);
66
+ if (isSSRFragment(value)) throw new TypeError(`renderToString() does not support serialized fragments inside <${tag}> raw text.`);
67
+ if (Array.isArray(value)) {
68
+ let text = "";
69
+ for (const child of value) text += serializeSSRRawTextValue(child, tag);
70
+ return text;
71
+ }
72
+ if (value == null || typeof value === "boolean") return "";
73
+ if (typeof value === "string") return value;
74
+ if (typeof value === "number") return String(value);
75
+ throw new TypeError("renderToString() received an unsupported SSR value.");
76
+ }
77
+ function escapeSSRRawText(value, tag) {
78
+ if (tag === "script") return escapeSSRScriptText(value);
79
+ return value.replace(RAW_TEXT_END_TAG[tag], (match) => `${RAW_TEXT_ESCAPE[tag]}${match.slice(1)}`);
80
+ }
81
+ function escapeSSRScriptText(value) {
82
+ let escaped = false;
83
+ let result = "";
84
+ for (let index = 0; index < value.length;) {
85
+ if (matchesRawTextTag(value, index, "script", true)) {
86
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 8)}`;
87
+ index += 8;
88
+ continue;
89
+ }
90
+ if (!escaped && value.startsWith("<!--", index)) {
91
+ result += "<!--";
92
+ escaped = true;
93
+ index += 4;
94
+ continue;
95
+ }
96
+ if (escaped && value.startsWith("-->", index)) {
97
+ result += "-->";
98
+ escaped = false;
99
+ index += 3;
100
+ continue;
101
+ }
102
+ if (escaped && matchesRawTextTag(value, index, "script", false)) {
103
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 7)}`;
104
+ index += 7;
105
+ continue;
106
+ }
107
+ result += value[index];
108
+ index++;
109
+ }
110
+ return result;
111
+ }
112
+ function matchesRawTextTag(value, index, tag, closing) {
113
+ const prefix = `${closing ? "</" : "<"}${tag}`;
114
+ if (value.slice(index, index + prefix.length).toLowerCase() !== prefix) return false;
115
+ const delimiter = value[index + prefix.length];
116
+ return delimiter === void 0 || /[\t\n\f\r />]/.test(delimiter);
117
+ }
118
+ function isPromiseLike(value) {
119
+ return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
120
+ }
121
+ //#endregion
122
+ //#region packages/core/runtime-ssr/src/render.ts
123
+ function renderToString(input) {
124
+ if (typeof input !== "function") throw new TypeError("renderToString() expects a synchronous render function.");
125
+ return createRoot((dispose) => {
126
+ try {
127
+ return serializeSSRNode(input());
128
+ } finally {
129
+ dispose();
130
+ }
131
+ });
132
+ }
133
+ //#endregion
134
+ //#region packages/core/runtime-ssr/src/text.ts
135
+ function ssrStatic(html) {
136
+ return createSSRFragment(html);
137
+ }
138
+ function ssrText(value) {
139
+ return createSSRFragment(serializeSSRNode(value));
140
+ }
141
+ //#endregion
142
+ //#region packages/core/runtime-ssr/src/property.ts
143
+ const SSR_PROPERTY = Symbol.for("zeus.ssr.property");
144
+ const BOOLEAN_PROPERTY_ELEMENTS = {
145
+ checked: /* @__PURE__ */ new Set(["input"]),
146
+ disabled: /* @__PURE__ */ new Set([
147
+ "button",
148
+ "fieldset",
149
+ "input",
150
+ "optgroup",
151
+ "option",
152
+ "select",
153
+ "textarea"
154
+ ]),
155
+ multiple: /* @__PURE__ */ new Set(["input", "select"]),
156
+ readOnly: /* @__PURE__ */ new Set(["input", "textarea"]),
157
+ selected: /* @__PURE__ */ new Set(["option"])
158
+ };
159
+ const VALUE_PROPERTY_ELEMENTS = /* @__PURE__ */ new Set([
160
+ "button",
161
+ "input",
162
+ "option"
163
+ ]);
164
+ const SUPPORTED_PROPERTY_NAMES = /* @__PURE__ */ new Set([
165
+ ...Object.keys(BOOLEAN_PROPERTY_ELEMENTS),
166
+ "htmlFor",
167
+ "tabIndex",
168
+ "value"
169
+ ]);
170
+ function createSSRProperty(name, value) {
171
+ assertSyncSSRValue(value);
172
+ if (!SUPPORTED_PROPERTY_NAMES.has(name)) throw new TypeError(`SSR cannot serialize property "${name}".`);
173
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") return null;
174
+ return {
175
+ [SSR_PROPERTY]: true,
176
+ name,
177
+ propertyValue: value,
178
+ value: value === true ? true : String(value)
179
+ };
180
+ }
181
+ function resolveSSRElementProperties(tag, entries, children) {
182
+ const attributes = [];
183
+ const properties = [];
184
+ for (const entry of entries) {
185
+ assertSyncSSRValue(entry);
186
+ if (!entry) continue;
187
+ assertSyncSSRValue(entry.value);
188
+ if (isSSRProperty(entry)) properties.push(entry);
189
+ else attributes.push(entry);
190
+ }
191
+ let resolvedChildren = children;
192
+ for (const property of properties) {
193
+ const serialization = getSSRPropertySerialization(tag, property.name);
194
+ if (!serialization) throw new TypeError(`SSR cannot serialize property "${property.name}" on <${tag}>.`);
195
+ if (serialization.kind === "text-content") {
196
+ removeAttribute(attributes, "value");
197
+ resolvedChildren = normalizeTextareaValue(property.propertyValue);
198
+ continue;
199
+ }
200
+ removeAttribute(attributes, serialization.name);
201
+ if (serialization.kind === "boolean-attribute") {
202
+ if (Boolean(property.propertyValue)) attributes.push({
203
+ name: serialization.name,
204
+ value: true
205
+ });
206
+ continue;
207
+ }
208
+ attributes.push({
209
+ name: serialization.name,
210
+ value: property.name === "tabIndex" ? normalizeTabIndex(property.propertyValue) : String(property.propertyValue)
211
+ });
212
+ }
213
+ return {
214
+ attributes,
215
+ children: resolvedChildren
216
+ };
217
+ }
218
+ function getSSRPropertySerialization(tag, name) {
219
+ const normalizedTag = tag.toLowerCase();
220
+ if (name === "tabIndex") return {
221
+ kind: "string-attribute",
222
+ name: "tabindex"
223
+ };
224
+ if (name === "htmlFor") return normalizedTag === "label" ? {
225
+ kind: "string-attribute",
226
+ name: "for"
227
+ } : void 0;
228
+ if (name === "value") {
229
+ if (normalizedTag === "textarea") return { kind: "text-content" };
230
+ return VALUE_PROPERTY_ELEMENTS.has(normalizedTag) ? {
231
+ kind: "string-attribute",
232
+ name: "value"
233
+ } : void 0;
234
+ }
235
+ if (!BOOLEAN_PROPERTY_ELEMENTS[name]?.has(normalizedTag)) return void 0;
236
+ return {
237
+ kind: "boolean-attribute",
238
+ name: name === "readOnly" ? "readonly" : name
239
+ };
240
+ }
241
+ function isSSRProperty(attribute) {
242
+ return attribute[SSR_PROPERTY] === true;
243
+ }
244
+ function removeAttribute(attributes, name) {
245
+ const normalizedName = name.toLowerCase();
246
+ for (let index = attributes.length - 1; index >= 0; index--) if (attributes[index].name.toLowerCase() === normalizedName) attributes.splice(index, 1);
247
+ }
248
+ function normalizeTabIndex(value) {
249
+ const number = Number(value);
250
+ return String(Number.isFinite(number) ? Math.trunc(number) : 0);
251
+ }
252
+ function normalizeTextareaValue(value) {
253
+ const normalized = String(value).replace(/\r\n?/g, "\n");
254
+ return normalized.startsWith("\n") ? `\n${normalized}` : normalized;
255
+ }
256
+ //#endregion
257
+ //#region packages/core/runtime-ssr/src/element.ts
258
+ const VOID_ELEMENTS = /* @__PURE__ */ new Set([
259
+ "area",
260
+ "base",
261
+ "br",
262
+ "col",
263
+ "embed",
264
+ "hr",
265
+ "img",
266
+ "input",
267
+ "link",
268
+ "meta",
269
+ "param",
270
+ "source",
271
+ "track",
272
+ "wbr"
273
+ ]);
274
+ function ssrElement(tag, attributes = [], children = null, isVoid = VOID_ELEMENTS.has(tag.toLowerCase())) {
275
+ const resolved = resolveSSRElementProperties(tag, attributes, children);
276
+ const opening = `<${tag}${serializeAttributes(resolved.attributes)}>`;
277
+ if (isVoid) return createSSRFragment(opening);
278
+ const normalizedTag = tag.toLowerCase();
279
+ return createSSRFragment(`${opening}${normalizedTag === "script" || normalizedTag === "style" ? serializeSSRRawText(resolved.children, normalizedTag) : serializeSSRNode(resolved.children)}</${tag}>`);
280
+ }
281
+ function ssrAttr(name, value) {
282
+ assertSyncSSRValue(value);
283
+ const normalizedName = normalizeAttributeName(name);
284
+ if (normalizedName === "class") {
285
+ const normalized = normalizeClass(value);
286
+ return normalized ? createSSRAttribute("class", normalized) : null;
287
+ }
288
+ if (normalizedName === "style") return createStyleAttribute(value);
289
+ if (value == null || value === false) return null;
290
+ return createSSRAttribute(normalizedName, value === true ? true : String(value));
291
+ }
292
+ function createStyleAttribute(value) {
293
+ assertSyncSSRValue(value);
294
+ if (value == null) return null;
295
+ if (typeof value === "string") return createSSRAttribute("style", value);
296
+ const declarations = [];
297
+ for (const [key, declarationValue] of Object.entries(value)) {
298
+ assertSyncSSRValue(declarationValue);
299
+ if (declarationValue == null) continue;
300
+ declarations.push(`${normalizeStyleName(key)}:${normalizeStyleValue(key, declarationValue)}`);
301
+ }
302
+ return declarations.length ? createSSRAttribute("style", declarations.join(";")) : null;
303
+ }
304
+ function ssrProp(name, value) {
305
+ return createSSRProperty(name, value);
306
+ }
307
+ function createSSRAttribute(name, value) {
308
+ return {
309
+ name,
310
+ value
311
+ };
312
+ }
313
+ function serializeAttributes(attributes) {
314
+ let html = "";
315
+ for (const attribute of attributes) {
316
+ assertSyncSSRValue(attribute);
317
+ if (!attribute) continue;
318
+ assertSyncSSRValue(attribute.value);
319
+ html += ` ${attribute.name}`;
320
+ if (attribute.value !== true) html += `="${escapeHTMLAttribute(attribute.value)}"`;
321
+ }
322
+ return html;
323
+ }
324
+ function normalizeAttributeName(name) {
325
+ return name === "className" ? "class" : name;
326
+ }
327
+ function normalizeClass(value) {
328
+ assertSyncSSRValue(value);
329
+ if (!value) return "";
330
+ if (typeof value === "string") return value;
331
+ if (Array.isArray(value)) return value.map(normalizeClass).filter(Boolean).join(" ");
332
+ const tokens = value;
333
+ return Object.keys(tokens).filter((key) => {
334
+ assertSyncSSRValue(tokens[key]);
335
+ return tokens[key];
336
+ }).join(" ");
337
+ }
338
+ function normalizeStyleName(name) {
339
+ if (name.startsWith("--")) return name;
340
+ return name.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`);
341
+ }
342
+ function normalizeStyleValue(name, value) {
343
+ if (typeof value === "number" && value !== 0 && !name.startsWith("--") && !UNITLESS_STYLES.has(name)) return `${value}px`;
344
+ return String(value);
345
+ }
346
+ const UNITLESS_STYLES = /* @__PURE__ */ new Set([
347
+ "opacity",
348
+ "zIndex",
349
+ "fontWeight",
350
+ "lineHeight",
351
+ "flex",
352
+ "flexGrow",
353
+ "flexShrink",
354
+ "order"
355
+ ]);
356
+ //#endregion
357
+ //#region packages/core/runtime-ssr/src/component.ts
358
+ function ssrComponent(component, props) {
359
+ return component(props);
360
+ }
361
+ //#endregion
362
+ //#region packages/core/runtime-ssr/src/controlFlow.ts
363
+ function ssrShow(when, children, fallback) {
364
+ return resolve(when) ? resolve(children) : resolve(fallback) ?? null;
365
+ }
366
+ function Show(props) {
367
+ return resolve(props.when ? props.children : props.fallback) ?? null;
368
+ }
369
+ function ssrFor(each, render) {
370
+ return resolve(each)?.map((item, index) => render(item, index)) ?? null;
371
+ }
372
+ function For(props) {
373
+ return ssrFor(props.each, props.children);
374
+ }
375
+ function resolve(value) {
376
+ return typeof value === "function" ? value() : value;
377
+ }
378
+ //#endregion
379
+ export { For, Show, renderToString, ssrAttr, ssrComponent, ssrElement, ssrFor, ssrProp, ssrShow, ssrStatic, ssrText };
@@ -0,0 +1,393 @@
1
+ /**
2
+ * runtime-ssr v0.1.0-canary.20260805.97.1.fa5d9cef
3
+ * (c) 2026 baicie
4
+ * Released under the MIT License.
5
+ **/
6
+ Object.defineProperties(exports, {
7
+ __esModule: { value: true },
8
+ [Symbol.toStringTag]: { value: "Module" }
9
+ });
10
+ let _zeus_js_signal = require("@zeus-js/signal");
11
+ //#region packages/core/runtime-ssr/src/serialize.ts
12
+ const SSR_FRAGMENT = Symbol.for("zeus.ssr.fragment");
13
+ const RAW_TEXT_END_TAG = {
14
+ script: /<\/script(?=[\t\n\f\r />]|$)/gi,
15
+ style: /<\/style(?=[\t\n\f\r />]|$)/gi
16
+ };
17
+ const RAW_TEXT_ESCAPE = {
18
+ script: "\\u003C",
19
+ style: "\\3C "
20
+ };
21
+ function createSSRFragment(html) {
22
+ return Object.freeze({
23
+ [SSR_FRAGMENT]: true,
24
+ html
25
+ });
26
+ }
27
+ function isSSRFragment(value) {
28
+ return typeof value === "object" && value !== null && value[SSR_FRAGMENT] === true;
29
+ }
30
+ function escapeHTMLText(value) {
31
+ return value.replace(/[&<>]/g, (character) => TEXT_ESCAPE[character]);
32
+ }
33
+ function escapeHTMLAttribute(value) {
34
+ return value.replace(/[&"<>]/g, (character) => ATTRIBUTE_ESCAPE[character]);
35
+ }
36
+ function assertSyncSSRValue(value) {
37
+ if (!isPromiseLike(value)) return;
38
+ Promise.resolve(value).catch(() => {});
39
+ throw new TypeError("renderToString() does not support async render values.");
40
+ }
41
+ const TEXT_ESCAPE = {
42
+ "&": "&amp;",
43
+ "<": "&lt;",
44
+ ">": "&gt;"
45
+ };
46
+ const ATTRIBUTE_ESCAPE = {
47
+ "&": "&amp;",
48
+ "\"": "&quot;",
49
+ "<": "&lt;",
50
+ ">": "&gt;"
51
+ };
52
+ function serializeSSRNode(value) {
53
+ assertSyncSSRValue(value);
54
+ if (isSSRFragment(value)) return value.html;
55
+ if (Array.isArray(value)) {
56
+ let html = "";
57
+ for (const child of value) html += serializeSSRNode(child);
58
+ return html;
59
+ }
60
+ if (value == null || typeof value === "boolean") return "";
61
+ if (typeof value === "string") return escapeHTMLText(value);
62
+ if (typeof value === "number") return String(value);
63
+ throw new TypeError("renderToString() received an unsupported SSR value.");
64
+ }
65
+ function serializeSSRRawText(value, tag) {
66
+ return escapeSSRRawText(serializeSSRRawTextValue(value, tag), tag);
67
+ }
68
+ function serializeSSRRawTextValue(value, tag) {
69
+ assertSyncSSRValue(value);
70
+ if (isSSRFragment(value)) throw new TypeError(`renderToString() does not support serialized fragments inside <${tag}> raw text.`);
71
+ if (Array.isArray(value)) {
72
+ let text = "";
73
+ for (const child of value) text += serializeSSRRawTextValue(child, tag);
74
+ return text;
75
+ }
76
+ if (value == null || typeof value === "boolean") return "";
77
+ if (typeof value === "string") return value;
78
+ if (typeof value === "number") return String(value);
79
+ throw new TypeError("renderToString() received an unsupported SSR value.");
80
+ }
81
+ function escapeSSRRawText(value, tag) {
82
+ if (tag === "script") return escapeSSRScriptText(value);
83
+ return value.replace(RAW_TEXT_END_TAG[tag], (match) => `${RAW_TEXT_ESCAPE[tag]}${match.slice(1)}`);
84
+ }
85
+ function escapeSSRScriptText(value) {
86
+ let escaped = false;
87
+ let result = "";
88
+ for (let index = 0; index < value.length;) {
89
+ if (matchesRawTextTag(value, index, "script", true)) {
90
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 8)}`;
91
+ index += 8;
92
+ continue;
93
+ }
94
+ if (!escaped && value.startsWith("<!--", index)) {
95
+ result += "<!--";
96
+ escaped = true;
97
+ index += 4;
98
+ continue;
99
+ }
100
+ if (escaped && value.startsWith("-->", index)) {
101
+ result += "-->";
102
+ escaped = false;
103
+ index += 3;
104
+ continue;
105
+ }
106
+ if (escaped && matchesRawTextTag(value, index, "script", false)) {
107
+ result += `${RAW_TEXT_ESCAPE.script}${value.slice(index + 1, index + 7)}`;
108
+ index += 7;
109
+ continue;
110
+ }
111
+ result += value[index];
112
+ index++;
113
+ }
114
+ return result;
115
+ }
116
+ function matchesRawTextTag(value, index, tag, closing) {
117
+ const prefix = `${closing ? "</" : "<"}${tag}`;
118
+ if (value.slice(index, index + prefix.length).toLowerCase() !== prefix) return false;
119
+ const delimiter = value[index + prefix.length];
120
+ return delimiter === void 0 || /[\t\n\f\r />]/.test(delimiter);
121
+ }
122
+ function isPromiseLike(value) {
123
+ return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
124
+ }
125
+ //#endregion
126
+ //#region packages/core/runtime-ssr/src/render.ts
127
+ function renderToString(input) {
128
+ if (typeof input !== "function") throw new TypeError("renderToString() expects a synchronous render function.");
129
+ return (0, _zeus_js_signal.createRoot)((dispose) => {
130
+ try {
131
+ return serializeSSRNode(input());
132
+ } finally {
133
+ dispose();
134
+ }
135
+ });
136
+ }
137
+ //#endregion
138
+ //#region packages/core/runtime-ssr/src/text.ts
139
+ function ssrStatic(html) {
140
+ return createSSRFragment(html);
141
+ }
142
+ function ssrText(value) {
143
+ return createSSRFragment(serializeSSRNode(value));
144
+ }
145
+ //#endregion
146
+ //#region packages/core/runtime-ssr/src/property.ts
147
+ const SSR_PROPERTY = Symbol.for("zeus.ssr.property");
148
+ const BOOLEAN_PROPERTY_ELEMENTS = {
149
+ checked: /* @__PURE__ */ new Set(["input"]),
150
+ disabled: /* @__PURE__ */ new Set([
151
+ "button",
152
+ "fieldset",
153
+ "input",
154
+ "optgroup",
155
+ "option",
156
+ "select",
157
+ "textarea"
158
+ ]),
159
+ multiple: /* @__PURE__ */ new Set(["input", "select"]),
160
+ readOnly: /* @__PURE__ */ new Set(["input", "textarea"]),
161
+ selected: /* @__PURE__ */ new Set(["option"])
162
+ };
163
+ const VALUE_PROPERTY_ELEMENTS = /* @__PURE__ */ new Set([
164
+ "button",
165
+ "input",
166
+ "option"
167
+ ]);
168
+ const SUPPORTED_PROPERTY_NAMES = /* @__PURE__ */ new Set([
169
+ ...Object.keys(BOOLEAN_PROPERTY_ELEMENTS),
170
+ "htmlFor",
171
+ "tabIndex",
172
+ "value"
173
+ ]);
174
+ function createSSRProperty(name, value) {
175
+ assertSyncSSRValue(value);
176
+ if (!SUPPORTED_PROPERTY_NAMES.has(name)) throw new TypeError(`SSR cannot serialize property "${name}".`);
177
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") return null;
178
+ return {
179
+ [SSR_PROPERTY]: true,
180
+ name,
181
+ propertyValue: value,
182
+ value: value === true ? true : String(value)
183
+ };
184
+ }
185
+ function resolveSSRElementProperties(tag, entries, children) {
186
+ const attributes = [];
187
+ const properties = [];
188
+ for (const entry of entries) {
189
+ assertSyncSSRValue(entry);
190
+ if (!entry) continue;
191
+ assertSyncSSRValue(entry.value);
192
+ if (isSSRProperty(entry)) properties.push(entry);
193
+ else attributes.push(entry);
194
+ }
195
+ let resolvedChildren = children;
196
+ for (const property of properties) {
197
+ const serialization = getSSRPropertySerialization(tag, property.name);
198
+ if (!serialization) throw new TypeError(`SSR cannot serialize property "${property.name}" on <${tag}>.`);
199
+ if (serialization.kind === "text-content") {
200
+ removeAttribute(attributes, "value");
201
+ resolvedChildren = normalizeTextareaValue(property.propertyValue);
202
+ continue;
203
+ }
204
+ removeAttribute(attributes, serialization.name);
205
+ if (serialization.kind === "boolean-attribute") {
206
+ if (Boolean(property.propertyValue)) attributes.push({
207
+ name: serialization.name,
208
+ value: true
209
+ });
210
+ continue;
211
+ }
212
+ attributes.push({
213
+ name: serialization.name,
214
+ value: property.name === "tabIndex" ? normalizeTabIndex(property.propertyValue) : String(property.propertyValue)
215
+ });
216
+ }
217
+ return {
218
+ attributes,
219
+ children: resolvedChildren
220
+ };
221
+ }
222
+ function getSSRPropertySerialization(tag, name) {
223
+ const normalizedTag = tag.toLowerCase();
224
+ if (name === "tabIndex") return {
225
+ kind: "string-attribute",
226
+ name: "tabindex"
227
+ };
228
+ if (name === "htmlFor") return normalizedTag === "label" ? {
229
+ kind: "string-attribute",
230
+ name: "for"
231
+ } : void 0;
232
+ if (name === "value") {
233
+ if (normalizedTag === "textarea") return { kind: "text-content" };
234
+ return VALUE_PROPERTY_ELEMENTS.has(normalizedTag) ? {
235
+ kind: "string-attribute",
236
+ name: "value"
237
+ } : void 0;
238
+ }
239
+ if (!BOOLEAN_PROPERTY_ELEMENTS[name]?.has(normalizedTag)) return void 0;
240
+ return {
241
+ kind: "boolean-attribute",
242
+ name: name === "readOnly" ? "readonly" : name
243
+ };
244
+ }
245
+ function isSSRProperty(attribute) {
246
+ return attribute[SSR_PROPERTY] === true;
247
+ }
248
+ function removeAttribute(attributes, name) {
249
+ const normalizedName = name.toLowerCase();
250
+ for (let index = attributes.length - 1; index >= 0; index--) if (attributes[index].name.toLowerCase() === normalizedName) attributes.splice(index, 1);
251
+ }
252
+ function normalizeTabIndex(value) {
253
+ const number = Number(value);
254
+ return String(Number.isFinite(number) ? Math.trunc(number) : 0);
255
+ }
256
+ function normalizeTextareaValue(value) {
257
+ const normalized = String(value).replace(/\r\n?/g, "\n");
258
+ return normalized.startsWith("\n") ? `\n${normalized}` : normalized;
259
+ }
260
+ //#endregion
261
+ //#region packages/core/runtime-ssr/src/element.ts
262
+ const VOID_ELEMENTS = /* @__PURE__ */ new Set([
263
+ "area",
264
+ "base",
265
+ "br",
266
+ "col",
267
+ "embed",
268
+ "hr",
269
+ "img",
270
+ "input",
271
+ "link",
272
+ "meta",
273
+ "param",
274
+ "source",
275
+ "track",
276
+ "wbr"
277
+ ]);
278
+ function ssrElement(tag, attributes = [], children = null, isVoid = VOID_ELEMENTS.has(tag.toLowerCase())) {
279
+ const resolved = resolveSSRElementProperties(tag, attributes, children);
280
+ const opening = `<${tag}${serializeAttributes(resolved.attributes)}>`;
281
+ if (isVoid) return createSSRFragment(opening);
282
+ const normalizedTag = tag.toLowerCase();
283
+ return createSSRFragment(`${opening}${normalizedTag === "script" || normalizedTag === "style" ? serializeSSRRawText(resolved.children, normalizedTag) : serializeSSRNode(resolved.children)}</${tag}>`);
284
+ }
285
+ function ssrAttr(name, value) {
286
+ assertSyncSSRValue(value);
287
+ const normalizedName = normalizeAttributeName(name);
288
+ if (normalizedName === "class") {
289
+ const normalized = normalizeClass(value);
290
+ return normalized ? createSSRAttribute("class", normalized) : null;
291
+ }
292
+ if (normalizedName === "style") return createStyleAttribute(value);
293
+ if (value == null || value === false) return null;
294
+ return createSSRAttribute(normalizedName, value === true ? true : String(value));
295
+ }
296
+ function createStyleAttribute(value) {
297
+ assertSyncSSRValue(value);
298
+ if (value == null) return null;
299
+ if (typeof value === "string") return createSSRAttribute("style", value);
300
+ const declarations = [];
301
+ for (const [key, declarationValue] of Object.entries(value)) {
302
+ assertSyncSSRValue(declarationValue);
303
+ if (declarationValue == null) continue;
304
+ declarations.push(`${normalizeStyleName(key)}:${normalizeStyleValue(key, declarationValue)}`);
305
+ }
306
+ return declarations.length ? createSSRAttribute("style", declarations.join(";")) : null;
307
+ }
308
+ function ssrProp(name, value) {
309
+ return createSSRProperty(name, value);
310
+ }
311
+ function createSSRAttribute(name, value) {
312
+ return {
313
+ name,
314
+ value
315
+ };
316
+ }
317
+ function serializeAttributes(attributes) {
318
+ let html = "";
319
+ for (const attribute of attributes) {
320
+ assertSyncSSRValue(attribute);
321
+ if (!attribute) continue;
322
+ assertSyncSSRValue(attribute.value);
323
+ html += ` ${attribute.name}`;
324
+ if (attribute.value !== true) html += `="${escapeHTMLAttribute(attribute.value)}"`;
325
+ }
326
+ return html;
327
+ }
328
+ function normalizeAttributeName(name) {
329
+ return name === "className" ? "class" : name;
330
+ }
331
+ function normalizeClass(value) {
332
+ assertSyncSSRValue(value);
333
+ if (!value) return "";
334
+ if (typeof value === "string") return value;
335
+ if (Array.isArray(value)) return value.map(normalizeClass).filter(Boolean).join(" ");
336
+ const tokens = value;
337
+ return Object.keys(tokens).filter((key) => {
338
+ assertSyncSSRValue(tokens[key]);
339
+ return tokens[key];
340
+ }).join(" ");
341
+ }
342
+ function normalizeStyleName(name) {
343
+ if (name.startsWith("--")) return name;
344
+ return name.replace(/[A-Z]/g, (character) => `-${character.toLowerCase()}`);
345
+ }
346
+ function normalizeStyleValue(name, value) {
347
+ if (typeof value === "number" && value !== 0 && !name.startsWith("--") && !UNITLESS_STYLES.has(name)) return `${value}px`;
348
+ return String(value);
349
+ }
350
+ const UNITLESS_STYLES = /* @__PURE__ */ new Set([
351
+ "opacity",
352
+ "zIndex",
353
+ "fontWeight",
354
+ "lineHeight",
355
+ "flex",
356
+ "flexGrow",
357
+ "flexShrink",
358
+ "order"
359
+ ]);
360
+ //#endregion
361
+ //#region packages/core/runtime-ssr/src/component.ts
362
+ function ssrComponent(component, props) {
363
+ return component(props);
364
+ }
365
+ //#endregion
366
+ //#region packages/core/runtime-ssr/src/controlFlow.ts
367
+ function ssrShow(when, children, fallback) {
368
+ return resolve(when) ? resolve(children) : resolve(fallback) ?? null;
369
+ }
370
+ function Show(props) {
371
+ return resolve(props.when ? props.children : props.fallback) ?? null;
372
+ }
373
+ function ssrFor(each, render) {
374
+ return resolve(each)?.map((item, index) => render(item, index)) ?? null;
375
+ }
376
+ function For(props) {
377
+ return ssrFor(props.each, props.children);
378
+ }
379
+ function resolve(value) {
380
+ return typeof value === "function" ? value() : value;
381
+ }
382
+ //#endregion
383
+ exports.For = For;
384
+ exports.Show = Show;
385
+ exports.renderToString = renderToString;
386
+ exports.ssrAttr = ssrAttr;
387
+ exports.ssrComponent = ssrComponent;
388
+ exports.ssrElement = ssrElement;
389
+ exports.ssrFor = ssrFor;
390
+ exports.ssrProp = ssrProp;
391
+ exports.ssrShow = ssrShow;
392
+ exports.ssrStatic = ssrStatic;
393
+ exports.ssrText = ssrText;
package/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ if (process.env.NODE_ENV === 'production') {
4
+ module.exports = require('./dist/runtime-ssr.prod.cjs')
5
+ } else {
6
+ module.exports = require('./dist/runtime-ssr.cjs')
7
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@zeus-js/runtime-ssr",
3
+ "type": "module",
4
+ "version": "0.1.0-canary.20260805.97.1.fa5d9cef",
5
+ "description": "Server-side string rendering runtime for Zeus",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/baicie/zeus.git",
10
+ "directory": "packages/core/runtime-ssr"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "provenance": true
15
+ },
16
+ "sideEffects": false,
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/runtime-ssr.d.ts",
20
+ "module": "./dist/runtime-ssr.esm-bundler.js",
21
+ "import": "./dist/runtime-ssr.esm-bundler.js",
22
+ "require": {
23
+ "production": "./dist/runtime-ssr.prod.cjs",
24
+ "development": "./dist/runtime-ssr.cjs",
25
+ "default": "./index.cjs"
26
+ }
27
+ }
28
+ },
29
+ "files": [
30
+ "index.cjs",
31
+ "dist"
32
+ ],
33
+ "dependencies": {
34
+ "@zeus-js/signal": "0.1.0-canary.20260805.97.1.fa5d9cef"
35
+ },
36
+ "buildOptions": {
37
+ "name": "ZeusRuntimeSSR",
38
+ "formats": [
39
+ "esm-bundler",
40
+ "cjs"
41
+ ],
42
+ "target": "es2022"
43
+ },
44
+ "engines": {
45
+ "node": "^22.18.0 || >=24.11.0"
46
+ },
47
+ "main": "index.cjs",
48
+ "module": "dist/runtime-ssr.esm-bundler.js",
49
+ "types": "dist/runtime-ssr.d.ts"
50
+ }