sinwan 1.0.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.
Files changed (47) hide show
  1. package/dist/cjs/index.development.js +962 -94
  2. package/dist/cjs/index.development.js.map +14 -13
  3. package/dist/cjs/index.production.min.js +2 -2
  4. package/dist/cjs/index.production.min.js.map +14 -13
  5. package/dist/cjs/renderer/index.development.js +419 -13
  6. package/dist/cjs/renderer/index.development.js.map +9 -8
  7. package/dist/cjs/renderer/index.production.min.js +2 -2
  8. package/dist/cjs/renderer/index.production.min.js.map +9 -8
  9. package/dist/cjs/server/index.development.js +560 -48
  10. package/dist/cjs/server/index.development.js.map +9 -7
  11. package/dist/cjs/server/index.production.min.js +2 -2
  12. package/dist/cjs/server/index.production.min.js.map +9 -7
  13. package/dist/component/control-flow.d.ts +54 -1
  14. package/dist/component/control-flow.d.ts.map +1 -1
  15. package/dist/component/index.d.ts +2 -2
  16. package/dist/component/index.d.ts.map +1 -1
  17. package/dist/esm/index.development.js +962 -94
  18. package/dist/esm/index.development.js.map +14 -13
  19. package/dist/esm/index.production.min.js +2 -2
  20. package/dist/esm/index.production.min.js.map +14 -13
  21. package/dist/esm/renderer/index.development.js +419 -13
  22. package/dist/esm/renderer/index.development.js.map +9 -8
  23. package/dist/esm/renderer/index.production.min.js +2 -2
  24. package/dist/esm/renderer/index.production.min.js.map +9 -8
  25. package/dist/esm/server/index.development.js +560 -48
  26. package/dist/esm/server/index.development.js.map +9 -7
  27. package/dist/esm/server/index.production.min.js +2 -2
  28. package/dist/esm/server/index.production.min.js.map +9 -7
  29. package/dist/hydration/walk.d.ts.map +1 -1
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/renderer/attributes.d.ts +11 -0
  33. package/dist/renderer/attributes.d.ts.map +1 -1
  34. package/dist/renderer/index.d.ts +1 -1
  35. package/dist/renderer/index.d.ts.map +1 -1
  36. package/dist/renderer/render-control-flow.d.ts +3 -3
  37. package/dist/renderer/render-control-flow.d.ts.map +1 -1
  38. package/dist/renderer/render-element.d.ts.map +1 -1
  39. package/dist/renderer/types.d.ts +8 -1
  40. package/dist/renderer/types.d.ts.map +1 -1
  41. package/dist/renderer/unmount.d.ts.map +1 -1
  42. package/dist/server/attribute-utils.d.ts +2 -0
  43. package/dist/server/attribute-utils.d.ts.map +1 -0
  44. package/dist/server/hydration-markers.d.ts.map +1 -1
  45. package/dist/server/renderer.d.ts.map +1 -1
  46. package/dist/server/stream.d.ts.map +1 -1
  47. package/package.json +5 -5
@@ -99,6 +99,37 @@ function isSafeHtml(value) {
99
99
  return value instanceof HtmlEscapedString;
100
100
  }
101
101
 
102
+ // src/server/attribute-utils.ts
103
+ var PROP_ALIASES = {
104
+ className: "class",
105
+ htmlFor: "for",
106
+ tabIndex: "tabindex",
107
+ crossOrigin: "crossorigin"
108
+ };
109
+ function renderServerAttribute(key, value) {
110
+ const attrName = PROP_ALIASES[key] ?? key;
111
+ if (value == null || value === false) {
112
+ return "";
113
+ }
114
+ if (value === true) {
115
+ return ` ${attrName}`;
116
+ }
117
+ const attrValue = attrName === "class" && typeof value === "object" ? stringifyClass(value) : attrName === "style" && typeof value === "object" ? stringifyStyle(value) : String(value);
118
+ return ` ${attrName}="${escapeHtml(attrValue)}"`;
119
+ }
120
+ function stringifyClass(value) {
121
+ if (Array.isArray(value)) {
122
+ return value.filter(Boolean).join(" ");
123
+ }
124
+ return Object.entries(value).filter(([, enabled]) => Boolean(enabled)).map(([name]) => name).join(" ");
125
+ }
126
+ function stringifyStyle(value) {
127
+ return Object.entries(value).filter(([, val]) => val != null && val !== false).map(([prop, val]) => `${toKebabCase(prop)}:${String(val)}`).join(";");
128
+ }
129
+ function toKebabCase(value) {
130
+ return value.includes("-") ? value : value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
131
+ }
132
+
102
133
  // src/reactivity/scheduler.ts
103
134
  var pendingEffects = new Set;
104
135
  var flushScheduled = false;
@@ -429,10 +460,28 @@ function bindEvents(el, props) {
429
460
  }
430
461
  return cleanups;
431
462
  }
432
-
463
+ // src/reactivity/batch.ts
464
+ var batchDepth = 0;
465
+ function batch(fn) {
466
+ batchDepth++;
467
+ try {
468
+ fn();
469
+ } finally {
470
+ batchDepth--;
471
+ if (batchDepth === 0) {
472
+ flushSync();
473
+ }
474
+ }
475
+ }
433
476
  // src/component/control-flow.ts
434
477
  var SHOW_TYPE = Symbol.for("Sinwan.Show");
435
478
  var FOR_TYPE = Symbol.for("Sinwan.For");
479
+ var SWITCH_TYPE = Symbol.for("Sinwan.Switch");
480
+ var MATCH_TYPE = Symbol.for("Sinwan.Match");
481
+ var INDEX_TYPE = Symbol.for("Sinwan.Index");
482
+ var KEY_TYPE = Symbol.for("Sinwan.Key");
483
+ var DYNAMIC_TYPE = Symbol.for("Sinwan.Dynamic");
484
+ var PORTAL_TYPE = Symbol.for("Sinwan.Portal");
436
485
  function Show(props) {
437
486
  return {
438
487
  tag: SHOW_TYPE,
@@ -447,12 +496,114 @@ function For(props) {
447
496
  children: []
448
497
  };
449
498
  }
499
+ function Switch(props) {
500
+ return {
501
+ tag: SWITCH_TYPE,
502
+ props,
503
+ children: []
504
+ };
505
+ }
506
+ function Match(props) {
507
+ return {
508
+ tag: MATCH_TYPE,
509
+ props,
510
+ children: []
511
+ };
512
+ }
513
+ function Index(props) {
514
+ return {
515
+ tag: INDEX_TYPE,
516
+ props,
517
+ children: []
518
+ };
519
+ }
520
+ function Key(props) {
521
+ return {
522
+ tag: KEY_TYPE,
523
+ props,
524
+ children: []
525
+ };
526
+ }
527
+ function Dynamic(props) {
528
+ return {
529
+ tag: DYNAMIC_TYPE,
530
+ props,
531
+ children: []
532
+ };
533
+ }
534
+ function Visible(props) {
535
+ const {
536
+ when,
537
+ as = "span",
538
+ style,
539
+ children,
540
+ ...rest
541
+ } = props;
542
+ const visibleStyle = computed(() => {
543
+ const base = readReactive(style);
544
+ const visible = Boolean(readReactive(when));
545
+ if (typeof base === "string") {
546
+ return visible ? base : appendHiddenDisplay(base);
547
+ }
548
+ const styleObject = base && typeof base === "object" ? { ...base } : {};
549
+ styleObject.display = visible ? styleObject.display : "none";
550
+ return styleObject;
551
+ });
552
+ return {
553
+ tag: as,
554
+ props: {
555
+ ...rest,
556
+ style: visibleStyle,
557
+ children
558
+ },
559
+ children: normalizeChildren2(children)
560
+ };
561
+ }
562
+ function Portal(props) {
563
+ return {
564
+ tag: PORTAL_TYPE,
565
+ props,
566
+ children: []
567
+ };
568
+ }
450
569
  function isShowElement(element) {
451
570
  return element.tag === SHOW_TYPE;
452
571
  }
453
572
  function isForElement(element) {
454
573
  return element.tag === FOR_TYPE;
455
574
  }
575
+ function isSwitchElement(element) {
576
+ return element.tag === SWITCH_TYPE;
577
+ }
578
+ function isMatchElement(element) {
579
+ return element.tag === MATCH_TYPE;
580
+ }
581
+ function isIndexElement(element) {
582
+ return element.tag === INDEX_TYPE;
583
+ }
584
+ function isKeyElement(element) {
585
+ return element.tag === KEY_TYPE;
586
+ }
587
+ function isDynamicElement(element) {
588
+ return element.tag === DYNAMIC_TYPE;
589
+ }
590
+ function isPortalElement(element) {
591
+ return element.tag === PORTAL_TYPE;
592
+ }
593
+ function normalizeChildren2(children) {
594
+ if (children == null || typeof children === "boolean") {
595
+ return [];
596
+ }
597
+ return Array.isArray(children) ? children : [children];
598
+ }
599
+ function readReactive(value) {
600
+ return isSignal(value) || isComputed(value) ? value.value : value;
601
+ }
602
+ function appendHiddenDisplay(style) {
603
+ const trimmed = style.trim();
604
+ const separator = trimmed.length > 0 && !trimmed.endsWith(";") ? ";" : "";
605
+ return `${trimmed}${separator}display:none`;
606
+ }
456
607
 
457
608
  // src/server/renderer.ts
458
609
  var componentCache = new WeakMap;
@@ -501,13 +652,41 @@ async function renderToString(node) {
501
652
  }
502
653
  async function renderElement(element) {
503
654
  const { tag, props, children } = element;
655
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
656
+ return renderElement(tag(props));
657
+ }
658
+ if (tag === Visible) {
659
+ return renderElement(tag(props));
660
+ }
504
661
  if (isShowElement(element)) {
505
- const when = readReactive(props.when);
662
+ const when = readReactive2(props.when);
506
663
  return renderToString(when ? resolveShowChildren(element, when) : props.fallback);
507
664
  }
508
665
  if (isForElement(element)) {
509
666
  return renderForElement(element);
510
667
  }
668
+ if (isSwitchElement(element)) {
669
+ return renderToString(resolveSwitchContent(element));
670
+ }
671
+ if (isMatchElement(element)) {
672
+ const when = readReactive2(props.when);
673
+ return renderToString(when ? resolveMatchChildren(element, when) : null);
674
+ }
675
+ if (isIndexElement(element)) {
676
+ return renderIndexElement(element);
677
+ }
678
+ if (isKeyElement(element)) {
679
+ const key = readReactive2(props.when);
680
+ return renderToString(resolveKeyChildren(element, key));
681
+ }
682
+ if (isDynamicElement(element)) {
683
+ const tag2 = readReactive2(props.component);
684
+ const dynamic = createDynamicElement(element, tag2);
685
+ return dynamic ? renderElement(dynamic) : "";
686
+ }
687
+ if (isPortalElement(element)) {
688
+ return "";
689
+ }
511
690
  if (typeof tag === "function") {
512
691
  const result = await tag(props);
513
692
  return renderToString(result);
@@ -547,17 +726,10 @@ function renderAttributes(props) {
547
726
  if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
548
727
  continue;
549
728
  }
550
- const resolvedValue = readReactive(value);
729
+ const resolvedValue = readReactive2(value);
551
730
  if (resolvedValue == null || resolvedValue === false)
552
731
  continue;
553
- const attrName = key === "className" ? "class" : key;
554
- const finalName = attrName === "htmlFor" ? "for" : attrName;
555
- if (resolvedValue === true) {
556
- attrs += ` ${finalName}`;
557
- continue;
558
- }
559
- const attrValue = escapeHtml(String(resolvedValue));
560
- attrs += ` ${finalName}="${attrValue}"`;
732
+ attrs += renderServerAttribute(key, resolvedValue);
561
733
  }
562
734
  return attrs;
563
735
  }
@@ -573,13 +745,69 @@ function isSlots(children) {
573
745
  }
574
746
  async function renderForElement(element) {
575
747
  const props = element.props;
576
- const each = readReactive(props.each);
748
+ const each = readReactive2(props.each);
577
749
  if (!Array.isArray(each) || typeof props.children !== "function") {
578
- return "";
750
+ return props.fallback ? renderToString(props.fallback) : "";
751
+ }
752
+ if (each.length === 0) {
753
+ return props.fallback ? renderToString(props.fallback) : "";
579
754
  }
580
755
  const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(item, () => index))));
581
756
  return rendered.join("");
582
757
  }
758
+ async function renderIndexElement(element) {
759
+ const props = element.props;
760
+ const each = readReactive2(props.each);
761
+ if (!Array.isArray(each) || typeof props.children !== "function") {
762
+ return props.fallback ? renderToString(props.fallback) : "";
763
+ }
764
+ if (each.length === 0) {
765
+ return props.fallback ? renderToString(props.fallback) : "";
766
+ }
767
+ const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(() => item, index))));
768
+ return rendered.join("");
769
+ }
770
+ function resolveSwitchContent(element) {
771
+ const props = element.props;
772
+ const children = normalizeContent(props.children ?? element.children);
773
+ for (const child of children) {
774
+ const match = getMatchElement(child);
775
+ if (!match) {
776
+ continue;
777
+ }
778
+ const when = readReactive2(match.props.when);
779
+ if (when) {
780
+ return resolveMatchChildren(match, when);
781
+ }
782
+ }
783
+ return props.fallback;
784
+ }
785
+ function resolveMatchChildren(element, value) {
786
+ const children = element.props.children ?? element.children;
787
+ if (typeof children === "function") {
788
+ return children(value);
789
+ }
790
+ return children;
791
+ }
792
+ function resolveKeyChildren(element, value) {
793
+ const children = element.props.children ?? element.children;
794
+ if (typeof children === "function") {
795
+ return children(value);
796
+ }
797
+ return children;
798
+ }
799
+ function createDynamicElement(element, tag) {
800
+ if (typeof tag !== "string" && typeof tag !== "function") {
801
+ return null;
802
+ }
803
+ const { component, ...props } = element.props;
804
+ const children = normalizeContent(props.children ?? element.children);
805
+ return {
806
+ tag,
807
+ props,
808
+ children
809
+ };
810
+ }
583
811
  function resolveShowChildren(element, value) {
584
812
  const children = element.props.children ?? element.children;
585
813
  if (typeof children === "function") {
@@ -587,9 +815,27 @@ function resolveShowChildren(element, value) {
587
815
  }
588
816
  return children;
589
817
  }
590
- function readReactive(value) {
818
+ function readReactive2(value) {
591
819
  return isSignal(value) || isComputed(value) ? value.value : value;
592
820
  }
821
+ function normalizeContent(content) {
822
+ if (content == null || typeof content === "boolean") {
823
+ return [];
824
+ }
825
+ return Array.isArray(content) ? content : [content];
826
+ }
827
+ function isElementLike(value) {
828
+ return value != null && typeof value === "object" && "tag" in value;
829
+ }
830
+ function getMatchElement(value) {
831
+ if (!isElementLike(value)) {
832
+ return null;
833
+ }
834
+ if (isMatchElement(value)) {
835
+ return value;
836
+ }
837
+ return value.tag === Match ? Match(value.props) : null;
838
+ }
593
839
  // src/component/instance.ts
594
840
  var uidCounter = 0;
595
841
  function createComponentInstance(component, props, parent) {
@@ -813,8 +1059,16 @@ async function streamNode(node, controller, encoder) {
813
1059
  }
814
1060
  async function streamElement(element, controller, encoder) {
815
1061
  const { tag, props, children } = element;
1062
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1063
+ await streamElement(tag(props), controller, encoder);
1064
+ return;
1065
+ }
1066
+ if (tag === Visible) {
1067
+ await streamElement(tag(props), controller, encoder);
1068
+ return;
1069
+ }
816
1070
  if (isShowElement(element)) {
817
- const when = readReactive2(props.when);
1071
+ const when = readReactive3(props.when);
818
1072
  await streamNode(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder);
819
1073
  return;
820
1074
  }
@@ -822,6 +1076,35 @@ async function streamElement(element, controller, encoder) {
822
1076
  await streamForElement(element, controller, encoder);
823
1077
  return;
824
1078
  }
1079
+ if (isSwitchElement(element)) {
1080
+ await streamNode(resolveSwitchContent2(element), controller, encoder);
1081
+ return;
1082
+ }
1083
+ if (isMatchElement(element)) {
1084
+ const when = readReactive3(props.when);
1085
+ await streamNode(when ? resolveMatchChildren2(element, when) : null, controller, encoder);
1086
+ return;
1087
+ }
1088
+ if (isIndexElement(element)) {
1089
+ await streamIndexElement(element, controller, encoder);
1090
+ return;
1091
+ }
1092
+ if (isKeyElement(element)) {
1093
+ const key = readReactive3(props.when);
1094
+ await streamNode(resolveKeyChildren2(element, key), controller, encoder);
1095
+ return;
1096
+ }
1097
+ if (isDynamicElement(element)) {
1098
+ const dynamicTag = readReactive3(props.component);
1099
+ const dynamic = createDynamicElement2(element, dynamicTag);
1100
+ if (dynamic) {
1101
+ await streamElement(dynamic, controller, encoder);
1102
+ }
1103
+ return;
1104
+ }
1105
+ if (isPortalElement(element)) {
1106
+ return;
1107
+ }
825
1108
  if (typeof tag === "function") {
826
1109
  const result = await tag(props);
827
1110
  await streamNode(result, controller, encoder);
@@ -856,16 +1139,10 @@ function renderAttributes2(props) {
856
1139
  if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
857
1140
  continue;
858
1141
  }
859
- const resolvedValue = readReactive2(value);
1142
+ const resolvedValue = readReactive3(value);
860
1143
  if (resolvedValue == null || resolvedValue === false)
861
1144
  continue;
862
- const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
863
- if (resolvedValue === true) {
864
- attrs += ` ${attrName}`;
865
- continue;
866
- }
867
- const attrValue = escapeHtml(String(resolvedValue));
868
- attrs += ` ${attrName}="${attrValue}"`;
1145
+ attrs += renderServerAttribute(key, resolvedValue);
869
1146
  }
870
1147
  return attrs;
871
1148
  }
@@ -910,12 +1187,16 @@ async function streamHydratableElement(element, controller, encoder, ctx, isComp
910
1187
  }
911
1188
  return;
912
1189
  }
913
- if (tag === Show || tag === For) {
1190
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1191
+ await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
1192
+ return;
1193
+ }
1194
+ if (tag === Visible) {
914
1195
  await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
915
1196
  return;
916
1197
  }
917
1198
  if (isShowElement(element)) {
918
- const when = readReactive2(props.when);
1199
+ const when = readReactive3(props.when);
919
1200
  await streamHydratableNodeToController(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder, ctx, isComponentRoot);
920
1201
  return;
921
1202
  }
@@ -923,6 +1204,35 @@ async function streamHydratableElement(element, controller, encoder, ctx, isComp
923
1204
  await streamHydratableForElement(element, controller, encoder, ctx);
924
1205
  return;
925
1206
  }
1207
+ if (isSwitchElement(element)) {
1208
+ await streamHydratableNodeToController(resolveSwitchContent2(element), controller, encoder, ctx, isComponentRoot);
1209
+ return;
1210
+ }
1211
+ if (isMatchElement(element)) {
1212
+ const when = readReactive3(props.when);
1213
+ await streamHydratableNodeToController(when ? resolveMatchChildren2(element, when) : null, controller, encoder, ctx, isComponentRoot);
1214
+ return;
1215
+ }
1216
+ if (isIndexElement(element)) {
1217
+ await streamHydratableIndexElement(element, controller, encoder, ctx);
1218
+ return;
1219
+ }
1220
+ if (isKeyElement(element)) {
1221
+ const key = readReactive3(props.when);
1222
+ await streamHydratableNodeToController(resolveKeyChildren2(element, key), controller, encoder, ctx, isComponentRoot);
1223
+ return;
1224
+ }
1225
+ if (isDynamicElement(element)) {
1226
+ const dynamicTag = readReactive3(props.component);
1227
+ const dynamic = createDynamicElement2(element, dynamicTag);
1228
+ if (dynamic) {
1229
+ await streamHydratableElement(dynamic, controller, encoder, ctx, isComponentRoot);
1230
+ }
1231
+ return;
1232
+ }
1233
+ if (isPortalElement(element)) {
1234
+ return;
1235
+ }
926
1236
  if (typeof tag === "function") {
927
1237
  await streamHydratableComponent(tag, props, controller, encoder, ctx, true);
928
1238
  return;
@@ -965,14 +1275,42 @@ async function streamHydratableIntrinsic(tag, props, children, controller, encod
965
1275
  }
966
1276
  async function streamHydratableForElement(element, controller, encoder, ctx) {
967
1277
  const props = element.props;
968
- const each = readReactive2(props.each);
1278
+ const each = readReactive3(props.each);
969
1279
  if (!Array.isArray(each) || typeof props.children !== "function") {
1280
+ if (props.fallback) {
1281
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1282
+ }
1283
+ return;
1284
+ }
1285
+ if (each.length === 0) {
1286
+ if (props.fallback) {
1287
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1288
+ }
970
1289
  return;
971
1290
  }
972
1291
  for (let index = 0;index < each.length; index++) {
973
1292
  await streamHydratableNodeToController(props.children(each[index], () => index), controller, encoder, ctx);
974
1293
  }
975
1294
  }
1295
+ async function streamHydratableIndexElement(element, controller, encoder, ctx) {
1296
+ const props = element.props;
1297
+ const each = readReactive3(props.each);
1298
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1299
+ if (props.fallback) {
1300
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1301
+ }
1302
+ return;
1303
+ }
1304
+ if (each.length === 0) {
1305
+ if (props.fallback) {
1306
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1307
+ }
1308
+ return;
1309
+ }
1310
+ for (let index = 0;index < each.length; index++) {
1311
+ await streamHydratableNodeToController(props.children(() => each[index], index), controller, encoder, ctx);
1312
+ }
1313
+ }
976
1314
  function renderHydratableAttributes(props, ctx, isComponentRoot) {
977
1315
  let attrs = "";
978
1316
  if (isComponentRoot) {
@@ -987,15 +1325,10 @@ function renderHydratableAttributes(props, ctx, isComponentRoot) {
987
1325
  eventParts.push(`${toEventName(key)}:${ctx.eventIndex++}`);
988
1326
  continue;
989
1327
  }
990
- const resolvedValue = readReactive2(value);
1328
+ const resolvedValue = readReactive3(value);
991
1329
  if (resolvedValue == null || resolvedValue === false)
992
1330
  continue;
993
- const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
994
- if (resolvedValue === true) {
995
- attrs += ` ${attrName}`;
996
- continue;
997
- }
998
- attrs += ` ${attrName}="${escapeHtml(String(resolvedValue))}"`;
1331
+ attrs += renderServerAttribute(key, resolvedValue);
999
1332
  }
1000
1333
  if (eventParts.length > 0) {
1001
1334
  attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
@@ -1007,14 +1340,42 @@ function enqueue(controller, encoder, html) {
1007
1340
  }
1008
1341
  async function streamForElement(element, controller, encoder) {
1009
1342
  const props = element.props;
1010
- const each = readReactive2(props.each);
1343
+ const each = readReactive3(props.each);
1011
1344
  if (!Array.isArray(each) || typeof props.children !== "function") {
1345
+ if (props.fallback) {
1346
+ await streamNode(props.fallback, controller, encoder);
1347
+ }
1348
+ return;
1349
+ }
1350
+ if (each.length === 0) {
1351
+ if (props.fallback) {
1352
+ await streamNode(props.fallback, controller, encoder);
1353
+ }
1012
1354
  return;
1013
1355
  }
1014
1356
  for (let index = 0;index < each.length; index++) {
1015
1357
  await streamNode(props.children(each[index], () => index), controller, encoder);
1016
1358
  }
1017
1359
  }
1360
+ async function streamIndexElement(element, controller, encoder) {
1361
+ const props = element.props;
1362
+ const each = readReactive3(props.each);
1363
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1364
+ if (props.fallback) {
1365
+ await streamNode(props.fallback, controller, encoder);
1366
+ }
1367
+ return;
1368
+ }
1369
+ if (each.length === 0) {
1370
+ if (props.fallback) {
1371
+ await streamNode(props.fallback, controller, encoder);
1372
+ }
1373
+ return;
1374
+ }
1375
+ for (let index = 0;index < each.length; index++) {
1376
+ await streamNode(props.children(() => each[index], index), controller, encoder);
1377
+ }
1378
+ }
1018
1379
  function resolveShowChildren2(element, value) {
1019
1380
  const children = element.props.children ?? element.children;
1020
1381
  if (typeof children === "function") {
@@ -1022,9 +1383,68 @@ function resolveShowChildren2(element, value) {
1022
1383
  }
1023
1384
  return children;
1024
1385
  }
1025
- function readReactive2(value) {
1386
+ function resolveSwitchContent2(element) {
1387
+ const props = element.props;
1388
+ const children = normalizeContent2(props.children ?? element.children);
1389
+ for (const child of children) {
1390
+ const match = getMatchElement2(child);
1391
+ if (!match) {
1392
+ continue;
1393
+ }
1394
+ const when = readReactive3(match.props.when);
1395
+ if (when) {
1396
+ return resolveMatchChildren2(match, when);
1397
+ }
1398
+ }
1399
+ return props.fallback;
1400
+ }
1401
+ function resolveMatchChildren2(element, value) {
1402
+ const children = element.props.children ?? element.children;
1403
+ if (typeof children === "function") {
1404
+ return children(value);
1405
+ }
1406
+ return children;
1407
+ }
1408
+ function resolveKeyChildren2(element, value) {
1409
+ const children = element.props.children ?? element.children;
1410
+ if (typeof children === "function") {
1411
+ return children(value);
1412
+ }
1413
+ return children;
1414
+ }
1415
+ function createDynamicElement2(element, tag) {
1416
+ if (typeof tag !== "string" && typeof tag !== "function") {
1417
+ return null;
1418
+ }
1419
+ const { component, ...props } = element.props;
1420
+ const children = normalizeContent2(props.children ?? element.children);
1421
+ return {
1422
+ tag,
1423
+ props,
1424
+ children
1425
+ };
1426
+ }
1427
+ function readReactive3(value) {
1026
1428
  return isSignal(value) || isComputed(value) ? value.value : value;
1027
1429
  }
1430
+ function normalizeContent2(content) {
1431
+ if (content == null || typeof content === "boolean") {
1432
+ return [];
1433
+ }
1434
+ return Array.isArray(content) ? content : [content];
1435
+ }
1436
+ function isElementLike2(value) {
1437
+ return value != null && typeof value === "object" && "tag" in value;
1438
+ }
1439
+ function getMatchElement2(value) {
1440
+ if (!isElementLike2(value)) {
1441
+ return null;
1442
+ }
1443
+ if (isMatchElement(value)) {
1444
+ return value;
1445
+ }
1446
+ return value.tag === Match ? Match(value.props) : null;
1447
+ }
1028
1448
  // src/server/hydration-markers.ts
1029
1449
  function createHydrationContext() {
1030
1450
  return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
@@ -1094,17 +1514,42 @@ function renderElementH(element, ctx, isComponentRoot) {
1094
1514
  if (tag === "") {
1095
1515
  return children.map((child) => renderNodeH(child, ctx)).join("");
1096
1516
  }
1097
- if (tag === Show || tag === For) {
1517
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1518
+ return renderElementH(tag(props), ctx, isComponentRoot);
1519
+ }
1520
+ if (tag === Visible) {
1098
1521
  return renderElementH(tag(props), ctx, isComponentRoot);
1099
1522
  }
1100
1523
  if (isShowElement(element)) {
1101
- const when = readReactive3(props.when);
1524
+ const when = readReactive4(props.when);
1102
1525
  const content = when ? resolveShowChildren3(element, when) : props.fallback;
1103
1526
  return renderNodeMaybeRoot(content, ctx, isComponentRoot);
1104
1527
  }
1105
1528
  if (isForElement(element)) {
1106
1529
  return renderForElementH(element, ctx);
1107
1530
  }
1531
+ if (isSwitchElement(element)) {
1532
+ return renderNodeMaybeRoot(resolveSwitchContent3(element), ctx, isComponentRoot);
1533
+ }
1534
+ if (isMatchElement(element)) {
1535
+ const when = readReactive4(props.when);
1536
+ return renderNodeMaybeRoot(when ? resolveMatchChildren3(element, when) : null, ctx, isComponentRoot);
1537
+ }
1538
+ if (isIndexElement(element)) {
1539
+ return renderIndexElementH(element, ctx);
1540
+ }
1541
+ if (isKeyElement(element)) {
1542
+ const key = readReactive4(props.when);
1543
+ return renderNodeMaybeRoot(resolveKeyChildren3(element, key), ctx, isComponentRoot);
1544
+ }
1545
+ if (isDynamicElement(element)) {
1546
+ const dynamicTag = readReactive4(props.component);
1547
+ const dynamic = createDynamicElement3(element, dynamicTag);
1548
+ return dynamic ? renderElementH(dynamic, ctx, isComponentRoot) : "";
1549
+ }
1550
+ if (isPortalElement(element)) {
1551
+ return "";
1552
+ }
1108
1553
  if (typeof tag === "function") {
1109
1554
  return renderComponentH(tag, props, ctx);
1110
1555
  }
@@ -1151,13 +1596,7 @@ function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
1151
1596
  if (isSignal(value) || isComputed(value)) {
1152
1597
  resolvedValue = value.value;
1153
1598
  }
1154
- if (resolvedValue === true) {
1155
- const attrName2 = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
1156
- attrs += ` ${attrName2}`;
1157
- continue;
1158
- }
1159
- const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
1160
- attrs += ` ${attrName}="${escapeHtml(String(resolvedValue))}"`;
1599
+ attrs += renderServerAttribute(key, resolvedValue);
1161
1600
  }
1162
1601
  if (eventParts.length > 0) {
1163
1602
  attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
@@ -1180,12 +1619,26 @@ function renderNodeMaybeRoot(node, ctx, isComponentRoot) {
1180
1619
  }
1181
1620
  function renderForElementH(element, ctx) {
1182
1621
  const props = element.props;
1183
- const each = readReactive3(props.each);
1622
+ const each = readReactive4(props.each);
1184
1623
  if (!Array.isArray(each) || typeof props.children !== "function") {
1185
- return "";
1624
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1625
+ }
1626
+ if (each.length === 0) {
1627
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1186
1628
  }
1187
1629
  return each.map((item, index) => renderNodeH(props.children(item, () => index), ctx)).join("");
1188
1630
  }
1631
+ function renderIndexElementH(element, ctx) {
1632
+ const props = element.props;
1633
+ const each = readReactive4(props.each);
1634
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1635
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1636
+ }
1637
+ if (each.length === 0) {
1638
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1639
+ }
1640
+ return each.map((item, index) => renderNodeH(props.children(() => item, index), ctx)).join("");
1641
+ }
1189
1642
  function resolveShowChildren3(element, value) {
1190
1643
  const children = element.props.children ?? element.children;
1191
1644
  if (typeof children === "function") {
@@ -1193,9 +1646,68 @@ function resolveShowChildren3(element, value) {
1193
1646
  }
1194
1647
  return children;
1195
1648
  }
1196
- function readReactive3(value) {
1649
+ function resolveSwitchContent3(element) {
1650
+ const props = element.props;
1651
+ const children = normalizeContent3(props.children ?? element.children);
1652
+ for (const child of children) {
1653
+ const match = getMatchElement3(child);
1654
+ if (!match) {
1655
+ continue;
1656
+ }
1657
+ const when = readReactive4(match.props.when);
1658
+ if (when) {
1659
+ return resolveMatchChildren3(match, when);
1660
+ }
1661
+ }
1662
+ return props.fallback;
1663
+ }
1664
+ function resolveMatchChildren3(element, value) {
1665
+ const children = element.props.children ?? element.children;
1666
+ if (typeof children === "function") {
1667
+ return children(value);
1668
+ }
1669
+ return children;
1670
+ }
1671
+ function resolveKeyChildren3(element, value) {
1672
+ const children = element.props.children ?? element.children;
1673
+ if (typeof children === "function") {
1674
+ return children(value);
1675
+ }
1676
+ return children;
1677
+ }
1678
+ function createDynamicElement3(element, tag) {
1679
+ if (typeof tag !== "string" && typeof tag !== "function") {
1680
+ return null;
1681
+ }
1682
+ const { component, ...props } = element.props;
1683
+ const children = normalizeContent3(props.children ?? element.children);
1684
+ return {
1685
+ tag,
1686
+ props,
1687
+ children
1688
+ };
1689
+ }
1690
+ function readReactive4(value) {
1197
1691
  return isSignal(value) || isComputed(value) ? value.value : value;
1198
1692
  }
1693
+ function normalizeContent3(content) {
1694
+ if (content == null || typeof content === "boolean") {
1695
+ return [];
1696
+ }
1697
+ return Array.isArray(content) ? content : [content];
1698
+ }
1699
+ function isElementLike3(value) {
1700
+ return value != null && typeof value === "object" && "tag" in value;
1701
+ }
1702
+ function getMatchElement3(value) {
1703
+ if (!isElementLike3(value)) {
1704
+ return null;
1705
+ }
1706
+ if (isMatchElement(value)) {
1707
+ return value;
1708
+ }
1709
+ return value.tag === Match ? Match(value.props) : null;
1710
+ }
1199
1711
  export {
1200
1712
  streamPage,
1201
1713
  streamHydratablePage,
@@ -1210,5 +1722,5 @@ export {
1210
1722
  getPage
1211
1723
  };
1212
1724
 
1213
- //# debugId=E47F9E2EB5705D1864756E2164756E21
1725
+ //# debugId=46896ED83A2048E464756E2164756E21
1214
1726
  //# sourceMappingURL=index.development.js.map