sinwan 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -39
- package/dist/cjs/index.development.js +2373 -842
- package/dist/cjs/index.development.js.map +22 -18
- package/dist/cjs/index.production.min.js +2 -2
- package/dist/cjs/index.production.min.js.map +22 -18
- package/dist/cjs/jsx/jsx-dev-runtime.development.js +6 -16
- package/dist/cjs/jsx/jsx-dev-runtime.development.js.map +3 -3
- package/dist/cjs/jsx/jsx-dev-runtime.production.min.js +2 -2
- package/dist/cjs/jsx/jsx-dev-runtime.production.min.js.map +3 -3
- package/dist/cjs/jsx/jsx-runtime.development.js +6 -16
- package/dist/cjs/jsx/jsx-runtime.development.js.map +3 -3
- package/dist/cjs/jsx/jsx-runtime.production.min.js +2 -2
- package/dist/cjs/jsx/jsx-runtime.production.min.js.map +3 -3
- package/dist/cjs/renderer/index.development.js +1581 -0
- package/dist/cjs/renderer/index.development.js.map +25 -0
- package/dist/cjs/renderer/index.production.min.js +3 -0
- package/dist/cjs/renderer/index.production.min.js.map +25 -0
- package/dist/cjs/server/index.development.js +1210 -362
- package/dist/cjs/server/index.development.js.map +13 -10
- package/dist/cjs/server/index.production.min.js +2 -2
- package/dist/cjs/server/index.production.min.js.map +13 -10
- package/dist/component/control-flow.d.ts +71 -0
- package/dist/component/control-flow.d.ts.map +1 -0
- package/dist/component/index.d.ts +3 -1
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/instance.d.ts +7 -1
- package/dist/component/instance.d.ts.map +1 -1
- package/dist/component/lifecycle.d.ts +2 -1
- package/dist/component/lifecycle.d.ts.map +1 -1
- package/dist/component/provide-inject.d.ts +11 -5
- package/dist/component/provide-inject.d.ts.map +1 -1
- package/dist/esm/index.development.js +2253 -744
- package/dist/esm/index.development.js.map +22 -18
- package/dist/esm/index.production.min.js +2 -2
- package/dist/esm/index.production.min.js.map +22 -18
- package/dist/esm/jsx/jsx-dev-runtime.development.js +6 -16
- package/dist/esm/jsx/jsx-dev-runtime.development.js.map +3 -3
- package/dist/esm/jsx/jsx-dev-runtime.production.min.js +2 -2
- package/dist/esm/jsx/jsx-dev-runtime.production.min.js.map +3 -3
- package/dist/esm/jsx/jsx-runtime.development.js +6 -16
- package/dist/esm/jsx/jsx-runtime.development.js.map +3 -3
- package/dist/esm/jsx/jsx-runtime.production.min.js +2 -2
- package/dist/esm/jsx/jsx-runtime.production.min.js.map +3 -3
- package/dist/esm/renderer/index.development.js +1530 -0
- package/dist/esm/renderer/index.development.js.map +25 -0
- package/dist/esm/renderer/index.production.min.js +4 -0
- package/dist/esm/renderer/index.production.min.js.map +25 -0
- package/dist/esm/server/index.development.js +1210 -362
- package/dist/esm/server/index.development.js.map +13 -10
- package/dist/esm/server/index.production.min.js +2 -2
- package/dist/esm/server/index.production.min.js.map +13 -10
- package/dist/hydration/walk.d.ts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/jsx/jsx-runtime.d.ts +13 -0
- package/dist/jsx/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx/jsx-types.d.ts +122 -57
- package/dist/jsx/jsx-types.d.ts.map +1 -1
- package/dist/renderer/attributes.d.ts +11 -0
- package/dist/renderer/attributes.d.ts.map +1 -1
- package/dist/renderer/dom-ops.d.ts +4 -1
- package/dist/renderer/dom-ops.d.ts.map +1 -1
- package/dist/renderer/index.d.ts +2 -2
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/mount.d.ts +2 -5
- package/dist/renderer/mount.d.ts.map +1 -1
- package/dist/renderer/render-children.d.ts +2 -2
- package/dist/renderer/render-children.d.ts.map +1 -1
- package/dist/renderer/render-control-flow.d.ts +13 -0
- package/dist/renderer/render-control-flow.d.ts.map +1 -0
- package/dist/renderer/render-element.d.ts +1 -1
- package/dist/renderer/render-element.d.ts.map +1 -1
- package/dist/renderer/types.d.ts +10 -1
- package/dist/renderer/types.d.ts.map +1 -1
- package/dist/renderer/unmount.d.ts +20 -0
- package/dist/renderer/unmount.d.ts.map +1 -0
- package/dist/renderer.d.ts +1 -0
- package/dist/renderer.js +7 -0
- package/dist/renderer.mjs +4 -0
- package/dist/server/attribute-utils.d.ts +2 -0
- package/dist/server/attribute-utils.d.ts.map +1 -0
- package/dist/server/hydration-markers.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/renderer.d.ts.map +1 -1
- package/dist/server/stream.d.ts +9 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -5
|
@@ -87,22 +87,12 @@ function buildElement(type, props, children) {
|
|
|
87
87
|
if (type === Fragment) {
|
|
88
88
|
return { tag: "", props: {}, children };
|
|
89
89
|
}
|
|
90
|
-
if (typeof type === "function") {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return result2;
|
|
95
|
-
}
|
|
96
|
-
return { tag: "", props: {}, children: normalizeChildren(result2) };
|
|
97
|
-
}
|
|
98
|
-
const result = type(props);
|
|
99
|
-
if (result && typeof result === "object" && "tag" in result) {
|
|
100
|
-
return result;
|
|
90
|
+
if (typeof type === "function" || typeof type === "string") {
|
|
91
|
+
const finalProps = props ?? {};
|
|
92
|
+
if (children.length > 0 && finalProps.children === undefined) {
|
|
93
|
+
finalProps.children = children.length === 1 ? children[0] : children;
|
|
101
94
|
}
|
|
102
|
-
return { tag:
|
|
103
|
-
}
|
|
104
|
-
if (typeof type === "string") {
|
|
105
|
-
return { tag: type, props: props || {}, children };
|
|
95
|
+
return { tag: type, props: finalProps, children };
|
|
106
96
|
}
|
|
107
97
|
return { tag: "", props: {}, children };
|
|
108
98
|
}
|
|
@@ -122,270 +112,88 @@ function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
|
122
112
|
return element;
|
|
123
113
|
}
|
|
124
114
|
|
|
125
|
-
// src/
|
|
126
|
-
var
|
|
127
|
-
__export(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
115
|
+
// src/renderer/index.ts
|
|
116
|
+
var exports_renderer = {};
|
|
117
|
+
__export(exports_renderer, {
|
|
118
|
+
unmountNode: () => unmountNode,
|
|
119
|
+
toEventName: () => toEventName,
|
|
120
|
+
setDOMOps: () => setDOMOps,
|
|
121
|
+
resetDOMOps: () => resetDOMOps,
|
|
122
|
+
renderNodeToDOM: () => renderNodeToDOM,
|
|
123
|
+
renderElementToDOM: () => renderElementToDOM,
|
|
124
|
+
renderChildrenToDOM: () => renderChildrenToDOM,
|
|
125
|
+
render: () => render,
|
|
126
|
+
mount: () => mount,
|
|
127
|
+
isEventProp: () => isEventProp,
|
|
128
|
+
domOps: () => domOps,
|
|
129
|
+
bindEvents: () => bindEvents,
|
|
130
|
+
bindEvent: () => bindEvent,
|
|
131
|
+
applyAttributes: () => applyAttributes
|
|
137
132
|
});
|
|
138
|
-
module.exports = __toCommonJS(
|
|
139
|
-
|
|
140
|
-
// src/escaper.ts
|
|
141
|
-
var _bun = globalThis.Bun;
|
|
142
|
-
var _nativeEscape = typeof _bun?.escapeHTML === "function" ? _bun.escapeHTML.bind(_bun) : undefined;
|
|
143
|
-
var HTML_ESCAPE_RE = /[&<>"']/g;
|
|
144
|
-
var HTML_ESCAPE_MAP = {
|
|
145
|
-
"&": "&",
|
|
146
|
-
"<": "<",
|
|
147
|
-
">": ">",
|
|
148
|
-
'"': """,
|
|
149
|
-
"'": "'"
|
|
150
|
-
};
|
|
151
|
-
function portableEscape(str) {
|
|
152
|
-
HTML_ESCAPE_RE.lastIndex = 0;
|
|
153
|
-
if (!HTML_ESCAPE_RE.test(str))
|
|
154
|
-
return str;
|
|
155
|
-
return str.replace(HTML_ESCAPE_RE, (c) => HTML_ESCAPE_MAP[c]);
|
|
156
|
-
}
|
|
157
|
-
function escapeHtml(value) {
|
|
158
|
-
if (value == null || typeof value === "boolean")
|
|
159
|
-
return "";
|
|
160
|
-
if (typeof value === "number")
|
|
161
|
-
return String(value);
|
|
162
|
-
if (value instanceof HtmlEscapedString)
|
|
163
|
-
return value.value;
|
|
164
|
-
const s = String(value);
|
|
165
|
-
return _nativeEscape ? _nativeEscape(s) : portableEscape(s);
|
|
166
|
-
}
|
|
167
|
-
function safeHtml(html) {
|
|
168
|
-
return raw(html);
|
|
169
|
-
}
|
|
170
|
-
function isSafeHtml(value) {
|
|
171
|
-
return value instanceof HtmlEscapedString;
|
|
172
|
-
}
|
|
133
|
+
module.exports = __toCommonJS(exports_renderer);
|
|
173
134
|
|
|
174
|
-
// src/
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
if (typeof tag === "string") {
|
|
223
|
-
return renderIntrinsicElement(tag, props, children);
|
|
224
|
-
}
|
|
225
|
-
return renderToString(children);
|
|
226
|
-
}
|
|
227
|
-
var VOID_ELEMENTS2 = new Set([
|
|
228
|
-
"area",
|
|
229
|
-
"base",
|
|
230
|
-
"br",
|
|
231
|
-
"col",
|
|
232
|
-
"embed",
|
|
233
|
-
"hr",
|
|
234
|
-
"img",
|
|
235
|
-
"input",
|
|
236
|
-
"link",
|
|
237
|
-
"meta",
|
|
238
|
-
"param",
|
|
239
|
-
"source",
|
|
240
|
-
"track",
|
|
241
|
-
"wbr"
|
|
242
|
-
]);
|
|
243
|
-
async function renderIntrinsicElement(tag, props, children) {
|
|
244
|
-
const attrs = renderAttributes(props);
|
|
245
|
-
if (VOID_ELEMENTS2.has(tag)) {
|
|
246
|
-
return attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
247
|
-
}
|
|
248
|
-
const childrenHtml = await renderChildren(children, props);
|
|
249
|
-
return attrs ? `<${tag}${attrs}>${childrenHtml}</${tag}>` : `<${tag}>${childrenHtml}</${tag}>`;
|
|
250
|
-
}
|
|
251
|
-
function renderAttributes(props) {
|
|
252
|
-
let attrs = "";
|
|
253
|
-
for (const [key, value] of Object.entries(props)) {
|
|
254
|
-
if (key === "children")
|
|
255
|
-
continue;
|
|
256
|
-
if (value == null || value === false)
|
|
257
|
-
continue;
|
|
258
|
-
if (value === true) {
|
|
259
|
-
attrs += ` ${key}`;
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
if (key === "dangerouslySetInnerHTML") {
|
|
263
|
-
continue;
|
|
264
|
-
}
|
|
265
|
-
const attrName = key === "className" ? "class" : key;
|
|
266
|
-
const finalName = attrName === "htmlFor" ? "for" : attrName;
|
|
267
|
-
const attrValue = escapeHtml(String(value));
|
|
268
|
-
attrs += ` ${finalName}="${attrValue}"`;
|
|
269
|
-
}
|
|
270
|
-
return attrs;
|
|
271
|
-
}
|
|
272
|
-
async function renderChildren(children, props) {
|
|
273
|
-
const dangerous = props.dangerouslySetInnerHTML;
|
|
274
|
-
if (dangerous && typeof dangerous.__html === "string") {
|
|
275
|
-
return dangerous.__html;
|
|
276
|
-
}
|
|
277
|
-
return renderToString(children);
|
|
278
|
-
}
|
|
279
|
-
function isSlots(children) {
|
|
280
|
-
return children != null && typeof children === "object" && !Array.isArray(children) && !(children instanceof HtmlEscapedString);
|
|
281
|
-
}
|
|
282
|
-
// src/server/stream.ts
|
|
283
|
-
var VOID_ELEMENTS3 = new Set([
|
|
284
|
-
"area",
|
|
285
|
-
"base",
|
|
286
|
-
"br",
|
|
287
|
-
"col",
|
|
288
|
-
"embed",
|
|
289
|
-
"hr",
|
|
290
|
-
"img",
|
|
291
|
-
"input",
|
|
292
|
-
"link",
|
|
293
|
-
"meta",
|
|
294
|
-
"param",
|
|
295
|
-
"source",
|
|
296
|
-
"track",
|
|
297
|
-
"wbr"
|
|
298
|
-
]);
|
|
299
|
-
function streamPage(page, data) {
|
|
300
|
-
const encoder = new TextEncoder;
|
|
301
|
-
return new ReadableStream({
|
|
302
|
-
async start(controller) {
|
|
303
|
-
try {
|
|
304
|
-
const element = await page(data);
|
|
305
|
-
await streamNode(element, controller, encoder);
|
|
306
|
-
controller.close();
|
|
307
|
-
} catch (error) {
|
|
308
|
-
controller.error(error);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
async function streamNode(node, controller, encoder) {
|
|
314
|
-
if (node == null || typeof node === "boolean") {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
if (typeof node === "string") {
|
|
318
|
-
controller.enqueue(encoder.encode(escapeHtml(node)));
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
if (typeof node === "number") {
|
|
322
|
-
controller.enqueue(encoder.encode(String(node)));
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
if (node instanceof HtmlEscapedString) {
|
|
326
|
-
controller.enqueue(encoder.encode(node.value));
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
if (Array.isArray(node)) {
|
|
330
|
-
for (const child of node) {
|
|
331
|
-
await streamNode(child, controller, encoder);
|
|
135
|
+
// src/renderer/dom-ops.ts
|
|
136
|
+
function createDefaultDOMOps() {
|
|
137
|
+
return {
|
|
138
|
+
createElement(tag) {
|
|
139
|
+
return document.createElement(tag);
|
|
140
|
+
},
|
|
141
|
+
createElementNS(namespace, tag) {
|
|
142
|
+
return document.createElementNS(namespace, tag);
|
|
143
|
+
},
|
|
144
|
+
createTextNode(text) {
|
|
145
|
+
return document.createTextNode(text);
|
|
146
|
+
},
|
|
147
|
+
createComment(text) {
|
|
148
|
+
return document.createComment(text);
|
|
149
|
+
},
|
|
150
|
+
setAttribute(el, key, value) {
|
|
151
|
+
el.setAttribute(key, value);
|
|
152
|
+
},
|
|
153
|
+
removeAttribute(el, key) {
|
|
154
|
+
el.removeAttribute(key);
|
|
155
|
+
},
|
|
156
|
+
setProperty(el, key, value) {
|
|
157
|
+
el[key] = value;
|
|
158
|
+
},
|
|
159
|
+
insertBefore(parent, child, anchor) {
|
|
160
|
+
parent.insertBefore(child, anchor);
|
|
161
|
+
},
|
|
162
|
+
appendChild(parent, child) {
|
|
163
|
+
parent.appendChild(child);
|
|
164
|
+
},
|
|
165
|
+
remove(node) {
|
|
166
|
+
node.parentNode?.removeChild(node);
|
|
167
|
+
},
|
|
168
|
+
setTextContent(node, text) {
|
|
169
|
+
node.data = text;
|
|
170
|
+
},
|
|
171
|
+
addEventListener(el, event, handler) {
|
|
172
|
+
el.addEventListener(event, handler);
|
|
173
|
+
},
|
|
174
|
+
removeEventListener(el, event, handler) {
|
|
175
|
+
el.removeEventListener(event, handler);
|
|
176
|
+
},
|
|
177
|
+
parentNode(node) {
|
|
178
|
+
return node.parentNode;
|
|
179
|
+
},
|
|
180
|
+
nextSibling(node) {
|
|
181
|
+
return node.nextSibling;
|
|
332
182
|
}
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
if (node instanceof Promise) {
|
|
336
|
-
const resolved = await node;
|
|
337
|
-
await streamElement(resolved, controller, encoder);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
await streamElement(node, controller, encoder);
|
|
341
|
-
}
|
|
342
|
-
async function streamElement(element, controller, encoder) {
|
|
343
|
-
const { tag, props, children } = element;
|
|
344
|
-
if (typeof tag === "function") {
|
|
345
|
-
const result = await tag(props);
|
|
346
|
-
await streamNode(result, controller, encoder);
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
if (typeof tag === "string") {
|
|
350
|
-
await streamIntrinsicElement(tag, props, children, controller, encoder);
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
await streamNode(children, controller, encoder);
|
|
183
|
+
};
|
|
354
184
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const html = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
360
|
-
controller.enqueue(encoder.encode(html));
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const openTag = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
364
|
-
controller.enqueue(encoder.encode(openTag));
|
|
365
|
-
if (dangerous && typeof dangerous.__html === "string") {
|
|
366
|
-
controller.enqueue(encoder.encode(dangerous.__html));
|
|
367
|
-
} else {
|
|
368
|
-
await streamNode(children, controller, encoder);
|
|
369
|
-
}
|
|
370
|
-
controller.enqueue(encoder.encode(`</${tag}>`));
|
|
185
|
+
var defaultDOMOps = createDefaultDOMOps();
|
|
186
|
+
var domOps = { ...defaultDOMOps };
|
|
187
|
+
function setDOMOps(overrides) {
|
|
188
|
+
Object.assign(domOps, overrides);
|
|
371
189
|
}
|
|
372
|
-
function
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (key === "children" || key === "dangerouslySetInnerHTML")
|
|
376
|
-
continue;
|
|
377
|
-
if (value == null || value === false)
|
|
378
|
-
continue;
|
|
379
|
-
if (value === true) {
|
|
380
|
-
attrs += ` ${key}`;
|
|
381
|
-
continue;
|
|
382
|
-
}
|
|
383
|
-
const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
|
|
384
|
-
const attrValue = escapeHtml(String(value));
|
|
385
|
-
attrs += ` ${attrName}="${attrValue}"`;
|
|
190
|
+
function resetDOMOps() {
|
|
191
|
+
for (const key of Object.keys(domOps)) {
|
|
192
|
+
delete domOps[key];
|
|
386
193
|
}
|
|
387
|
-
|
|
194
|
+
Object.assign(domOps, defaultDOMOps);
|
|
388
195
|
}
|
|
196
|
+
|
|
389
197
|
// src/reactivity/scheduler.ts
|
|
390
198
|
var pendingEffects = new Set;
|
|
391
199
|
var flushScheduled = false;
|
|
@@ -628,79 +436,6 @@ function isComputed(value) {
|
|
|
628
436
|
return value != null && typeof value === "object" && COMPUTED_BRAND in value;
|
|
629
437
|
}
|
|
630
438
|
|
|
631
|
-
// src/hydration/markers.ts
|
|
632
|
-
var COMP_ID_ATTR = "data-sinwan-id";
|
|
633
|
-
var COMP_ID_PREFIX = "c";
|
|
634
|
-
var TEXT_MARKER_OPEN = "sinwan-t:";
|
|
635
|
-
var TEXT_MARKER_CLOSE = "/sinwan-t";
|
|
636
|
-
var EVENT_ATTR = "data-sinwan-ev";
|
|
637
|
-
function compId(index) {
|
|
638
|
-
return `${COMP_ID_PREFIX}${index}`;
|
|
639
|
-
}
|
|
640
|
-
function textMarkerOpen(index) {
|
|
641
|
-
return `<!--${TEXT_MARKER_OPEN}${index}-->`;
|
|
642
|
-
}
|
|
643
|
-
function textMarkerCloseStr() {
|
|
644
|
-
return `<!--${TEXT_MARKER_CLOSE}-->`;
|
|
645
|
-
}
|
|
646
|
-
function parseTextOpenMarker(node) {
|
|
647
|
-
const data = node.data;
|
|
648
|
-
if (data.startsWith(TEXT_MARKER_OPEN)) {
|
|
649
|
-
const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);
|
|
650
|
-
return Number.isNaN(idx) ? -1 : idx;
|
|
651
|
-
}
|
|
652
|
-
return -1;
|
|
653
|
-
}
|
|
654
|
-
function isTextCloseMarker(node) {
|
|
655
|
-
return node.data === TEXT_MARKER_CLOSE;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// src/renderer/dom-ops.ts
|
|
659
|
-
var domOps = {
|
|
660
|
-
createElement(tag) {
|
|
661
|
-
return document.createElement(tag);
|
|
662
|
-
},
|
|
663
|
-
createTextNode(text) {
|
|
664
|
-
return document.createTextNode(text);
|
|
665
|
-
},
|
|
666
|
-
createComment(text) {
|
|
667
|
-
return document.createComment(text);
|
|
668
|
-
},
|
|
669
|
-
setAttribute(el, key, value) {
|
|
670
|
-
el.setAttribute(key, value);
|
|
671
|
-
},
|
|
672
|
-
removeAttribute(el, key) {
|
|
673
|
-
el.removeAttribute(key);
|
|
674
|
-
},
|
|
675
|
-
setProperty(el, key, value) {
|
|
676
|
-
el[key] = value;
|
|
677
|
-
},
|
|
678
|
-
insertBefore(parent, child, anchor) {
|
|
679
|
-
parent.insertBefore(child, anchor);
|
|
680
|
-
},
|
|
681
|
-
appendChild(parent, child) {
|
|
682
|
-
parent.appendChild(child);
|
|
683
|
-
},
|
|
684
|
-
remove(node) {
|
|
685
|
-
node.parentNode?.removeChild(node);
|
|
686
|
-
},
|
|
687
|
-
setTextContent(node, text) {
|
|
688
|
-
node.data = text;
|
|
689
|
-
},
|
|
690
|
-
addEventListener(el, event, handler) {
|
|
691
|
-
el.addEventListener(event, handler);
|
|
692
|
-
},
|
|
693
|
-
removeEventListener(el, event, handler) {
|
|
694
|
-
el.removeEventListener(event, handler);
|
|
695
|
-
},
|
|
696
|
-
parentNode(node) {
|
|
697
|
-
return node.parentNode;
|
|
698
|
-
},
|
|
699
|
-
nextSibling(node) {
|
|
700
|
-
return node.nextSibling;
|
|
701
|
-
}
|
|
702
|
-
};
|
|
703
|
-
|
|
704
439
|
// src/renderer/events.ts
|
|
705
440
|
function isEventProp(key) {
|
|
706
441
|
return key.length > 2 && key[0] === "o" && key[1] === "n" && key[2] >= "A" && key[2] <= "Z";
|
|
@@ -757,7 +492,18 @@ function setCurrentInstance(instance) {
|
|
|
757
492
|
currentInstance = instance;
|
|
758
493
|
return prev;
|
|
759
494
|
}
|
|
495
|
+
function withInstance(instance, fn) {
|
|
496
|
+
const prev = setCurrentInstance(instance);
|
|
497
|
+
try {
|
|
498
|
+
return fn();
|
|
499
|
+
} finally {
|
|
500
|
+
setCurrentInstance(prev);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
760
503
|
function fireMountedHooks(instance) {
|
|
504
|
+
if (instance.isUnmounted) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
761
507
|
for (const child of instance.children) {
|
|
762
508
|
fireMountedHooks(child);
|
|
763
509
|
}
|
|
@@ -784,6 +530,24 @@ function fireUnmountedHooks(instance) {
|
|
|
784
530
|
instance.effects.length = 0;
|
|
785
531
|
}
|
|
786
532
|
}
|
|
533
|
+
function fireUpdatedHooks(instance) {
|
|
534
|
+
for (const hook of instance._updatedHooks) {
|
|
535
|
+
hook();
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
var queuedUpdatedHooks = new Set;
|
|
539
|
+
function queueUpdatedHooks(instance) {
|
|
540
|
+
if (!instance || !instance.isMounted || instance.isUnmounted || instance._updatedHooks.length === 0 || queuedUpdatedHooks.has(instance)) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
queuedUpdatedHooks.add(instance);
|
|
544
|
+
nextTick(() => {
|
|
545
|
+
queuedUpdatedHooks.delete(instance);
|
|
546
|
+
if (instance.isMounted && !instance.isUnmounted) {
|
|
547
|
+
fireUpdatedHooks(instance);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
}
|
|
787
551
|
function handleComponentError(instance, err) {
|
|
788
552
|
let current = instance;
|
|
789
553
|
while (current) {
|
|
@@ -798,177 +562,125 @@ function handleComponentError(instance, err) {
|
|
|
798
562
|
console.error("[Sinwan] Unhandled component error:", err);
|
|
799
563
|
}
|
|
800
564
|
|
|
801
|
-
// src/
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
565
|
+
// src/renderer/attributes.ts
|
|
566
|
+
var SKIP_PROPS = new Set(["children", "key", "ref", "dangerouslySetInnerHTML"]);
|
|
567
|
+
var DOM_PROPERTIES = new Set(["value", "checked", "selected", "disabled", "readOnly", "multiple", "indeterminate"]);
|
|
568
|
+
var PROP_ALIASES = {
|
|
569
|
+
className: "class",
|
|
570
|
+
htmlFor: "for",
|
|
571
|
+
tabIndex: "tabindex",
|
|
572
|
+
crossOrigin: "crossorigin"
|
|
573
|
+
};
|
|
574
|
+
function applyAttributes(el, props) {
|
|
575
|
+
const disposers = [];
|
|
576
|
+
const owner = getCurrentInstance();
|
|
577
|
+
for (const [key, value] of Object.entries(props)) {
|
|
578
|
+
if (SKIP_PROPS.has(key) || isEventProp(key))
|
|
579
|
+
continue;
|
|
580
|
+
if (isSignal(value) || isComputed(value)) {
|
|
581
|
+
const state = { previousStyleProps: new Set };
|
|
582
|
+
let initialized = false;
|
|
583
|
+
const dispose = effect(() => {
|
|
584
|
+
setSingleAttribute(el, key, value.value, state);
|
|
585
|
+
if (initialized) {
|
|
586
|
+
queueUpdatedHooks(owner);
|
|
587
|
+
}
|
|
588
|
+
initialized = true;
|
|
589
|
+
});
|
|
590
|
+
disposers.push(dispose);
|
|
591
|
+
} else {
|
|
592
|
+
setSingleAttribute(el, key, value);
|
|
593
|
+
}
|
|
814
594
|
}
|
|
815
|
-
return
|
|
816
|
-
}
|
|
817
|
-
async function renderNodeToHydratableString(node) {
|
|
818
|
-
const ctx = createHydrationContext();
|
|
819
|
-
return renderNodeH(node, ctx);
|
|
595
|
+
return disposers;
|
|
820
596
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
"
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
"embed",
|
|
827
|
-
"hr",
|
|
828
|
-
"img",
|
|
829
|
-
"input",
|
|
830
|
-
"link",
|
|
831
|
-
"meta",
|
|
832
|
-
"param",
|
|
833
|
-
"source",
|
|
834
|
-
"track",
|
|
835
|
-
"wbr"
|
|
836
|
-
]);
|
|
837
|
-
function renderNodeH(node, ctx) {
|
|
838
|
-
if (node == null || typeof node === "boolean")
|
|
839
|
-
return "";
|
|
840
|
-
if (typeof node === "string")
|
|
841
|
-
return escapeHtml(node);
|
|
842
|
-
if (typeof node === "number")
|
|
843
|
-
return String(node);
|
|
844
|
-
if (node instanceof HtmlEscapedString)
|
|
845
|
-
return node.value;
|
|
846
|
-
if (isSignal(node) || isComputed(node)) {
|
|
847
|
-
const value = node.value;
|
|
848
|
-
const idx = ctx.textIndex++;
|
|
849
|
-
return `${textMarkerOpen(idx)}${escapeHtml(String(value))}${textMarkerCloseStr()}`;
|
|
850
|
-
}
|
|
851
|
-
if (Array.isArray(node)) {
|
|
852
|
-
return node.map((child) => renderNodeH(child, ctx)).join("");
|
|
597
|
+
function setSingleAttribute(el, key, value, state) {
|
|
598
|
+
const attrName = resolveAttributeName(key);
|
|
599
|
+
if (attrName === "style" && typeof value === "object" && value !== null) {
|
|
600
|
+
applyStyle(el, value, state);
|
|
601
|
+
return;
|
|
853
602
|
}
|
|
854
|
-
if (
|
|
855
|
-
|
|
603
|
+
if (attrName === "class" && typeof value === "object" && value !== null) {
|
|
604
|
+
applyClass(el, value);
|
|
605
|
+
return;
|
|
856
606
|
}
|
|
857
|
-
if (
|
|
858
|
-
|
|
607
|
+
if (value == null || value === false) {
|
|
608
|
+
domOps.removeAttribute(el, attrName);
|
|
609
|
+
if (attrName === "style" && state) {
|
|
610
|
+
state.previousStyleProps.clear();
|
|
611
|
+
}
|
|
612
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
613
|
+
domOps.setProperty(el, attrName, attrName === "value" ? "" : false);
|
|
614
|
+
}
|
|
615
|
+
return;
|
|
859
616
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
617
|
+
if (value === true) {
|
|
618
|
+
domOps.setAttribute(el, attrName, "");
|
|
619
|
+
if (attrName === "style" && state) {
|
|
620
|
+
state.previousStyleProps.clear();
|
|
621
|
+
}
|
|
622
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
623
|
+
domOps.setProperty(el, attrName, true);
|
|
624
|
+
}
|
|
625
|
+
return;
|
|
866
626
|
}
|
|
867
|
-
if (
|
|
868
|
-
|
|
627
|
+
if (DOM_PROPERTIES.has(attrName)) {
|
|
628
|
+
if (attrName === "style" && state) {
|
|
629
|
+
state.previousStyleProps.clear();
|
|
630
|
+
}
|
|
631
|
+
domOps.setProperty(el, attrName, value);
|
|
632
|
+
return;
|
|
869
633
|
}
|
|
870
|
-
if (
|
|
871
|
-
|
|
634
|
+
if (attrName === "style" && state) {
|
|
635
|
+
state.previousStyleProps.clear();
|
|
872
636
|
}
|
|
873
|
-
|
|
637
|
+
domOps.setAttribute(el, attrName, String(value));
|
|
874
638
|
}
|
|
875
|
-
function
|
|
876
|
-
|
|
877
|
-
const instance = createComponentInstance(component, props, null);
|
|
878
|
-
const prev = setCurrentInstance(instance);
|
|
879
|
-
const result = component(props);
|
|
880
|
-
setCurrentInstance(prev);
|
|
881
|
-
if (result && typeof result === "object" && "tag" in result) {
|
|
882
|
-
return renderElementH(result, ctx, true);
|
|
883
|
-
}
|
|
884
|
-
return renderNodeH(result, ctx);
|
|
639
|
+
function resolveAttributeName(key) {
|
|
640
|
+
return PROP_ALIASES[key] ?? key;
|
|
885
641
|
}
|
|
886
|
-
function
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
for (const [key, value] of Object.entries(props)) {
|
|
893
|
-
if (key === "children" || key === "dangerouslySetInnerHTML")
|
|
894
|
-
continue;
|
|
895
|
-
if (isEventProp(key)) {
|
|
896
|
-
const eventName = toEventName(key);
|
|
897
|
-
eventParts.push(`${eventName}:${ctx.eventIndex++}`);
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
if (value == null || value === false)
|
|
642
|
+
function applyStyle(el, styles, state) {
|
|
643
|
+
const nextProps = new Set;
|
|
644
|
+
for (const [prop, val] of Object.entries(styles)) {
|
|
645
|
+
nextProps.add(prop);
|
|
646
|
+
if (val == null) {
|
|
647
|
+
removeStyleProperty(el, prop);
|
|
901
648
|
continue;
|
|
902
|
-
let resolvedValue = value;
|
|
903
|
-
if (isSignal(value) || isComputed(value)) {
|
|
904
|
-
resolvedValue = value.value;
|
|
905
649
|
}
|
|
906
|
-
if (
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
650
|
+
if (prop.includes("-")) {
|
|
651
|
+
el.style.setProperty(prop, String(val));
|
|
652
|
+
} else {
|
|
653
|
+
el.style[prop] = val;
|
|
910
654
|
}
|
|
911
|
-
const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
|
|
912
|
-
attrs += ` ${attrName}="${escapeHtml(String(resolvedValue))}"`;
|
|
913
655
|
}
|
|
914
|
-
if (
|
|
915
|
-
|
|
656
|
+
if (!state) {
|
|
657
|
+
return;
|
|
916
658
|
}
|
|
917
|
-
|
|
918
|
-
|
|
659
|
+
for (const previousProp of state.previousStyleProps) {
|
|
660
|
+
if (!nextProps.has(previousProp)) {
|
|
661
|
+
removeStyleProperty(el, previousProp);
|
|
662
|
+
}
|
|
919
663
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
664
|
+
state.previousStyleProps = nextProps;
|
|
665
|
+
}
|
|
666
|
+
function removeStyleProperty(el, prop) {
|
|
667
|
+
if (prop.includes("-")) {
|
|
668
|
+
el.style.removeProperty(prop);
|
|
669
|
+
} else {
|
|
670
|
+
el.style[prop] = "";
|
|
923
671
|
}
|
|
924
|
-
const childrenHtml = children.map((child) => renderNodeH(child, ctx)).join("");
|
|
925
|
-
return `<${tag}${attrs}>${childrenHtml}</${tag}>`;
|
|
926
672
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
renderNodeToDOM: () => renderNodeToDOM,
|
|
939
|
-
renderElementToDOM: () => renderElementToDOM,
|
|
940
|
-
render: () => render,
|
|
941
|
-
registerPage: () => registerPage,
|
|
942
|
-
raw: () => raw,
|
|
943
|
-
provide: () => provide,
|
|
944
|
-
onUpdated: () => onUpdated,
|
|
945
|
-
onUnmounted: () => onUnmounted,
|
|
946
|
-
onMounted: () => onMounted,
|
|
947
|
-
onError: () => onError,
|
|
948
|
-
nextTick: () => nextTick,
|
|
949
|
-
mount: () => mount,
|
|
950
|
-
jsxs: () => jsxs,
|
|
951
|
-
jsxDEV: () => jsxDEV,
|
|
952
|
-
jsx: () => jsx,
|
|
953
|
-
isSignal: () => isSignal,
|
|
954
|
-
isSafeHtml: () => isSafeHtml,
|
|
955
|
-
isComputed: () => isComputed,
|
|
956
|
-
inject: () => inject,
|
|
957
|
-
hydrate: () => hydrate,
|
|
958
|
-
hasPage: () => hasPage,
|
|
959
|
-
getPage: () => getPage,
|
|
960
|
-
getCurrentInstance: () => getCurrentInstance,
|
|
961
|
-
escapeHtml: () => escapeHtml,
|
|
962
|
-
effect: () => effect,
|
|
963
|
-
createPage: () => createPage,
|
|
964
|
-
createLayout: () => createLayout,
|
|
965
|
-
createComponent: () => createComponent,
|
|
966
|
-
computed: () => computed,
|
|
967
|
-
batch: () => batch,
|
|
968
|
-
HtmlEscapedString: () => HtmlEscapedString,
|
|
969
|
-
Fragment: () => Fragment
|
|
970
|
-
});
|
|
971
|
-
module.exports = __toCommonJS(exports_src);
|
|
673
|
+
function applyClass(el, value) {
|
|
674
|
+
let classStr;
|
|
675
|
+
if (Array.isArray(value)) {
|
|
676
|
+
classStr = value.filter(Boolean).join(" ");
|
|
677
|
+
} else if (typeof value === "object" && value !== null) {
|
|
678
|
+
classStr = Object.entries(value).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
|
|
679
|
+
} else {
|
|
680
|
+
classStr = String(value);
|
|
681
|
+
}
|
|
682
|
+
domOps.setAttribute(el, "class", classStr);
|
|
683
|
+
}
|
|
972
684
|
// src/reactivity/batch.ts
|
|
973
685
|
var batchDepth = 0;
|
|
974
686
|
function batch(fn) {
|
|
@@ -982,150 +694,1734 @@ function batch(fn) {
|
|
|
982
694
|
}
|
|
983
695
|
}
|
|
984
696
|
}
|
|
985
|
-
// src/component/
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
697
|
+
// src/component/control-flow.ts
|
|
698
|
+
var SHOW_TYPE = Symbol.for("Sinwan.Show");
|
|
699
|
+
var FOR_TYPE = Symbol.for("Sinwan.For");
|
|
700
|
+
var SWITCH_TYPE = Symbol.for("Sinwan.Switch");
|
|
701
|
+
var MATCH_TYPE = Symbol.for("Sinwan.Match");
|
|
702
|
+
var INDEX_TYPE = Symbol.for("Sinwan.Index");
|
|
703
|
+
var KEY_TYPE = Symbol.for("Sinwan.Key");
|
|
704
|
+
var DYNAMIC_TYPE = Symbol.for("Sinwan.Dynamic");
|
|
705
|
+
var PORTAL_TYPE = Symbol.for("Sinwan.Portal");
|
|
706
|
+
function Show(props) {
|
|
707
|
+
return {
|
|
708
|
+
tag: SHOW_TYPE,
|
|
709
|
+
props,
|
|
710
|
+
children: []
|
|
711
|
+
};
|
|
992
712
|
}
|
|
993
|
-
function
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
713
|
+
function For(props) {
|
|
714
|
+
return {
|
|
715
|
+
tag: FOR_TYPE,
|
|
716
|
+
props,
|
|
717
|
+
children: []
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
function Switch(props) {
|
|
721
|
+
return {
|
|
722
|
+
tag: SWITCH_TYPE,
|
|
723
|
+
props,
|
|
724
|
+
children: []
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
function Match(props) {
|
|
728
|
+
return {
|
|
729
|
+
tag: MATCH_TYPE,
|
|
730
|
+
props,
|
|
731
|
+
children: []
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function Index(props) {
|
|
735
|
+
return {
|
|
736
|
+
tag: INDEX_TYPE,
|
|
737
|
+
props,
|
|
738
|
+
children: []
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
function Key(props) {
|
|
742
|
+
return {
|
|
743
|
+
tag: KEY_TYPE,
|
|
744
|
+
props,
|
|
745
|
+
children: []
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
function Dynamic(props) {
|
|
749
|
+
return {
|
|
750
|
+
tag: DYNAMIC_TYPE,
|
|
751
|
+
props,
|
|
752
|
+
children: []
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
function Visible(props) {
|
|
756
|
+
const {
|
|
757
|
+
when,
|
|
758
|
+
as = "span",
|
|
759
|
+
style,
|
|
760
|
+
children,
|
|
761
|
+
...rest
|
|
762
|
+
} = props;
|
|
763
|
+
const visibleStyle = computed(() => {
|
|
764
|
+
const base = readReactive(style);
|
|
765
|
+
const visible = Boolean(readReactive(when));
|
|
766
|
+
if (typeof base === "string") {
|
|
767
|
+
return visible ? base : appendHiddenDisplay(base);
|
|
768
|
+
}
|
|
769
|
+
const styleObject = base && typeof base === "object" ? { ...base } : {};
|
|
770
|
+
styleObject.display = visible ? styleObject.display : "none";
|
|
771
|
+
return styleObject;
|
|
772
|
+
});
|
|
773
|
+
return {
|
|
774
|
+
tag: as,
|
|
775
|
+
props: {
|
|
776
|
+
...rest,
|
|
777
|
+
style: visibleStyle,
|
|
778
|
+
children
|
|
779
|
+
},
|
|
780
|
+
children: normalizeChildren2(children)
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
function Portal(props) {
|
|
784
|
+
return {
|
|
785
|
+
tag: PORTAL_TYPE,
|
|
786
|
+
props,
|
|
787
|
+
children: []
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
function isShowElement(element) {
|
|
791
|
+
return element.tag === SHOW_TYPE;
|
|
792
|
+
}
|
|
793
|
+
function isForElement(element) {
|
|
794
|
+
return element.tag === FOR_TYPE;
|
|
795
|
+
}
|
|
796
|
+
function isSwitchElement(element) {
|
|
797
|
+
return element.tag === SWITCH_TYPE;
|
|
798
|
+
}
|
|
799
|
+
function isMatchElement(element) {
|
|
800
|
+
return element.tag === MATCH_TYPE;
|
|
801
|
+
}
|
|
802
|
+
function isIndexElement(element) {
|
|
803
|
+
return element.tag === INDEX_TYPE;
|
|
804
|
+
}
|
|
805
|
+
function isKeyElement(element) {
|
|
806
|
+
return element.tag === KEY_TYPE;
|
|
807
|
+
}
|
|
808
|
+
function isDynamicElement(element) {
|
|
809
|
+
return element.tag === DYNAMIC_TYPE;
|
|
810
|
+
}
|
|
811
|
+
function isPortalElement(element) {
|
|
812
|
+
return element.tag === PORTAL_TYPE;
|
|
813
|
+
}
|
|
814
|
+
function normalizeChildren2(children) {
|
|
815
|
+
if (children == null || typeof children === "boolean") {
|
|
816
|
+
return [];
|
|
817
|
+
}
|
|
818
|
+
return Array.isArray(children) ? children : [children];
|
|
819
|
+
}
|
|
820
|
+
function readReactive(value) {
|
|
821
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
822
|
+
}
|
|
823
|
+
function appendHiddenDisplay(style) {
|
|
824
|
+
const trimmed = style.trim();
|
|
825
|
+
const separator = trimmed.length > 0 && !trimmed.endsWith(";") ? ";" : "";
|
|
826
|
+
return `${trimmed}${separator}display:none`;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// src/renderer/unmount.ts
|
|
830
|
+
function getMountedDomNodes(node) {
|
|
831
|
+
switch (node.type) {
|
|
832
|
+
case "text":
|
|
833
|
+
case "reactive-text":
|
|
834
|
+
return [node.node];
|
|
835
|
+
case "element":
|
|
836
|
+
return [node.node];
|
|
837
|
+
case "fragment":
|
|
838
|
+
return [
|
|
839
|
+
node.anchor,
|
|
840
|
+
...node.children.flatMap((child) => getMountedDomNodes(child))
|
|
841
|
+
];
|
|
842
|
+
case "reactive-block":
|
|
843
|
+
return [
|
|
844
|
+
node.startAnchor,
|
|
845
|
+
...node.children.flatMap((child) => getMountedDomNodes(child)),
|
|
846
|
+
node.endAnchor
|
|
847
|
+
];
|
|
848
|
+
case "component":
|
|
849
|
+
return node.children.flatMap((child) => getMountedDomNodes(child));
|
|
850
|
+
case "portal":
|
|
851
|
+
return [node.anchor];
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
function unmountNode(node) {
|
|
855
|
+
switch (node.type) {
|
|
856
|
+
case "text":
|
|
857
|
+
break;
|
|
858
|
+
case "reactive-text":
|
|
859
|
+
node.dispose();
|
|
860
|
+
break;
|
|
861
|
+
case "element":
|
|
862
|
+
for (const dispose of node.attrDisposers) {
|
|
863
|
+
dispose();
|
|
864
|
+
}
|
|
865
|
+
for (const cleanup of node.eventCleanups) {
|
|
866
|
+
cleanup();
|
|
867
|
+
}
|
|
868
|
+
node.refCleanup?.();
|
|
869
|
+
for (const child of node.children) {
|
|
870
|
+
unmountNode(child);
|
|
871
|
+
}
|
|
872
|
+
break;
|
|
873
|
+
case "fragment":
|
|
874
|
+
for (const child of node.children) {
|
|
875
|
+
unmountNode(child);
|
|
876
|
+
}
|
|
877
|
+
break;
|
|
878
|
+
case "reactive-block":
|
|
879
|
+
node.dispose();
|
|
880
|
+
for (const child of node.children) {
|
|
881
|
+
unmountNode(child);
|
|
882
|
+
}
|
|
883
|
+
break;
|
|
884
|
+
case "component":
|
|
885
|
+
if (node.instance) {
|
|
886
|
+
fireUnmountedHooks(node.instance);
|
|
887
|
+
} else {
|
|
888
|
+
for (const dispose of node.disposers) {
|
|
889
|
+
dispose();
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
for (const child of node.children) {
|
|
893
|
+
unmountNode(child);
|
|
894
|
+
}
|
|
895
|
+
break;
|
|
896
|
+
case "portal":
|
|
897
|
+
node.dispose();
|
|
898
|
+
for (const child of node.children) {
|
|
899
|
+
removeMountedNode(child);
|
|
900
|
+
}
|
|
901
|
+
node.children = [];
|
|
902
|
+
break;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
function removeMountedNode(node) {
|
|
906
|
+
const domNodes = getMountedDomNodes(node);
|
|
907
|
+
unmountNode(node);
|
|
908
|
+
for (const domNode of domNodes) {
|
|
909
|
+
if (domNode.parentNode) {
|
|
910
|
+
domOps.remove(domNode);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// src/renderer/render-control-flow.ts
|
|
916
|
+
function renderControlFlowToDOM(element, parent, anchor, namespace) {
|
|
917
|
+
if (isPortalElement(element)) {
|
|
918
|
+
return renderPortal(element, parent, anchor, namespace);
|
|
919
|
+
}
|
|
920
|
+
const startAnchor = domOps.createComment("Sinwan-b");
|
|
921
|
+
const endAnchor = domOps.createComment("/Sinwan-b");
|
|
922
|
+
insertNode(parent, startAnchor, anchor);
|
|
923
|
+
insertNode(parent, endAnchor, anchor);
|
|
924
|
+
const owner = getCurrentInstance();
|
|
925
|
+
let disposeEffect = () => {};
|
|
926
|
+
const block = {
|
|
927
|
+
type: "reactive-block",
|
|
928
|
+
dispose: () => disposeEffect(),
|
|
929
|
+
children: [],
|
|
930
|
+
startAnchor,
|
|
931
|
+
endAnchor
|
|
932
|
+
};
|
|
933
|
+
if (isShowElement(element)) {
|
|
934
|
+
disposeEffect = renderShowBlock(element, block, parent, namespace, owner);
|
|
935
|
+
} else if (isForElement(element)) {
|
|
936
|
+
disposeEffect = renderForBlock(element, block, parent, namespace, owner);
|
|
937
|
+
} else if (isSwitchElement(element)) {
|
|
938
|
+
disposeEffect = renderSwitchBlock(element, block, parent, namespace, owner);
|
|
939
|
+
} else if (isIndexElement(element)) {
|
|
940
|
+
disposeEffect = renderIndexBlock(element, block, parent, namespace, owner);
|
|
941
|
+
} else if (isKeyElement(element)) {
|
|
942
|
+
disposeEffect = renderKeyBlock(element, block, parent, namespace, owner);
|
|
943
|
+
} else if (isDynamicElement(element)) {
|
|
944
|
+
disposeEffect = renderDynamicBlock(element, block, parent, namespace, owner);
|
|
945
|
+
}
|
|
946
|
+
return block;
|
|
947
|
+
}
|
|
948
|
+
function renderShowBlock(element, block, parent, namespace, owner) {
|
|
949
|
+
let initialized = false;
|
|
950
|
+
return effect(() => {
|
|
951
|
+
clearChildren(block);
|
|
952
|
+
const when = readReactive2(element.props.when);
|
|
953
|
+
const content = withOptionalInstance(owner, () => when ? resolveShowChildren(element, when) : element.props.fallback);
|
|
954
|
+
block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
|
|
955
|
+
if (initialized) {
|
|
956
|
+
fireMountedAndQueueUpdated(owner);
|
|
957
|
+
}
|
|
958
|
+
initialized = true;
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
function renderForBlock(element, block, parent, namespace, owner) {
|
|
962
|
+
let initialized = false;
|
|
963
|
+
let records = [];
|
|
964
|
+
return effect(() => {
|
|
965
|
+
const props = element.props;
|
|
966
|
+
const items = readReactive2(props.each);
|
|
967
|
+
const list = Array.isArray(items) ? items : [];
|
|
968
|
+
const renderChild = props.children;
|
|
969
|
+
if (typeof renderChild !== "function") {
|
|
970
|
+
clearChildren(block);
|
|
971
|
+
records = [];
|
|
972
|
+
if (initialized) {
|
|
973
|
+
queueUpdatedHooks(owner);
|
|
974
|
+
}
|
|
975
|
+
initialized = true;
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
if (list.length === 0) {
|
|
979
|
+
clearChildren(block);
|
|
980
|
+
records = [];
|
|
981
|
+
block.children = renderBlockContent(props.fallback, parent, block.endAnchor, namespace, owner);
|
|
982
|
+
if (initialized) {
|
|
983
|
+
fireMountedAndQueueUpdated(owner);
|
|
984
|
+
}
|
|
985
|
+
initialized = true;
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
if (records.length === 0 && block.children.length > 0) {
|
|
989
|
+
clearChildren(block);
|
|
990
|
+
}
|
|
991
|
+
const oldByKey = new Map;
|
|
992
|
+
for (const record of records) {
|
|
993
|
+
oldByKey.set(record.key, record);
|
|
994
|
+
}
|
|
995
|
+
const nextRecords = [];
|
|
996
|
+
list.forEach((item, index) => {
|
|
997
|
+
const key = props.key ? props.key(item, index) : item;
|
|
998
|
+
const old = oldByKey.get(key);
|
|
999
|
+
if (old && old.item === item) {
|
|
1000
|
+
old.index = index;
|
|
1001
|
+
moveBeforeEnd(parent, old.mounted, block.endAnchor);
|
|
1002
|
+
nextRecords.push(old);
|
|
1003
|
+
oldByKey.delete(key);
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
if (old) {
|
|
1007
|
+
removeMountedNode(old.mounted);
|
|
1008
|
+
oldByKey.delete(key);
|
|
1009
|
+
}
|
|
1010
|
+
const record = {
|
|
1011
|
+
key,
|
|
1012
|
+
item,
|
|
1013
|
+
index,
|
|
1014
|
+
mounted: { type: "text", node: domOps.createTextNode("") }
|
|
1015
|
+
};
|
|
1016
|
+
record.mounted = withOptionalInstance(owner, () => renderNodeToDOM(renderChild(item, () => record.index), parent, block.endAnchor, namespace));
|
|
1017
|
+
nextRecords.push(record);
|
|
1018
|
+
});
|
|
1019
|
+
for (const record of oldByKey.values()) {
|
|
1020
|
+
removeMountedNode(record.mounted);
|
|
1021
|
+
}
|
|
1022
|
+
records = nextRecords;
|
|
1023
|
+
block.children = nextRecords.map((record) => record.mounted);
|
|
1024
|
+
if (initialized) {
|
|
1025
|
+
fireMountedAndQueueUpdated(owner);
|
|
1026
|
+
}
|
|
1027
|
+
initialized = true;
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
function renderSwitchBlock(element, block, parent, namespace, owner) {
|
|
1031
|
+
let initialized = false;
|
|
1032
|
+
return effect(() => {
|
|
1033
|
+
clearChildren(block);
|
|
1034
|
+
const content = withOptionalInstance(owner, () => resolveSwitchContent(element));
|
|
1035
|
+
block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
|
|
1036
|
+
if (initialized) {
|
|
1037
|
+
fireMountedAndQueueUpdated(owner);
|
|
1038
|
+
}
|
|
1039
|
+
initialized = true;
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
function renderIndexBlock(element, block, parent, namespace, owner) {
|
|
1043
|
+
let initialized = false;
|
|
1044
|
+
let records = [];
|
|
1045
|
+
return effect(() => {
|
|
1046
|
+
const props = element.props;
|
|
1047
|
+
const items = readReactive2(props.each);
|
|
1048
|
+
const list = Array.isArray(items) ? items : [];
|
|
1049
|
+
const renderChild = props.children;
|
|
1050
|
+
if (typeof renderChild !== "function") {
|
|
1051
|
+
clearChildren(block);
|
|
1052
|
+
records = [];
|
|
1053
|
+
if (initialized) {
|
|
1054
|
+
queueUpdatedHooks(owner);
|
|
1055
|
+
}
|
|
1056
|
+
initialized = true;
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
if (list.length === 0) {
|
|
1060
|
+
clearChildren(block);
|
|
1061
|
+
records = [];
|
|
1062
|
+
block.children = renderBlockContent(props.fallback, parent, block.endAnchor, namespace, owner);
|
|
1063
|
+
if (initialized) {
|
|
1064
|
+
fireMountedAndQueueUpdated(owner);
|
|
1065
|
+
}
|
|
1066
|
+
initialized = true;
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
if (records.length === 0 && block.children.length > 0) {
|
|
1070
|
+
clearChildren(block);
|
|
1071
|
+
}
|
|
1072
|
+
for (let index = 0;index < list.length; index++) {
|
|
1073
|
+
const existing = records[index];
|
|
1074
|
+
if (existing) {
|
|
1075
|
+
existing.item.value = list[index];
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
const itemSignal = signal(list[index]);
|
|
1079
|
+
const record = {
|
|
1080
|
+
item: itemSignal,
|
|
1081
|
+
mounted: withOptionalInstance(owner, () => renderNodeToDOM(renderChild(() => itemSignal.value, index), parent, block.endAnchor, namespace))
|
|
1082
|
+
};
|
|
1083
|
+
records.push(record);
|
|
1084
|
+
}
|
|
1085
|
+
while (records.length > list.length) {
|
|
1086
|
+
const removed = records.pop();
|
|
1087
|
+
removeMountedNode(removed.mounted);
|
|
1088
|
+
}
|
|
1089
|
+
block.children = records.map((record) => record.mounted);
|
|
1090
|
+
if (initialized) {
|
|
1091
|
+
fireMountedAndQueueUpdated(owner);
|
|
1092
|
+
}
|
|
1093
|
+
initialized = true;
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
function renderKeyBlock(element, block, parent, namespace, owner) {
|
|
1097
|
+
let initialized = false;
|
|
1098
|
+
let hasKey = false;
|
|
1099
|
+
let currentKey;
|
|
1100
|
+
return effect(() => {
|
|
1101
|
+
const key = readReactive2(element.props.when);
|
|
1102
|
+
if (hasKey && Object.is(currentKey, key)) {
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
currentKey = key;
|
|
1106
|
+
hasKey = true;
|
|
1107
|
+
clearChildren(block);
|
|
1108
|
+
const content = withOptionalInstance(owner, () => resolveKeyChildren(element, key));
|
|
1109
|
+
block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
|
|
1110
|
+
if (initialized) {
|
|
1111
|
+
fireMountedAndQueueUpdated(owner);
|
|
1112
|
+
}
|
|
1113
|
+
initialized = true;
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
function renderDynamicBlock(element, block, parent, namespace, owner) {
|
|
1117
|
+
let initialized = false;
|
|
1118
|
+
let hasTag = false;
|
|
1119
|
+
let currentTag;
|
|
1120
|
+
return effect(() => {
|
|
1121
|
+
const tag = readReactive2(element.props.component);
|
|
1122
|
+
if (hasTag && Object.is(currentTag, tag)) {
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
currentTag = tag;
|
|
1126
|
+
hasTag = true;
|
|
1127
|
+
clearChildren(block);
|
|
1128
|
+
const content = tag ? createDynamicElement(element, tag) : null;
|
|
1129
|
+
block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
|
|
1130
|
+
if (initialized) {
|
|
1131
|
+
fireMountedAndQueueUpdated(owner);
|
|
1132
|
+
}
|
|
1133
|
+
initialized = true;
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
function renderPortal(element, parent, anchor, namespace) {
|
|
1137
|
+
const placeholder = domOps.createComment("Sinwan-p");
|
|
1138
|
+
insertNode(parent, placeholder, anchor);
|
|
1139
|
+
const owner = getCurrentInstance();
|
|
1140
|
+
let disposeEffect = () => {};
|
|
1141
|
+
const portal = {
|
|
1142
|
+
type: "portal",
|
|
1143
|
+
anchor: placeholder,
|
|
1144
|
+
children: [],
|
|
1145
|
+
dispose: () => disposeEffect()
|
|
1146
|
+
};
|
|
1147
|
+
let initialized = false;
|
|
1148
|
+
disposeEffect = effect(() => {
|
|
1149
|
+
clearPortalChildren(portal);
|
|
1150
|
+
const target = resolvePortalTarget(element.props.mount);
|
|
1151
|
+
if (target) {
|
|
1152
|
+
portal.children = renderBlockContent(element.props.children ?? element.children, target, null, namespace, owner);
|
|
1153
|
+
}
|
|
1154
|
+
if (initialized) {
|
|
1155
|
+
fireMountedAndQueueUpdated(owner);
|
|
1156
|
+
}
|
|
1157
|
+
initialized = true;
|
|
1158
|
+
});
|
|
1159
|
+
return portal;
|
|
1160
|
+
}
|
|
1161
|
+
function resolveShowChildren(element, value) {
|
|
1162
|
+
const children = element.props.children ?? element.children;
|
|
1163
|
+
if (typeof children === "function") {
|
|
1164
|
+
return children(value);
|
|
1165
|
+
}
|
|
1166
|
+
return children;
|
|
1167
|
+
}
|
|
1168
|
+
function resolveSwitchContent(element) {
|
|
1169
|
+
const props = element.props;
|
|
1170
|
+
const children = normalizeContent(props.children ?? element.children);
|
|
1171
|
+
for (const child of children) {
|
|
1172
|
+
const match = getMatchElement(child);
|
|
1173
|
+
if (!match) {
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
const when = readReactive2(match.props.when);
|
|
1177
|
+
if (when) {
|
|
1178
|
+
return resolveMatchChildren(match, when);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
return props.fallback;
|
|
1182
|
+
}
|
|
1183
|
+
function resolveMatchChildren(element, value) {
|
|
1184
|
+
const children = element.props.children ?? element.children;
|
|
1185
|
+
if (typeof children === "function") {
|
|
1186
|
+
return children(value);
|
|
1187
|
+
}
|
|
1188
|
+
return children;
|
|
1189
|
+
}
|
|
1190
|
+
function resolveKeyChildren(element, value) {
|
|
1191
|
+
const children = element.props.children ?? element.children;
|
|
1192
|
+
if (typeof children === "function") {
|
|
1193
|
+
return children(value);
|
|
1194
|
+
}
|
|
1195
|
+
return children;
|
|
1196
|
+
}
|
|
1197
|
+
function createDynamicElement(element, tag) {
|
|
1198
|
+
if (typeof tag !== "string" && typeof tag !== "function") {
|
|
1199
|
+
return null;
|
|
1200
|
+
}
|
|
1201
|
+
const { component, ...props } = element.props;
|
|
1202
|
+
const children = normalizeContent(props.children ?? element.children);
|
|
1203
|
+
return {
|
|
1204
|
+
tag,
|
|
1205
|
+
props,
|
|
1206
|
+
children
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
function renderBlockContent(content, parent, anchor, namespace, owner) {
|
|
1210
|
+
if (content == null || typeof content === "boolean") {
|
|
1211
|
+
return [];
|
|
1212
|
+
}
|
|
1213
|
+
const nodes = Array.isArray(content) ? content : [content];
|
|
1214
|
+
return nodes.map((node) => withOptionalInstance(owner, () => renderNodeToDOM(node, parent, anchor, namespace)));
|
|
1215
|
+
}
|
|
1216
|
+
function clearChildren(block) {
|
|
1217
|
+
for (const child of block.children) {
|
|
1218
|
+
removeMountedNode(child);
|
|
1219
|
+
}
|
|
1220
|
+
block.children = [];
|
|
1221
|
+
}
|
|
1222
|
+
function clearPortalChildren(portal) {
|
|
1223
|
+
for (const child of portal.children) {
|
|
1224
|
+
removeMountedNode(child);
|
|
1225
|
+
}
|
|
1226
|
+
portal.children = [];
|
|
1227
|
+
}
|
|
1228
|
+
function moveBeforeEnd(parent, mounted, endAnchor) {
|
|
1229
|
+
for (const node of getMountedDomNodes(mounted)) {
|
|
1230
|
+
domOps.insertBefore(parent, node, endAnchor);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
function fireMountedAndQueueUpdated(owner) {
|
|
1234
|
+
if (owner) {
|
|
1235
|
+
fireMountedHooks(owner);
|
|
1236
|
+
}
|
|
1237
|
+
queueUpdatedHooks(owner);
|
|
1238
|
+
}
|
|
1239
|
+
function withOptionalInstance(owner, fn) {
|
|
1240
|
+
return owner ? withInstance(owner, fn) : fn();
|
|
1241
|
+
}
|
|
1242
|
+
function readReactive2(value) {
|
|
1243
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
1244
|
+
}
|
|
1245
|
+
function normalizeContent(content) {
|
|
1246
|
+
if (content == null || typeof content === "boolean") {
|
|
1247
|
+
return [];
|
|
1248
|
+
}
|
|
1249
|
+
return Array.isArray(content) ? content : [content];
|
|
1250
|
+
}
|
|
1251
|
+
function isElementLike(value) {
|
|
1252
|
+
return value != null && typeof value === "object" && "tag" in value;
|
|
1253
|
+
}
|
|
1254
|
+
function getMatchElement(value) {
|
|
1255
|
+
if (!isElementLike(value)) {
|
|
1256
|
+
return null;
|
|
1257
|
+
}
|
|
1258
|
+
if (isMatchElement(value)) {
|
|
1259
|
+
return value;
|
|
1260
|
+
}
|
|
1261
|
+
return value.tag === Match ? Match(value.props) : null;
|
|
1262
|
+
}
|
|
1263
|
+
function resolvePortalTarget(value) {
|
|
1264
|
+
const target = readReactive2(value);
|
|
1265
|
+
if (target == null) {
|
|
1266
|
+
return typeof document === "undefined" ? null : document.body;
|
|
1267
|
+
}
|
|
1268
|
+
if (typeof target === "string") {
|
|
1269
|
+
return document.querySelector(target);
|
|
1270
|
+
}
|
|
1271
|
+
if (typeof target === "function") {
|
|
1272
|
+
return target();
|
|
1273
|
+
}
|
|
1274
|
+
if (typeof target === "object" && "nodeType" in target) {
|
|
1275
|
+
return target;
|
|
1276
|
+
}
|
|
1277
|
+
return null;
|
|
1278
|
+
}
|
|
1279
|
+
function insertNode(parent, child, anchor) {
|
|
1280
|
+
if (anchor) {
|
|
1281
|
+
domOps.insertBefore(parent, child, anchor);
|
|
1282
|
+
} else {
|
|
1283
|
+
domOps.appendChild(parent, child);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/renderer/render-element.ts
|
|
1288
|
+
var VOID_ELEMENTS2 = new Set([
|
|
1289
|
+
"area",
|
|
1290
|
+
"base",
|
|
1291
|
+
"br",
|
|
1292
|
+
"col",
|
|
1293
|
+
"embed",
|
|
1294
|
+
"hr",
|
|
1295
|
+
"img",
|
|
1296
|
+
"input",
|
|
1297
|
+
"link",
|
|
1298
|
+
"meta",
|
|
1299
|
+
"param",
|
|
1300
|
+
"source",
|
|
1301
|
+
"track",
|
|
1302
|
+
"wbr"
|
|
1303
|
+
]);
|
|
1304
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1305
|
+
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
|
|
1306
|
+
function renderElementToDOM(element, parent, anchor = null, namespace = null) {
|
|
1307
|
+
const { tag, props, children } = element;
|
|
1308
|
+
if (tag === "" || tag === Fragment) {
|
|
1309
|
+
return renderFragmentToDOM(children, parent, anchor, namespace);
|
|
1310
|
+
}
|
|
1311
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
1312
|
+
return renderElementToDOM(tag(props), parent, anchor, namespace);
|
|
1313
|
+
}
|
|
1314
|
+
if (tag === Visible) {
|
|
1315
|
+
return renderElementToDOM(tag(props), parent, anchor, namespace);
|
|
1316
|
+
}
|
|
1317
|
+
if (isShowElement(element) || isForElement(element) || isSwitchElement(element) || isIndexElement(element) || isKeyElement(element) || isDynamicElement(element) || isPortalElement(element)) {
|
|
1318
|
+
return renderControlFlowToDOM(element, parent, anchor, namespace);
|
|
1319
|
+
}
|
|
1320
|
+
if (typeof tag === "function") {
|
|
1321
|
+
return renderComponentToDOM(tag, props, parent, anchor, namespace);
|
|
1322
|
+
}
|
|
1323
|
+
if (typeof tag === "string") {
|
|
1324
|
+
return renderIntrinsicToDOM(tag, props, children, parent, anchor, namespace);
|
|
1325
|
+
}
|
|
1326
|
+
return renderFragmentToDOM(children, parent, anchor, namespace);
|
|
1327
|
+
}
|
|
1328
|
+
function renderIntrinsicToDOM(tag, props, children, parent, anchor, parentNamespace) {
|
|
1329
|
+
const namespace = getElementNamespace(tag, parentNamespace);
|
|
1330
|
+
const el = namespace ? domOps.createElementNS(namespace, tag) : domOps.createElement(tag);
|
|
1331
|
+
const attrDisposers = applyAttributes(el, props);
|
|
1332
|
+
const eventCleanups = bindEvents(el, props);
|
|
1333
|
+
let mountedChildren = [];
|
|
1334
|
+
if (!VOID_ELEMENTS2.has(tag)) {
|
|
1335
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
1336
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
1337
|
+
el.innerHTML = dangerous.__html;
|
|
1338
|
+
} else {
|
|
1339
|
+
mountedChildren = renderChildrenToDOM(children, el, getChildNamespace(tag, namespace));
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (anchor) {
|
|
1343
|
+
domOps.insertBefore(parent, el, anchor);
|
|
1344
|
+
} else {
|
|
1345
|
+
domOps.appendChild(parent, el);
|
|
1346
|
+
}
|
|
1347
|
+
const refCleanup = applyRef(el, props.ref);
|
|
1348
|
+
return {
|
|
1349
|
+
type: "element",
|
|
1350
|
+
node: el,
|
|
1351
|
+
children: mountedChildren,
|
|
1352
|
+
eventCleanups,
|
|
1353
|
+
attrDisposers,
|
|
1354
|
+
refCleanup
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
function renderComponentToDOM(component, props, parent, anchor, namespace) {
|
|
1358
|
+
const parentInstance = getCurrentInstance();
|
|
1359
|
+
const instance = createComponentInstance(component, props, parentInstance);
|
|
1360
|
+
if (parentInstance) {
|
|
1361
|
+
parentInstance.children.push(instance);
|
|
1362
|
+
}
|
|
1363
|
+
const prevInstance = setCurrentInstance(instance);
|
|
1364
|
+
let result;
|
|
1365
|
+
let child;
|
|
1366
|
+
try {
|
|
1367
|
+
result = component(props);
|
|
1368
|
+
if (result && typeof result === "object" && "tag" in result) {
|
|
1369
|
+
child = renderElementToDOM(result, parent, anchor, namespace);
|
|
1370
|
+
} else {
|
|
1371
|
+
child = renderNodeToDOM(result, parent, anchor, namespace);
|
|
1372
|
+
}
|
|
1373
|
+
} catch (err) {
|
|
1374
|
+
setCurrentInstance(prevInstance);
|
|
1375
|
+
handleComponentError(instance, err);
|
|
1376
|
+
const text = domOps.createTextNode("");
|
|
1377
|
+
if (anchor) {
|
|
1378
|
+
domOps.insertBefore(parent, text, anchor);
|
|
1379
|
+
} else {
|
|
1380
|
+
domOps.appendChild(parent, text);
|
|
1381
|
+
}
|
|
1382
|
+
return {
|
|
1383
|
+
type: "component",
|
|
1384
|
+
children: [{ type: "text", node: text }],
|
|
1385
|
+
disposers: [],
|
|
1386
|
+
instance
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
setCurrentInstance(prevInstance);
|
|
1390
|
+
instance.element = child;
|
|
1391
|
+
return {
|
|
1392
|
+
type: "component",
|
|
1393
|
+
children: [child],
|
|
1394
|
+
disposers: instance.effects,
|
|
1395
|
+
instance
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
function renderFragmentToDOM(children, parent, anchor, namespace) {
|
|
1399
|
+
const anchorComment = domOps.createComment("Sinwan-f");
|
|
1400
|
+
if (anchor) {
|
|
1401
|
+
domOps.insertBefore(parent, anchorComment, anchor);
|
|
1402
|
+
} else {
|
|
1403
|
+
domOps.appendChild(parent, anchorComment);
|
|
1404
|
+
}
|
|
1405
|
+
const mounted = [];
|
|
1406
|
+
for (const child of children) {
|
|
1407
|
+
mounted.push(renderNodeToDOM(child, parent, anchor, namespace));
|
|
1408
|
+
}
|
|
1409
|
+
return { type: "fragment", children: mounted, anchor: anchorComment };
|
|
1410
|
+
}
|
|
1411
|
+
function getElementNamespace(tag, parentNamespace) {
|
|
1412
|
+
if (tag === "svg")
|
|
1413
|
+
return SVG_NS;
|
|
1414
|
+
if (tag === "math")
|
|
1415
|
+
return MATH_NS;
|
|
1416
|
+
return parentNamespace;
|
|
1417
|
+
}
|
|
1418
|
+
function getChildNamespace(tag, namespace) {
|
|
1419
|
+
if (namespace === SVG_NS && tag === "foreignObject") {
|
|
1420
|
+
return null;
|
|
1421
|
+
}
|
|
1422
|
+
return namespace;
|
|
1423
|
+
}
|
|
1424
|
+
function applyRef(el, ref) {
|
|
1425
|
+
const value = ref;
|
|
1426
|
+
if (!value) {
|
|
1427
|
+
return null;
|
|
1428
|
+
}
|
|
1429
|
+
if (typeof value === "function") {
|
|
1430
|
+
value(el);
|
|
1431
|
+
return () => value(null);
|
|
1432
|
+
}
|
|
1433
|
+
if (typeof value === "object" && "current" in value) {
|
|
1434
|
+
value.current = el;
|
|
1435
|
+
return () => {
|
|
1436
|
+
value.current = null;
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
return null;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
// src/renderer/render-children.ts
|
|
1443
|
+
function renderNodeToDOM(node, parent, anchor = null, namespace = null) {
|
|
1444
|
+
if (node == null || typeof node === "boolean") {
|
|
1445
|
+
const text2 = domOps.createTextNode("");
|
|
1446
|
+
insertNode2(parent, text2, anchor);
|
|
1447
|
+
return { type: "text", node: text2 };
|
|
1448
|
+
}
|
|
1449
|
+
if (typeof node === "string") {
|
|
1450
|
+
const text2 = domOps.createTextNode(node);
|
|
1451
|
+
insertNode2(parent, text2, anchor);
|
|
1452
|
+
return { type: "text", node: text2 };
|
|
1453
|
+
}
|
|
1454
|
+
if (typeof node === "number") {
|
|
1455
|
+
const text2 = domOps.createTextNode(String(node));
|
|
1456
|
+
insertNode2(parent, text2, anchor);
|
|
1457
|
+
return { type: "text", node: text2 };
|
|
1458
|
+
}
|
|
1459
|
+
if (node instanceof HtmlEscapedString) {
|
|
1460
|
+
const text2 = domOps.createTextNode(node.value);
|
|
1461
|
+
insertNode2(parent, text2, anchor);
|
|
1462
|
+
return { type: "text", node: text2 };
|
|
1463
|
+
}
|
|
1464
|
+
if (isSignal(node) || isComputed(node)) {
|
|
1465
|
+
const text2 = domOps.createTextNode(String(node.value));
|
|
1466
|
+
insertNode2(parent, text2, anchor);
|
|
1467
|
+
const owner = getCurrentInstance();
|
|
1468
|
+
let initialized = false;
|
|
1469
|
+
const dispose = effect(() => {
|
|
1470
|
+
domOps.setTextContent(text2, String(node.value));
|
|
1471
|
+
if (initialized) {
|
|
1472
|
+
queueUpdatedHooks(owner);
|
|
1473
|
+
}
|
|
1474
|
+
initialized = true;
|
|
1475
|
+
});
|
|
1476
|
+
return { type: "reactive-text", node: text2, dispose };
|
|
1477
|
+
}
|
|
1478
|
+
if (Array.isArray(node)) {
|
|
1479
|
+
return renderArrayToDOM(node, parent, anchor, namespace);
|
|
1480
|
+
}
|
|
1481
|
+
if (node instanceof Promise) {
|
|
1482
|
+
const placeholder = domOps.createTextNode("");
|
|
1483
|
+
insertNode2(parent, placeholder, anchor);
|
|
1484
|
+
node.then((resolved) => {
|
|
1485
|
+
const mounted = renderNodeToDOM(resolved, parent, placeholder, namespace);
|
|
1486
|
+
domOps.remove(placeholder);
|
|
1487
|
+
});
|
|
1488
|
+
return { type: "text", node: placeholder };
|
|
1489
|
+
}
|
|
1490
|
+
if (typeof node === "object" && "tag" in node) {
|
|
1491
|
+
return renderElementToDOM(node, parent, anchor, namespace);
|
|
1492
|
+
}
|
|
1493
|
+
const text = domOps.createTextNode(String(node));
|
|
1494
|
+
insertNode2(parent, text, anchor);
|
|
1495
|
+
return { type: "text", node: text };
|
|
1496
|
+
}
|
|
1497
|
+
function renderArrayToDOM(nodes, parent, anchor, namespace) {
|
|
1498
|
+
const anchorComment = domOps.createComment("Sinwan-f");
|
|
1499
|
+
insertNode2(parent, anchorComment, anchor);
|
|
1500
|
+
const children = [];
|
|
1501
|
+
for (const child of nodes) {
|
|
1502
|
+
children.push(renderNodeToDOM(child, parent, anchor, namespace));
|
|
1503
|
+
}
|
|
1504
|
+
return { type: "fragment", children, anchor: anchorComment };
|
|
1505
|
+
}
|
|
1506
|
+
function renderChildrenToDOM(children, parent, namespace = null) {
|
|
1507
|
+
const mounted = [];
|
|
1508
|
+
for (const child of children) {
|
|
1509
|
+
mounted.push(renderNodeToDOM(child, parent, null, namespace));
|
|
1510
|
+
}
|
|
1511
|
+
return mounted;
|
|
1512
|
+
}
|
|
1513
|
+
function insertNode2(parent, child, anchor) {
|
|
1514
|
+
if (anchor) {
|
|
1515
|
+
domOps.insertBefore(parent, child, anchor);
|
|
1516
|
+
} else {
|
|
1517
|
+
domOps.appendChild(parent, child);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// src/renderer/mount.ts
|
|
1522
|
+
function mount(component, container, props) {
|
|
1523
|
+
container.innerHTML = "";
|
|
1524
|
+
const mergedProps = props ?? {};
|
|
1525
|
+
const instance = createComponentInstance(component, mergedProps, null);
|
|
1526
|
+
let result;
|
|
1527
|
+
let root;
|
|
1528
|
+
setCurrentInstance(instance);
|
|
1529
|
+
try {
|
|
1530
|
+
result = component(mergedProps);
|
|
1531
|
+
if (result instanceof Promise) {
|
|
1532
|
+
const placeholder = document.createTextNode("");
|
|
1533
|
+
container.appendChild(placeholder);
|
|
1534
|
+
root = { type: "text", node: placeholder };
|
|
1535
|
+
result.then((resolved) => {
|
|
1536
|
+
container.innerHTML = "";
|
|
1537
|
+
setCurrentInstance(instance);
|
|
1538
|
+
root = renderElementToDOM(resolved, container);
|
|
1539
|
+
setCurrentInstance(null);
|
|
1540
|
+
instance.element = root;
|
|
1541
|
+
fireMountedHooks(instance);
|
|
1542
|
+
});
|
|
1543
|
+
} else if (result && typeof result === "object" && "tag" in result) {
|
|
1544
|
+
root = renderElementToDOM(result, container);
|
|
1545
|
+
} else {
|
|
1546
|
+
root = renderNodeToDOM(result, container);
|
|
1547
|
+
}
|
|
1548
|
+
} catch (err) {
|
|
1549
|
+
setCurrentInstance(null);
|
|
1550
|
+
handleComponentError(instance, err);
|
|
1551
|
+
return {
|
|
1552
|
+
root: { type: "text", node: document.createTextNode("") },
|
|
1553
|
+
unmount() {}
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
setCurrentInstance(null);
|
|
1557
|
+
instance.element = root;
|
|
1558
|
+
fireMountedHooks(instance);
|
|
1559
|
+
return {
|
|
1560
|
+
root,
|
|
1561
|
+
unmount() {
|
|
1562
|
+
fireUnmountedHooks(instance);
|
|
1563
|
+
unmountNode(root);
|
|
1564
|
+
container.innerHTML = "";
|
|
1565
|
+
}
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
function render(node, container) {
|
|
1569
|
+
container.innerHTML = "";
|
|
1570
|
+
const root = renderNodeToDOM(node, container);
|
|
1571
|
+
return {
|
|
1572
|
+
root,
|
|
1573
|
+
unmount() {
|
|
1574
|
+
unmountNode(root);
|
|
1575
|
+
container.innerHTML = "";
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
// src/server/index.ts
|
|
1580
|
+
var exports_server = {};
|
|
1581
|
+
__export(exports_server, {
|
|
1582
|
+
streamPage: () => streamPage,
|
|
1583
|
+
streamHydratablePage: () => streamHydratablePage,
|
|
1584
|
+
streamHydratableNode: () => streamHydratableNode,
|
|
1585
|
+
renderToString: () => renderToString,
|
|
1586
|
+
renderToHydratableString: () => renderToHydratableString,
|
|
1587
|
+
renderPage: () => renderPage,
|
|
1588
|
+
renderNodeToHydratableString: () => renderNodeToHydratableString,
|
|
1589
|
+
registerPage: () => registerPage,
|
|
1590
|
+
isSlots: () => isSlots,
|
|
1591
|
+
hasPage: () => hasPage,
|
|
1592
|
+
getPage: () => getPage
|
|
1593
|
+
});
|
|
1594
|
+
module.exports = __toCommonJS(exports_server);
|
|
1595
|
+
|
|
1596
|
+
// src/escaper.ts
|
|
1597
|
+
var _bun = globalThis.Bun;
|
|
1598
|
+
var _nativeEscape = typeof _bun?.escapeHTML === "function" ? _bun.escapeHTML.bind(_bun) : undefined;
|
|
1599
|
+
var HTML_ESCAPE_RE = /[&<>"']/g;
|
|
1600
|
+
var HTML_ESCAPE_MAP = {
|
|
1601
|
+
"&": "&",
|
|
1602
|
+
"<": "<",
|
|
1603
|
+
">": ">",
|
|
1604
|
+
'"': """,
|
|
1605
|
+
"'": "'"
|
|
1606
|
+
};
|
|
1607
|
+
function portableEscape(str) {
|
|
1608
|
+
HTML_ESCAPE_RE.lastIndex = 0;
|
|
1609
|
+
if (!HTML_ESCAPE_RE.test(str))
|
|
1610
|
+
return str;
|
|
1611
|
+
return str.replace(HTML_ESCAPE_RE, (c) => HTML_ESCAPE_MAP[c]);
|
|
1612
|
+
}
|
|
1613
|
+
function escapeHtml(value) {
|
|
1614
|
+
if (value == null || typeof value === "boolean")
|
|
1615
|
+
return "";
|
|
1616
|
+
if (typeof value === "number")
|
|
1617
|
+
return String(value);
|
|
1618
|
+
if (value instanceof HtmlEscapedString)
|
|
1619
|
+
return value.value;
|
|
1620
|
+
const s = String(value);
|
|
1621
|
+
return _nativeEscape ? _nativeEscape(s) : portableEscape(s);
|
|
1622
|
+
}
|
|
1623
|
+
function safeHtml(html) {
|
|
1624
|
+
return raw(html);
|
|
1625
|
+
}
|
|
1626
|
+
function isSafeHtml(value) {
|
|
1627
|
+
return value instanceof HtmlEscapedString;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// src/server/attribute-utils.ts
|
|
1631
|
+
var PROP_ALIASES2 = {
|
|
1632
|
+
className: "class",
|
|
1633
|
+
htmlFor: "for",
|
|
1634
|
+
tabIndex: "tabindex",
|
|
1635
|
+
crossOrigin: "crossorigin"
|
|
1636
|
+
};
|
|
1637
|
+
function renderServerAttribute(key, value) {
|
|
1638
|
+
const attrName = PROP_ALIASES2[key] ?? key;
|
|
1639
|
+
if (value == null || value === false) {
|
|
1640
|
+
return "";
|
|
1641
|
+
}
|
|
1642
|
+
if (value === true) {
|
|
1643
|
+
return ` ${attrName}`;
|
|
1644
|
+
}
|
|
1645
|
+
const attrValue = attrName === "class" && typeof value === "object" ? stringifyClass(value) : attrName === "style" && typeof value === "object" ? stringifyStyle(value) : String(value);
|
|
1646
|
+
return ` ${attrName}="${escapeHtml(attrValue)}"`;
|
|
1647
|
+
}
|
|
1648
|
+
function stringifyClass(value) {
|
|
1649
|
+
if (Array.isArray(value)) {
|
|
1650
|
+
return value.filter(Boolean).join(" ");
|
|
1651
|
+
}
|
|
1652
|
+
return Object.entries(value).filter(([, enabled]) => Boolean(enabled)).map(([name]) => name).join(" ");
|
|
1653
|
+
}
|
|
1654
|
+
function stringifyStyle(value) {
|
|
1655
|
+
return Object.entries(value).filter(([, val]) => val != null && val !== false).map(([prop, val]) => `${toKebabCase(prop)}:${String(val)}`).join(";");
|
|
1656
|
+
}
|
|
1657
|
+
function toKebabCase(value) {
|
|
1658
|
+
return value.includes("-") ? value : value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
// src/server/renderer.ts
|
|
1662
|
+
var componentCache = new WeakMap;
|
|
1663
|
+
var pageRegistry = new Map;
|
|
1664
|
+
function registerPage(name, page) {
|
|
1665
|
+
pageRegistry.set(name, page);
|
|
1666
|
+
}
|
|
1667
|
+
function getPage(name) {
|
|
1668
|
+
return pageRegistry.get(name);
|
|
1669
|
+
}
|
|
1670
|
+
function hasPage(name) {
|
|
1671
|
+
return pageRegistry.has(name);
|
|
1672
|
+
}
|
|
1673
|
+
async function renderPage(name, data) {
|
|
1674
|
+
const page = getPage(name);
|
|
1675
|
+
if (!page) {
|
|
1676
|
+
throw new Error(`Page "${name}" not found in registry`);
|
|
1677
|
+
}
|
|
1678
|
+
const element = await page(data);
|
|
1679
|
+
return renderToString(element);
|
|
1680
|
+
}
|
|
1681
|
+
async function renderToString(node) {
|
|
1682
|
+
if (node == null || typeof node === "boolean") {
|
|
1683
|
+
return "";
|
|
1684
|
+
}
|
|
1685
|
+
if (typeof node === "string") {
|
|
1686
|
+
return escapeHtml(node);
|
|
1687
|
+
}
|
|
1688
|
+
if (typeof node === "number") {
|
|
1689
|
+
return String(node);
|
|
1690
|
+
}
|
|
1691
|
+
if (node instanceof HtmlEscapedString) {
|
|
1692
|
+
return node.value;
|
|
1693
|
+
}
|
|
1694
|
+
if (isSignal(node) || isComputed(node)) {
|
|
1695
|
+
return escapeHtml(String(node.value));
|
|
1696
|
+
}
|
|
1697
|
+
if (Array.isArray(node)) {
|
|
1698
|
+
const results = await Promise.all(node.map((child) => renderToString(child)));
|
|
1699
|
+
return results.join("");
|
|
1700
|
+
}
|
|
1701
|
+
if (node instanceof Promise) {
|
|
1702
|
+
return renderElement(await node);
|
|
1703
|
+
}
|
|
1704
|
+
return renderElement(node);
|
|
1705
|
+
}
|
|
1706
|
+
async function renderElement(element) {
|
|
1707
|
+
const { tag, props, children } = element;
|
|
1708
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
1709
|
+
return renderElement(tag(props));
|
|
1710
|
+
}
|
|
1711
|
+
if (tag === Visible) {
|
|
1712
|
+
return renderElement(tag(props));
|
|
1713
|
+
}
|
|
1714
|
+
if (isShowElement(element)) {
|
|
1715
|
+
const when = readReactive3(props.when);
|
|
1716
|
+
return renderToString(when ? resolveShowChildren2(element, when) : props.fallback);
|
|
1717
|
+
}
|
|
1718
|
+
if (isForElement(element)) {
|
|
1719
|
+
return renderForElement(element);
|
|
1720
|
+
}
|
|
1721
|
+
if (isSwitchElement(element)) {
|
|
1722
|
+
return renderToString(resolveSwitchContent2(element));
|
|
1723
|
+
}
|
|
1724
|
+
if (isMatchElement(element)) {
|
|
1725
|
+
const when = readReactive3(props.when);
|
|
1726
|
+
return renderToString(when ? resolveMatchChildren2(element, when) : null);
|
|
1727
|
+
}
|
|
1728
|
+
if (isIndexElement(element)) {
|
|
1729
|
+
return renderIndexElement(element);
|
|
1730
|
+
}
|
|
1731
|
+
if (isKeyElement(element)) {
|
|
1732
|
+
const key = readReactive3(props.when);
|
|
1733
|
+
return renderToString(resolveKeyChildren2(element, key));
|
|
1734
|
+
}
|
|
1735
|
+
if (isDynamicElement(element)) {
|
|
1736
|
+
const tag2 = readReactive3(props.component);
|
|
1737
|
+
const dynamic = createDynamicElement2(element, tag2);
|
|
1738
|
+
return dynamic ? renderElement(dynamic) : "";
|
|
1739
|
+
}
|
|
1740
|
+
if (isPortalElement(element)) {
|
|
1741
|
+
return "";
|
|
1742
|
+
}
|
|
1743
|
+
if (typeof tag === "function") {
|
|
1744
|
+
const result = await tag(props);
|
|
1745
|
+
return renderToString(result);
|
|
1746
|
+
}
|
|
1747
|
+
if (typeof tag === "string") {
|
|
1748
|
+
return renderIntrinsicElement(tag, props, children);
|
|
1749
|
+
}
|
|
1750
|
+
return renderToString(children);
|
|
1751
|
+
}
|
|
1752
|
+
var VOID_ELEMENTS3 = new Set([
|
|
1753
|
+
"area",
|
|
1754
|
+
"base",
|
|
1755
|
+
"br",
|
|
1756
|
+
"col",
|
|
1757
|
+
"embed",
|
|
1758
|
+
"hr",
|
|
1759
|
+
"img",
|
|
1760
|
+
"input",
|
|
1761
|
+
"link",
|
|
1762
|
+
"meta",
|
|
1763
|
+
"param",
|
|
1764
|
+
"source",
|
|
1765
|
+
"track",
|
|
1766
|
+
"wbr"
|
|
1767
|
+
]);
|
|
1768
|
+
async function renderIntrinsicElement(tag, props, children) {
|
|
1769
|
+
const attrs = renderAttributes(props);
|
|
1770
|
+
if (VOID_ELEMENTS3.has(tag)) {
|
|
1771
|
+
return attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
1772
|
+
}
|
|
1773
|
+
const childrenHtml = await renderChildren(children, props);
|
|
1774
|
+
return attrs ? `<${tag}${attrs}>${childrenHtml}</${tag}>` : `<${tag}>${childrenHtml}</${tag}>`;
|
|
1775
|
+
}
|
|
1776
|
+
function renderAttributes(props) {
|
|
1777
|
+
let attrs = "";
|
|
1778
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1779
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
|
|
1780
|
+
continue;
|
|
1781
|
+
}
|
|
1782
|
+
const resolvedValue = readReactive3(value);
|
|
1783
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
1784
|
+
continue;
|
|
1785
|
+
attrs += renderServerAttribute(key, resolvedValue);
|
|
1786
|
+
}
|
|
1787
|
+
return attrs;
|
|
1788
|
+
}
|
|
1789
|
+
async function renderChildren(children, props) {
|
|
1790
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
1791
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
1792
|
+
return dangerous.__html;
|
|
1793
|
+
}
|
|
1794
|
+
return renderToString(children);
|
|
1795
|
+
}
|
|
1796
|
+
function isSlots(children) {
|
|
1797
|
+
return children != null && typeof children === "object" && !Array.isArray(children) && !(children instanceof HtmlEscapedString);
|
|
1798
|
+
}
|
|
1799
|
+
async function renderForElement(element) {
|
|
1800
|
+
const props = element.props;
|
|
1801
|
+
const each = readReactive3(props.each);
|
|
1802
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
1803
|
+
return props.fallback ? renderToString(props.fallback) : "";
|
|
1804
|
+
}
|
|
1805
|
+
if (each.length === 0) {
|
|
1806
|
+
return props.fallback ? renderToString(props.fallback) : "";
|
|
1807
|
+
}
|
|
1808
|
+
const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(item, () => index))));
|
|
1809
|
+
return rendered.join("");
|
|
1810
|
+
}
|
|
1811
|
+
async function renderIndexElement(element) {
|
|
1812
|
+
const props = element.props;
|
|
1813
|
+
const each = readReactive3(props.each);
|
|
1814
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
1815
|
+
return props.fallback ? renderToString(props.fallback) : "";
|
|
1816
|
+
}
|
|
1817
|
+
if (each.length === 0) {
|
|
1818
|
+
return props.fallback ? renderToString(props.fallback) : "";
|
|
1819
|
+
}
|
|
1820
|
+
const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(() => item, index))));
|
|
1821
|
+
return rendered.join("");
|
|
1822
|
+
}
|
|
1823
|
+
function resolveSwitchContent2(element) {
|
|
1824
|
+
const props = element.props;
|
|
1825
|
+
const children = normalizeContent2(props.children ?? element.children);
|
|
1826
|
+
for (const child of children) {
|
|
1827
|
+
const match = getMatchElement2(child);
|
|
1828
|
+
if (!match) {
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
const when = readReactive3(match.props.when);
|
|
1832
|
+
if (when) {
|
|
1833
|
+
return resolveMatchChildren2(match, when);
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
return props.fallback;
|
|
1837
|
+
}
|
|
1838
|
+
function resolveMatchChildren2(element, value) {
|
|
1839
|
+
const children = element.props.children ?? element.children;
|
|
1840
|
+
if (typeof children === "function") {
|
|
1841
|
+
return children(value);
|
|
1842
|
+
}
|
|
1843
|
+
return children;
|
|
1844
|
+
}
|
|
1845
|
+
function resolveKeyChildren2(element, value) {
|
|
1846
|
+
const children = element.props.children ?? element.children;
|
|
1847
|
+
if (typeof children === "function") {
|
|
1848
|
+
return children(value);
|
|
1849
|
+
}
|
|
1850
|
+
return children;
|
|
1851
|
+
}
|
|
1852
|
+
function createDynamicElement2(element, tag) {
|
|
1853
|
+
if (typeof tag !== "string" && typeof tag !== "function") {
|
|
1854
|
+
return null;
|
|
1855
|
+
}
|
|
1856
|
+
const { component, ...props } = element.props;
|
|
1857
|
+
const children = normalizeContent2(props.children ?? element.children);
|
|
1858
|
+
return {
|
|
1859
|
+
tag,
|
|
1860
|
+
props,
|
|
1861
|
+
children
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1864
|
+
function resolveShowChildren2(element, value) {
|
|
1865
|
+
const children = element.props.children ?? element.children;
|
|
1866
|
+
if (typeof children === "function") {
|
|
1867
|
+
return children(value);
|
|
1868
|
+
}
|
|
1869
|
+
return children;
|
|
1870
|
+
}
|
|
1871
|
+
function readReactive3(value) {
|
|
1872
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
1873
|
+
}
|
|
1874
|
+
function normalizeContent2(content) {
|
|
1875
|
+
if (content == null || typeof content === "boolean") {
|
|
1876
|
+
return [];
|
|
1877
|
+
}
|
|
1878
|
+
return Array.isArray(content) ? content : [content];
|
|
1879
|
+
}
|
|
1880
|
+
function isElementLike2(value) {
|
|
1881
|
+
return value != null && typeof value === "object" && "tag" in value;
|
|
1882
|
+
}
|
|
1883
|
+
function getMatchElement2(value) {
|
|
1884
|
+
if (!isElementLike2(value)) {
|
|
1885
|
+
return null;
|
|
1886
|
+
}
|
|
1887
|
+
if (isMatchElement(value)) {
|
|
1888
|
+
return value;
|
|
1889
|
+
}
|
|
1890
|
+
return value.tag === Match ? Match(value.props) : null;
|
|
1891
|
+
}
|
|
1892
|
+
// src/hydration/markers.ts
|
|
1893
|
+
var COMP_ID_ATTR = "data-sinwan-id";
|
|
1894
|
+
var COMP_ID_PREFIX = "c";
|
|
1895
|
+
var TEXT_MARKER_OPEN = "sinwan-t:";
|
|
1896
|
+
var TEXT_MARKER_CLOSE = "/sinwan-t";
|
|
1897
|
+
var EVENT_ATTR = "data-sinwan-ev";
|
|
1898
|
+
function compId(index) {
|
|
1899
|
+
return `${COMP_ID_PREFIX}${index}`;
|
|
1900
|
+
}
|
|
1901
|
+
function textMarkerOpen(index) {
|
|
1902
|
+
return `<!--${TEXT_MARKER_OPEN}${index}-->`;
|
|
1903
|
+
}
|
|
1904
|
+
function textMarkerCloseStr() {
|
|
1905
|
+
return `<!--${TEXT_MARKER_CLOSE}-->`;
|
|
1906
|
+
}
|
|
1907
|
+
function parseTextOpenMarker(node) {
|
|
1908
|
+
const data = node.data;
|
|
1909
|
+
if (data.startsWith(TEXT_MARKER_OPEN)) {
|
|
1910
|
+
const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);
|
|
1911
|
+
return Number.isNaN(idx) ? -1 : idx;
|
|
1912
|
+
}
|
|
1913
|
+
return -1;
|
|
1914
|
+
}
|
|
1915
|
+
function isTextCloseMarker(node) {
|
|
1916
|
+
return node.data === TEXT_MARKER_CLOSE;
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
// src/server/stream.ts
|
|
1920
|
+
function createHydratableStreamContext() {
|
|
1921
|
+
return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
|
|
1922
|
+
}
|
|
1923
|
+
var VOID_ELEMENTS4 = new Set([
|
|
1924
|
+
"area",
|
|
1925
|
+
"base",
|
|
1926
|
+
"br",
|
|
1927
|
+
"col",
|
|
1928
|
+
"embed",
|
|
1929
|
+
"hr",
|
|
1930
|
+
"img",
|
|
1931
|
+
"input",
|
|
1932
|
+
"link",
|
|
1933
|
+
"meta",
|
|
1934
|
+
"param",
|
|
1935
|
+
"source",
|
|
1936
|
+
"track",
|
|
1937
|
+
"wbr"
|
|
1938
|
+
]);
|
|
1939
|
+
function streamPage(page, data) {
|
|
1940
|
+
const encoder = new TextEncoder;
|
|
1941
|
+
return new ReadableStream({
|
|
1942
|
+
async start(controller) {
|
|
1943
|
+
try {
|
|
1944
|
+
const element = await page(data);
|
|
1945
|
+
await streamNode(element, controller, encoder);
|
|
1946
|
+
controller.close();
|
|
1947
|
+
} catch (error) {
|
|
1948
|
+
controller.error(error);
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
function streamHydratablePage(component, props) {
|
|
1954
|
+
const encoder = new TextEncoder;
|
|
1955
|
+
const ctx = createHydratableStreamContext();
|
|
1956
|
+
return new ReadableStream({
|
|
1957
|
+
async start(controller) {
|
|
1958
|
+
try {
|
|
1959
|
+
await streamHydratableComponent(component, props ?? {}, controller, encoder, ctx, true);
|
|
1960
|
+
controller.close();
|
|
1961
|
+
} catch (error) {
|
|
1962
|
+
controller.error(error);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
function streamHydratableNode(node) {
|
|
1968
|
+
const encoder = new TextEncoder;
|
|
1969
|
+
const ctx = createHydratableStreamContext();
|
|
1970
|
+
return new ReadableStream({
|
|
1971
|
+
async start(controller) {
|
|
1972
|
+
try {
|
|
1973
|
+
await streamHydratableNodeToController(node, controller, encoder, ctx);
|
|
1974
|
+
controller.close();
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
controller.error(error);
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
async function streamNode(node, controller, encoder) {
|
|
1982
|
+
if (node == null || typeof node === "boolean") {
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
if (typeof node === "string") {
|
|
1986
|
+
controller.enqueue(encoder.encode(escapeHtml(node)));
|
|
1987
|
+
return;
|
|
1988
|
+
}
|
|
1989
|
+
if (typeof node === "number") {
|
|
1990
|
+
controller.enqueue(encoder.encode(String(node)));
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
if (node instanceof HtmlEscapedString) {
|
|
1994
|
+
controller.enqueue(encoder.encode(node.value));
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1997
|
+
if (isSignal(node) || isComputed(node)) {
|
|
1998
|
+
controller.enqueue(encoder.encode(escapeHtml(String(node.value))));
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
2001
|
+
if (Array.isArray(node)) {
|
|
2002
|
+
for (const child of node) {
|
|
2003
|
+
await streamNode(child, controller, encoder);
|
|
2004
|
+
}
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
2007
|
+
if (node instanceof Promise) {
|
|
2008
|
+
const resolved = await node;
|
|
2009
|
+
await streamElement(resolved, controller, encoder);
|
|
2010
|
+
return;
|
|
997
2011
|
}
|
|
998
|
-
|
|
2012
|
+
await streamElement(node, controller, encoder);
|
|
999
2013
|
}
|
|
1000
|
-
function
|
|
1001
|
-
const
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
2014
|
+
async function streamElement(element, controller, encoder) {
|
|
2015
|
+
const { tag, props, children } = element;
|
|
2016
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
2017
|
+
await streamElement(tag(props), controller, encoder);
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
if (tag === Visible) {
|
|
2021
|
+
await streamElement(tag(props), controller, encoder);
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
if (isShowElement(element)) {
|
|
2025
|
+
const when = readReactive4(props.when);
|
|
2026
|
+
await streamNode(when ? resolveShowChildren3(element, when) : props.fallback, controller, encoder);
|
|
2027
|
+
return;
|
|
2028
|
+
}
|
|
2029
|
+
if (isForElement(element)) {
|
|
2030
|
+
await streamForElement(element, controller, encoder);
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
if (isSwitchElement(element)) {
|
|
2034
|
+
await streamNode(resolveSwitchContent3(element), controller, encoder);
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
if (isMatchElement(element)) {
|
|
2038
|
+
const when = readReactive4(props.when);
|
|
2039
|
+
await streamNode(when ? resolveMatchChildren3(element, when) : null, controller, encoder);
|
|
2040
|
+
return;
|
|
2041
|
+
}
|
|
2042
|
+
if (isIndexElement(element)) {
|
|
2043
|
+
await streamIndexElement(element, controller, encoder);
|
|
2044
|
+
return;
|
|
1004
2045
|
}
|
|
1005
|
-
|
|
2046
|
+
if (isKeyElement(element)) {
|
|
2047
|
+
const key = readReactive4(props.when);
|
|
2048
|
+
await streamNode(resolveKeyChildren3(element, key), controller, encoder);
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
if (isDynamicElement(element)) {
|
|
2052
|
+
const dynamicTag = readReactive4(props.component);
|
|
2053
|
+
const dynamic = createDynamicElement3(element, dynamicTag);
|
|
2054
|
+
if (dynamic) {
|
|
2055
|
+
await streamElement(dynamic, controller, encoder);
|
|
2056
|
+
}
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
if (isPortalElement(element)) {
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
2062
|
+
if (typeof tag === "function") {
|
|
2063
|
+
const result = await tag(props);
|
|
2064
|
+
await streamNode(result, controller, encoder);
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
if (typeof tag === "string") {
|
|
2068
|
+
await streamIntrinsicElement(tag, props, children, controller, encoder);
|
|
2069
|
+
return;
|
|
2070
|
+
}
|
|
2071
|
+
await streamNode(children, controller, encoder);
|
|
1006
2072
|
}
|
|
1007
|
-
function
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1010
|
-
|
|
2073
|
+
async function streamIntrinsicElement(tag, props, children, controller, encoder) {
|
|
2074
|
+
const attrs = renderAttributes2(props);
|
|
2075
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
2076
|
+
if (VOID_ELEMENTS4.has(tag)) {
|
|
2077
|
+
const html = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
2078
|
+
controller.enqueue(encoder.encode(html));
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
const openTag = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
2082
|
+
controller.enqueue(encoder.encode(openTag));
|
|
2083
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
2084
|
+
controller.enqueue(encoder.encode(dangerous.__html));
|
|
2085
|
+
} else {
|
|
2086
|
+
await streamNode(children, controller, encoder);
|
|
1011
2087
|
}
|
|
1012
|
-
|
|
2088
|
+
controller.enqueue(encoder.encode(`</${tag}>`));
|
|
1013
2089
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
2090
|
+
function renderAttributes2(props) {
|
|
2091
|
+
let attrs = "";
|
|
2092
|
+
for (const [key, value] of Object.entries(props)) {
|
|
2093
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
const resolvedValue = readReactive4(value);
|
|
2097
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
2098
|
+
continue;
|
|
2099
|
+
attrs += renderServerAttribute(key, resolvedValue);
|
|
2100
|
+
}
|
|
2101
|
+
return attrs;
|
|
1020
2102
|
}
|
|
1021
|
-
function
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
2103
|
+
async function streamHydratableNodeToController(node, controller, encoder, ctx, isComponentRoot = false) {
|
|
2104
|
+
if (node == null || typeof node === "boolean") {
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
if (typeof node === "string") {
|
|
2108
|
+
enqueue(controller, encoder, escapeHtml(node));
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if (typeof node === "number") {
|
|
2112
|
+
enqueue(controller, encoder, String(node));
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
if (node instanceof HtmlEscapedString) {
|
|
2116
|
+
enqueue(controller, encoder, node.value);
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
if (isSignal(node) || isComputed(node)) {
|
|
2120
|
+
const idx = ctx.textIndex++;
|
|
2121
|
+
enqueue(controller, encoder, `${textMarkerOpen(idx)}${escapeHtml(String(node.value))}${textMarkerCloseStr()}`);
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
if (Array.isArray(node)) {
|
|
2125
|
+
for (const child of node) {
|
|
2126
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
2127
|
+
}
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
if (node instanceof Promise) {
|
|
2131
|
+
await streamHydratableElement(await node, controller, encoder, ctx, isComponentRoot);
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
await streamHydratableElement(node, controller, encoder, ctx, isComponentRoot);
|
|
1026
2135
|
}
|
|
1027
|
-
function
|
|
1028
|
-
|
|
2136
|
+
async function streamHydratableElement(element, controller, encoder, ctx, isComponentRoot) {
|
|
2137
|
+
const { tag, props, children } = element;
|
|
2138
|
+
if (tag === "") {
|
|
2139
|
+
for (const child of children) {
|
|
2140
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
2141
|
+
}
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
2145
|
+
await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
if (tag === Visible) {
|
|
2149
|
+
await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
if (isShowElement(element)) {
|
|
2153
|
+
const when = readReactive4(props.when);
|
|
2154
|
+
await streamHydratableNodeToController(when ? resolveShowChildren3(element, when) : props.fallback, controller, encoder, ctx, isComponentRoot);
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
if (isForElement(element)) {
|
|
2158
|
+
await streamHydratableForElement(element, controller, encoder, ctx);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
if (isSwitchElement(element)) {
|
|
2162
|
+
await streamHydratableNodeToController(resolveSwitchContent3(element), controller, encoder, ctx, isComponentRoot);
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
if (isMatchElement(element)) {
|
|
2166
|
+
const when = readReactive4(props.when);
|
|
2167
|
+
await streamHydratableNodeToController(when ? resolveMatchChildren3(element, when) : null, controller, encoder, ctx, isComponentRoot);
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
if (isIndexElement(element)) {
|
|
2171
|
+
await streamHydratableIndexElement(element, controller, encoder, ctx);
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2174
|
+
if (isKeyElement(element)) {
|
|
2175
|
+
const key = readReactive4(props.when);
|
|
2176
|
+
await streamHydratableNodeToController(resolveKeyChildren3(element, key), controller, encoder, ctx, isComponentRoot);
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
if (isDynamicElement(element)) {
|
|
2180
|
+
const dynamicTag = readReactive4(props.component);
|
|
2181
|
+
const dynamic = createDynamicElement3(element, dynamicTag);
|
|
2182
|
+
if (dynamic) {
|
|
2183
|
+
await streamHydratableElement(dynamic, controller, encoder, ctx, isComponentRoot);
|
|
2184
|
+
}
|
|
2185
|
+
return;
|
|
2186
|
+
}
|
|
2187
|
+
if (isPortalElement(element)) {
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
if (typeof tag === "function") {
|
|
2191
|
+
await streamHydratableComponent(tag, props, controller, encoder, ctx, true);
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
if (typeof tag === "string") {
|
|
2195
|
+
await streamHydratableIntrinsic(tag, props, children, controller, encoder, ctx, isComponentRoot);
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
await streamHydratableNodeToController(children, controller, encoder, ctx);
|
|
1029
2199
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
const instance =
|
|
1033
|
-
if (
|
|
1034
|
-
|
|
2200
|
+
async function streamHydratableComponent(component, props, controller, encoder, ctx, isComponentRoot) {
|
|
2201
|
+
const parentInstance = getCurrentInstance();
|
|
2202
|
+
const instance = createComponentInstance(component, props, parentInstance);
|
|
2203
|
+
if (parentInstance) {
|
|
2204
|
+
parentInstance.children.push(instance);
|
|
2205
|
+
}
|
|
2206
|
+
const prev = setCurrentInstance(instance);
|
|
2207
|
+
try {
|
|
2208
|
+
const result = await component(props);
|
|
2209
|
+
await streamHydratableNodeToController(result, controller, encoder, ctx, isComponentRoot);
|
|
2210
|
+
} finally {
|
|
2211
|
+
setCurrentInstance(prev);
|
|
1035
2212
|
}
|
|
1036
|
-
instance.provides[key] = value;
|
|
1037
2213
|
}
|
|
1038
|
-
function
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1041
|
-
|
|
2214
|
+
async function streamHydratableIntrinsic(tag, props, children, controller, encoder, ctx, isComponentRoot) {
|
|
2215
|
+
const attrs = renderHydratableAttributes(props, ctx, isComponentRoot);
|
|
2216
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
2217
|
+
enqueue(controller, encoder, attrs ? `<${tag}${attrs}>` : `<${tag}>`);
|
|
2218
|
+
if (VOID_ELEMENTS4.has(tag)) {
|
|
2219
|
+
return;
|
|
1042
2220
|
}
|
|
1043
|
-
if (
|
|
1044
|
-
|
|
2221
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
2222
|
+
enqueue(controller, encoder, dangerous.__html);
|
|
2223
|
+
} else {
|
|
2224
|
+
for (const child of children) {
|
|
2225
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
2226
|
+
}
|
|
1045
2227
|
}
|
|
1046
|
-
|
|
1047
|
-
|
|
2228
|
+
enqueue(controller, encoder, `</${tag}>`);
|
|
2229
|
+
}
|
|
2230
|
+
async function streamHydratableForElement(element, controller, encoder, ctx) {
|
|
2231
|
+
const props = element.props;
|
|
2232
|
+
const each = readReactive4(props.each);
|
|
2233
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2234
|
+
if (props.fallback) {
|
|
2235
|
+
await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
|
|
2236
|
+
}
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
if (each.length === 0) {
|
|
2240
|
+
if (props.fallback) {
|
|
2241
|
+
await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
|
|
2242
|
+
}
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
for (let index = 0;index < each.length; index++) {
|
|
2246
|
+
await streamHydratableNodeToController(props.children(each[index], () => index), controller, encoder, ctx);
|
|
1048
2247
|
}
|
|
1049
|
-
console.warn(`[Sinwan] inject() key "${String(key)}" not found and no default provided.`);
|
|
1050
|
-
return;
|
|
1051
2248
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
|
|
2249
|
+
async function streamHydratableIndexElement(element, controller, encoder, ctx) {
|
|
2250
|
+
const props = element.props;
|
|
2251
|
+
const each = readReactive4(props.each);
|
|
2252
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2253
|
+
if (props.fallback) {
|
|
2254
|
+
await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
|
|
2255
|
+
}
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
if (each.length === 0) {
|
|
2259
|
+
if (props.fallback) {
|
|
2260
|
+
await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
|
|
2261
|
+
}
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
for (let index = 0;index < each.length; index++) {
|
|
2265
|
+
await streamHydratableNodeToController(props.children(() => each[index], index), controller, encoder, ctx);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
function renderHydratableAttributes(props, ctx, isComponentRoot) {
|
|
2269
|
+
let attrs = "";
|
|
2270
|
+
if (isComponentRoot) {
|
|
2271
|
+
attrs += ` ${COMP_ID_ATTR}="${compId(ctx.componentIndex++)}"`;
|
|
2272
|
+
}
|
|
2273
|
+
const eventParts = [];
|
|
1063
2274
|
for (const [key, value] of Object.entries(props)) {
|
|
1064
|
-
if (
|
|
2275
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") {
|
|
2276
|
+
continue;
|
|
2277
|
+
}
|
|
2278
|
+
if (isEventProp(key)) {
|
|
2279
|
+
eventParts.push(`${toEventName(key)}:${ctx.eventIndex++}`);
|
|
1065
2280
|
continue;
|
|
1066
|
-
if (isSignal(value) || isComputed(value)) {
|
|
1067
|
-
const dispose = effect(() => {
|
|
1068
|
-
setSingleAttribute(el, key, value.value);
|
|
1069
|
-
});
|
|
1070
|
-
disposers.push(dispose);
|
|
1071
|
-
} else {
|
|
1072
|
-
setSingleAttribute(el, key, value);
|
|
1073
2281
|
}
|
|
2282
|
+
const resolvedValue = readReactive4(value);
|
|
2283
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
2284
|
+
continue;
|
|
2285
|
+
attrs += renderServerAttribute(key, resolvedValue);
|
|
1074
2286
|
}
|
|
1075
|
-
|
|
2287
|
+
if (eventParts.length > 0) {
|
|
2288
|
+
attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
|
|
2289
|
+
}
|
|
2290
|
+
return attrs;
|
|
1076
2291
|
}
|
|
1077
|
-
function
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
2292
|
+
function enqueue(controller, encoder, html) {
|
|
2293
|
+
controller.enqueue(encoder.encode(html));
|
|
2294
|
+
}
|
|
2295
|
+
async function streamForElement(element, controller, encoder) {
|
|
2296
|
+
const props = element.props;
|
|
2297
|
+
const each = readReactive4(props.each);
|
|
2298
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2299
|
+
if (props.fallback) {
|
|
2300
|
+
await streamNode(props.fallback, controller, encoder);
|
|
2301
|
+
}
|
|
1081
2302
|
return;
|
|
1082
2303
|
}
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
2304
|
+
if (each.length === 0) {
|
|
2305
|
+
if (props.fallback) {
|
|
2306
|
+
await streamNode(props.fallback, controller, encoder);
|
|
2307
|
+
}
|
|
1085
2308
|
return;
|
|
1086
2309
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
2310
|
+
for (let index = 0;index < each.length; index++) {
|
|
2311
|
+
await streamNode(props.children(each[index], () => index), controller, encoder);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
async function streamIndexElement(element, controller, encoder) {
|
|
2315
|
+
const props = element.props;
|
|
2316
|
+
const each = readReactive4(props.each);
|
|
2317
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2318
|
+
if (props.fallback) {
|
|
2319
|
+
await streamNode(props.fallback, controller, encoder);
|
|
1091
2320
|
}
|
|
1092
2321
|
return;
|
|
1093
2322
|
}
|
|
1094
|
-
if (
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
domOps.setProperty(el, attrName, true);
|
|
2323
|
+
if (each.length === 0) {
|
|
2324
|
+
if (props.fallback) {
|
|
2325
|
+
await streamNode(props.fallback, controller, encoder);
|
|
1098
2326
|
}
|
|
1099
2327
|
return;
|
|
1100
2328
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
return;
|
|
2329
|
+
for (let index = 0;index < each.length; index++) {
|
|
2330
|
+
await streamNode(props.children(() => each[index], index), controller, encoder);
|
|
1104
2331
|
}
|
|
1105
|
-
domOps.setAttribute(el, attrName, String(value));
|
|
1106
2332
|
}
|
|
1107
|
-
function
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
2333
|
+
function resolveShowChildren3(element, value) {
|
|
2334
|
+
const children = element.props.children ?? element.children;
|
|
2335
|
+
if (typeof children === "function") {
|
|
2336
|
+
return children(value);
|
|
2337
|
+
}
|
|
2338
|
+
return children;
|
|
2339
|
+
}
|
|
2340
|
+
function resolveSwitchContent3(element) {
|
|
2341
|
+
const props = element.props;
|
|
2342
|
+
const children = normalizeContent3(props.children ?? element.children);
|
|
2343
|
+
for (const child of children) {
|
|
2344
|
+
const match = getMatchElement3(child);
|
|
2345
|
+
if (!match) {
|
|
2346
|
+
continue;
|
|
2347
|
+
}
|
|
2348
|
+
const when = readReactive4(match.props.when);
|
|
2349
|
+
if (when) {
|
|
2350
|
+
return resolveMatchChildren3(match, when);
|
|
1113
2351
|
}
|
|
1114
2352
|
}
|
|
2353
|
+
return props.fallback;
|
|
1115
2354
|
}
|
|
1116
|
-
function
|
|
1117
|
-
|
|
1118
|
-
if (
|
|
1119
|
-
|
|
1120
|
-
} else if (typeof value === "object" && value !== null) {
|
|
1121
|
-
classStr = Object.entries(value).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
|
|
1122
|
-
} else {
|
|
1123
|
-
classStr = String(value);
|
|
2355
|
+
function resolveMatchChildren3(element, value) {
|
|
2356
|
+
const children = element.props.children ?? element.children;
|
|
2357
|
+
if (typeof children === "function") {
|
|
2358
|
+
return children(value);
|
|
1124
2359
|
}
|
|
1125
|
-
|
|
2360
|
+
return children;
|
|
2361
|
+
}
|
|
2362
|
+
function resolveKeyChildren3(element, value) {
|
|
2363
|
+
const children = element.props.children ?? element.children;
|
|
2364
|
+
if (typeof children === "function") {
|
|
2365
|
+
return children(value);
|
|
2366
|
+
}
|
|
2367
|
+
return children;
|
|
2368
|
+
}
|
|
2369
|
+
function createDynamicElement3(element, tag) {
|
|
2370
|
+
if (typeof tag !== "string" && typeof tag !== "function") {
|
|
2371
|
+
return null;
|
|
2372
|
+
}
|
|
2373
|
+
const { component, ...props } = element.props;
|
|
2374
|
+
const children = normalizeContent3(props.children ?? element.children);
|
|
2375
|
+
return {
|
|
2376
|
+
tag,
|
|
2377
|
+
props,
|
|
2378
|
+
children
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
function readReactive4(value) {
|
|
2382
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
2383
|
+
}
|
|
2384
|
+
function normalizeContent3(content) {
|
|
2385
|
+
if (content == null || typeof content === "boolean") {
|
|
2386
|
+
return [];
|
|
2387
|
+
}
|
|
2388
|
+
return Array.isArray(content) ? content : [content];
|
|
2389
|
+
}
|
|
2390
|
+
function isElementLike3(value) {
|
|
2391
|
+
return value != null && typeof value === "object" && "tag" in value;
|
|
2392
|
+
}
|
|
2393
|
+
function getMatchElement3(value) {
|
|
2394
|
+
if (!isElementLike3(value)) {
|
|
2395
|
+
return null;
|
|
2396
|
+
}
|
|
2397
|
+
if (isMatchElement(value)) {
|
|
2398
|
+
return value;
|
|
2399
|
+
}
|
|
2400
|
+
return value.tag === Match ? Match(value.props) : null;
|
|
2401
|
+
}
|
|
2402
|
+
// src/server/hydration-markers.ts
|
|
2403
|
+
function createHydrationContext() {
|
|
2404
|
+
return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
|
|
2405
|
+
}
|
|
2406
|
+
async function renderToHydratableString(component, props) {
|
|
2407
|
+
const ctx = createHydrationContext();
|
|
2408
|
+
const mergedProps = props ?? {};
|
|
2409
|
+
const instance = createComponentInstance(component, mergedProps, null);
|
|
2410
|
+
const prev = setCurrentInstance(instance);
|
|
2411
|
+
try {
|
|
2412
|
+
const result = await component(mergedProps);
|
|
2413
|
+
if (result && typeof result === "object" && "tag" in result) {
|
|
2414
|
+
return renderElementH(result, ctx, true);
|
|
2415
|
+
}
|
|
2416
|
+
return renderNodeH(result, ctx);
|
|
2417
|
+
} finally {
|
|
2418
|
+
setCurrentInstance(prev);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
async function renderNodeToHydratableString(node) {
|
|
2422
|
+
const ctx = createHydrationContext();
|
|
2423
|
+
return renderNodeH(node, ctx);
|
|
1126
2424
|
}
|
|
1127
|
-
|
|
1128
|
-
// src/renderer/render-element.ts
|
|
1129
2425
|
var VOID_ELEMENTS5 = new Set([
|
|
1130
2426
|
"area",
|
|
1131
2427
|
"base",
|
|
@@ -1142,273 +2438,355 @@ var VOID_ELEMENTS5 = new Set([
|
|
|
1142
2438
|
"track",
|
|
1143
2439
|
"wbr"
|
|
1144
2440
|
]);
|
|
1145
|
-
function
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
2441
|
+
function renderNodeH(node, ctx) {
|
|
2442
|
+
if (node == null || typeof node === "boolean")
|
|
2443
|
+
return "";
|
|
2444
|
+
if (typeof node === "string")
|
|
2445
|
+
return escapeHtml(node);
|
|
2446
|
+
if (typeof node === "number")
|
|
2447
|
+
return String(node);
|
|
2448
|
+
if (node instanceof HtmlEscapedString)
|
|
2449
|
+
return node.value;
|
|
2450
|
+
if (isSignal(node) || isComputed(node)) {
|
|
2451
|
+
const value = node.value;
|
|
2452
|
+
const idx = ctx.textIndex++;
|
|
2453
|
+
return `${textMarkerOpen(idx)}${escapeHtml(String(value))}${textMarkerCloseStr()}`;
|
|
1149
2454
|
}
|
|
1150
|
-
if (
|
|
1151
|
-
return
|
|
2455
|
+
if (Array.isArray(node)) {
|
|
2456
|
+
return node.map((child) => renderNodeH(child, ctx)).join("");
|
|
1152
2457
|
}
|
|
1153
|
-
if (
|
|
1154
|
-
return
|
|
2458
|
+
if (node instanceof Promise) {
|
|
2459
|
+
return "";
|
|
2460
|
+
}
|
|
2461
|
+
if (typeof node === "object" && "tag" in node) {
|
|
2462
|
+
return renderElementH(node, ctx, false);
|
|
1155
2463
|
}
|
|
1156
|
-
return
|
|
2464
|
+
return escapeHtml(String(node));
|
|
1157
2465
|
}
|
|
1158
|
-
function
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
let mountedChildren = [];
|
|
1163
|
-
if (!VOID_ELEMENTS5.has(tag)) {
|
|
1164
|
-
const dangerous = props.dangerouslySetInnerHTML;
|
|
1165
|
-
if (dangerous && typeof dangerous.__html === "string") {
|
|
1166
|
-
el.innerHTML = dangerous.__html;
|
|
1167
|
-
} else {
|
|
1168
|
-
mountedChildren = renderChildrenToDOM(children, el);
|
|
1169
|
-
}
|
|
2466
|
+
function renderElementH(element, ctx, isComponentRoot) {
|
|
2467
|
+
const { tag, props, children } = element;
|
|
2468
|
+
if (tag === "") {
|
|
2469
|
+
return children.map((child) => renderNodeH(child, ctx)).join("");
|
|
1170
2470
|
}
|
|
1171
|
-
if (
|
|
1172
|
-
|
|
1173
|
-
} else {
|
|
1174
|
-
domOps.appendChild(parent, el);
|
|
2471
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
2472
|
+
return renderElementH(tag(props), ctx, isComponentRoot);
|
|
1175
2473
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
2474
|
+
if (tag === Visible) {
|
|
2475
|
+
return renderElementH(tag(props), ctx, isComponentRoot);
|
|
2476
|
+
}
|
|
2477
|
+
if (isShowElement(element)) {
|
|
2478
|
+
const when = readReactive5(props.when);
|
|
2479
|
+
const content = when ? resolveShowChildren4(element, when) : props.fallback;
|
|
2480
|
+
return renderNodeMaybeRoot(content, ctx, isComponentRoot);
|
|
2481
|
+
}
|
|
2482
|
+
if (isForElement(element)) {
|
|
2483
|
+
return renderForElementH(element, ctx);
|
|
2484
|
+
}
|
|
2485
|
+
if (isSwitchElement(element)) {
|
|
2486
|
+
return renderNodeMaybeRoot(resolveSwitchContent4(element), ctx, isComponentRoot);
|
|
2487
|
+
}
|
|
2488
|
+
if (isMatchElement(element)) {
|
|
2489
|
+
const when = readReactive5(props.when);
|
|
2490
|
+
return renderNodeMaybeRoot(when ? resolveMatchChildren4(element, when) : null, ctx, isComponentRoot);
|
|
2491
|
+
}
|
|
2492
|
+
if (isIndexElement(element)) {
|
|
2493
|
+
return renderIndexElementH(element, ctx);
|
|
2494
|
+
}
|
|
2495
|
+
if (isKeyElement(element)) {
|
|
2496
|
+
const key = readReactive5(props.when);
|
|
2497
|
+
return renderNodeMaybeRoot(resolveKeyChildren4(element, key), ctx, isComponentRoot);
|
|
2498
|
+
}
|
|
2499
|
+
if (isDynamicElement(element)) {
|
|
2500
|
+
const dynamicTag = readReactive5(props.component);
|
|
2501
|
+
const dynamic = createDynamicElement4(element, dynamicTag);
|
|
2502
|
+
return dynamic ? renderElementH(dynamic, ctx, isComponentRoot) : "";
|
|
2503
|
+
}
|
|
2504
|
+
if (isPortalElement(element)) {
|
|
2505
|
+
return "";
|
|
2506
|
+
}
|
|
2507
|
+
if (typeof tag === "function") {
|
|
2508
|
+
return renderComponentH(tag, props, ctx);
|
|
2509
|
+
}
|
|
2510
|
+
if (typeof tag === "string") {
|
|
2511
|
+
return renderIntrinsicH(tag, props, children, ctx, isComponentRoot);
|
|
2512
|
+
}
|
|
2513
|
+
return children.map((child) => renderNodeH(child, ctx)).join("");
|
|
1183
2514
|
}
|
|
1184
|
-
function
|
|
2515
|
+
function renderComponentH(component, props, ctx) {
|
|
1185
2516
|
const parentInstance = getCurrentInstance();
|
|
1186
2517
|
const instance = createComponentInstance(component, props, parentInstance);
|
|
1187
2518
|
if (parentInstance) {
|
|
1188
2519
|
parentInstance.children.push(instance);
|
|
1189
2520
|
}
|
|
1190
|
-
const
|
|
1191
|
-
let result;
|
|
1192
|
-
let child;
|
|
2521
|
+
const prev = setCurrentInstance(instance);
|
|
1193
2522
|
try {
|
|
1194
|
-
result = component(props);
|
|
2523
|
+
const result = component(props);
|
|
1195
2524
|
if (result && typeof result === "object" && "tag" in result) {
|
|
1196
|
-
|
|
1197
|
-
} else {
|
|
1198
|
-
child = renderNodeToDOM(result, parent, anchor);
|
|
2525
|
+
return renderElementH(result, ctx, true);
|
|
1199
2526
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
2527
|
+
return renderNodeH(result, ctx);
|
|
2528
|
+
} finally {
|
|
2529
|
+
setCurrentInstance(prev);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
|
|
2533
|
+
let attrs = "";
|
|
2534
|
+
if (isComponentRoot) {
|
|
2535
|
+
attrs += ` ${COMP_ID_ATTR}="${compId(ctx.componentIndex++)}"`;
|
|
2536
|
+
}
|
|
2537
|
+
const eventParts = [];
|
|
2538
|
+
for (const [key, value] of Object.entries(props)) {
|
|
2539
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") {
|
|
2540
|
+
continue;
|
|
1208
2541
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
2542
|
+
if (isEventProp(key)) {
|
|
2543
|
+
const eventName = toEventName(key);
|
|
2544
|
+
eventParts.push(`${eventName}:${ctx.eventIndex++}`);
|
|
2545
|
+
continue;
|
|
2546
|
+
}
|
|
2547
|
+
if (value == null || value === false)
|
|
2548
|
+
continue;
|
|
2549
|
+
let resolvedValue = value;
|
|
2550
|
+
if (isSignal(value) || isComputed(value)) {
|
|
2551
|
+
resolvedValue = value.value;
|
|
2552
|
+
}
|
|
2553
|
+
attrs += renderServerAttribute(key, resolvedValue);
|
|
1215
2554
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
2555
|
+
if (eventParts.length > 0) {
|
|
2556
|
+
attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
|
|
2557
|
+
}
|
|
2558
|
+
if (VOID_ELEMENTS5.has(tag)) {
|
|
2559
|
+
return `<${tag}${attrs}>`;
|
|
2560
|
+
}
|
|
2561
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
2562
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
2563
|
+
return `<${tag}${attrs}>${dangerous.__html}</${tag}>`;
|
|
2564
|
+
}
|
|
2565
|
+
const childrenHtml = children.map((child) => renderNodeH(child, ctx)).join("");
|
|
2566
|
+
return `<${tag}${attrs}>${childrenHtml}</${tag}>`;
|
|
1224
2567
|
}
|
|
1225
|
-
function
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
domOps.insertBefore(parent, anchorComment, anchor);
|
|
1229
|
-
} else {
|
|
1230
|
-
domOps.appendChild(parent, anchorComment);
|
|
2568
|
+
function renderNodeMaybeRoot(node, ctx, isComponentRoot) {
|
|
2569
|
+
if (isComponentRoot && node && typeof node === "object" && !Array.isArray(node) && "tag" in node) {
|
|
2570
|
+
return renderElementH(node, ctx, true);
|
|
1231
2571
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
2572
|
+
return renderNodeH(node, ctx);
|
|
2573
|
+
}
|
|
2574
|
+
function renderForElementH(element, ctx) {
|
|
2575
|
+
const props = element.props;
|
|
2576
|
+
const each = readReactive5(props.each);
|
|
2577
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2578
|
+
return props.fallback ? renderNodeH(props.fallback, ctx) : "";
|
|
1235
2579
|
}
|
|
1236
|
-
|
|
2580
|
+
if (each.length === 0) {
|
|
2581
|
+
return props.fallback ? renderNodeH(props.fallback, ctx) : "";
|
|
2582
|
+
}
|
|
2583
|
+
return each.map((item, index) => renderNodeH(props.children(item, () => index), ctx)).join("");
|
|
1237
2584
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
if (
|
|
1242
|
-
|
|
1243
|
-
insertNode(parent, text2, anchor);
|
|
1244
|
-
return { type: "text", node: text2 };
|
|
2585
|
+
function renderIndexElementH(element, ctx) {
|
|
2586
|
+
const props = element.props;
|
|
2587
|
+
const each = readReactive5(props.each);
|
|
2588
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
2589
|
+
return props.fallback ? renderNodeH(props.fallback, ctx) : "";
|
|
1245
2590
|
}
|
|
1246
|
-
if (
|
|
1247
|
-
|
|
1248
|
-
insertNode(parent, text2, anchor);
|
|
1249
|
-
return { type: "text", node: text2 };
|
|
2591
|
+
if (each.length === 0) {
|
|
2592
|
+
return props.fallback ? renderNodeH(props.fallback, ctx) : "";
|
|
1250
2593
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
2594
|
+
return each.map((item, index) => renderNodeH(props.children(() => item, index), ctx)).join("");
|
|
2595
|
+
}
|
|
2596
|
+
function resolveShowChildren4(element, value) {
|
|
2597
|
+
const children = element.props.children ?? element.children;
|
|
2598
|
+
if (typeof children === "function") {
|
|
2599
|
+
return children(value);
|
|
1255
2600
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
2601
|
+
return children;
|
|
2602
|
+
}
|
|
2603
|
+
function resolveSwitchContent4(element) {
|
|
2604
|
+
const props = element.props;
|
|
2605
|
+
const children = normalizeContent4(props.children ?? element.children);
|
|
2606
|
+
for (const child of children) {
|
|
2607
|
+
const match = getMatchElement4(child);
|
|
2608
|
+
if (!match) {
|
|
2609
|
+
continue;
|
|
2610
|
+
}
|
|
2611
|
+
const when = readReactive5(match.props.when);
|
|
2612
|
+
if (when) {
|
|
2613
|
+
return resolveMatchChildren4(match, when);
|
|
2614
|
+
}
|
|
1260
2615
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
return { type: "reactive-text", node: text2, dispose };
|
|
2616
|
+
return props.fallback;
|
|
2617
|
+
}
|
|
2618
|
+
function resolveMatchChildren4(element, value) {
|
|
2619
|
+
const children = element.props.children ?? element.children;
|
|
2620
|
+
if (typeof children === "function") {
|
|
2621
|
+
return children(value);
|
|
1268
2622
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
2623
|
+
return children;
|
|
2624
|
+
}
|
|
2625
|
+
function resolveKeyChildren4(element, value) {
|
|
2626
|
+
const children = element.props.children ?? element.children;
|
|
2627
|
+
if (typeof children === "function") {
|
|
2628
|
+
return children(value);
|
|
1271
2629
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
domOps.remove(placeholder);
|
|
1278
|
-
});
|
|
1279
|
-
return { type: "text", node: placeholder };
|
|
2630
|
+
return children;
|
|
2631
|
+
}
|
|
2632
|
+
function createDynamicElement4(element, tag) {
|
|
2633
|
+
if (typeof tag !== "string" && typeof tag !== "function") {
|
|
2634
|
+
return null;
|
|
1280
2635
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
2636
|
+
const { component, ...props } = element.props;
|
|
2637
|
+
const children = normalizeContent4(props.children ?? element.children);
|
|
2638
|
+
return {
|
|
2639
|
+
tag,
|
|
2640
|
+
props,
|
|
2641
|
+
children
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
function readReactive5(value) {
|
|
2645
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
2646
|
+
}
|
|
2647
|
+
function normalizeContent4(content) {
|
|
2648
|
+
if (content == null || typeof content === "boolean") {
|
|
2649
|
+
return [];
|
|
2650
|
+
}
|
|
2651
|
+
return Array.isArray(content) ? content : [content];
|
|
2652
|
+
}
|
|
2653
|
+
function isElementLike4(value) {
|
|
2654
|
+
return value != null && typeof value === "object" && "tag" in value;
|
|
2655
|
+
}
|
|
2656
|
+
function getMatchElement4(value) {
|
|
2657
|
+
if (!isElementLike4(value)) {
|
|
2658
|
+
return null;
|
|
2659
|
+
}
|
|
2660
|
+
if (isMatchElement(value)) {
|
|
2661
|
+
return value;
|
|
1283
2662
|
}
|
|
1284
|
-
|
|
1285
|
-
insertNode(parent, text, anchor);
|
|
1286
|
-
return { type: "text", node: text };
|
|
2663
|
+
return value.tag === Match ? Match(value.props) : null;
|
|
1287
2664
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
2665
|
+
// src/index.ts
|
|
2666
|
+
var exports_src = {};
|
|
2667
|
+
__export(exports_src, {
|
|
2668
|
+
unmountNode: () => unmountNode,
|
|
2669
|
+
streamPage: () => streamPage,
|
|
2670
|
+
streamHydratablePage: () => streamHydratablePage,
|
|
2671
|
+
streamHydratableNode: () => streamHydratableNode,
|
|
2672
|
+
signal: () => signal,
|
|
2673
|
+
setDOMOps: () => setDOMOps,
|
|
2674
|
+
safeHtml: () => safeHtml,
|
|
2675
|
+
resetDOMOps: () => resetDOMOps,
|
|
2676
|
+
renderToString: () => renderToString,
|
|
2677
|
+
renderToHydratableString: () => renderToHydratableString,
|
|
2678
|
+
renderPage: () => renderPage,
|
|
2679
|
+
renderNodeToHydratableString: () => renderNodeToHydratableString,
|
|
2680
|
+
renderNodeToDOM: () => renderNodeToDOM,
|
|
2681
|
+
renderElementToDOM: () => renderElementToDOM,
|
|
2682
|
+
render: () => render,
|
|
2683
|
+
registerPage: () => registerPage,
|
|
2684
|
+
raw: () => raw,
|
|
2685
|
+
provide: () => provide,
|
|
2686
|
+
onUpdated: () => onUpdated,
|
|
2687
|
+
onUnmounted: () => onUnmounted,
|
|
2688
|
+
onMounted: () => onMounted,
|
|
2689
|
+
onError: () => onError,
|
|
2690
|
+
nextTick: () => nextTick,
|
|
2691
|
+
mount: () => mount,
|
|
2692
|
+
jsxs: () => jsxs,
|
|
2693
|
+
jsxDEV: () => jsxDEV,
|
|
2694
|
+
jsx: () => jsx,
|
|
2695
|
+
isSignal: () => isSignal,
|
|
2696
|
+
isSafeHtml: () => isSafeHtml,
|
|
2697
|
+
isComputed: () => isComputed,
|
|
2698
|
+
inject: () => inject,
|
|
2699
|
+
hydrate: () => hydrate,
|
|
2700
|
+
hasPage: () => hasPage,
|
|
2701
|
+
getPage: () => getPage,
|
|
2702
|
+
getCurrentInstance: () => getCurrentInstance,
|
|
2703
|
+
escapeHtml: () => escapeHtml,
|
|
2704
|
+
effect: () => effect,
|
|
2705
|
+
domOps: () => domOps,
|
|
2706
|
+
createPage: () => createPage,
|
|
2707
|
+
createLayout: () => createLayout,
|
|
2708
|
+
createComponent: () => createComponent,
|
|
2709
|
+
computed: () => computed,
|
|
2710
|
+
batch: () => batch,
|
|
2711
|
+
Visible: () => Visible,
|
|
2712
|
+
Switch: () => Switch,
|
|
2713
|
+
Show: () => Show,
|
|
2714
|
+
Portal: () => Portal,
|
|
2715
|
+
Match: () => Match,
|
|
2716
|
+
Key: () => Key,
|
|
2717
|
+
Index: () => Index,
|
|
2718
|
+
HtmlEscapedString: () => HtmlEscapedString,
|
|
2719
|
+
Fragment: () => Fragment,
|
|
2720
|
+
For: () => For,
|
|
2721
|
+
Dynamic: () => Dynamic
|
|
2722
|
+
});
|
|
2723
|
+
module.exports = __toCommonJS(exports_src);
|
|
2724
|
+
// src/component/lifecycle.ts
|
|
2725
|
+
function onMounted(fn) {
|
|
2726
|
+
const instance = getCurrentInstance();
|
|
2727
|
+
if (!instance) {
|
|
2728
|
+
throw new Error("onMounted() called outside of component setup.");
|
|
1294
2729
|
}
|
|
1295
|
-
|
|
2730
|
+
instance._mountedHooks.push(() => withInstance(instance, fn));
|
|
1296
2731
|
}
|
|
1297
|
-
function
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
|
|
2732
|
+
function onUnmounted(fn) {
|
|
2733
|
+
const instance = getCurrentInstance();
|
|
2734
|
+
if (!instance) {
|
|
2735
|
+
throw new Error("onUnmounted() called outside of component setup.");
|
|
1301
2736
|
}
|
|
1302
|
-
|
|
2737
|
+
instance._unmountedHooks.push(() => withInstance(instance, fn));
|
|
1303
2738
|
}
|
|
1304
|
-
function
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
domOps.appendChild(parent, child);
|
|
2739
|
+
function onUpdated(fn) {
|
|
2740
|
+
const instance = getCurrentInstance();
|
|
2741
|
+
if (!instance) {
|
|
2742
|
+
throw new Error("onUpdated() called outside of component setup.");
|
|
1309
2743
|
}
|
|
2744
|
+
instance._updatedHooks.push(() => withInstance(instance, fn));
|
|
1310
2745
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
const mergedProps = props ?? {};
|
|
1316
|
-
const instance = createComponentInstance(component, mergedProps, null);
|
|
1317
|
-
let result;
|
|
1318
|
-
let root;
|
|
1319
|
-
setCurrentInstance(instance);
|
|
1320
|
-
try {
|
|
1321
|
-
result = component(mergedProps);
|
|
1322
|
-
if (result instanceof Promise) {
|
|
1323
|
-
const placeholder = document.createTextNode("");
|
|
1324
|
-
container.appendChild(placeholder);
|
|
1325
|
-
root = { type: "text", node: placeholder };
|
|
1326
|
-
result.then((resolved) => {
|
|
1327
|
-
container.innerHTML = "";
|
|
1328
|
-
setCurrentInstance(instance);
|
|
1329
|
-
root = renderElementToDOM(resolved, container);
|
|
1330
|
-
setCurrentInstance(null);
|
|
1331
|
-
instance.element = root;
|
|
1332
|
-
fireMountedHooks(instance);
|
|
1333
|
-
});
|
|
1334
|
-
} else if (result && typeof result === "object" && "tag" in result) {
|
|
1335
|
-
root = renderElementToDOM(result, container);
|
|
1336
|
-
} else {
|
|
1337
|
-
root = renderNodeToDOM(result, container);
|
|
1338
|
-
}
|
|
1339
|
-
} catch (err) {
|
|
1340
|
-
setCurrentInstance(null);
|
|
1341
|
-
handleComponentError(instance, err);
|
|
1342
|
-
return {
|
|
1343
|
-
root: { type: "text", node: document.createTextNode("") },
|
|
1344
|
-
unmount() {}
|
|
1345
|
-
};
|
|
2746
|
+
function onError(fn) {
|
|
2747
|
+
const instance = getCurrentInstance();
|
|
2748
|
+
if (!instance) {
|
|
2749
|
+
throw new Error("onError() called outside of component setup.");
|
|
1346
2750
|
}
|
|
1347
|
-
|
|
1348
|
-
instance.element = root;
|
|
1349
|
-
fireMountedHooks(instance);
|
|
1350
|
-
return {
|
|
1351
|
-
root,
|
|
1352
|
-
unmount() {
|
|
1353
|
-
fireUnmountedHooks(instance);
|
|
1354
|
-
unmountNode(root);
|
|
1355
|
-
container.innerHTML = "";
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
2751
|
+
instance._errorHooks.push((err) => withInstance(instance, () => fn(err)));
|
|
1358
2752
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
unmountNode(root);
|
|
1366
|
-
container.innerHTML = "";
|
|
1367
|
-
}
|
|
1368
|
-
};
|
|
2753
|
+
// src/component/create.ts
|
|
2754
|
+
function createComponent(fn) {
|
|
2755
|
+
const component = (props) => fn(props);
|
|
2756
|
+
component._SinwanComponent = true;
|
|
2757
|
+
component._displayName = fn.name || "AnonymousComponent";
|
|
2758
|
+
return component;
|
|
1369
2759
|
}
|
|
1370
|
-
function
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
for (const child of node.children) {
|
|
1385
|
-
unmountNode(child);
|
|
1386
|
-
}
|
|
1387
|
-
break;
|
|
1388
|
-
case "fragment":
|
|
1389
|
-
for (const child of node.children) {
|
|
1390
|
-
unmountNode(child);
|
|
1391
|
-
}
|
|
1392
|
-
break;
|
|
1393
|
-
case "reactive-block":
|
|
1394
|
-
node.dispose();
|
|
1395
|
-
for (const child of node.children) {
|
|
1396
|
-
unmountNode(child);
|
|
1397
|
-
}
|
|
1398
|
-
break;
|
|
1399
|
-
case "component":
|
|
1400
|
-
if (node.instance) {
|
|
1401
|
-
fireUnmountedHooks(node.instance);
|
|
1402
|
-
} else {
|
|
1403
|
-
for (const dispose of node.disposers) {
|
|
1404
|
-
dispose();
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
for (const child of node.children) {
|
|
1408
|
-
unmountNode(child);
|
|
1409
|
-
}
|
|
1410
|
-
break;
|
|
2760
|
+
function createPage(fn) {
|
|
2761
|
+
const page = (data) => fn(data);
|
|
2762
|
+
page._SinwanPage = true;
|
|
2763
|
+
page._displayName = fn.name || "AnonymousPage";
|
|
2764
|
+
return page;
|
|
2765
|
+
}
|
|
2766
|
+
function createLayout(fn) {
|
|
2767
|
+
return createComponent(fn);
|
|
2768
|
+
}
|
|
2769
|
+
// src/component/provide-inject.ts
|
|
2770
|
+
function provide(key, value) {
|
|
2771
|
+
const instance = getCurrentInstance();
|
|
2772
|
+
if (!instance) {
|
|
2773
|
+
throw new Error("provide() called outside of component setup.");
|
|
1411
2774
|
}
|
|
2775
|
+
instance.provides[key] = value;
|
|
2776
|
+
}
|
|
2777
|
+
function inject(key, defaultValue) {
|
|
2778
|
+
const instance = getCurrentInstance();
|
|
2779
|
+
if (!instance) {
|
|
2780
|
+
throw new Error("inject() called outside of component setup.");
|
|
2781
|
+
}
|
|
2782
|
+
if (key in instance.provides) {
|
|
2783
|
+
return instance.provides[key];
|
|
2784
|
+
}
|
|
2785
|
+
if (arguments.length >= 2) {
|
|
2786
|
+
return defaultValue;
|
|
2787
|
+
}
|
|
2788
|
+
console.warn(`[Sinwan] inject() key "${String(key)}" not found and no default provided.`);
|
|
2789
|
+
return;
|
|
1412
2790
|
}
|
|
1413
2791
|
// src/hydration/walk.ts
|
|
1414
2792
|
function advance(cursor) {
|
|
@@ -1449,6 +2827,7 @@ function hydrateNode(node, cursor) {
|
|
|
1449
2827
|
}
|
|
1450
2828
|
function hydrateReactiveText(reactive, cursor) {
|
|
1451
2829
|
const openComment = cursor.current;
|
|
2830
|
+
const owner = getCurrentInstance();
|
|
1452
2831
|
if (openComment && openComment.nodeType === 8 && parseTextOpenMarker(openComment) >= 0) {
|
|
1453
2832
|
advance(cursor);
|
|
1454
2833
|
const textNode2 = advance(cursor);
|
|
@@ -1456,21 +2835,36 @@ function hydrateReactiveText(reactive, cursor) {
|
|
|
1456
2835
|
if (closeComment && closeComment.nodeType === 8 && isTextCloseMarker(closeComment)) {
|
|
1457
2836
|
advance(cursor);
|
|
1458
2837
|
}
|
|
2838
|
+
let initialized2 = false;
|
|
1459
2839
|
const dispose2 = effect(() => {
|
|
1460
2840
|
textNode2.data = String(reactive.value);
|
|
2841
|
+
if (initialized2) {
|
|
2842
|
+
queueUpdatedHooks(owner);
|
|
2843
|
+
}
|
|
2844
|
+
initialized2 = true;
|
|
1461
2845
|
});
|
|
1462
2846
|
return { type: "reactive-text", node: textNode2, dispose: dispose2 };
|
|
1463
2847
|
}
|
|
1464
2848
|
const textNode = advance(cursor);
|
|
1465
2849
|
if (textNode) {
|
|
2850
|
+
let initialized2 = false;
|
|
1466
2851
|
const dispose2 = effect(() => {
|
|
1467
2852
|
textNode.data = String(reactive.value);
|
|
2853
|
+
if (initialized2) {
|
|
2854
|
+
queueUpdatedHooks(owner);
|
|
2855
|
+
}
|
|
2856
|
+
initialized2 = true;
|
|
1468
2857
|
});
|
|
1469
2858
|
return { type: "reactive-text", node: textNode, dispose: dispose2 };
|
|
1470
2859
|
}
|
|
1471
2860
|
const newText = document.createTextNode(String(reactive.value));
|
|
2861
|
+
let initialized = false;
|
|
1472
2862
|
const dispose = effect(() => {
|
|
1473
2863
|
newText.data = String(reactive.value);
|
|
2864
|
+
if (initialized) {
|
|
2865
|
+
queueUpdatedHooks(owner);
|
|
2866
|
+
}
|
|
2867
|
+
initialized = true;
|
|
1474
2868
|
});
|
|
1475
2869
|
return { type: "reactive-text", node: newText, dispose };
|
|
1476
2870
|
}
|
|
@@ -1479,6 +2873,18 @@ function hydrateElement(element, cursor) {
|
|
|
1479
2873
|
if (tag === "") {
|
|
1480
2874
|
return hydrateArray(children, cursor);
|
|
1481
2875
|
}
|
|
2876
|
+
if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
|
|
2877
|
+
return hydrateElement(tag(props), cursor);
|
|
2878
|
+
}
|
|
2879
|
+
if (tag === Visible) {
|
|
2880
|
+
return hydrateElement(tag(props), cursor);
|
|
2881
|
+
}
|
|
2882
|
+
if (isPortalElement(element)) {
|
|
2883
|
+
return renderControlFlowToDOM(element, cursor.parent, cursor.current, null);
|
|
2884
|
+
}
|
|
2885
|
+
if (isShowElement(element) || isForElement(element) || isSwitchElement(element) || isIndexElement(element) || isKeyElement(element) || isDynamicElement(element)) {
|
|
2886
|
+
return hydrateControlFlow(element, cursor);
|
|
2887
|
+
}
|
|
1482
2888
|
if (typeof tag === "function") {
|
|
1483
2889
|
return hydrateComponent(tag, props, cursor);
|
|
1484
2890
|
}
|
|
@@ -1497,6 +2903,7 @@ function hydrateIntrinsic(tag, props, children, cursor) {
|
|
|
1497
2903
|
el.removeAttribute("data-sinwan-ev");
|
|
1498
2904
|
const attrDisposers = hydrateAttributes(el, props);
|
|
1499
2905
|
const eventCleanups = bindEvents(el, props);
|
|
2906
|
+
const refCleanup = applyRef2(el, props.ref);
|
|
1500
2907
|
const childCursor = {
|
|
1501
2908
|
parent: el,
|
|
1502
2909
|
current: el.firstChild
|
|
@@ -1510,31 +2917,155 @@ function hydrateIntrinsic(tag, props, children, cursor) {
|
|
|
1510
2917
|
node: el,
|
|
1511
2918
|
children: mountedChildren,
|
|
1512
2919
|
eventCleanups,
|
|
1513
|
-
attrDisposers
|
|
2920
|
+
attrDisposers,
|
|
2921
|
+
refCleanup
|
|
1514
2922
|
};
|
|
1515
2923
|
}
|
|
1516
2924
|
function hydrateAttributes(el, props) {
|
|
1517
2925
|
const disposers = [];
|
|
2926
|
+
const owner = getCurrentInstance();
|
|
1518
2927
|
for (const [key, value] of Object.entries(props)) {
|
|
1519
|
-
if (key === "children" || key === "key" || key === "ref" || isEventProp(key))
|
|
2928
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key))
|
|
1520
2929
|
continue;
|
|
1521
2930
|
if (isSignal(value) || isComputed(value)) {
|
|
2931
|
+
const state = { previousStyleProps: new Set };
|
|
2932
|
+
let initialized = false;
|
|
1522
2933
|
const dispose = effect(() => {
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
el.removeAttribute(attrName);
|
|
1527
|
-
} else if (v === true) {
|
|
1528
|
-
el.setAttribute(attrName, "");
|
|
1529
|
-
} else {
|
|
1530
|
-
el.setAttribute(attrName, String(v));
|
|
2934
|
+
setSingleAttribute(el, key, value.value, state);
|
|
2935
|
+
if (initialized) {
|
|
2936
|
+
queueUpdatedHooks(owner);
|
|
1531
2937
|
}
|
|
2938
|
+
initialized = true;
|
|
1532
2939
|
});
|
|
1533
2940
|
disposers.push(dispose);
|
|
1534
2941
|
}
|
|
1535
2942
|
}
|
|
1536
2943
|
return disposers;
|
|
1537
2944
|
}
|
|
2945
|
+
function hydrateControlFlow(element, cursor) {
|
|
2946
|
+
if (isShowElement(element)) {
|
|
2947
|
+
const when = readReactive6(element.props.when);
|
|
2948
|
+
const content = when ? resolveShowChildren5(element, when) : element.props.fallback;
|
|
2949
|
+
return hydrateContent(content, cursor);
|
|
2950
|
+
}
|
|
2951
|
+
if (isForElement(element)) {
|
|
2952
|
+
const props = element.props;
|
|
2953
|
+
const items = readReactive6(props.each);
|
|
2954
|
+
const children = Array.isArray(items) && typeof props.children === "function" ? items.map((item, index) => props.children(item, () => index)) : props.fallback ? [props.fallback] : [];
|
|
2955
|
+
return hydrateArray(children, cursor);
|
|
2956
|
+
}
|
|
2957
|
+
if (isSwitchElement(element)) {
|
|
2958
|
+
return hydrateContent(resolveSwitchContent5(element), cursor);
|
|
2959
|
+
}
|
|
2960
|
+
if (isIndexElement(element)) {
|
|
2961
|
+
const props = element.props;
|
|
2962
|
+
const items = readReactive6(props.each);
|
|
2963
|
+
const children = Array.isArray(items) && typeof props.children === "function" ? items.map((item, index) => props.children(() => item, index)) : props.fallback ? [props.fallback] : [];
|
|
2964
|
+
return hydrateArray(children, cursor);
|
|
2965
|
+
}
|
|
2966
|
+
if (isKeyElement(element)) {
|
|
2967
|
+
const key = readReactive6(element.props.when);
|
|
2968
|
+
return hydrateContent(resolveKeyChildren5(element, key), cursor);
|
|
2969
|
+
}
|
|
2970
|
+
if (isDynamicElement(element)) {
|
|
2971
|
+
const tag = readReactive6(element.props.component);
|
|
2972
|
+
const dynamic = createDynamicElement5(element, tag);
|
|
2973
|
+
return dynamic ? hydrateElement(dynamic, cursor) : hydrateArray([], cursor);
|
|
2974
|
+
}
|
|
2975
|
+
return hydrateArray(element.children, cursor);
|
|
2976
|
+
}
|
|
2977
|
+
function hydrateContent(content, cursor) {
|
|
2978
|
+
if (content == null || typeof content === "boolean") {
|
|
2979
|
+
return hydrateArray([], cursor);
|
|
2980
|
+
}
|
|
2981
|
+
return Array.isArray(content) ? hydrateArray(content, cursor) : hydrateNode(content, cursor);
|
|
2982
|
+
}
|
|
2983
|
+
function resolveShowChildren5(element, value) {
|
|
2984
|
+
const children = element.props.children ?? element.children;
|
|
2985
|
+
if (typeof children === "function") {
|
|
2986
|
+
return children(value);
|
|
2987
|
+
}
|
|
2988
|
+
return children;
|
|
2989
|
+
}
|
|
2990
|
+
function resolveSwitchContent5(element) {
|
|
2991
|
+
const props = element.props;
|
|
2992
|
+
const children = normalizeContent5(props.children ?? element.children);
|
|
2993
|
+
for (const child of children) {
|
|
2994
|
+
const match = getMatchElement5(child);
|
|
2995
|
+
if (!match) {
|
|
2996
|
+
continue;
|
|
2997
|
+
}
|
|
2998
|
+
const when = readReactive6(match.props.when);
|
|
2999
|
+
if (when) {
|
|
3000
|
+
return resolveMatchChildren5(match, when);
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
return props.fallback;
|
|
3004
|
+
}
|
|
3005
|
+
function resolveMatchChildren5(element, value) {
|
|
3006
|
+
const children = element.props.children ?? element.children;
|
|
3007
|
+
if (typeof children === "function") {
|
|
3008
|
+
return children(value);
|
|
3009
|
+
}
|
|
3010
|
+
return children;
|
|
3011
|
+
}
|
|
3012
|
+
function resolveKeyChildren5(element, value) {
|
|
3013
|
+
const children = element.props.children ?? element.children;
|
|
3014
|
+
if (typeof children === "function") {
|
|
3015
|
+
return children(value);
|
|
3016
|
+
}
|
|
3017
|
+
return children;
|
|
3018
|
+
}
|
|
3019
|
+
function createDynamicElement5(element, tag) {
|
|
3020
|
+
if (typeof tag !== "string" && typeof tag !== "function") {
|
|
3021
|
+
return null;
|
|
3022
|
+
}
|
|
3023
|
+
const { component, ...props } = element.props;
|
|
3024
|
+
const children = normalizeContent5(props.children ?? element.children);
|
|
3025
|
+
return {
|
|
3026
|
+
tag,
|
|
3027
|
+
props,
|
|
3028
|
+
children
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
function readReactive6(value) {
|
|
3032
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
3033
|
+
}
|
|
3034
|
+
function normalizeContent5(content) {
|
|
3035
|
+
if (content == null || typeof content === "boolean") {
|
|
3036
|
+
return [];
|
|
3037
|
+
}
|
|
3038
|
+
return Array.isArray(content) ? content : [content];
|
|
3039
|
+
}
|
|
3040
|
+
function isElementLike5(value) {
|
|
3041
|
+
return value != null && typeof value === "object" && "tag" in value;
|
|
3042
|
+
}
|
|
3043
|
+
function getMatchElement5(value) {
|
|
3044
|
+
if (!isElementLike5(value)) {
|
|
3045
|
+
return null;
|
|
3046
|
+
}
|
|
3047
|
+
if (isMatchElement(value)) {
|
|
3048
|
+
return value;
|
|
3049
|
+
}
|
|
3050
|
+
return value.tag === Match ? Match(value.props) : null;
|
|
3051
|
+
}
|
|
3052
|
+
function applyRef2(el, ref) {
|
|
3053
|
+
const value = ref;
|
|
3054
|
+
if (!value) {
|
|
3055
|
+
return null;
|
|
3056
|
+
}
|
|
3057
|
+
if (typeof value === "function") {
|
|
3058
|
+
value(el);
|
|
3059
|
+
return () => value(null);
|
|
3060
|
+
}
|
|
3061
|
+
if (typeof value === "object" && "current" in value) {
|
|
3062
|
+
value.current = el;
|
|
3063
|
+
return () => {
|
|
3064
|
+
value.current = null;
|
|
3065
|
+
};
|
|
3066
|
+
}
|
|
3067
|
+
return null;
|
|
3068
|
+
}
|
|
1538
3069
|
function hydrateComponent(component, props, cursor) {
|
|
1539
3070
|
const parentInstance = getCurrentInstance();
|
|
1540
3071
|
const instance = createComponentInstance(component, props, parentInstance);
|
|
@@ -1621,5 +3152,5 @@ function hydrate(component, container, props) {
|
|
|
1621
3152
|
};
|
|
1622
3153
|
}
|
|
1623
3154
|
|
|
1624
|
-
//# debugId=
|
|
3155
|
+
//# debugId=B2FFEB8D17EB811D64756E2164756E21
|
|
1625
3156
|
//# sourceMappingURL=index.development.js.map
|