sinwan 0.1.0 → 1.0.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 +1624 -961
- package/dist/cjs/index.development.js.map +21 -18
- package/dist/cjs/index.production.min.js +2 -2
- package/dist/cjs/index.production.min.js.map +21 -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 +1175 -0
- package/dist/cjs/renderer/index.development.js.map +24 -0
- package/dist/cjs/renderer/index.production.min.js +3 -0
- package/dist/cjs/renderer/index.production.min.js.map +24 -0
- package/dist/cjs/server/index.development.js +665 -329
- package/dist/cjs/server/index.development.js.map +11 -10
- package/dist/cjs/server/index.production.min.js +2 -2
- package/dist/cjs/server/index.production.min.js.map +11 -10
- package/dist/component/control-flow.d.ts +18 -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 +1301 -660
- package/dist/esm/index.development.js.map +21 -18
- package/dist/esm/index.production.min.js +2 -2
- package/dist/esm/index.production.min.js.map +21 -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 +1124 -0
- package/dist/esm/renderer/index.development.js.map +24 -0
- package/dist/esm/renderer/index.production.min.js +4 -0
- package/dist/esm/renderer/index.production.min.js.map +24 -0
- package/dist/esm/server/index.development.js +665 -329
- package/dist/esm/server/index.development.js.map +11 -10
- package/dist/esm/server/index.production.min.js +2 -2
- package/dist/esm/server/index.production.min.js.map +11 -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.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 +1 -1
- 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 +2 -0
- 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/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 +15 -1
|
@@ -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
|
}
|
|
@@ -126,6 +116,8 @@ function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
|
126
116
|
var exports_server = {};
|
|
127
117
|
__export(exports_server, {
|
|
128
118
|
streamPage: () => streamPage,
|
|
119
|
+
streamHydratablePage: () => streamHydratablePage,
|
|
120
|
+
streamHydratableNode: () => streamHydratableNode,
|
|
129
121
|
renderToString: () => renderToString,
|
|
130
122
|
renderToHydratableString: () => renderToHydratableString,
|
|
131
123
|
renderPage: () => renderPage,
|
|
@@ -171,221 +163,6 @@ function isSafeHtml(value) {
|
|
|
171
163
|
return value instanceof HtmlEscapedString;
|
|
172
164
|
}
|
|
173
165
|
|
|
174
|
-
// src/server/renderer.ts
|
|
175
|
-
var componentCache = new WeakMap;
|
|
176
|
-
var pageRegistry = new Map;
|
|
177
|
-
function registerPage(name, page) {
|
|
178
|
-
pageRegistry.set(name, page);
|
|
179
|
-
}
|
|
180
|
-
function getPage(name) {
|
|
181
|
-
return pageRegistry.get(name);
|
|
182
|
-
}
|
|
183
|
-
function hasPage(name) {
|
|
184
|
-
return pageRegistry.has(name);
|
|
185
|
-
}
|
|
186
|
-
async function renderPage(name, data) {
|
|
187
|
-
const page = getPage(name);
|
|
188
|
-
if (!page) {
|
|
189
|
-
throw new Error(`Page "${name}" not found in registry`);
|
|
190
|
-
}
|
|
191
|
-
const element = await page(data);
|
|
192
|
-
return renderToString(element);
|
|
193
|
-
}
|
|
194
|
-
async function renderToString(node) {
|
|
195
|
-
if (node == null || typeof node === "boolean") {
|
|
196
|
-
return "";
|
|
197
|
-
}
|
|
198
|
-
if (typeof node === "string") {
|
|
199
|
-
return escapeHtml(node);
|
|
200
|
-
}
|
|
201
|
-
if (typeof node === "number") {
|
|
202
|
-
return String(node);
|
|
203
|
-
}
|
|
204
|
-
if (node instanceof HtmlEscapedString) {
|
|
205
|
-
return node.value;
|
|
206
|
-
}
|
|
207
|
-
if (Array.isArray(node)) {
|
|
208
|
-
const results = await Promise.all(node.map((child) => renderToString(child)));
|
|
209
|
-
return results.join("");
|
|
210
|
-
}
|
|
211
|
-
if (node instanceof Promise) {
|
|
212
|
-
return renderElement(await node);
|
|
213
|
-
}
|
|
214
|
-
return renderElement(node);
|
|
215
|
-
}
|
|
216
|
-
async function renderElement(element) {
|
|
217
|
-
const { tag, props, children } = element;
|
|
218
|
-
if (typeof tag === "function") {
|
|
219
|
-
const result = await tag(props);
|
|
220
|
-
return renderToString(result);
|
|
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);
|
|
332
|
-
}
|
|
333
|
-
return;
|
|
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);
|
|
354
|
-
}
|
|
355
|
-
async function streamIntrinsicElement(tag, props, children, controller, encoder) {
|
|
356
|
-
const attrs = renderAttributes2(props);
|
|
357
|
-
const dangerous = props.dangerouslySetInnerHTML;
|
|
358
|
-
if (VOID_ELEMENTS3.has(tag)) {
|
|
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}>`));
|
|
371
|
-
}
|
|
372
|
-
function renderAttributes2(props) {
|
|
373
|
-
let attrs = "";
|
|
374
|
-
for (const [key, value] of Object.entries(props)) {
|
|
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}"`;
|
|
386
|
-
}
|
|
387
|
-
return attrs;
|
|
388
|
-
}
|
|
389
166
|
// src/reactivity/scheduler.ts
|
|
390
167
|
var pendingEffects = new Set;
|
|
391
168
|
var flushScheduled = false;
|
|
@@ -628,79 +405,68 @@ function isComputed(value) {
|
|
|
628
405
|
return value != null && typeof value === "object" && COMPUTED_BRAND in value;
|
|
629
406
|
}
|
|
630
407
|
|
|
631
|
-
// src/
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
|
|
408
|
+
// src/renderer/dom-ops.ts
|
|
409
|
+
function createDefaultDOMOps() {
|
|
410
|
+
return {
|
|
411
|
+
createElement(tag) {
|
|
412
|
+
return document.createElement(tag);
|
|
413
|
+
},
|
|
414
|
+
createElementNS(namespace, tag) {
|
|
415
|
+
return document.createElementNS(namespace, tag);
|
|
416
|
+
},
|
|
417
|
+
createTextNode(text) {
|
|
418
|
+
return document.createTextNode(text);
|
|
419
|
+
},
|
|
420
|
+
createComment(text) {
|
|
421
|
+
return document.createComment(text);
|
|
422
|
+
},
|
|
423
|
+
setAttribute(el, key, value) {
|
|
424
|
+
el.setAttribute(key, value);
|
|
425
|
+
},
|
|
426
|
+
removeAttribute(el, key) {
|
|
427
|
+
el.removeAttribute(key);
|
|
428
|
+
},
|
|
429
|
+
setProperty(el, key, value) {
|
|
430
|
+
el[key] = value;
|
|
431
|
+
},
|
|
432
|
+
insertBefore(parent, child, anchor) {
|
|
433
|
+
parent.insertBefore(child, anchor);
|
|
434
|
+
},
|
|
435
|
+
appendChild(parent, child) {
|
|
436
|
+
parent.appendChild(child);
|
|
437
|
+
},
|
|
438
|
+
remove(node) {
|
|
439
|
+
node.parentNode?.removeChild(node);
|
|
440
|
+
},
|
|
441
|
+
setTextContent(node, text) {
|
|
442
|
+
node.data = text;
|
|
443
|
+
},
|
|
444
|
+
addEventListener(el, event, handler) {
|
|
445
|
+
el.addEventListener(event, handler);
|
|
446
|
+
},
|
|
447
|
+
removeEventListener(el, event, handler) {
|
|
448
|
+
el.removeEventListener(event, handler);
|
|
449
|
+
},
|
|
450
|
+
parentNode(node) {
|
|
451
|
+
return node.parentNode;
|
|
452
|
+
},
|
|
453
|
+
nextSibling(node) {
|
|
454
|
+
return node.nextSibling;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
642
457
|
}
|
|
643
|
-
|
|
644
|
-
|
|
458
|
+
var defaultDOMOps = createDefaultDOMOps();
|
|
459
|
+
var domOps = { ...defaultDOMOps };
|
|
460
|
+
function setDOMOps(overrides) {
|
|
461
|
+
Object.assign(domOps, overrides);
|
|
645
462
|
}
|
|
646
|
-
function
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);
|
|
650
|
-
return Number.isNaN(idx) ? -1 : idx;
|
|
463
|
+
function resetDOMOps() {
|
|
464
|
+
for (const key of Object.keys(domOps)) {
|
|
465
|
+
delete domOps[key];
|
|
651
466
|
}
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
function isTextCloseMarker(node) {
|
|
655
|
-
return node.data === TEXT_MARKER_CLOSE;
|
|
467
|
+
Object.assign(domOps, defaultDOMOps);
|
|
656
468
|
}
|
|
657
469
|
|
|
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
470
|
// src/renderer/events.ts
|
|
705
471
|
function isEventProp(key) {
|
|
706
472
|
return key.length > 2 && key[0] === "o" && key[1] === "n" && key[2] >= "A" && key[2] <= "Z";
|
|
@@ -728,24 +494,184 @@ function bindEvents(el, props) {
|
|
|
728
494
|
return cleanups;
|
|
729
495
|
}
|
|
730
496
|
|
|
731
|
-
// src/component/
|
|
732
|
-
var
|
|
733
|
-
|
|
497
|
+
// src/component/control-flow.ts
|
|
498
|
+
var SHOW_TYPE = Symbol.for("Sinwan.Show");
|
|
499
|
+
var FOR_TYPE = Symbol.for("Sinwan.For");
|
|
500
|
+
function Show(props) {
|
|
734
501
|
return {
|
|
735
|
-
|
|
736
|
-
component,
|
|
502
|
+
tag: SHOW_TYPE,
|
|
737
503
|
props,
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
504
|
+
children: []
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function For(props) {
|
|
508
|
+
return {
|
|
509
|
+
tag: FOR_TYPE,
|
|
510
|
+
props,
|
|
511
|
+
children: []
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
function isShowElement(element) {
|
|
515
|
+
return element.tag === SHOW_TYPE;
|
|
516
|
+
}
|
|
517
|
+
function isForElement(element) {
|
|
518
|
+
return element.tag === FOR_TYPE;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/server/renderer.ts
|
|
522
|
+
var componentCache = new WeakMap;
|
|
523
|
+
var pageRegistry = new Map;
|
|
524
|
+
function registerPage(name, page) {
|
|
525
|
+
pageRegistry.set(name, page);
|
|
526
|
+
}
|
|
527
|
+
function getPage(name) {
|
|
528
|
+
return pageRegistry.get(name);
|
|
529
|
+
}
|
|
530
|
+
function hasPage(name) {
|
|
531
|
+
return pageRegistry.has(name);
|
|
532
|
+
}
|
|
533
|
+
async function renderPage(name, data) {
|
|
534
|
+
const page = getPage(name);
|
|
535
|
+
if (!page) {
|
|
536
|
+
throw new Error(`Page "${name}" not found in registry`);
|
|
537
|
+
}
|
|
538
|
+
const element = await page(data);
|
|
539
|
+
return renderToString(element);
|
|
540
|
+
}
|
|
541
|
+
async function renderToString(node) {
|
|
542
|
+
if (node == null || typeof node === "boolean") {
|
|
543
|
+
return "";
|
|
544
|
+
}
|
|
545
|
+
if (typeof node === "string") {
|
|
546
|
+
return escapeHtml(node);
|
|
547
|
+
}
|
|
548
|
+
if (typeof node === "number") {
|
|
549
|
+
return String(node);
|
|
550
|
+
}
|
|
551
|
+
if (node instanceof HtmlEscapedString) {
|
|
552
|
+
return node.value;
|
|
553
|
+
}
|
|
554
|
+
if (isSignal(node) || isComputed(node)) {
|
|
555
|
+
return escapeHtml(String(node.value));
|
|
556
|
+
}
|
|
557
|
+
if (Array.isArray(node)) {
|
|
558
|
+
const results = await Promise.all(node.map((child) => renderToString(child)));
|
|
559
|
+
return results.join("");
|
|
560
|
+
}
|
|
561
|
+
if (node instanceof Promise) {
|
|
562
|
+
return renderElement(await node);
|
|
563
|
+
}
|
|
564
|
+
return renderElement(node);
|
|
565
|
+
}
|
|
566
|
+
async function renderElement(element) {
|
|
567
|
+
const { tag, props, children } = element;
|
|
568
|
+
if (isShowElement(element)) {
|
|
569
|
+
const when = readReactive(props.when);
|
|
570
|
+
return renderToString(when ? resolveShowChildren(element, when) : props.fallback);
|
|
571
|
+
}
|
|
572
|
+
if (isForElement(element)) {
|
|
573
|
+
return renderForElement(element);
|
|
574
|
+
}
|
|
575
|
+
if (typeof tag === "function") {
|
|
576
|
+
const result = await tag(props);
|
|
577
|
+
return renderToString(result);
|
|
578
|
+
}
|
|
579
|
+
if (typeof tag === "string") {
|
|
580
|
+
return renderIntrinsicElement(tag, props, children);
|
|
581
|
+
}
|
|
582
|
+
return renderToString(children);
|
|
583
|
+
}
|
|
584
|
+
var VOID_ELEMENTS2 = new Set([
|
|
585
|
+
"area",
|
|
586
|
+
"base",
|
|
587
|
+
"br",
|
|
588
|
+
"col",
|
|
589
|
+
"embed",
|
|
590
|
+
"hr",
|
|
591
|
+
"img",
|
|
592
|
+
"input",
|
|
593
|
+
"link",
|
|
594
|
+
"meta",
|
|
595
|
+
"param",
|
|
596
|
+
"source",
|
|
597
|
+
"track",
|
|
598
|
+
"wbr"
|
|
599
|
+
]);
|
|
600
|
+
async function renderIntrinsicElement(tag, props, children) {
|
|
601
|
+
const attrs = renderAttributes(props);
|
|
602
|
+
if (VOID_ELEMENTS2.has(tag)) {
|
|
603
|
+
return attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
604
|
+
}
|
|
605
|
+
const childrenHtml = await renderChildren(children, props);
|
|
606
|
+
return attrs ? `<${tag}${attrs}>${childrenHtml}</${tag}>` : `<${tag}>${childrenHtml}</${tag}>`;
|
|
607
|
+
}
|
|
608
|
+
function renderAttributes(props) {
|
|
609
|
+
let attrs = "";
|
|
610
|
+
for (const [key, value] of Object.entries(props)) {
|
|
611
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
const resolvedValue = readReactive(value);
|
|
615
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
616
|
+
continue;
|
|
617
|
+
const attrName = key === "className" ? "class" : key;
|
|
618
|
+
const finalName = attrName === "htmlFor" ? "for" : attrName;
|
|
619
|
+
if (resolvedValue === true) {
|
|
620
|
+
attrs += ` ${finalName}`;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
const attrValue = escapeHtml(String(resolvedValue));
|
|
624
|
+
attrs += ` ${finalName}="${attrValue}"`;
|
|
625
|
+
}
|
|
626
|
+
return attrs;
|
|
627
|
+
}
|
|
628
|
+
async function renderChildren(children, props) {
|
|
629
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
630
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
631
|
+
return dangerous.__html;
|
|
632
|
+
}
|
|
633
|
+
return renderToString(children);
|
|
634
|
+
}
|
|
635
|
+
function isSlots(children) {
|
|
636
|
+
return children != null && typeof children === "object" && !Array.isArray(children) && !(children instanceof HtmlEscapedString);
|
|
637
|
+
}
|
|
638
|
+
async function renderForElement(element) {
|
|
639
|
+
const props = element.props;
|
|
640
|
+
const each = readReactive(props.each);
|
|
641
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
642
|
+
return "";
|
|
643
|
+
}
|
|
644
|
+
const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(item, () => index))));
|
|
645
|
+
return rendered.join("");
|
|
646
|
+
}
|
|
647
|
+
function resolveShowChildren(element, value) {
|
|
648
|
+
const children = element.props.children ?? element.children;
|
|
649
|
+
if (typeof children === "function") {
|
|
650
|
+
return children(value);
|
|
651
|
+
}
|
|
652
|
+
return children;
|
|
653
|
+
}
|
|
654
|
+
function readReactive(value) {
|
|
655
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
656
|
+
}
|
|
657
|
+
// src/component/instance.ts
|
|
658
|
+
var uidCounter = 0;
|
|
659
|
+
function createComponentInstance(component, props, parent) {
|
|
660
|
+
return {
|
|
661
|
+
uid: uidCounter++,
|
|
662
|
+
component,
|
|
663
|
+
props,
|
|
664
|
+
element: null,
|
|
665
|
+
parent,
|
|
666
|
+
children: [],
|
|
667
|
+
effects: [],
|
|
668
|
+
_mountedHooks: [],
|
|
669
|
+
_unmountedHooks: [],
|
|
670
|
+
_updatedHooks: [],
|
|
671
|
+
_errorHooks: [],
|
|
672
|
+
provides: parent ? Object.create(parent.provides) : Object.create(null),
|
|
673
|
+
isMounted: false,
|
|
674
|
+
isUnmounted: false
|
|
749
675
|
};
|
|
750
676
|
}
|
|
751
677
|
var currentInstance = null;
|
|
@@ -757,7 +683,18 @@ function setCurrentInstance(instance) {
|
|
|
757
683
|
currentInstance = instance;
|
|
758
684
|
return prev;
|
|
759
685
|
}
|
|
686
|
+
function withInstance(instance, fn) {
|
|
687
|
+
const prev = setCurrentInstance(instance);
|
|
688
|
+
try {
|
|
689
|
+
return fn();
|
|
690
|
+
} finally {
|
|
691
|
+
setCurrentInstance(prev);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
760
694
|
function fireMountedHooks(instance) {
|
|
695
|
+
if (instance.isUnmounted) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
761
698
|
for (const child of instance.children) {
|
|
762
699
|
fireMountedHooks(child);
|
|
763
700
|
}
|
|
@@ -784,6 +721,24 @@ function fireUnmountedHooks(instance) {
|
|
|
784
721
|
instance.effects.length = 0;
|
|
785
722
|
}
|
|
786
723
|
}
|
|
724
|
+
function fireUpdatedHooks(instance) {
|
|
725
|
+
for (const hook of instance._updatedHooks) {
|
|
726
|
+
hook();
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
var queuedUpdatedHooks = new Set;
|
|
730
|
+
function queueUpdatedHooks(instance) {
|
|
731
|
+
if (!instance || !instance.isMounted || instance.isUnmounted || instance._updatedHooks.length === 0 || queuedUpdatedHooks.has(instance)) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
queuedUpdatedHooks.add(instance);
|
|
735
|
+
nextTick(() => {
|
|
736
|
+
queuedUpdatedHooks.delete(instance);
|
|
737
|
+
if (instance.isMounted && !instance.isUnmounted) {
|
|
738
|
+
fireUpdatedHooks(instance);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
}
|
|
787
742
|
function handleComponentError(instance, err) {
|
|
788
743
|
let current = instance;
|
|
789
744
|
while (current) {
|
|
@@ -798,6 +753,342 @@ function handleComponentError(instance, err) {
|
|
|
798
753
|
console.error("[Sinwan] Unhandled component error:", err);
|
|
799
754
|
}
|
|
800
755
|
|
|
756
|
+
// src/hydration/markers.ts
|
|
757
|
+
var COMP_ID_ATTR = "data-sinwan-id";
|
|
758
|
+
var COMP_ID_PREFIX = "c";
|
|
759
|
+
var TEXT_MARKER_OPEN = "sinwan-t:";
|
|
760
|
+
var TEXT_MARKER_CLOSE = "/sinwan-t";
|
|
761
|
+
var EVENT_ATTR = "data-sinwan-ev";
|
|
762
|
+
function compId(index) {
|
|
763
|
+
return `${COMP_ID_PREFIX}${index}`;
|
|
764
|
+
}
|
|
765
|
+
function textMarkerOpen(index) {
|
|
766
|
+
return `<!--${TEXT_MARKER_OPEN}${index}-->`;
|
|
767
|
+
}
|
|
768
|
+
function textMarkerCloseStr() {
|
|
769
|
+
return `<!--${TEXT_MARKER_CLOSE}-->`;
|
|
770
|
+
}
|
|
771
|
+
function parseTextOpenMarker(node) {
|
|
772
|
+
const data = node.data;
|
|
773
|
+
if (data.startsWith(TEXT_MARKER_OPEN)) {
|
|
774
|
+
const idx = parseInt(data.slice(TEXT_MARKER_OPEN.length), 10);
|
|
775
|
+
return Number.isNaN(idx) ? -1 : idx;
|
|
776
|
+
}
|
|
777
|
+
return -1;
|
|
778
|
+
}
|
|
779
|
+
function isTextCloseMarker(node) {
|
|
780
|
+
return node.data === TEXT_MARKER_CLOSE;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// src/server/stream.ts
|
|
784
|
+
function createHydratableStreamContext() {
|
|
785
|
+
return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
|
|
786
|
+
}
|
|
787
|
+
var VOID_ELEMENTS3 = new Set([
|
|
788
|
+
"area",
|
|
789
|
+
"base",
|
|
790
|
+
"br",
|
|
791
|
+
"col",
|
|
792
|
+
"embed",
|
|
793
|
+
"hr",
|
|
794
|
+
"img",
|
|
795
|
+
"input",
|
|
796
|
+
"link",
|
|
797
|
+
"meta",
|
|
798
|
+
"param",
|
|
799
|
+
"source",
|
|
800
|
+
"track",
|
|
801
|
+
"wbr"
|
|
802
|
+
]);
|
|
803
|
+
function streamPage(page, data) {
|
|
804
|
+
const encoder = new TextEncoder;
|
|
805
|
+
return new ReadableStream({
|
|
806
|
+
async start(controller) {
|
|
807
|
+
try {
|
|
808
|
+
const element = await page(data);
|
|
809
|
+
await streamNode(element, controller, encoder);
|
|
810
|
+
controller.close();
|
|
811
|
+
} catch (error) {
|
|
812
|
+
controller.error(error);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
function streamHydratablePage(component, props) {
|
|
818
|
+
const encoder = new TextEncoder;
|
|
819
|
+
const ctx = createHydratableStreamContext();
|
|
820
|
+
return new ReadableStream({
|
|
821
|
+
async start(controller) {
|
|
822
|
+
try {
|
|
823
|
+
await streamHydratableComponent(component, props ?? {}, controller, encoder, ctx, true);
|
|
824
|
+
controller.close();
|
|
825
|
+
} catch (error) {
|
|
826
|
+
controller.error(error);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
function streamHydratableNode(node) {
|
|
832
|
+
const encoder = new TextEncoder;
|
|
833
|
+
const ctx = createHydratableStreamContext();
|
|
834
|
+
return new ReadableStream({
|
|
835
|
+
async start(controller) {
|
|
836
|
+
try {
|
|
837
|
+
await streamHydratableNodeToController(node, controller, encoder, ctx);
|
|
838
|
+
controller.close();
|
|
839
|
+
} catch (error) {
|
|
840
|
+
controller.error(error);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
async function streamNode(node, controller, encoder) {
|
|
846
|
+
if (node == null || typeof node === "boolean") {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (typeof node === "string") {
|
|
850
|
+
controller.enqueue(encoder.encode(escapeHtml(node)));
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (typeof node === "number") {
|
|
854
|
+
controller.enqueue(encoder.encode(String(node)));
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (node instanceof HtmlEscapedString) {
|
|
858
|
+
controller.enqueue(encoder.encode(node.value));
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (isSignal(node) || isComputed(node)) {
|
|
862
|
+
controller.enqueue(encoder.encode(escapeHtml(String(node.value))));
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (Array.isArray(node)) {
|
|
866
|
+
for (const child of node) {
|
|
867
|
+
await streamNode(child, controller, encoder);
|
|
868
|
+
}
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
if (node instanceof Promise) {
|
|
872
|
+
const resolved = await node;
|
|
873
|
+
await streamElement(resolved, controller, encoder);
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
await streamElement(node, controller, encoder);
|
|
877
|
+
}
|
|
878
|
+
async function streamElement(element, controller, encoder) {
|
|
879
|
+
const { tag, props, children } = element;
|
|
880
|
+
if (isShowElement(element)) {
|
|
881
|
+
const when = readReactive2(props.when);
|
|
882
|
+
await streamNode(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
if (isForElement(element)) {
|
|
886
|
+
await streamForElement(element, controller, encoder);
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (typeof tag === "function") {
|
|
890
|
+
const result = await tag(props);
|
|
891
|
+
await streamNode(result, controller, encoder);
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (typeof tag === "string") {
|
|
895
|
+
await streamIntrinsicElement(tag, props, children, controller, encoder);
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
await streamNode(children, controller, encoder);
|
|
899
|
+
}
|
|
900
|
+
async function streamIntrinsicElement(tag, props, children, controller, encoder) {
|
|
901
|
+
const attrs = renderAttributes2(props);
|
|
902
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
903
|
+
if (VOID_ELEMENTS3.has(tag)) {
|
|
904
|
+
const html = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
905
|
+
controller.enqueue(encoder.encode(html));
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
const openTag = attrs ? `<${tag}${attrs}>` : `<${tag}>`;
|
|
909
|
+
controller.enqueue(encoder.encode(openTag));
|
|
910
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
911
|
+
controller.enqueue(encoder.encode(dangerous.__html));
|
|
912
|
+
} else {
|
|
913
|
+
await streamNode(children, controller, encoder);
|
|
914
|
+
}
|
|
915
|
+
controller.enqueue(encoder.encode(`</${tag}>`));
|
|
916
|
+
}
|
|
917
|
+
function renderAttributes2(props) {
|
|
918
|
+
let attrs = "";
|
|
919
|
+
for (const [key, value] of Object.entries(props)) {
|
|
920
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
const resolvedValue = readReactive2(value);
|
|
924
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
925
|
+
continue;
|
|
926
|
+
const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
|
|
927
|
+
if (resolvedValue === true) {
|
|
928
|
+
attrs += ` ${attrName}`;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
const attrValue = escapeHtml(String(resolvedValue));
|
|
932
|
+
attrs += ` ${attrName}="${attrValue}"`;
|
|
933
|
+
}
|
|
934
|
+
return attrs;
|
|
935
|
+
}
|
|
936
|
+
async function streamHydratableNodeToController(node, controller, encoder, ctx, isComponentRoot = false) {
|
|
937
|
+
if (node == null || typeof node === "boolean") {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (typeof node === "string") {
|
|
941
|
+
enqueue(controller, encoder, escapeHtml(node));
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (typeof node === "number") {
|
|
945
|
+
enqueue(controller, encoder, String(node));
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (node instanceof HtmlEscapedString) {
|
|
949
|
+
enqueue(controller, encoder, node.value);
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
if (isSignal(node) || isComputed(node)) {
|
|
953
|
+
const idx = ctx.textIndex++;
|
|
954
|
+
enqueue(controller, encoder, `${textMarkerOpen(idx)}${escapeHtml(String(node.value))}${textMarkerCloseStr()}`);
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
if (Array.isArray(node)) {
|
|
958
|
+
for (const child of node) {
|
|
959
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
960
|
+
}
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
if (node instanceof Promise) {
|
|
964
|
+
await streamHydratableElement(await node, controller, encoder, ctx, isComponentRoot);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
await streamHydratableElement(node, controller, encoder, ctx, isComponentRoot);
|
|
968
|
+
}
|
|
969
|
+
async function streamHydratableElement(element, controller, encoder, ctx, isComponentRoot) {
|
|
970
|
+
const { tag, props, children } = element;
|
|
971
|
+
if (tag === "") {
|
|
972
|
+
for (const child of children) {
|
|
973
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
974
|
+
}
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
if (tag === Show || tag === For) {
|
|
978
|
+
await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
if (isShowElement(element)) {
|
|
982
|
+
const when = readReactive2(props.when);
|
|
983
|
+
await streamHydratableNodeToController(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder, ctx, isComponentRoot);
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
if (isForElement(element)) {
|
|
987
|
+
await streamHydratableForElement(element, controller, encoder, ctx);
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
if (typeof tag === "function") {
|
|
991
|
+
await streamHydratableComponent(tag, props, controller, encoder, ctx, true);
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
if (typeof tag === "string") {
|
|
995
|
+
await streamHydratableIntrinsic(tag, props, children, controller, encoder, ctx, isComponentRoot);
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
await streamHydratableNodeToController(children, controller, encoder, ctx);
|
|
999
|
+
}
|
|
1000
|
+
async function streamHydratableComponent(component, props, controller, encoder, ctx, isComponentRoot) {
|
|
1001
|
+
const parentInstance = getCurrentInstance();
|
|
1002
|
+
const instance = createComponentInstance(component, props, parentInstance);
|
|
1003
|
+
if (parentInstance) {
|
|
1004
|
+
parentInstance.children.push(instance);
|
|
1005
|
+
}
|
|
1006
|
+
const prev = setCurrentInstance(instance);
|
|
1007
|
+
try {
|
|
1008
|
+
const result = await component(props);
|
|
1009
|
+
await streamHydratableNodeToController(result, controller, encoder, ctx, isComponentRoot);
|
|
1010
|
+
} finally {
|
|
1011
|
+
setCurrentInstance(prev);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async function streamHydratableIntrinsic(tag, props, children, controller, encoder, ctx, isComponentRoot) {
|
|
1015
|
+
const attrs = renderHydratableAttributes(props, ctx, isComponentRoot);
|
|
1016
|
+
const dangerous = props.dangerouslySetInnerHTML;
|
|
1017
|
+
enqueue(controller, encoder, attrs ? `<${tag}${attrs}>` : `<${tag}>`);
|
|
1018
|
+
if (VOID_ELEMENTS3.has(tag)) {
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
if (dangerous && typeof dangerous.__html === "string") {
|
|
1022
|
+
enqueue(controller, encoder, dangerous.__html);
|
|
1023
|
+
} else {
|
|
1024
|
+
for (const child of children) {
|
|
1025
|
+
await streamHydratableNodeToController(child, controller, encoder, ctx);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
enqueue(controller, encoder, `</${tag}>`);
|
|
1029
|
+
}
|
|
1030
|
+
async function streamHydratableForElement(element, controller, encoder, ctx) {
|
|
1031
|
+
const props = element.props;
|
|
1032
|
+
const each = readReactive2(props.each);
|
|
1033
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
for (let index = 0;index < each.length; index++) {
|
|
1037
|
+
await streamHydratableNodeToController(props.children(each[index], () => index), controller, encoder, ctx);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
function renderHydratableAttributes(props, ctx, isComponentRoot) {
|
|
1041
|
+
let attrs = "";
|
|
1042
|
+
if (isComponentRoot) {
|
|
1043
|
+
attrs += ` ${COMP_ID_ATTR}="${compId(ctx.componentIndex++)}"`;
|
|
1044
|
+
}
|
|
1045
|
+
const eventParts = [];
|
|
1046
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1047
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") {
|
|
1048
|
+
continue;
|
|
1049
|
+
}
|
|
1050
|
+
if (isEventProp(key)) {
|
|
1051
|
+
eventParts.push(`${toEventName(key)}:${ctx.eventIndex++}`);
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
const resolvedValue = readReactive2(value);
|
|
1055
|
+
if (resolvedValue == null || resolvedValue === false)
|
|
1056
|
+
continue;
|
|
1057
|
+
const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
|
|
1058
|
+
if (resolvedValue === true) {
|
|
1059
|
+
attrs += ` ${attrName}`;
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
1062
|
+
attrs += ` ${attrName}="${escapeHtml(String(resolvedValue))}"`;
|
|
1063
|
+
}
|
|
1064
|
+
if (eventParts.length > 0) {
|
|
1065
|
+
attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
|
|
1066
|
+
}
|
|
1067
|
+
return attrs;
|
|
1068
|
+
}
|
|
1069
|
+
function enqueue(controller, encoder, html) {
|
|
1070
|
+
controller.enqueue(encoder.encode(html));
|
|
1071
|
+
}
|
|
1072
|
+
async function streamForElement(element, controller, encoder) {
|
|
1073
|
+
const props = element.props;
|
|
1074
|
+
const each = readReactive2(props.each);
|
|
1075
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
for (let index = 0;index < each.length; index++) {
|
|
1079
|
+
await streamNode(props.children(each[index], () => index), controller, encoder);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
function resolveShowChildren2(element, value) {
|
|
1083
|
+
const children = element.props.children ?? element.children;
|
|
1084
|
+
if (typeof children === "function") {
|
|
1085
|
+
return children(value);
|
|
1086
|
+
}
|
|
1087
|
+
return children;
|
|
1088
|
+
}
|
|
1089
|
+
function readReactive2(value) {
|
|
1090
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
1091
|
+
}
|
|
801
1092
|
// src/server/hydration-markers.ts
|
|
802
1093
|
function createHydrationContext() {
|
|
803
1094
|
return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
|
|
@@ -806,13 +1097,16 @@ async function renderToHydratableString(component, props) {
|
|
|
806
1097
|
const ctx = createHydrationContext();
|
|
807
1098
|
const mergedProps = props ?? {};
|
|
808
1099
|
const instance = createComponentInstance(component, mergedProps, null);
|
|
809
|
-
setCurrentInstance(instance);
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1100
|
+
const prev = setCurrentInstance(instance);
|
|
1101
|
+
try {
|
|
1102
|
+
const result = await component(mergedProps);
|
|
1103
|
+
if (result && typeof result === "object" && "tag" in result) {
|
|
1104
|
+
return renderElementH(result, ctx, true);
|
|
1105
|
+
}
|
|
1106
|
+
return renderNodeH(result, ctx);
|
|
1107
|
+
} finally {
|
|
1108
|
+
setCurrentInstance(prev);
|
|
814
1109
|
}
|
|
815
|
-
return renderNodeH(result, ctx);
|
|
816
1110
|
}
|
|
817
1111
|
async function renderNodeToHydratableString(node) {
|
|
818
1112
|
const ctx = createHydrationContext();
|
|
@@ -864,6 +1158,17 @@ function renderElementH(element, ctx, isComponentRoot) {
|
|
|
864
1158
|
if (tag === "") {
|
|
865
1159
|
return children.map((child) => renderNodeH(child, ctx)).join("");
|
|
866
1160
|
}
|
|
1161
|
+
if (tag === Show || tag === For) {
|
|
1162
|
+
return renderElementH(tag(props), ctx, isComponentRoot);
|
|
1163
|
+
}
|
|
1164
|
+
if (isShowElement(element)) {
|
|
1165
|
+
const when = readReactive3(props.when);
|
|
1166
|
+
const content = when ? resolveShowChildren3(element, when) : props.fallback;
|
|
1167
|
+
return renderNodeMaybeRoot(content, ctx, isComponentRoot);
|
|
1168
|
+
}
|
|
1169
|
+
if (isForElement(element)) {
|
|
1170
|
+
return renderForElementH(element, ctx);
|
|
1171
|
+
}
|
|
867
1172
|
if (typeof tag === "function") {
|
|
868
1173
|
return renderComponentH(tag, props, ctx);
|
|
869
1174
|
}
|
|
@@ -873,15 +1178,21 @@ function renderElementH(element, ctx, isComponentRoot) {
|
|
|
873
1178
|
return children.map((child) => renderNodeH(child, ctx)).join("");
|
|
874
1179
|
}
|
|
875
1180
|
function renderComponentH(component, props, ctx) {
|
|
876
|
-
const parentInstance =
|
|
877
|
-
const instance = createComponentInstance(component, props,
|
|
1181
|
+
const parentInstance = getCurrentInstance();
|
|
1182
|
+
const instance = createComponentInstance(component, props, parentInstance);
|
|
1183
|
+
if (parentInstance) {
|
|
1184
|
+
parentInstance.children.push(instance);
|
|
1185
|
+
}
|
|
878
1186
|
const prev = setCurrentInstance(instance);
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1187
|
+
try {
|
|
1188
|
+
const result = component(props);
|
|
1189
|
+
if (result && typeof result === "object" && "tag" in result) {
|
|
1190
|
+
return renderElementH(result, ctx, true);
|
|
1191
|
+
}
|
|
1192
|
+
return renderNodeH(result, ctx);
|
|
1193
|
+
} finally {
|
|
1194
|
+
setCurrentInstance(prev);
|
|
883
1195
|
}
|
|
884
|
-
return renderNodeH(result, ctx);
|
|
885
1196
|
}
|
|
886
1197
|
function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
|
|
887
1198
|
let attrs = "";
|
|
@@ -890,8 +1201,9 @@ function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
|
|
|
890
1201
|
}
|
|
891
1202
|
const eventParts = [];
|
|
892
1203
|
for (const [key, value] of Object.entries(props)) {
|
|
893
|
-
if (key === "children" || key === "dangerouslySetInnerHTML")
|
|
1204
|
+
if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML") {
|
|
894
1205
|
continue;
|
|
1206
|
+
}
|
|
895
1207
|
if (isEventProp(key)) {
|
|
896
1208
|
const eventName = toEventName(key);
|
|
897
1209
|
eventParts.push(`${eventName}:${ctx.eventIndex++}`);
|
|
@@ -924,6 +1236,30 @@ function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
|
|
|
924
1236
|
const childrenHtml = children.map((child) => renderNodeH(child, ctx)).join("");
|
|
925
1237
|
return `<${tag}${attrs}>${childrenHtml}</${tag}>`;
|
|
926
1238
|
}
|
|
1239
|
+
function renderNodeMaybeRoot(node, ctx, isComponentRoot) {
|
|
1240
|
+
if (isComponentRoot && node && typeof node === "object" && !Array.isArray(node) && "tag" in node) {
|
|
1241
|
+
return renderElementH(node, ctx, true);
|
|
1242
|
+
}
|
|
1243
|
+
return renderNodeH(node, ctx);
|
|
1244
|
+
}
|
|
1245
|
+
function renderForElementH(element, ctx) {
|
|
1246
|
+
const props = element.props;
|
|
1247
|
+
const each = readReactive3(props.each);
|
|
1248
|
+
if (!Array.isArray(each) || typeof props.children !== "function") {
|
|
1249
|
+
return "";
|
|
1250
|
+
}
|
|
1251
|
+
return each.map((item, index) => renderNodeH(props.children(item, () => index), ctx)).join("");
|
|
1252
|
+
}
|
|
1253
|
+
function resolveShowChildren3(element, value) {
|
|
1254
|
+
const children = element.props.children ?? element.children;
|
|
1255
|
+
if (typeof children === "function") {
|
|
1256
|
+
return children(value);
|
|
1257
|
+
}
|
|
1258
|
+
return children;
|
|
1259
|
+
}
|
|
1260
|
+
function readReactive3(value) {
|
|
1261
|
+
return isSignal(value) || isComputed(value) ? value.value : value;
|
|
1262
|
+
}
|
|
927
1263
|
|
|
928
|
-
//# debugId=
|
|
1264
|
+
//# debugId=107ADB344D9D30F764756E2164756E21
|
|
929
1265
|
//# sourceMappingURL=index.development.js.map
|