sinwan 1.1.1 → 1.1.2

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 (38) hide show
  1. package/README.md +34 -3
  2. package/dist/cjs/index.development.js +296 -192
  3. package/dist/cjs/index.development.js.map +9 -9
  4. package/dist/cjs/index.production.min.js +2 -2
  5. package/dist/cjs/index.production.min.js.map +9 -9
  6. package/dist/cjs/renderer/index.development.js +239 -87
  7. package/dist/cjs/renderer/index.development.js.map +8 -8
  8. package/dist/cjs/renderer/index.production.min.js +2 -2
  9. package/dist/cjs/renderer/index.production.min.js.map +8 -8
  10. package/dist/cjs/server/index.development.js +132 -67
  11. package/dist/cjs/server/index.development.js.map +6 -6
  12. package/dist/cjs/server/index.production.min.js +2 -2
  13. package/dist/cjs/server/index.production.min.js.map +6 -6
  14. package/dist/component/control-flow.d.ts +6 -1
  15. package/dist/component/control-flow.d.ts.map +1 -1
  16. package/dist/component/instance.d.ts.map +1 -1
  17. package/dist/esm/index.development.js +296 -192
  18. package/dist/esm/index.development.js.map +9 -9
  19. package/dist/esm/index.production.min.js +2 -2
  20. package/dist/esm/index.production.min.js.map +9 -9
  21. package/dist/esm/renderer/index.development.js +239 -87
  22. package/dist/esm/renderer/index.development.js.map +8 -8
  23. package/dist/esm/renderer/index.production.min.js +2 -2
  24. package/dist/esm/renderer/index.production.min.js.map +8 -8
  25. package/dist/esm/server/index.development.js +132 -67
  26. package/dist/esm/server/index.development.js.map +6 -6
  27. package/dist/esm/server/index.production.min.js +2 -2
  28. package/dist/esm/server/index.production.min.js.map +6 -6
  29. package/dist/reactivity/index.d.ts +1 -1
  30. package/dist/reactivity/index.d.ts.map +1 -1
  31. package/dist/renderer/attributes.d.ts.map +1 -1
  32. package/dist/renderer/events.d.ts.map +1 -1
  33. package/dist/renderer/render-control-flow.d.ts.map +1 -1
  34. package/dist/renderer/render-element.d.ts.map +1 -1
  35. package/dist/renderer/types.d.ts +2 -0
  36. package/dist/renderer/types.d.ts.map +1 -1
  37. package/dist/server/renderer.d.ts.map +1 -1
  38. package/package.json +5 -2
@@ -395,7 +395,7 @@ function resolve(value) {
395
395
  }
396
396
  // src/renderer/events.ts
397
397
  function isEventProp(key) {
398
- return key.length > 2 && key[0] === "o" && key[1] === "n" && key[2] >= "A" && key[2] <= "Z";
398
+ return key.length > 2 && key.startsWith("on");
399
399
  }
400
400
  function toEventName(key) {
401
401
  return key.slice(2).toLowerCase();
@@ -472,19 +472,28 @@ function fireMountedHooks(instance) {
472
472
  }
473
473
  }
474
474
  function fireUnmountedHooks(instance) {
475
- for (const child of instance.children) {
475
+ const children = [...instance.children];
476
+ for (const child of children) {
476
477
  fireUnmountedHooks(child);
477
478
  }
478
- if (instance.isMounted && !instance.isUnmounted) {
479
+ if (!instance.isUnmounted) {
479
480
  instance.isUnmounted = true;
480
- instance.isMounted = false;
481
- for (const hook of instance._unmountedHooks) {
482
- hook();
481
+ if (instance.isMounted) {
482
+ instance.isMounted = false;
483
+ for (const hook of instance._unmountedHooks) {
484
+ hook();
485
+ }
483
486
  }
484
487
  for (const dispose of instance.effects) {
485
488
  dispose();
486
489
  }
487
490
  instance.effects.length = 0;
491
+ if (instance.parent) {
492
+ const idx = instance.parent.children.indexOf(instance);
493
+ if (idx !== -1) {
494
+ instance.parent.children.splice(idx, 1);
495
+ }
496
+ }
488
497
  }
489
498
  }
490
499
  function fireUpdatedHooks(instance) {
@@ -534,7 +543,9 @@ function applyAttributes(el, props) {
534
543
  for (const [key, value] of Object.entries(props)) {
535
544
  if (SKIP_PROPS.has(key) || isEventProp(key))
536
545
  continue;
537
- if (isReactive(value)) {
546
+ const attrName = resolveAttributeName(key);
547
+ const isComplex = attrName === "class" || attrName === "style";
548
+ if (isReactive(value) || isComplex && containsReactive(value)) {
538
549
  const state = { previousStyleProps: new Set };
539
550
  let initialized = false;
540
551
  const dispose = effect(() => {
@@ -596,19 +607,17 @@ function setSingleAttribute(el, key, value, state) {
596
607
  function resolveAttributeName(key) {
597
608
  return PROP_ALIASES[key] ?? key;
598
609
  }
599
- function applyStyle(el, styles, state) {
610
+ function applyStyle(el, value, state) {
611
+ const styleObj = normalizeStyle(value);
600
612
  const nextProps = new Set;
601
- for (const [prop, val] of Object.entries(styles)) {
613
+ for (const [prop, val] of Object.entries(styleObj)) {
602
614
  nextProps.add(prop);
603
615
  if (val == null) {
604
616
  removeStyleProperty(el, prop);
605
617
  continue;
606
618
  }
607
- if (prop.includes("-")) {
608
- el.style.setProperty(prop, String(val));
609
- } else {
610
- el.style[prop] = val;
611
- }
619
+ const kebabProp = prop.startsWith("--") ? prop : camelToKebab(prop);
620
+ el.style.setProperty(kebabProp, String(val));
612
621
  }
613
622
  if (!state) {
614
623
  return;
@@ -620,23 +629,75 @@ function applyStyle(el, styles, state) {
620
629
  }
621
630
  state.previousStyleProps = nextProps;
622
631
  }
632
+ function normalizeStyle(value) {
633
+ const resolved = resolve(value);
634
+ if (!resolved)
635
+ return {};
636
+ if (typeof resolved === "string") {
637
+ return parseStyleString(resolved);
638
+ }
639
+ if (Array.isArray(resolved)) {
640
+ return resolved.reduce((acc, item) => {
641
+ const normalized = normalizeStyle(item);
642
+ return Object.assign(acc, normalized);
643
+ }, {});
644
+ }
645
+ if (typeof resolved === "object") {
646
+ const result = {};
647
+ for (const [k, v] of Object.entries(resolved)) {
648
+ result[k] = resolve(v);
649
+ }
650
+ return result;
651
+ }
652
+ return {};
653
+ }
654
+ function parseStyleString(style) {
655
+ const result = {};
656
+ style.split(";").forEach((rule) => {
657
+ const i = rule.indexOf(":");
658
+ if (i > 0) {
659
+ const prop = rule.slice(0, i).trim();
660
+ const val = rule.slice(i + 1).trim();
661
+ if (prop && val) {
662
+ result[prop] = val;
663
+ }
664
+ }
665
+ });
666
+ return result;
667
+ }
623
668
  function removeStyleProperty(el, prop) {
624
- if (prop.includes("-")) {
625
- el.style.removeProperty(prop);
626
- } else {
627
- el.style[prop] = "";
628
- }
669
+ const kebabProp = prop.startsWith("--") ? prop : camelToKebab(prop);
670
+ el.style.removeProperty(kebabProp);
629
671
  }
630
672
  function applyClass(el, value) {
631
- let classStr;
632
- if (Array.isArray(value)) {
633
- classStr = value.filter(Boolean).join(" ");
634
- } else if (typeof value === "object" && value !== null) {
635
- classStr = Object.entries(value).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
636
- } else {
637
- classStr = String(value);
673
+ domOps.setAttribute(el, "class", normalizeClass(value));
674
+ }
675
+ function normalizeClass(value) {
676
+ const resolved = resolve(value);
677
+ if (!resolved)
678
+ return "";
679
+ if (typeof resolved === "string")
680
+ return resolved;
681
+ if (Array.isArray(resolved)) {
682
+ return resolved.map(normalizeClass).filter(Boolean).join(" ");
683
+ }
684
+ if (typeof resolved === "object") {
685
+ return Object.entries(resolved).filter(([, v]) => Boolean(resolve(v))).map(([k]) => k).join(" ");
686
+ }
687
+ return String(resolved);
688
+ }
689
+ function containsReactive(value) {
690
+ if (isReactive(value))
691
+ return true;
692
+ if (Array.isArray(value))
693
+ return value.some(containsReactive);
694
+ if (typeof value === "object" && value !== null) {
695
+ return Object.values(value).some(containsReactive);
638
696
  }
639
- domOps.setAttribute(el, "class", classStr);
697
+ return false;
698
+ }
699
+ function camelToKebab(str) {
700
+ return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
640
701
  }
641
702
 
642
703
  // src/component/control-flow.ts
@@ -732,6 +793,9 @@ function Portal(props) {
732
793
  children: []
733
794
  };
734
795
  }
796
+ function isElementLike(value) {
797
+ return value != null && typeof value === "object" && "tag" in value;
798
+ }
735
799
  function isShowElement(element) {
736
800
  return element.tag === SHOW_TYPE;
737
801
  }
@@ -756,6 +820,107 @@ function isDynamicElement(element) {
756
820
  function isPortalElement(element) {
757
821
  return element.tag === PORTAL_TYPE;
758
822
  }
823
+ function resolveSwitchContent(element) {
824
+ const props = element.props;
825
+ const children = normalizeContent(props.children ?? element.children);
826
+ const match = findTruthyMatch(children);
827
+ return match !== undefined ? match : props.fallback;
828
+ }
829
+ function findTruthyMatch(nodes) {
830
+ for (const node of nodes) {
831
+ if (node == null || typeof node === "boolean")
832
+ continue;
833
+ if (Array.isArray(node)) {
834
+ const match = findTruthyMatch(node);
835
+ if (match !== undefined)
836
+ return match;
837
+ continue;
838
+ }
839
+ if (isElementLike(node)) {
840
+ let element = node;
841
+ if (typeof element.tag === "function") {
842
+ const tag = element.tag;
843
+ if (tag === Match || tag === Show || tag === For || tag === Index || tag === Key || tag === Switch) {
844
+ element = tag(element.props);
845
+ }
846
+ }
847
+ if (isMatchElement(element)) {
848
+ const when = readReactive(element.props.when);
849
+ if (when) {
850
+ return resolveMatchChildren(element, when);
851
+ }
852
+ } else if (isShowElement(element)) {
853
+ const when = readReactive(element.props.when);
854
+ if (when) {
855
+ const content = resolveShowChildren(element, when);
856
+ const match = findTruthyMatch(normalizeContent(content));
857
+ if (match !== undefined)
858
+ return match;
859
+ } else if (element.props.fallback) {
860
+ const match = findTruthyMatch(normalizeContent(element.props.fallback));
861
+ if (match !== undefined)
862
+ return match;
863
+ }
864
+ } else if (isForElement(element)) {
865
+ const props = element.props;
866
+ const items = readReactive(props.each);
867
+ if (Array.isArray(items)) {
868
+ for (let i = 0;i < items.length; i++) {
869
+ const child = props.children(items[i], () => i);
870
+ const match = findTruthyMatch(normalizeContent(child));
871
+ if (match !== undefined)
872
+ return match;
873
+ }
874
+ }
875
+ } else if (isIndexElement(element)) {
876
+ const props = element.props;
877
+ const items = readReactive(props.each);
878
+ if (Array.isArray(items)) {
879
+ for (let i = 0;i < items.length; i++) {
880
+ const child = props.children(() => items[i], i);
881
+ const match = findTruthyMatch(normalizeContent(child));
882
+ if (match !== undefined)
883
+ return match;
884
+ }
885
+ }
886
+ } else if (isKeyElement(element)) {
887
+ const key = readReactive(element.props.when);
888
+ const child = resolveKeyChildren(element, key);
889
+ const match = findTruthyMatch(normalizeContent(child));
890
+ if (match !== undefined)
891
+ return match;
892
+ }
893
+ }
894
+ }
895
+ return;
896
+ }
897
+ function resolveMatchChildren(element, value) {
898
+ const children = element.props.children ?? element.children;
899
+ if (typeof children === "function") {
900
+ return children(value);
901
+ }
902
+ return children;
903
+ }
904
+ function resolveShowChildren(element, value) {
905
+ const children = element.props.children ?? element.children;
906
+ if (typeof children === "function") {
907
+ return children(value);
908
+ }
909
+ return children;
910
+ }
911
+ function resolveKeyChildren(element, value) {
912
+ const children = element.props.children ?? element.children;
913
+ if (typeof children === "function") {
914
+ return children(value);
915
+ }
916
+ return children;
917
+ }
918
+ function normalizeContent(content) {
919
+ if (content == null || typeof content === "boolean") {
920
+ return [];
921
+ }
922
+ return Array.isArray(content) ? content : [content];
923
+ }
759
924
  function normalizeChildren2(children) {
760
925
  if (children == null || typeof children === "boolean") {
761
926
  return [];
@@ -895,8 +1060,10 @@ function renderShowBlock(element, block, parent, namespace, owner) {
895
1060
  return effect(() => {
896
1061
  clearChildren(block);
897
1062
  const when = readReactive2(element.props.when);
898
- const content = withOptionalInstance(owner, () => when ? resolveShowChildren(element, when) : element.props.fallback);
899
- block.children = renderBlockContent(content, parent, block.endAnchor, namespace, owner);
1063
+ block.children = withOptionalInstance(owner, () => {
1064
+ const content = when ? resolveShowChildren(element, when) : element.props.fallback;
1065
+ return renderBlockContent(content, parent, block.endAnchor, namespace, owner);
1066
+ });
900
1067
  if (initialized) {
901
1068
  fireMountedAndQueueUpdated(owner);
902
1069
  }
@@ -1083,18 +1250,31 @@ function renderPortal(element, parent, anchor, namespace) {
1083
1250
  insertNode(parent, placeholder, anchor);
1084
1251
  const owner = getCurrentInstance();
1085
1252
  let disposeEffect = () => {};
1253
+ const targetAnchor = domOps.createComment("Sinwan-pa");
1254
+ let lastTarget = null;
1086
1255
  const portal = {
1087
1256
  type: "portal",
1088
1257
  anchor: placeholder,
1089
1258
  children: [],
1090
- dispose: () => disposeEffect()
1259
+ dispose: () => disposeEffect(),
1260
+ targetAnchor
1091
1261
  };
1092
1262
  let initialized = false;
1093
1263
  disposeEffect = effect(() => {
1094
- clearPortalChildren(portal);
1095
1264
  const target = resolvePortalTarget(element.props.mount);
1265
+ if (target !== lastTarget) {
1266
+ if (lastTarget) {
1267
+ domOps.remove(targetAnchor);
1268
+ }
1269
+ if (target) {
1270
+ domOps.appendChild(target, targetAnchor);
1271
+ }
1272
+ lastTarget = target;
1273
+ portal.target = target;
1274
+ }
1275
+ clearPortalChildren(portal);
1096
1276
  if (target) {
1097
- portal.children = renderBlockContent(element.props.children ?? element.children, target, null, namespace, owner);
1277
+ portal.children = renderBlockContent(element.props.children ?? element.children, target, targetAnchor, namespace, owner);
1098
1278
  }
1099
1279
  if (initialized) {
1100
1280
  fireMountedAndQueueUpdated(owner);
@@ -1103,48 +1283,12 @@ function renderPortal(element, parent, anchor, namespace) {
1103
1283
  });
1104
1284
  return portal;
1105
1285
  }
1106
- function resolveShowChildren(element, value) {
1107
- const children = element.props.children ?? element.children;
1108
- if (typeof children === "function") {
1109
- return children(value);
1110
- }
1111
- return children;
1112
- }
1113
- function resolveSwitchContent(element) {
1114
- const props = element.props;
1115
- const children = normalizeContent(props.children ?? element.children);
1116
- for (const child of children) {
1117
- const match = getMatchElement(child);
1118
- if (!match) {
1119
- continue;
1120
- }
1121
- const when = readReactive2(match.props.when);
1122
- if (when) {
1123
- return resolveMatchChildren(match, when);
1124
- }
1125
- }
1126
- return props.fallback;
1127
- }
1128
- function resolveMatchChildren(element, value) {
1129
- const children = element.props.children ?? element.children;
1130
- if (typeof children === "function") {
1131
- return children(value);
1132
- }
1133
- return children;
1134
- }
1135
- function resolveKeyChildren(element, value) {
1136
- const children = element.props.children ?? element.children;
1137
- if (typeof children === "function") {
1138
- return children(value);
1139
- }
1140
- return children;
1141
- }
1142
1286
  function createDynamicElement(element, tag) {
1143
1287
  if (typeof tag !== "string" && typeof tag !== "function") {
1144
1288
  return null;
1145
1289
  }
1146
1290
  const { component, ...props } = element.props;
1147
- const children = normalizeContent(props.children ?? element.children);
1291
+ const children = normalizeContent2(props.children ?? element.children);
1148
1292
  return {
1149
1293
  tag,
1150
1294
  props,
@@ -1152,11 +1296,14 @@ function createDynamicElement(element, tag) {
1152
1296
  };
1153
1297
  }
1154
1298
  function renderBlockContent(content, parent, anchor, namespace, owner) {
1155
- if (content == null || typeof content === "boolean") {
1299
+ if (content == null || typeof content === "boolean")
1156
1300
  return [];
1157
- }
1158
- const nodes = Array.isArray(content) ? content : [content];
1159
- return nodes.map((node) => withOptionalInstance(owner, () => renderNodeToDOM(node, parent, anchor, namespace)));
1301
+ return withOptionalInstance(owner, () => {
1302
+ if (Array.isArray(content)) {
1303
+ return content.map((child) => renderNodeToDOM(child, parent, anchor, namespace));
1304
+ }
1305
+ return [renderNodeToDOM(content, parent, anchor, namespace)];
1306
+ });
1160
1307
  }
1161
1308
  function clearChildren(block) {
1162
1309
  for (const child of block.children) {
@@ -1174,6 +1321,23 @@ function moveBeforeEnd(parent, mounted, endAnchor) {
1174
1321
  for (const node of getMountedDomNodes(mounted)) {
1175
1322
  domOps.insertBefore(parent, node, endAnchor);
1176
1323
  }
1324
+ syncPortalOrder(mounted);
1325
+ }
1326
+ function syncPortalOrder(mounted) {
1327
+ if (mounted.type === "portal") {
1328
+ if (mounted.target && mounted.targetAnchor) {
1329
+ for (const child of mounted.children) {
1330
+ for (const node of getMountedDomNodes(child)) {
1331
+ domOps.appendChild(mounted.target, node);
1332
+ }
1333
+ }
1334
+ domOps.appendChild(mounted.target, mounted.targetAnchor);
1335
+ }
1336
+ } else if ("children" in mounted && Array.isArray(mounted.children)) {
1337
+ for (const child of mounted.children) {
1338
+ syncPortalOrder(child);
1339
+ }
1340
+ }
1177
1341
  }
1178
1342
  function fireMountedAndQueueUpdated(owner) {
1179
1343
  if (owner) {
@@ -1187,24 +1351,12 @@ function withOptionalInstance(owner, fn) {
1187
1351
  function readReactive2(value) {
1188
1352
  return resolve(value);
1189
1353
  }
1190
- function normalizeContent(content) {
1354
+ function normalizeContent2(content) {
1191
1355
  if (content == null || typeof content === "boolean") {
1192
1356
  return [];
1193
1357
  }
1194
1358
  return Array.isArray(content) ? content : [content];
1195
1359
  }
1196
- function isElementLike(value) {
1197
- return value != null && typeof value === "object" && "tag" in value;
1198
- }
1199
- function getMatchElement(value) {
1200
- if (!isElementLike(value)) {
1201
- return null;
1202
- }
1203
- if (isMatchElement(value)) {
1204
- return value;
1205
- }
1206
- return value.tag === Match ? Match(value.props) : null;
1207
- }
1208
1360
  function resolvePortalTarget(value) {
1209
1361
  const target = readReactive2(value);
1210
1362
  if (target == null) {
@@ -1558,5 +1710,5 @@ export {
1558
1710
  applyAttributes
1559
1711
  };
1560
1712
 
1561
- //# debugId=ECCB38F4A76AE39C64756E2164756E21
1713
+ //# debugId=EBE55516E78B698564756E2164756E21
1562
1714
  //# sourceMappingURL=index.development.js.map