@fluixi/dom 1.0.0-alpha.83 → 1.0.0-alpha.85
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/cdn/dom-client.cjs +1427 -1
- package/dist/cdn/dom-client.d.ts +2 -2
- package/dist/cdn/dom-client.global.js +2 -1
- package/dist/cdn/dom-client.js +3 -3
- package/dist/cdn/dom-client.mjs +1430 -1
- package/dist/cdn/dom.cjs +3127 -1
- package/dist/cdn/dom.d.ts +2 -2
- package/dist/cdn/dom.global.js +2 -1
- package/dist/cdn/dom.js +4 -4
- package/dist/cdn/dom.mjs +3133 -1
- package/dist/index.cjs +3155 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +3149 -1
- package/dist/lib/component/index.cjs +128 -1
- package/dist/lib/component/index.mjs +105 -1
- package/dist/lib/component/modifiers.cjs +126 -1
- package/dist/lib/component/modifiers.d.ts +12 -0
- package/dist/lib/component/modifiers.d.ts.map +1 -1
- package/dist/lib/component/modifiers.js +12 -84
- package/dist/lib/component/modifiers.mjs +105 -1
- package/dist/lib/dom/delegate.cjs +60 -1
- package/dist/lib/dom/delegate.js +1 -1
- package/dist/lib/dom/delegate.mjs +39 -1
- package/dist/lib/dom/dynamic-element.cjs +949 -1
- package/dist/lib/dom/dynamic-element.d.ts +3 -3
- package/dist/lib/dom/dynamic-element.js +2 -2
- package/dist/lib/dom/dynamic-element.mjs +928 -1
- package/dist/lib/dom/hydration-state.cjs +93 -1
- package/dist/lib/dom/hydration-state.d.ts +1 -1
- package/dist/lib/dom/hydration-state.js +1 -1
- package/dist/lib/dom/hydration-state.mjs +72 -1
- package/dist/lib/dom/hydration.cjs +685 -1
- package/dist/lib/dom/hydration.js +8 -8
- package/dist/lib/dom/hydration.mjs +664 -1
- package/dist/lib/dom/index.cjs +2040 -1
- package/dist/lib/dom/index.js +1 -1
- package/dist/lib/dom/index.mjs +2020 -1
- package/dist/lib/dom/integration.cjs +71 -1
- package/dist/lib/dom/integration.js +3 -3
- package/dist/lib/dom/integration.mjs +51 -1
- package/dist/lib/dom/island.cjs +790 -1
- package/dist/lib/dom/island.d.ts +1 -1
- package/dist/lib/dom/island.js +11 -11
- package/dist/lib/dom/island.mjs +769 -1
- package/dist/lib/dom/runtime.cjs +1432 -1
- package/dist/lib/dom/runtime.d.ts +60 -17
- package/dist/lib/dom/runtime.d.ts.map +1 -1
- package/dist/lib/dom/runtime.js +122 -79
- package/dist/lib/dom/runtime.mjs +1414 -1
- package/dist/lib/dom/server/fx-data.cjs +53 -1
- package/dist/lib/dom/server/fx-data.d.ts +5 -5
- package/dist/lib/dom/server/fx-data.js +6 -6
- package/dist/lib/dom/server/fx-data.mjs +32 -1
- package/dist/lib/dom/server/host.cjs +66 -1
- package/dist/lib/dom/server/host.d.ts +6 -0
- package/dist/lib/dom/server/host.d.ts.map +1 -1
- package/dist/lib/dom/server/host.js +7 -1
- package/dist/lib/dom/server/host.mjs +45 -1
- package/dist/lib/dom/server/index.cjs +759 -1
- package/dist/lib/dom/server/index.d.ts +1 -1
- package/dist/lib/dom/server/index.js +1 -1
- package/dist/lib/dom/server/index.mjs +743 -1
- package/dist/lib/dom/server/nodes.cjs +302 -1
- package/dist/lib/dom/server/nodes.d.ts +2 -2
- package/dist/lib/dom/server/nodes.d.ts.map +1 -1
- package/dist/lib/dom/server/nodes.js +4 -4
- package/dist/lib/dom/server/nodes.mjs +279 -1
- package/dist/lib/dom/server/parse-template.cjs +395 -1
- package/dist/lib/dom/server/parse-template.d.ts +1 -1
- package/dist/lib/dom/server/parse-template.js +4 -4
- package/dist/lib/dom/server/parse-template.mjs +372 -1
- package/dist/lib/dom/server/render.cjs +691 -1
- package/dist/lib/dom/server/render.d.ts +9 -1
- package/dist/lib/dom/server/render.d.ts.map +1 -1
- package/dist/lib/dom/server/render.js +23 -15
- package/dist/lib/dom/server/render.mjs +677 -1
- package/dist/lib/dom/server/request-context.cjs +110 -1
- package/dist/lib/dom/server/request-context.d.ts +29 -9
- package/dist/lib/dom/server/request-context.d.ts.map +1 -1
- package/dist/lib/dom/server/request-context.js +28 -8
- package/dist/lib/dom/server/request-context.mjs +89 -1
- package/dist/lib/dom/server/serialize.cjs +187 -1
- package/dist/lib/dom/server/serialize.js +3 -3
- package/dist/lib/dom/server/serialize.mjs +164 -1
- package/dist/lib/dom/server-renderer.cjs +760 -1
- package/dist/lib/dom/server-renderer.js +1 -1
- package/dist/lib/dom/server-renderer.mjs +745 -1
- package/dist/lib/dom/types.cjs +18 -1
- package/dist/lib/dom/utils.cjs +381 -1
- package/dist/lib/dom/utils.d.ts +1 -88
- package/dist/lib/dom/utils.d.ts.map +1 -1
- package/dist/lib/dom/utils.js +2 -99
- package/dist/lib/dom/utils.mjs +361 -1
- package/dist/lib/dom/versions.cjs +60 -1
- package/dist/lib/dom/versions.d.ts +3 -3
- package/dist/lib/dom/versions.d.ts.map +1 -1
- package/dist/lib/dom/versions.js +17 -5
- package/dist/lib/dom/versions.mjs +37 -1
- package/dist/lib/element/attributes.cjs +19 -1
- package/dist/lib/element/attributes.d.ts +7 -7
- package/dist/lib/element/attributes.js +1 -1
- package/dist/lib/element/attributes.mjs +1 -0
- package/dist/lib/element/index.cjs +19 -1
- package/dist/lib/element/index.mjs +1 -0
- package/dist/lib/element/types.cjs +18 -1
- package/dist/lib/element/types.d.ts +4 -5
- package/dist/lib/element/types.d.ts.map +1 -1
- package/dist/lib/element/types.js +0 -1
- package/dist/lib/flow/class-map.cjs +38 -1
- package/dist/lib/flow/class-map.d.ts +3 -3
- package/dist/lib/flow/class-map.js +2 -2
- package/dist/lib/flow/class-map.mjs +17 -1
- package/dist/lib/flow/client-only.cjs +57 -1
- package/dist/lib/flow/client-only.d.ts +4 -4
- package/dist/lib/flow/client-only.js +3 -3
- package/dist/lib/flow/client-only.mjs +36 -1
- package/dist/lib/flow/dynamic.cjs +53 -1
- package/dist/lib/flow/dynamic.d.ts +2 -2
- package/dist/lib/flow/dynamic.js +3 -3
- package/dist/lib/flow/dynamic.mjs +32 -1
- package/dist/lib/flow/error-boundary.cjs +43 -1
- package/dist/lib/flow/error-boundary.d.ts +2 -2
- package/dist/lib/flow/error-boundary.js +3 -3
- package/dist/lib/flow/error-boundary.mjs +22 -1
- package/dist/lib/flow/for.cjs +66 -1
- package/dist/lib/flow/for.d.ts +9 -9
- package/dist/lib/flow/for.d.ts.map +1 -1
- package/dist/lib/flow/for.js +2 -2
- package/dist/lib/flow/for.mjs +45 -1
- package/dist/lib/flow/index-flow.cjs +67 -1
- package/dist/lib/flow/index-flow.d.ts +5 -5
- package/dist/lib/flow/index-flow.js +4 -4
- package/dist/lib/flow/index-flow.mjs +46 -1
- package/dist/lib/flow/index.cjs +805 -1
- package/dist/lib/flow/index.mjs +792 -1
- package/dist/lib/flow/portal.cjs +538 -1
- package/dist/lib/flow/portal.mjs +519 -1
- package/dist/lib/flow/show.cjs +81 -1
- package/dist/lib/flow/show.d.ts +1 -1
- package/dist/lib/flow/show.d.ts.map +1 -1
- package/dist/lib/flow/show.js +4 -115
- package/dist/lib/flow/show.mjs +67 -1
- package/dist/lib/flow/style-map.cjs +43 -1
- package/dist/lib/flow/style-map.d.ts +3 -3
- package/dist/lib/flow/style-map.js +3 -3
- package/dist/lib/flow/style-map.mjs +22 -1
- package/dist/lib/flow/switch.cjs +91 -1
- package/dist/lib/flow/switch.d.ts +3 -3
- package/dist/lib/flow/switch.d.ts.map +1 -1
- package/dist/lib/flow/switch.js +6 -6
- package/dist/lib/flow/switch.mjs +70 -1
- package/dist/lib/flow/utils.cjs +44 -1
- package/dist/lib/flow/utils.d.ts +1 -1
- package/dist/lib/flow/utils.js +1 -1
- package/dist/lib/flow/utils.mjs +23 -1
- package/dist/lib/html.cjs +32 -1
- package/dist/lib/html.d.ts +6 -6
- package/dist/lib/html.js +5 -5
- package/dist/lib/html.mjs +11 -1
- package/dist/lib/index.cjs +3104 -1
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -3
- package/dist/lib/index.mjs +3097 -1
- package/dist/lib/shared/types.cjs +18 -1
- package/dist/lib/shared/types.d.ts +8 -8
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/version.generated.cjs +26 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +2 -2
- package/dist/version.generated.mjs +5 -1
- package/package.json +7 -6
- package/dist/lib/jsx/control-flow/flow.cjs +0 -1
- package/dist/lib/jsx/control-flow/flow.d.ts +0 -2
- package/dist/lib/jsx/control-flow/flow.d.ts.map +0 -1
- package/dist/lib/jsx/control-flow/flow.js +0 -627
- package/dist/lib/jsx/control-flow/flow.mjs +0 -0
- package/dist/lib/jsx/control-flow/for-flow.cjs +0 -1
- package/dist/lib/jsx/control-flow/for-flow.d.ts +0 -2
- package/dist/lib/jsx/control-flow/for-flow.d.ts.map +0 -1
- package/dist/lib/jsx/control-flow/for-flow.js +0 -1
- package/dist/lib/jsx/control-flow/for-flow.mjs +0 -0
|
@@ -1 +1,677 @@
|
|
|
1
|
-
|
|
1
|
+
// src/lib/dom/server/render.ts
|
|
2
|
+
import { createRoot } from "@fluixi/reactive/signal";
|
|
3
|
+
import {
|
|
4
|
+
setResourceTracker,
|
|
5
|
+
setResourceIdSource,
|
|
6
|
+
setResourceDataSink,
|
|
7
|
+
getOwner,
|
|
8
|
+
runWithOwner,
|
|
9
|
+
flush
|
|
10
|
+
} from "@fluixi/reactive/signal";
|
|
11
|
+
|
|
12
|
+
// src/lib/dom/server/host.ts
|
|
13
|
+
var SERVER_NODE = /* @__PURE__ */ Symbol.for("fluixi.server-node");
|
|
14
|
+
var STATE = /* @__PURE__ */ Symbol.for("fluixi.dom.server-host");
|
|
15
|
+
var realm = globalThis;
|
|
16
|
+
var state = realm[STATE] ??= {
|
|
17
|
+
server: typeof document === "undefined",
|
|
18
|
+
nodes: null
|
|
19
|
+
};
|
|
20
|
+
function isServer() {
|
|
21
|
+
return state.server;
|
|
22
|
+
}
|
|
23
|
+
function setServerMode(on) {
|
|
24
|
+
state.server = on;
|
|
25
|
+
}
|
|
26
|
+
function registerServerNodes(factory) {
|
|
27
|
+
state.nodes = factory;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/lib/dom/server/nodes.ts
|
|
31
|
+
var NODE_ELEMENT = 1;
|
|
32
|
+
var NODE_TEXT = 3;
|
|
33
|
+
var NODE_COMMENT = 8;
|
|
34
|
+
var _a;
|
|
35
|
+
_a = SERVER_NODE;
|
|
36
|
+
var ServerNode = class {
|
|
37
|
+
constructor() {
|
|
38
|
+
// Brand the host.ts guards check for (lets them skip an instanceof on these classes).
|
|
39
|
+
this[_a] = true;
|
|
40
|
+
this.parentNode = null;
|
|
41
|
+
this.childNodes = [];
|
|
42
|
+
}
|
|
43
|
+
get firstChild() {
|
|
44
|
+
return this.childNodes[0] ?? null;
|
|
45
|
+
}
|
|
46
|
+
get lastChild() {
|
|
47
|
+
return this.childNodes[this.childNodes.length - 1] ?? null;
|
|
48
|
+
}
|
|
49
|
+
get nextSibling() {
|
|
50
|
+
const p = this.parentNode;
|
|
51
|
+
if (!p) return null;
|
|
52
|
+
const i = p.childNodes.indexOf(this);
|
|
53
|
+
return i >= 0 ? p.childNodes[i + 1] ?? null : null;
|
|
54
|
+
}
|
|
55
|
+
get previousSibling() {
|
|
56
|
+
const p = this.parentNode;
|
|
57
|
+
if (!p) return null;
|
|
58
|
+
const i = p.childNodes.indexOf(this);
|
|
59
|
+
return i > 0 ? p.childNodes[i - 1] ?? null : null;
|
|
60
|
+
}
|
|
61
|
+
get parentElement() {
|
|
62
|
+
return this.parentNode;
|
|
63
|
+
}
|
|
64
|
+
appendChild(child) {
|
|
65
|
+
if (child.parentNode) child.parentNode.removeChild(child);
|
|
66
|
+
child.parentNode = this;
|
|
67
|
+
this.childNodes.push(child);
|
|
68
|
+
return child;
|
|
69
|
+
}
|
|
70
|
+
insertBefore(child, ref) {
|
|
71
|
+
if (ref == null) return this.appendChild(child);
|
|
72
|
+
if (child.parentNode) child.parentNode.removeChild(child);
|
|
73
|
+
const i = this.childNodes.indexOf(ref);
|
|
74
|
+
child.parentNode = this;
|
|
75
|
+
if (i < 0) this.childNodes.push(child);
|
|
76
|
+
else this.childNodes.splice(i, 0, child);
|
|
77
|
+
return child;
|
|
78
|
+
}
|
|
79
|
+
removeChild(child) {
|
|
80
|
+
const i = this.childNodes.indexOf(child);
|
|
81
|
+
if (i >= 0) this.childNodes.splice(i, 1);
|
|
82
|
+
child.parentNode = null;
|
|
83
|
+
return child;
|
|
84
|
+
}
|
|
85
|
+
replaceChild(next, old) {
|
|
86
|
+
const i = this.childNodes.indexOf(old);
|
|
87
|
+
if (i >= 0) {
|
|
88
|
+
if (next.parentNode) next.parentNode.removeChild(next);
|
|
89
|
+
next.parentNode = this;
|
|
90
|
+
this.childNodes[i] = next;
|
|
91
|
+
old.parentNode = null;
|
|
92
|
+
}
|
|
93
|
+
return old;
|
|
94
|
+
}
|
|
95
|
+
// Event listeners are inert on the server.
|
|
96
|
+
addEventListener() {
|
|
97
|
+
}
|
|
98
|
+
removeEventListener() {
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var ServerText = class _ServerText extends ServerNode {
|
|
102
|
+
constructor(value) {
|
|
103
|
+
super();
|
|
104
|
+
this.nodeType = NODE_TEXT;
|
|
105
|
+
this.data = value;
|
|
106
|
+
}
|
|
107
|
+
get nodeValue() {
|
|
108
|
+
return this.data;
|
|
109
|
+
}
|
|
110
|
+
set nodeValue(v) {
|
|
111
|
+
this.data = v == null ? "" : String(v);
|
|
112
|
+
}
|
|
113
|
+
get textContent() {
|
|
114
|
+
return this.data;
|
|
115
|
+
}
|
|
116
|
+
set textContent(v) {
|
|
117
|
+
this.data = v == null ? "" : String(v);
|
|
118
|
+
}
|
|
119
|
+
cloneNode() {
|
|
120
|
+
return new _ServerText(this.data);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var ServerRaw = class _ServerRaw extends ServerNode {
|
|
124
|
+
constructor(html) {
|
|
125
|
+
super();
|
|
126
|
+
this.nodeType = NODE_ELEMENT;
|
|
127
|
+
this.rawOuterHTML = html;
|
|
128
|
+
}
|
|
129
|
+
get textContent() {
|
|
130
|
+
return this.rawOuterHTML.replace(/<[^>]*>/g, "");
|
|
131
|
+
}
|
|
132
|
+
cloneNode() {
|
|
133
|
+
return new _ServerRaw(this.rawOuterHTML);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var ServerComment = class _ServerComment extends ServerNode {
|
|
137
|
+
constructor(value) {
|
|
138
|
+
super();
|
|
139
|
+
this.nodeType = NODE_COMMENT;
|
|
140
|
+
this.data = value;
|
|
141
|
+
}
|
|
142
|
+
get nodeValue() {
|
|
143
|
+
return this.data;
|
|
144
|
+
}
|
|
145
|
+
set nodeValue(v) {
|
|
146
|
+
this.data = v == null ? "" : String(v);
|
|
147
|
+
}
|
|
148
|
+
cloneNode() {
|
|
149
|
+
return new _ServerComment(this.data);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
var ServerStyle = class {
|
|
153
|
+
constructor() {
|
|
154
|
+
// declared keys are stored as own props; cssText holds a raw string blob.
|
|
155
|
+
this.cssText = "";
|
|
156
|
+
}
|
|
157
|
+
setProperty(name, value) {
|
|
158
|
+
this[name] = value;
|
|
159
|
+
}
|
|
160
|
+
removeProperty(name) {
|
|
161
|
+
delete this[name];
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
var ServerClassList = class {
|
|
165
|
+
constructor(el) {
|
|
166
|
+
this.el = el;
|
|
167
|
+
}
|
|
168
|
+
list() {
|
|
169
|
+
const c = this.el.getAttribute("class");
|
|
170
|
+
return c ? c.split(/\s+/).filter(Boolean) : [];
|
|
171
|
+
}
|
|
172
|
+
write(arr) {
|
|
173
|
+
if (arr.length) this.el.setAttribute("class", arr.join(" "));
|
|
174
|
+
else this.el.removeAttribute("class");
|
|
175
|
+
}
|
|
176
|
+
add(...names) {
|
|
177
|
+
const arr = this.list();
|
|
178
|
+
for (const n of names) if (!arr.includes(n)) arr.push(n);
|
|
179
|
+
this.write(arr);
|
|
180
|
+
}
|
|
181
|
+
remove(...names) {
|
|
182
|
+
this.write(this.list().filter((c) => !names.includes(c)));
|
|
183
|
+
}
|
|
184
|
+
contains(name) {
|
|
185
|
+
return this.list().includes(name);
|
|
186
|
+
}
|
|
187
|
+
toggle(name, force) {
|
|
188
|
+
const has = this.contains(name);
|
|
189
|
+
const on = force === void 0 ? !has : force;
|
|
190
|
+
if (on) this.add(name);
|
|
191
|
+
else this.remove(name);
|
|
192
|
+
return on;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
var ServerElement = class _ServerElement extends ServerNode {
|
|
196
|
+
constructor(tag, isSVG = false) {
|
|
197
|
+
super();
|
|
198
|
+
this.nodeType = NODE_ELEMENT;
|
|
199
|
+
this.attributes = /* @__PURE__ */ new Map();
|
|
200
|
+
this.style = new ServerStyle();
|
|
201
|
+
this.classList = new ServerClassList(this);
|
|
202
|
+
/** raw HTML set via innerHTML: emitted verbatim, bypassing childNodes. */
|
|
203
|
+
this.rawHTML = null;
|
|
204
|
+
this.localName = tag.toLowerCase();
|
|
205
|
+
this.tagName = isSVG ? tag : tag.toUpperCase();
|
|
206
|
+
this.isSVG = isSVG;
|
|
207
|
+
this.namespaceURI = isSVG ? "http://www.w3.org/2000/svg" : null;
|
|
208
|
+
}
|
|
209
|
+
setAttribute(name, value) {
|
|
210
|
+
this.attributes.set(name, String(value));
|
|
211
|
+
}
|
|
212
|
+
removeAttribute(name) {
|
|
213
|
+
this.attributes.delete(name);
|
|
214
|
+
}
|
|
215
|
+
getAttribute(name) {
|
|
216
|
+
return this.attributes.has(name) ? this.attributes.get(name) : null;
|
|
217
|
+
}
|
|
218
|
+
hasAttribute(name) {
|
|
219
|
+
return this.attributes.has(name);
|
|
220
|
+
}
|
|
221
|
+
get id() {
|
|
222
|
+
return this.getAttribute("id") ?? "";
|
|
223
|
+
}
|
|
224
|
+
set id(v) {
|
|
225
|
+
if (v == null) this.removeAttribute("id");
|
|
226
|
+
else this.setAttribute("id", v);
|
|
227
|
+
}
|
|
228
|
+
// JSX_PROPERTIES: className/value/checked/selected/innerHTML/innerText/
|
|
229
|
+
// textContent/indeterminate/htmlFor flow through setProperty (element[k]=v).
|
|
230
|
+
get className() {
|
|
231
|
+
return this.getAttribute("class") ?? "";
|
|
232
|
+
}
|
|
233
|
+
set className(v) {
|
|
234
|
+
if (v == null) this.removeAttribute("class");
|
|
235
|
+
else this.setAttribute("class", v);
|
|
236
|
+
}
|
|
237
|
+
get htmlFor() {
|
|
238
|
+
return this.getAttribute("for") ?? "";
|
|
239
|
+
}
|
|
240
|
+
set htmlFor(v) {
|
|
241
|
+
if (v == null) this.removeAttribute("for");
|
|
242
|
+
else this.setAttribute("for", v);
|
|
243
|
+
}
|
|
244
|
+
set value(v) {
|
|
245
|
+
if (v == null) this.removeAttribute("value");
|
|
246
|
+
else this.setAttribute("value", String(v));
|
|
247
|
+
}
|
|
248
|
+
set checked(v) {
|
|
249
|
+
if (v) this.setAttribute("checked", "");
|
|
250
|
+
else this.removeAttribute("checked");
|
|
251
|
+
}
|
|
252
|
+
set selected(v) {
|
|
253
|
+
if (v) this.setAttribute("selected", "");
|
|
254
|
+
else this.removeAttribute("selected");
|
|
255
|
+
}
|
|
256
|
+
// indeterminate is a live-only DOM property with no HTML serialization.
|
|
257
|
+
set indeterminate(_v) {
|
|
258
|
+
}
|
|
259
|
+
get textContent() {
|
|
260
|
+
return this.childNodes.map((c) => c.textContent ?? "").join("");
|
|
261
|
+
}
|
|
262
|
+
set textContent(v) {
|
|
263
|
+
for (const c of this.childNodes) c.parentNode = null;
|
|
264
|
+
this.childNodes = [];
|
|
265
|
+
this.rawHTML = null;
|
|
266
|
+
if (v != null && v !== "") this.appendChild(new ServerText(String(v)));
|
|
267
|
+
}
|
|
268
|
+
set innerText(v) {
|
|
269
|
+
this.textContent = v;
|
|
270
|
+
}
|
|
271
|
+
set innerHTML(v) {
|
|
272
|
+
for (const c of this.childNodes) c.parentNode = null;
|
|
273
|
+
this.childNodes = [];
|
|
274
|
+
this.rawHTML = v == null ? "" : String(v);
|
|
275
|
+
}
|
|
276
|
+
cloneNode(deep = false) {
|
|
277
|
+
const el = new _ServerElement(this.localName, this.isSVG);
|
|
278
|
+
el.attributes = new Map(this.attributes);
|
|
279
|
+
el.style.cssText = this.style.cssText;
|
|
280
|
+
el.rawHTML = this.rawHTML;
|
|
281
|
+
if (deep) for (const c of this.childNodes) el.appendChild(c.cloneNode(true));
|
|
282
|
+
return el;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/lib/dom/server/serialize.ts
|
|
287
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
288
|
+
"area",
|
|
289
|
+
"base",
|
|
290
|
+
"br",
|
|
291
|
+
"col",
|
|
292
|
+
"embed",
|
|
293
|
+
"hr",
|
|
294
|
+
"img",
|
|
295
|
+
"input",
|
|
296
|
+
"link",
|
|
297
|
+
"meta",
|
|
298
|
+
"param",
|
|
299
|
+
"source",
|
|
300
|
+
"track",
|
|
301
|
+
"wbr"
|
|
302
|
+
]);
|
|
303
|
+
var AMP = /&/g;
|
|
304
|
+
var LT = /</g;
|
|
305
|
+
var GT = />/g;
|
|
306
|
+
var QUOT = /"/g;
|
|
307
|
+
function escapeText(s) {
|
|
308
|
+
return s.replace(AMP, "&").replace(LT, "<").replace(GT, ">");
|
|
309
|
+
}
|
|
310
|
+
function escapeAttr(s) {
|
|
311
|
+
return s.replace(AMP, "&").replace(QUOT, """).replace(LT, "<").replace(GT, ">");
|
|
312
|
+
}
|
|
313
|
+
function camelToKebab(k) {
|
|
314
|
+
if (k.startsWith("--")) return k;
|
|
315
|
+
return k.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
316
|
+
}
|
|
317
|
+
function serializeStyle(style) {
|
|
318
|
+
if (!style) return "";
|
|
319
|
+
const parts = [];
|
|
320
|
+
if (style.cssText) parts.push(style.cssText.trim().replace(/;\s*$/, ""));
|
|
321
|
+
for (const key of Object.keys(style)) {
|
|
322
|
+
if (key === "cssText") continue;
|
|
323
|
+
const v = style[key];
|
|
324
|
+
if (v == null || v === "") continue;
|
|
325
|
+
parts.push(`${camelToKebab(key)}: ${v}`);
|
|
326
|
+
}
|
|
327
|
+
return parts.join("; ");
|
|
328
|
+
}
|
|
329
|
+
function serializeAttrs(el) {
|
|
330
|
+
let out = "";
|
|
331
|
+
const inlineStyle = serializeStyle(el.style);
|
|
332
|
+
for (const [name, value] of el.attributes) {
|
|
333
|
+
if (name === "style" && inlineStyle) continue;
|
|
334
|
+
out += ` ${name}="${escapeAttr(value)}"`;
|
|
335
|
+
}
|
|
336
|
+
if (inlineStyle) {
|
|
337
|
+
const attrStyle = el.attributes.get("style");
|
|
338
|
+
const merged = attrStyle ? `${attrStyle.replace(/;\s*$/, "")}; ${inlineStyle}` : inlineStyle;
|
|
339
|
+
out += ` style="${escapeAttr(merged)}"`;
|
|
340
|
+
}
|
|
341
|
+
return out;
|
|
342
|
+
}
|
|
343
|
+
function serializeNode(node) {
|
|
344
|
+
if (node == null || node === false || node === true) return "";
|
|
345
|
+
if (typeof node === "string") return escapeText(node);
|
|
346
|
+
if (typeof node === "number") return escapeText(String(node));
|
|
347
|
+
if (typeof node === "function") return serializeNode(node());
|
|
348
|
+
if (Array.isArray(node)) return node.map(serializeNode).join("");
|
|
349
|
+
if (typeof node.rawOuterHTML === "string") return node.rawOuterHTML;
|
|
350
|
+
switch (node.nodeType) {
|
|
351
|
+
case NODE_TEXT:
|
|
352
|
+
return escapeText(node.data ?? "");
|
|
353
|
+
case NODE_COMMENT:
|
|
354
|
+
return `<!--${node.data ?? ""}-->`;
|
|
355
|
+
case NODE_ELEMENT: {
|
|
356
|
+
const tag = node.localName;
|
|
357
|
+
const open = `<${tag}${serializeAttrs(node)}>`;
|
|
358
|
+
if (VOID_ELEMENTS.has(tag)) return open;
|
|
359
|
+
const inner = node.rawHTML != null ? node.rawHTML : (node.childNodes ?? []).map(serializeNode).join("");
|
|
360
|
+
return `${open}${inner}</${tag}>`;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (Array.isArray(node.childNodes)) return node.childNodes.map(serializeNode).join("");
|
|
364
|
+
return "";
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// src/lib/dom/server/parse-template.ts
|
|
368
|
+
var VOID_ELEMENTS2 = /* @__PURE__ */ new Set([
|
|
369
|
+
"area",
|
|
370
|
+
"base",
|
|
371
|
+
"br",
|
|
372
|
+
"col",
|
|
373
|
+
"embed",
|
|
374
|
+
"hr",
|
|
375
|
+
"img",
|
|
376
|
+
"input",
|
|
377
|
+
"link",
|
|
378
|
+
"meta",
|
|
379
|
+
"param",
|
|
380
|
+
"source",
|
|
381
|
+
"track",
|
|
382
|
+
"wbr"
|
|
383
|
+
]);
|
|
384
|
+
var ENTITIES = {
|
|
385
|
+
amp: "&",
|
|
386
|
+
lt: "<",
|
|
387
|
+
gt: ">",
|
|
388
|
+
quot: '"',
|
|
389
|
+
"#39": "'"
|
|
390
|
+
};
|
|
391
|
+
function unescape(text) {
|
|
392
|
+
return text.replace(/&(#?\w+);/g, (whole, name) => ENTITIES[name] ?? whole);
|
|
393
|
+
}
|
|
394
|
+
var TemplateParseError = class extends Error {
|
|
395
|
+
};
|
|
396
|
+
function parseTemplate(html, isSVG = false) {
|
|
397
|
+
let i = 0;
|
|
398
|
+
const roots = [];
|
|
399
|
+
const stack = [];
|
|
400
|
+
const append = (node) => {
|
|
401
|
+
const parent = stack[stack.length - 1];
|
|
402
|
+
if (parent) parent.appendChild(node);
|
|
403
|
+
else roots.push(node);
|
|
404
|
+
};
|
|
405
|
+
while (i < html.length) {
|
|
406
|
+
const lt = html.indexOf("<", i);
|
|
407
|
+
if (lt === -1) {
|
|
408
|
+
addText(html.slice(i));
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
if (lt > i) addText(html.slice(i, lt));
|
|
412
|
+
if (html.startsWith("<!--", lt)) {
|
|
413
|
+
const end = html.indexOf("-->", lt);
|
|
414
|
+
if (end === -1) throw new TemplateParseError(`unterminated comment at ${lt}`);
|
|
415
|
+
append(new ServerComment(html.slice(lt + 4, end)));
|
|
416
|
+
i = end + 3;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (html[lt + 1] === "/") {
|
|
420
|
+
const end = html.indexOf(">", lt);
|
|
421
|
+
if (end === -1) throw new TemplateParseError(`unterminated closing tag at ${lt}`);
|
|
422
|
+
const tag = html.slice(lt + 2, end).trim().toLowerCase();
|
|
423
|
+
const open = stack.pop();
|
|
424
|
+
if (!open || open.localName !== tag) {
|
|
425
|
+
throw new TemplateParseError(
|
|
426
|
+
`</${tag}> does not close <${open?.localName ?? "nothing"}>`
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
i = end + 1;
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
i = openTag(lt);
|
|
433
|
+
}
|
|
434
|
+
if (stack.length > 0) {
|
|
435
|
+
throw new TemplateParseError(`unclosed <${stack[stack.length - 1].localName}>`);
|
|
436
|
+
}
|
|
437
|
+
const root = roots[0];
|
|
438
|
+
if (roots.length !== 1 || !(root instanceof ServerElement)) {
|
|
439
|
+
throw new TemplateParseError(`expected exactly one root element, got ${roots.length}`);
|
|
440
|
+
}
|
|
441
|
+
return root;
|
|
442
|
+
function addText(raw) {
|
|
443
|
+
if (raw === "") return;
|
|
444
|
+
append(new ServerText(unescape(raw)));
|
|
445
|
+
}
|
|
446
|
+
function openTag(lt) {
|
|
447
|
+
const nameEnd = /[\s/>]/.exec(html.slice(lt + 1));
|
|
448
|
+
if (!nameEnd) throw new TemplateParseError(`unterminated tag at ${lt}`);
|
|
449
|
+
const tag = html.slice(lt + 1, lt + 1 + nameEnd.index).toLowerCase();
|
|
450
|
+
const el = new ServerElement(tag, isSVG);
|
|
451
|
+
let j = lt + 1 + nameEnd.index;
|
|
452
|
+
while (j < html.length) {
|
|
453
|
+
while (j < html.length && /\s/.test(html[j])) j++;
|
|
454
|
+
if (html[j] === ">") {
|
|
455
|
+
j++;
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
if (html[j] === "/" && html[j + 1] === ">") {
|
|
459
|
+
j += 2;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
const attrStart = j;
|
|
463
|
+
while (j < html.length && !/[\s=/>]/.test(html[j])) j++;
|
|
464
|
+
const name = html.slice(attrStart, j);
|
|
465
|
+
if (name === "") throw new TemplateParseError(`malformed attribute at ${j}`);
|
|
466
|
+
if (html[j] === "=") {
|
|
467
|
+
if (html[j + 1] !== '"') {
|
|
468
|
+
throw new TemplateParseError(`attribute ${name} must have a double-quoted value`);
|
|
469
|
+
}
|
|
470
|
+
const close = html.indexOf('"', j + 2);
|
|
471
|
+
if (close === -1) throw new TemplateParseError(`unterminated value for ${name}`);
|
|
472
|
+
el.setAttribute(name, unescape(html.slice(j + 2, close)));
|
|
473
|
+
j = close + 1;
|
|
474
|
+
} else {
|
|
475
|
+
el.setAttribute(name, "");
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
append(el);
|
|
479
|
+
if (!VOID_ELEMENTS2.has(tag)) stack.push(el);
|
|
480
|
+
return j;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/lib/dom/server/fx-data.ts
|
|
485
|
+
var FX_DATA_ID = "__FX_DATA__";
|
|
486
|
+
function escapeFxJson(json) {
|
|
487
|
+
return json.replace(/[<>&\u2028\u2029]/g, (c) => "\\u" + c.charCodeAt(0).toString(16).padStart(4, "0"));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// src/lib/dom/server/request-context.ts
|
|
491
|
+
var _current;
|
|
492
|
+
var syncStore = {
|
|
493
|
+
getStore: () => _current,
|
|
494
|
+
run(ctx, fn) {
|
|
495
|
+
const prev = _current;
|
|
496
|
+
_current = ctx;
|
|
497
|
+
try {
|
|
498
|
+
return fn();
|
|
499
|
+
} finally {
|
|
500
|
+
_current = prev;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
var _store = syncStore;
|
|
505
|
+
function createRequestContext(event = {}) {
|
|
506
|
+
if (!event.locals) {
|
|
507
|
+
event.locals = event.request ? getRequestLocals(event.request) : {};
|
|
508
|
+
}
|
|
509
|
+
let id = 0;
|
|
510
|
+
let rid = 0;
|
|
511
|
+
let scope = null;
|
|
512
|
+
const scopeCounters = /* @__PURE__ */ new Map();
|
|
513
|
+
const islandCounts = /* @__PURE__ */ new Map();
|
|
514
|
+
return {
|
|
515
|
+
event,
|
|
516
|
+
routeData: /* @__PURE__ */ new Map(),
|
|
517
|
+
matchedRoute: /* @__PURE__ */ new Map(),
|
|
518
|
+
nextId: () => `s${id++}`,
|
|
519
|
+
nextResourceId: () => {
|
|
520
|
+
if (scope === null) return `r${rid++}`;
|
|
521
|
+
const n = scopeCounters.get(scope) ?? 0;
|
|
522
|
+
scopeCounters.set(scope, n + 1);
|
|
523
|
+
return `${scope}:r${n}`;
|
|
524
|
+
},
|
|
525
|
+
nextIslandNamespace: (name) => {
|
|
526
|
+
const n = islandCounts.get(name) ?? 0;
|
|
527
|
+
islandCounts.set(name, n + 1);
|
|
528
|
+
return `${name}#${n}`;
|
|
529
|
+
},
|
|
530
|
+
withResourceScope(ns, fn) {
|
|
531
|
+
const prev = scope;
|
|
532
|
+
scope = ns;
|
|
533
|
+
try {
|
|
534
|
+
return fn();
|
|
535
|
+
} finally {
|
|
536
|
+
scope = prev;
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
pending: /* @__PURE__ */ new Set(),
|
|
540
|
+
data: /* @__PURE__ */ new Map()
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
function runWithRequestContext(ctx, fn) {
|
|
544
|
+
return _store.run(ctx, fn);
|
|
545
|
+
}
|
|
546
|
+
function getRequestContext() {
|
|
547
|
+
return _store.getStore();
|
|
548
|
+
}
|
|
549
|
+
var _requestLocals = /* @__PURE__ */ new WeakMap();
|
|
550
|
+
function getRequestLocals(request) {
|
|
551
|
+
let bag = _requestLocals.get(request);
|
|
552
|
+
if (!bag) {
|
|
553
|
+
bag = {};
|
|
554
|
+
_requestLocals.set(request, bag);
|
|
555
|
+
}
|
|
556
|
+
return bag;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/lib/dom/server/render.ts
|
|
560
|
+
var _nodesRegistered = false;
|
|
561
|
+
function ensureServerNodes() {
|
|
562
|
+
if (_nodesRegistered) return;
|
|
563
|
+
_nodesRegistered = true;
|
|
564
|
+
registerServerNodes({
|
|
565
|
+
createElement: (tag, isSVG) => new ServerElement(tag, isSVG),
|
|
566
|
+
createText: (value) => new ServerText(value),
|
|
567
|
+
createRaw: (html) => new ServerRaw(html),
|
|
568
|
+
parseTemplate: (html, isSVG) => parseTemplate(html, isSVG),
|
|
569
|
+
createComment: (value) => new ServerComment(value)
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
function renderToString(app, options = {}) {
|
|
573
|
+
const prev = isServer();
|
|
574
|
+
ensureServerNodes();
|
|
575
|
+
setServerMode(true);
|
|
576
|
+
const ctx = createRequestContext(options.event);
|
|
577
|
+
try {
|
|
578
|
+
return runWithRequestContext(
|
|
579
|
+
ctx,
|
|
580
|
+
() => createRoot((dispose) => {
|
|
581
|
+
try {
|
|
582
|
+
const tree = typeof app === "function" ? app() : app;
|
|
583
|
+
return serializeNode(tree);
|
|
584
|
+
} finally {
|
|
585
|
+
dispose();
|
|
586
|
+
}
|
|
587
|
+
})
|
|
588
|
+
);
|
|
589
|
+
} finally {
|
|
590
|
+
setServerMode(prev);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
var _hooksInstalled = false;
|
|
594
|
+
function ensureResourceHooks() {
|
|
595
|
+
if (_hooksInstalled) return;
|
|
596
|
+
_hooksInstalled = true;
|
|
597
|
+
setResourceTracker((p) => {
|
|
598
|
+
getRequestContext()?.pending.add(p);
|
|
599
|
+
});
|
|
600
|
+
setResourceIdSource(() => getRequestContext()?.nextResourceId() ?? "");
|
|
601
|
+
setResourceDataSink((id, value) => {
|
|
602
|
+
if (id) getRequestContext()?.data.set(id, value);
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
var _redactor = null;
|
|
606
|
+
function setDataRedactor(fn) {
|
|
607
|
+
_redactor = fn;
|
|
608
|
+
}
|
|
609
|
+
function serializeResourceData(ctx) {
|
|
610
|
+
if (ctx.data.size === 0) return "";
|
|
611
|
+
const obj = {};
|
|
612
|
+
for (const [k, v] of ctx.data) {
|
|
613
|
+
let out = v;
|
|
614
|
+
if (_redactor) {
|
|
615
|
+
try {
|
|
616
|
+
out = _redactor(v, k);
|
|
617
|
+
} catch {
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (out === void 0) continue;
|
|
622
|
+
if (typeof out === "function" || typeof out === "symbol") continue;
|
|
623
|
+
obj[k] = out;
|
|
624
|
+
}
|
|
625
|
+
if (Object.keys(obj).length === 0) return "";
|
|
626
|
+
const json = escapeFxJson(JSON.stringify(obj));
|
|
627
|
+
if (json === "{}") return "";
|
|
628
|
+
return `<script type="application/json" id="${FX_DATA_ID}">${json}<\/script>`;
|
|
629
|
+
}
|
|
630
|
+
var MAX_ASYNC_ROUNDS = 50;
|
|
631
|
+
async function renderToStringAsync(app, options = {}) {
|
|
632
|
+
const prev = isServer();
|
|
633
|
+
ensureServerNodes();
|
|
634
|
+
setServerMode(true);
|
|
635
|
+
ensureResourceHooks();
|
|
636
|
+
const ctx = createRequestContext(options.event);
|
|
637
|
+
try {
|
|
638
|
+
return await runWithRequestContext(ctx, async () => {
|
|
639
|
+
if (options.preload) await options.preload(options.event);
|
|
640
|
+
let tree;
|
|
641
|
+
let rootOwner = null;
|
|
642
|
+
let dispose = () => {
|
|
643
|
+
};
|
|
644
|
+
createRoot((d) => {
|
|
645
|
+
dispose = d;
|
|
646
|
+
rootOwner = getOwner();
|
|
647
|
+
tree = typeof app === "function" ? app() : app;
|
|
648
|
+
});
|
|
649
|
+
const probe = () => {
|
|
650
|
+
try {
|
|
651
|
+
runWithOwner(rootOwner, () => serializeNode(tree));
|
|
652
|
+
} catch {
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
probe();
|
|
656
|
+
let rounds = 0;
|
|
657
|
+
while (ctx.pending.size > 0 && rounds++ < MAX_ASYNC_ROUNDS) {
|
|
658
|
+
const batch = Array.from(ctx.pending);
|
|
659
|
+
ctx.pending.clear();
|
|
660
|
+
await Promise.allSettled(batch);
|
|
661
|
+
await flush();
|
|
662
|
+
probe();
|
|
663
|
+
}
|
|
664
|
+
const html = runWithOwner(rootOwner, () => serializeNode(tree)) + serializeResourceData(ctx);
|
|
665
|
+
dispose();
|
|
666
|
+
return html;
|
|
667
|
+
});
|
|
668
|
+
} finally {
|
|
669
|
+
setServerMode(prev);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
export {
|
|
673
|
+
renderToString,
|
|
674
|
+
renderToStringAsync,
|
|
675
|
+
serializeResourceData,
|
|
676
|
+
setDataRedactor
|
|
677
|
+
};
|