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
@@ -163,6 +163,37 @@ function isSafeHtml(value) {
163
163
  return value instanceof HtmlEscapedString;
164
164
  }
165
165
 
166
+ // src/server/attribute-utils.ts
167
+ var PROP_ALIASES = {
168
+ className: "class",
169
+ htmlFor: "for",
170
+ tabIndex: "tabindex",
171
+ crossOrigin: "crossorigin"
172
+ };
173
+ function renderServerAttribute(key, value) {
174
+ const attrName = PROP_ALIASES[key] ?? key;
175
+ if (value == null || value === false) {
176
+ return "";
177
+ }
178
+ if (value === true) {
179
+ return ` ${attrName}`;
180
+ }
181
+ const attrValue = attrName === "class" && typeof value === "object" ? stringifyClass(value) : attrName === "style" && typeof value === "object" ? stringifyStyle(value) : String(value);
182
+ return ` ${attrName}="${escapeHtml(attrValue)}"`;
183
+ }
184
+ function stringifyClass(value) {
185
+ if (Array.isArray(value)) {
186
+ return value.filter(Boolean).join(" ");
187
+ }
188
+ return Object.entries(value).filter(([, enabled]) => Boolean(enabled)).map(([name]) => name).join(" ");
189
+ }
190
+ function stringifyStyle(value) {
191
+ return Object.entries(value).filter(([, val]) => val != null && val !== false).map(([prop, val]) => `${toKebabCase(prop)}:${String(val)}`).join(";");
192
+ }
193
+ function toKebabCase(value) {
194
+ return value.includes("-") ? value : value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
195
+ }
196
+
166
197
  // src/reactivity/scheduler.ts
167
198
  var pendingEffects = new Set;
168
199
  var flushScheduled = false;
@@ -493,10 +524,28 @@ function bindEvents(el, props) {
493
524
  }
494
525
  return cleanups;
495
526
  }
496
-
527
+ // src/reactivity/batch.ts
528
+ var batchDepth = 0;
529
+ function batch(fn) {
530
+ batchDepth++;
531
+ try {
532
+ fn();
533
+ } finally {
534
+ batchDepth--;
535
+ if (batchDepth === 0) {
536
+ flushSync();
537
+ }
538
+ }
539
+ }
497
540
  // src/component/control-flow.ts
498
541
  var SHOW_TYPE = Symbol.for("Sinwan.Show");
499
542
  var FOR_TYPE = Symbol.for("Sinwan.For");
543
+ var SWITCH_TYPE = Symbol.for("Sinwan.Switch");
544
+ var MATCH_TYPE = Symbol.for("Sinwan.Match");
545
+ var INDEX_TYPE = Symbol.for("Sinwan.Index");
546
+ var KEY_TYPE = Symbol.for("Sinwan.Key");
547
+ var DYNAMIC_TYPE = Symbol.for("Sinwan.Dynamic");
548
+ var PORTAL_TYPE = Symbol.for("Sinwan.Portal");
500
549
  function Show(props) {
501
550
  return {
502
551
  tag: SHOW_TYPE,
@@ -511,12 +560,114 @@ function For(props) {
511
560
  children: []
512
561
  };
513
562
  }
563
+ function Switch(props) {
564
+ return {
565
+ tag: SWITCH_TYPE,
566
+ props,
567
+ children: []
568
+ };
569
+ }
570
+ function Match(props) {
571
+ return {
572
+ tag: MATCH_TYPE,
573
+ props,
574
+ children: []
575
+ };
576
+ }
577
+ function Index(props) {
578
+ return {
579
+ tag: INDEX_TYPE,
580
+ props,
581
+ children: []
582
+ };
583
+ }
584
+ function Key(props) {
585
+ return {
586
+ tag: KEY_TYPE,
587
+ props,
588
+ children: []
589
+ };
590
+ }
591
+ function Dynamic(props) {
592
+ return {
593
+ tag: DYNAMIC_TYPE,
594
+ props,
595
+ children: []
596
+ };
597
+ }
598
+ function Visible(props) {
599
+ const {
600
+ when,
601
+ as = "span",
602
+ style,
603
+ children,
604
+ ...rest
605
+ } = props;
606
+ const visibleStyle = computed(() => {
607
+ const base = readReactive(style);
608
+ const visible = Boolean(readReactive(when));
609
+ if (typeof base === "string") {
610
+ return visible ? base : appendHiddenDisplay(base);
611
+ }
612
+ const styleObject = base && typeof base === "object" ? { ...base } : {};
613
+ styleObject.display = visible ? styleObject.display : "none";
614
+ return styleObject;
615
+ });
616
+ return {
617
+ tag: as,
618
+ props: {
619
+ ...rest,
620
+ style: visibleStyle,
621
+ children
622
+ },
623
+ children: normalizeChildren2(children)
624
+ };
625
+ }
626
+ function Portal(props) {
627
+ return {
628
+ tag: PORTAL_TYPE,
629
+ props,
630
+ children: []
631
+ };
632
+ }
514
633
  function isShowElement(element) {
515
634
  return element.tag === SHOW_TYPE;
516
635
  }
517
636
  function isForElement(element) {
518
637
  return element.tag === FOR_TYPE;
519
638
  }
639
+ function isSwitchElement(element) {
640
+ return element.tag === SWITCH_TYPE;
641
+ }
642
+ function isMatchElement(element) {
643
+ return element.tag === MATCH_TYPE;
644
+ }
645
+ function isIndexElement(element) {
646
+ return element.tag === INDEX_TYPE;
647
+ }
648
+ function isKeyElement(element) {
649
+ return element.tag === KEY_TYPE;
650
+ }
651
+ function isDynamicElement(element) {
652
+ return element.tag === DYNAMIC_TYPE;
653
+ }
654
+ function isPortalElement(element) {
655
+ return element.tag === PORTAL_TYPE;
656
+ }
657
+ function normalizeChildren2(children) {
658
+ if (children == null || typeof children === "boolean") {
659
+ return [];
660
+ }
661
+ return Array.isArray(children) ? children : [children];
662
+ }
663
+ function readReactive(value) {
664
+ return isSignal(value) || isComputed(value) ? value.value : value;
665
+ }
666
+ function appendHiddenDisplay(style) {
667
+ const trimmed = style.trim();
668
+ const separator = trimmed.length > 0 && !trimmed.endsWith(";") ? ";" : "";
669
+ return `${trimmed}${separator}display:none`;
670
+ }
520
671
 
521
672
  // src/server/renderer.ts
522
673
  var componentCache = new WeakMap;
@@ -565,13 +716,41 @@ async function renderToString(node) {
565
716
  }
566
717
  async function renderElement(element) {
567
718
  const { tag, props, children } = element;
719
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
720
+ return renderElement(tag(props));
721
+ }
722
+ if (tag === Visible) {
723
+ return renderElement(tag(props));
724
+ }
568
725
  if (isShowElement(element)) {
569
- const when = readReactive(props.when);
726
+ const when = readReactive2(props.when);
570
727
  return renderToString(when ? resolveShowChildren(element, when) : props.fallback);
571
728
  }
572
729
  if (isForElement(element)) {
573
730
  return renderForElement(element);
574
731
  }
732
+ if (isSwitchElement(element)) {
733
+ return renderToString(resolveSwitchContent(element));
734
+ }
735
+ if (isMatchElement(element)) {
736
+ const when = readReactive2(props.when);
737
+ return renderToString(when ? resolveMatchChildren(element, when) : null);
738
+ }
739
+ if (isIndexElement(element)) {
740
+ return renderIndexElement(element);
741
+ }
742
+ if (isKeyElement(element)) {
743
+ const key = readReactive2(props.when);
744
+ return renderToString(resolveKeyChildren(element, key));
745
+ }
746
+ if (isDynamicElement(element)) {
747
+ const tag2 = readReactive2(props.component);
748
+ const dynamic = createDynamicElement(element, tag2);
749
+ return dynamic ? renderElement(dynamic) : "";
750
+ }
751
+ if (isPortalElement(element)) {
752
+ return "";
753
+ }
575
754
  if (typeof tag === "function") {
576
755
  const result = await tag(props);
577
756
  return renderToString(result);
@@ -611,17 +790,10 @@ function renderAttributes(props) {
611
790
  if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
612
791
  continue;
613
792
  }
614
- const resolvedValue = readReactive(value);
793
+ const resolvedValue = readReactive2(value);
615
794
  if (resolvedValue == null || resolvedValue === false)
616
795
  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}"`;
796
+ attrs += renderServerAttribute(key, resolvedValue);
625
797
  }
626
798
  return attrs;
627
799
  }
@@ -637,13 +809,69 @@ function isSlots(children) {
637
809
  }
638
810
  async function renderForElement(element) {
639
811
  const props = element.props;
640
- const each = readReactive(props.each);
812
+ const each = readReactive2(props.each);
641
813
  if (!Array.isArray(each) || typeof props.children !== "function") {
642
- return "";
814
+ return props.fallback ? renderToString(props.fallback) : "";
815
+ }
816
+ if (each.length === 0) {
817
+ return props.fallback ? renderToString(props.fallback) : "";
643
818
  }
644
819
  const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(item, () => index))));
645
820
  return rendered.join("");
646
821
  }
822
+ async function renderIndexElement(element) {
823
+ const props = element.props;
824
+ const each = readReactive2(props.each);
825
+ if (!Array.isArray(each) || typeof props.children !== "function") {
826
+ return props.fallback ? renderToString(props.fallback) : "";
827
+ }
828
+ if (each.length === 0) {
829
+ return props.fallback ? renderToString(props.fallback) : "";
830
+ }
831
+ const rendered = await Promise.all(each.map((item, index) => renderToString(props.children(() => item, index))));
832
+ return rendered.join("");
833
+ }
834
+ function resolveSwitchContent(element) {
835
+ const props = element.props;
836
+ const children = normalizeContent(props.children ?? element.children);
837
+ for (const child of children) {
838
+ const match = getMatchElement(child);
839
+ if (!match) {
840
+ continue;
841
+ }
842
+ const when = readReactive2(match.props.when);
843
+ if (when) {
844
+ return resolveMatchChildren(match, when);
845
+ }
846
+ }
847
+ return props.fallback;
848
+ }
849
+ function resolveMatchChildren(element, value) {
850
+ const children = element.props.children ?? element.children;
851
+ if (typeof children === "function") {
852
+ return children(value);
853
+ }
854
+ return children;
855
+ }
856
+ function resolveKeyChildren(element, value) {
857
+ const children = element.props.children ?? element.children;
858
+ if (typeof children === "function") {
859
+ return children(value);
860
+ }
861
+ return children;
862
+ }
863
+ function createDynamicElement(element, tag) {
864
+ if (typeof tag !== "string" && typeof tag !== "function") {
865
+ return null;
866
+ }
867
+ const { component, ...props } = element.props;
868
+ const children = normalizeContent(props.children ?? element.children);
869
+ return {
870
+ tag,
871
+ props,
872
+ children
873
+ };
874
+ }
647
875
  function resolveShowChildren(element, value) {
648
876
  const children = element.props.children ?? element.children;
649
877
  if (typeof children === "function") {
@@ -651,9 +879,27 @@ function resolveShowChildren(element, value) {
651
879
  }
652
880
  return children;
653
881
  }
654
- function readReactive(value) {
882
+ function readReactive2(value) {
655
883
  return isSignal(value) || isComputed(value) ? value.value : value;
656
884
  }
885
+ function normalizeContent(content) {
886
+ if (content == null || typeof content === "boolean") {
887
+ return [];
888
+ }
889
+ return Array.isArray(content) ? content : [content];
890
+ }
891
+ function isElementLike(value) {
892
+ return value != null && typeof value === "object" && "tag" in value;
893
+ }
894
+ function getMatchElement(value) {
895
+ if (!isElementLike(value)) {
896
+ return null;
897
+ }
898
+ if (isMatchElement(value)) {
899
+ return value;
900
+ }
901
+ return value.tag === Match ? Match(value.props) : null;
902
+ }
657
903
  // src/component/instance.ts
658
904
  var uidCounter = 0;
659
905
  function createComponentInstance(component, props, parent) {
@@ -877,8 +1123,16 @@ async function streamNode(node, controller, encoder) {
877
1123
  }
878
1124
  async function streamElement(element, controller, encoder) {
879
1125
  const { tag, props, children } = element;
1126
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1127
+ await streamElement(tag(props), controller, encoder);
1128
+ return;
1129
+ }
1130
+ if (tag === Visible) {
1131
+ await streamElement(tag(props), controller, encoder);
1132
+ return;
1133
+ }
880
1134
  if (isShowElement(element)) {
881
- const when = readReactive2(props.when);
1135
+ const when = readReactive3(props.when);
882
1136
  await streamNode(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder);
883
1137
  return;
884
1138
  }
@@ -886,6 +1140,35 @@ async function streamElement(element, controller, encoder) {
886
1140
  await streamForElement(element, controller, encoder);
887
1141
  return;
888
1142
  }
1143
+ if (isSwitchElement(element)) {
1144
+ await streamNode(resolveSwitchContent2(element), controller, encoder);
1145
+ return;
1146
+ }
1147
+ if (isMatchElement(element)) {
1148
+ const when = readReactive3(props.when);
1149
+ await streamNode(when ? resolveMatchChildren2(element, when) : null, controller, encoder);
1150
+ return;
1151
+ }
1152
+ if (isIndexElement(element)) {
1153
+ await streamIndexElement(element, controller, encoder);
1154
+ return;
1155
+ }
1156
+ if (isKeyElement(element)) {
1157
+ const key = readReactive3(props.when);
1158
+ await streamNode(resolveKeyChildren2(element, key), controller, encoder);
1159
+ return;
1160
+ }
1161
+ if (isDynamicElement(element)) {
1162
+ const dynamicTag = readReactive3(props.component);
1163
+ const dynamic = createDynamicElement2(element, dynamicTag);
1164
+ if (dynamic) {
1165
+ await streamElement(dynamic, controller, encoder);
1166
+ }
1167
+ return;
1168
+ }
1169
+ if (isPortalElement(element)) {
1170
+ return;
1171
+ }
889
1172
  if (typeof tag === "function") {
890
1173
  const result = await tag(props);
891
1174
  await streamNode(result, controller, encoder);
@@ -920,16 +1203,10 @@ function renderAttributes2(props) {
920
1203
  if (key === "children" || key === "key" || key === "ref" || key === "dangerouslySetInnerHTML" || isEventProp(key)) {
921
1204
  continue;
922
1205
  }
923
- const resolvedValue = readReactive2(value);
1206
+ const resolvedValue = readReactive3(value);
924
1207
  if (resolvedValue == null || resolvedValue === false)
925
1208
  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}"`;
1209
+ attrs += renderServerAttribute(key, resolvedValue);
933
1210
  }
934
1211
  return attrs;
935
1212
  }
@@ -974,12 +1251,16 @@ async function streamHydratableElement(element, controller, encoder, ctx, isComp
974
1251
  }
975
1252
  return;
976
1253
  }
977
- if (tag === Show || tag === For) {
1254
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1255
+ await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
1256
+ return;
1257
+ }
1258
+ if (tag === Visible) {
978
1259
  await streamHydratableElement(tag(props), controller, encoder, ctx, isComponentRoot);
979
1260
  return;
980
1261
  }
981
1262
  if (isShowElement(element)) {
982
- const when = readReactive2(props.when);
1263
+ const when = readReactive3(props.when);
983
1264
  await streamHydratableNodeToController(when ? resolveShowChildren2(element, when) : props.fallback, controller, encoder, ctx, isComponentRoot);
984
1265
  return;
985
1266
  }
@@ -987,6 +1268,35 @@ async function streamHydratableElement(element, controller, encoder, ctx, isComp
987
1268
  await streamHydratableForElement(element, controller, encoder, ctx);
988
1269
  return;
989
1270
  }
1271
+ if (isSwitchElement(element)) {
1272
+ await streamHydratableNodeToController(resolveSwitchContent2(element), controller, encoder, ctx, isComponentRoot);
1273
+ return;
1274
+ }
1275
+ if (isMatchElement(element)) {
1276
+ const when = readReactive3(props.when);
1277
+ await streamHydratableNodeToController(when ? resolveMatchChildren2(element, when) : null, controller, encoder, ctx, isComponentRoot);
1278
+ return;
1279
+ }
1280
+ if (isIndexElement(element)) {
1281
+ await streamHydratableIndexElement(element, controller, encoder, ctx);
1282
+ return;
1283
+ }
1284
+ if (isKeyElement(element)) {
1285
+ const key = readReactive3(props.when);
1286
+ await streamHydratableNodeToController(resolveKeyChildren2(element, key), controller, encoder, ctx, isComponentRoot);
1287
+ return;
1288
+ }
1289
+ if (isDynamicElement(element)) {
1290
+ const dynamicTag = readReactive3(props.component);
1291
+ const dynamic = createDynamicElement2(element, dynamicTag);
1292
+ if (dynamic) {
1293
+ await streamHydratableElement(dynamic, controller, encoder, ctx, isComponentRoot);
1294
+ }
1295
+ return;
1296
+ }
1297
+ if (isPortalElement(element)) {
1298
+ return;
1299
+ }
990
1300
  if (typeof tag === "function") {
991
1301
  await streamHydratableComponent(tag, props, controller, encoder, ctx, true);
992
1302
  return;
@@ -1029,14 +1339,42 @@ async function streamHydratableIntrinsic(tag, props, children, controller, encod
1029
1339
  }
1030
1340
  async function streamHydratableForElement(element, controller, encoder, ctx) {
1031
1341
  const props = element.props;
1032
- const each = readReactive2(props.each);
1342
+ const each = readReactive3(props.each);
1033
1343
  if (!Array.isArray(each) || typeof props.children !== "function") {
1344
+ if (props.fallback) {
1345
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1346
+ }
1347
+ return;
1348
+ }
1349
+ if (each.length === 0) {
1350
+ if (props.fallback) {
1351
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1352
+ }
1034
1353
  return;
1035
1354
  }
1036
1355
  for (let index = 0;index < each.length; index++) {
1037
1356
  await streamHydratableNodeToController(props.children(each[index], () => index), controller, encoder, ctx);
1038
1357
  }
1039
1358
  }
1359
+ async function streamHydratableIndexElement(element, controller, encoder, ctx) {
1360
+ const props = element.props;
1361
+ const each = readReactive3(props.each);
1362
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1363
+ if (props.fallback) {
1364
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1365
+ }
1366
+ return;
1367
+ }
1368
+ if (each.length === 0) {
1369
+ if (props.fallback) {
1370
+ await streamHydratableNodeToController(props.fallback, controller, encoder, ctx);
1371
+ }
1372
+ return;
1373
+ }
1374
+ for (let index = 0;index < each.length; index++) {
1375
+ await streamHydratableNodeToController(props.children(() => each[index], index), controller, encoder, ctx);
1376
+ }
1377
+ }
1040
1378
  function renderHydratableAttributes(props, ctx, isComponentRoot) {
1041
1379
  let attrs = "";
1042
1380
  if (isComponentRoot) {
@@ -1051,15 +1389,10 @@ function renderHydratableAttributes(props, ctx, isComponentRoot) {
1051
1389
  eventParts.push(`${toEventName(key)}:${ctx.eventIndex++}`);
1052
1390
  continue;
1053
1391
  }
1054
- const resolvedValue = readReactive2(value);
1392
+ const resolvedValue = readReactive3(value);
1055
1393
  if (resolvedValue == null || resolvedValue === false)
1056
1394
  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))}"`;
1395
+ attrs += renderServerAttribute(key, resolvedValue);
1063
1396
  }
1064
1397
  if (eventParts.length > 0) {
1065
1398
  attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
@@ -1071,14 +1404,42 @@ function enqueue(controller, encoder, html) {
1071
1404
  }
1072
1405
  async function streamForElement(element, controller, encoder) {
1073
1406
  const props = element.props;
1074
- const each = readReactive2(props.each);
1407
+ const each = readReactive3(props.each);
1075
1408
  if (!Array.isArray(each) || typeof props.children !== "function") {
1409
+ if (props.fallback) {
1410
+ await streamNode(props.fallback, controller, encoder);
1411
+ }
1412
+ return;
1413
+ }
1414
+ if (each.length === 0) {
1415
+ if (props.fallback) {
1416
+ await streamNode(props.fallback, controller, encoder);
1417
+ }
1076
1418
  return;
1077
1419
  }
1078
1420
  for (let index = 0;index < each.length; index++) {
1079
1421
  await streamNode(props.children(each[index], () => index), controller, encoder);
1080
1422
  }
1081
1423
  }
1424
+ async function streamIndexElement(element, controller, encoder) {
1425
+ const props = element.props;
1426
+ const each = readReactive3(props.each);
1427
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1428
+ if (props.fallback) {
1429
+ await streamNode(props.fallback, controller, encoder);
1430
+ }
1431
+ return;
1432
+ }
1433
+ if (each.length === 0) {
1434
+ if (props.fallback) {
1435
+ await streamNode(props.fallback, controller, encoder);
1436
+ }
1437
+ return;
1438
+ }
1439
+ for (let index = 0;index < each.length; index++) {
1440
+ await streamNode(props.children(() => each[index], index), controller, encoder);
1441
+ }
1442
+ }
1082
1443
  function resolveShowChildren2(element, value) {
1083
1444
  const children = element.props.children ?? element.children;
1084
1445
  if (typeof children === "function") {
@@ -1086,9 +1447,68 @@ function resolveShowChildren2(element, value) {
1086
1447
  }
1087
1448
  return children;
1088
1449
  }
1089
- function readReactive2(value) {
1450
+ function resolveSwitchContent2(element) {
1451
+ const props = element.props;
1452
+ const children = normalizeContent2(props.children ?? element.children);
1453
+ for (const child of children) {
1454
+ const match = getMatchElement2(child);
1455
+ if (!match) {
1456
+ continue;
1457
+ }
1458
+ const when = readReactive3(match.props.when);
1459
+ if (when) {
1460
+ return resolveMatchChildren2(match, when);
1461
+ }
1462
+ }
1463
+ return props.fallback;
1464
+ }
1465
+ function resolveMatchChildren2(element, value) {
1466
+ const children = element.props.children ?? element.children;
1467
+ if (typeof children === "function") {
1468
+ return children(value);
1469
+ }
1470
+ return children;
1471
+ }
1472
+ function resolveKeyChildren2(element, value) {
1473
+ const children = element.props.children ?? element.children;
1474
+ if (typeof children === "function") {
1475
+ return children(value);
1476
+ }
1477
+ return children;
1478
+ }
1479
+ function createDynamicElement2(element, tag) {
1480
+ if (typeof tag !== "string" && typeof tag !== "function") {
1481
+ return null;
1482
+ }
1483
+ const { component, ...props } = element.props;
1484
+ const children = normalizeContent2(props.children ?? element.children);
1485
+ return {
1486
+ tag,
1487
+ props,
1488
+ children
1489
+ };
1490
+ }
1491
+ function readReactive3(value) {
1090
1492
  return isSignal(value) || isComputed(value) ? value.value : value;
1091
1493
  }
1494
+ function normalizeContent2(content) {
1495
+ if (content == null || typeof content === "boolean") {
1496
+ return [];
1497
+ }
1498
+ return Array.isArray(content) ? content : [content];
1499
+ }
1500
+ function isElementLike2(value) {
1501
+ return value != null && typeof value === "object" && "tag" in value;
1502
+ }
1503
+ function getMatchElement2(value) {
1504
+ if (!isElementLike2(value)) {
1505
+ return null;
1506
+ }
1507
+ if (isMatchElement(value)) {
1508
+ return value;
1509
+ }
1510
+ return value.tag === Match ? Match(value.props) : null;
1511
+ }
1092
1512
  // src/server/hydration-markers.ts
1093
1513
  function createHydrationContext() {
1094
1514
  return { componentIndex: 0, textIndex: 0, eventIndex: 0 };
@@ -1158,17 +1578,42 @@ function renderElementH(element, ctx, isComponentRoot) {
1158
1578
  if (tag === "") {
1159
1579
  return children.map((child) => renderNodeH(child, ctx)).join("");
1160
1580
  }
1161
- if (tag === Show || tag === For) {
1581
+ if (tag === Show || tag === For || tag === Switch || tag === Index || tag === Key || tag === Dynamic || tag === Portal) {
1582
+ return renderElementH(tag(props), ctx, isComponentRoot);
1583
+ }
1584
+ if (tag === Visible) {
1162
1585
  return renderElementH(tag(props), ctx, isComponentRoot);
1163
1586
  }
1164
1587
  if (isShowElement(element)) {
1165
- const when = readReactive3(props.when);
1588
+ const when = readReactive4(props.when);
1166
1589
  const content = when ? resolveShowChildren3(element, when) : props.fallback;
1167
1590
  return renderNodeMaybeRoot(content, ctx, isComponentRoot);
1168
1591
  }
1169
1592
  if (isForElement(element)) {
1170
1593
  return renderForElementH(element, ctx);
1171
1594
  }
1595
+ if (isSwitchElement(element)) {
1596
+ return renderNodeMaybeRoot(resolveSwitchContent3(element), ctx, isComponentRoot);
1597
+ }
1598
+ if (isMatchElement(element)) {
1599
+ const when = readReactive4(props.when);
1600
+ return renderNodeMaybeRoot(when ? resolveMatchChildren3(element, when) : null, ctx, isComponentRoot);
1601
+ }
1602
+ if (isIndexElement(element)) {
1603
+ return renderIndexElementH(element, ctx);
1604
+ }
1605
+ if (isKeyElement(element)) {
1606
+ const key = readReactive4(props.when);
1607
+ return renderNodeMaybeRoot(resolveKeyChildren3(element, key), ctx, isComponentRoot);
1608
+ }
1609
+ if (isDynamicElement(element)) {
1610
+ const dynamicTag = readReactive4(props.component);
1611
+ const dynamic = createDynamicElement3(element, dynamicTag);
1612
+ return dynamic ? renderElementH(dynamic, ctx, isComponentRoot) : "";
1613
+ }
1614
+ if (isPortalElement(element)) {
1615
+ return "";
1616
+ }
1172
1617
  if (typeof tag === "function") {
1173
1618
  return renderComponentH(tag, props, ctx);
1174
1619
  }
@@ -1215,13 +1660,7 @@ function renderIntrinsicH(tag, props, children, ctx, isComponentRoot) {
1215
1660
  if (isSignal(value) || isComputed(value)) {
1216
1661
  resolvedValue = value.value;
1217
1662
  }
1218
- if (resolvedValue === true) {
1219
- const attrName2 = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
1220
- attrs += ` ${attrName2}`;
1221
- continue;
1222
- }
1223
- const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key;
1224
- attrs += ` ${attrName}="${escapeHtml(String(resolvedValue))}"`;
1663
+ attrs += renderServerAttribute(key, resolvedValue);
1225
1664
  }
1226
1665
  if (eventParts.length > 0) {
1227
1666
  attrs += ` ${EVENT_ATTR}="${eventParts.join(",")}"`;
@@ -1244,12 +1683,26 @@ function renderNodeMaybeRoot(node, ctx, isComponentRoot) {
1244
1683
  }
1245
1684
  function renderForElementH(element, ctx) {
1246
1685
  const props = element.props;
1247
- const each = readReactive3(props.each);
1686
+ const each = readReactive4(props.each);
1248
1687
  if (!Array.isArray(each) || typeof props.children !== "function") {
1249
- return "";
1688
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1689
+ }
1690
+ if (each.length === 0) {
1691
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1250
1692
  }
1251
1693
  return each.map((item, index) => renderNodeH(props.children(item, () => index), ctx)).join("");
1252
1694
  }
1695
+ function renderIndexElementH(element, ctx) {
1696
+ const props = element.props;
1697
+ const each = readReactive4(props.each);
1698
+ if (!Array.isArray(each) || typeof props.children !== "function") {
1699
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1700
+ }
1701
+ if (each.length === 0) {
1702
+ return props.fallback ? renderNodeH(props.fallback, ctx) : "";
1703
+ }
1704
+ return each.map((item, index) => renderNodeH(props.children(() => item, index), ctx)).join("");
1705
+ }
1253
1706
  function resolveShowChildren3(element, value) {
1254
1707
  const children = element.props.children ?? element.children;
1255
1708
  if (typeof children === "function") {
@@ -1257,9 +1710,68 @@ function resolveShowChildren3(element, value) {
1257
1710
  }
1258
1711
  return children;
1259
1712
  }
1260
- function readReactive3(value) {
1713
+ function resolveSwitchContent3(element) {
1714
+ const props = element.props;
1715
+ const children = normalizeContent3(props.children ?? element.children);
1716
+ for (const child of children) {
1717
+ const match = getMatchElement3(child);
1718
+ if (!match) {
1719
+ continue;
1720
+ }
1721
+ const when = readReactive4(match.props.when);
1722
+ if (when) {
1723
+ return resolveMatchChildren3(match, when);
1724
+ }
1725
+ }
1726
+ return props.fallback;
1727
+ }
1728
+ function resolveMatchChildren3(element, value) {
1729
+ const children = element.props.children ?? element.children;
1730
+ if (typeof children === "function") {
1731
+ return children(value);
1732
+ }
1733
+ return children;
1734
+ }
1735
+ function resolveKeyChildren3(element, value) {
1736
+ const children = element.props.children ?? element.children;
1737
+ if (typeof children === "function") {
1738
+ return children(value);
1739
+ }
1740
+ return children;
1741
+ }
1742
+ function createDynamicElement3(element, tag) {
1743
+ if (typeof tag !== "string" && typeof tag !== "function") {
1744
+ return null;
1745
+ }
1746
+ const { component, ...props } = element.props;
1747
+ const children = normalizeContent3(props.children ?? element.children);
1748
+ return {
1749
+ tag,
1750
+ props,
1751
+ children
1752
+ };
1753
+ }
1754
+ function readReactive4(value) {
1261
1755
  return isSignal(value) || isComputed(value) ? value.value : value;
1262
1756
  }
1757
+ function normalizeContent3(content) {
1758
+ if (content == null || typeof content === "boolean") {
1759
+ return [];
1760
+ }
1761
+ return Array.isArray(content) ? content : [content];
1762
+ }
1763
+ function isElementLike3(value) {
1764
+ return value != null && typeof value === "object" && "tag" in value;
1765
+ }
1766
+ function getMatchElement3(value) {
1767
+ if (!isElementLike3(value)) {
1768
+ return null;
1769
+ }
1770
+ if (isMatchElement(value)) {
1771
+ return value;
1772
+ }
1773
+ return value.tag === Match ? Match(value.props) : null;
1774
+ }
1263
1775
 
1264
- //# debugId=107ADB344D9D30F764756E2164756E21
1776
+ //# debugId=B6B29A838DF26EA964756E2164756E21
1265
1777
  //# sourceMappingURL=index.development.js.map