@wsxjs/wsx-core 0.0.30 → 0.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.
@@ -47,11 +47,6 @@ function isHTMLString(str) {
47
47
  const looksLikeMath = /^[^<]*<[^>]*>[^>]*$/.test(trimmed) && !htmlTagPattern.test(trimmed);
48
48
  if (looksLikeMath) return false;
49
49
  const result = htmlTagPattern.test(trimmed);
50
- if (result) {
51
- console.log(`[WSX Debug] isHTMLString("${trimmed.substring(0, 50)}..."): ${result}`, {
52
- looksLikeMath
53
- });
54
- }
55
50
  return result;
56
51
  }
57
52
  function flattenChildren(children, skipHTMLDetection = false, depth = 0) {
@@ -77,11 +72,7 @@ function flattenChildren(children, skipHTMLDetection = false, depth = 0) {
77
72
  const nodes = parseHTMLToNodes(child);
78
73
  if (nodes.length > 0) {
79
74
  for (const node of nodes) {
80
- if (typeof node === "string") {
81
- result.push(node);
82
- } else {
83
- result.push(node);
84
- }
75
+ result.push(node);
85
76
  }
86
77
  } else {
87
78
  result.push(child);
@@ -95,15 +86,7 @@ function flattenChildren(children, skipHTMLDetection = false, depth = 0) {
95
86
  }
96
87
  } else if (child instanceof DocumentFragment) {
97
88
  const fragmentChildren = Array.from(child.childNodes);
98
- for (const fragChild of fragmentChildren) {
99
- if (fragChild instanceof HTMLElement || fragChild instanceof SVGElement) {
100
- result.push(fragChild);
101
- } else if (fragChild.nodeType === Node.TEXT_NODE) {
102
- result.push(fragChild.textContent || "");
103
- } else if (fragChild instanceof DocumentFragment) {
104
- result.push(...flattenChildren([fragChild], skipHTMLDetection, depth + 1));
105
- }
106
- }
89
+ result.push(...flattenChildren(fragmentChildren, skipHTMLDetection, depth + 1));
107
90
  } else {
108
91
  result.push(child);
109
92
  }
@@ -148,6 +131,8 @@ var RenderContext = _RenderContext;
148
131
  var INDEX_KEY = "__wsxIndex";
149
132
  var componentElementCounters = /* @__PURE__ */ new WeakMap();
150
133
  var componentIdCache = /* @__PURE__ */ new WeakMap();
134
+ var instanceAutoIds = /* @__PURE__ */ new WeakMap();
135
+ var globalAutoId = 0;
151
136
  function generateCacheKey(tag, props, componentId, component) {
152
137
  const userKey = props?.key;
153
138
  const index = props?.[INDEX_KEY];
@@ -179,7 +164,13 @@ function getComponentId() {
179
164
  if (cachedId) {
180
165
  return cachedId;
181
166
  }
182
- const instanceId = component._instanceId || "default";
167
+ let instanceId = component._wsxInstanceId;
168
+ if (instanceId === void 0 || instanceId === null) {
169
+ if (!instanceAutoIds.has(component)) {
170
+ instanceAutoIds.set(component, ++globalAutoId);
171
+ }
172
+ instanceId = String(instanceAutoIds.get(component));
173
+ }
183
174
  cachedId = `${component.constructor.name}:${instanceId}`;
184
175
  componentIdCache.set(component, cachedId);
185
176
  return cachedId;
@@ -716,8 +707,8 @@ function findElementNode(oldChild, parent) {
716
707
  function findTextNode(parent, domIndex, processedNodes) {
717
708
  for (let i = domIndex.value; i < parent.childNodes.length; i++) {
718
709
  const node = parent.childNodes[i];
719
- if (node.nodeType === Node.TEXT_NODE && node.__wsxManaged === true && !processedNodes.has(node)) {
720
- domIndex.value = i + 1;
710
+ if (node.nodeType === Node.TEXT_NODE && node.__wsxManaged === true && (!processedNodes || !processedNodes.has(node))) {
711
+ domIndex.value = i;
721
712
  return node;
722
713
  }
723
714
  }
@@ -800,11 +791,6 @@ function replaceOrInsertElementAtPosition(parent, newChild, oldNode, targetNextS
800
791
  if (existingNode instanceof HTMLElement || existingNode instanceof SVGElement) {
801
792
  const existingCacheKey = getElementCacheKey(existingNode);
802
793
  if (!existingCacheKey && existingNode.tagName.toLowerCase() === newChildTag && existingNode.textContent === newChildContent && existingNode !== newChild) {
803
- console.log(
804
- "[WSX Debug] Found duplicate content, keeping existing:",
805
- existingNode.tagName,
806
- existingNode.textContent
807
- );
808
794
  if (processedNodes) processedNodes.add(existingNode);
809
795
  return;
810
796
  }
@@ -838,35 +824,53 @@ function appendNewChild(parent, child, processedNodes) {
838
824
  }
839
825
  } else if (child instanceof DocumentFragment) {
840
826
  if (processedNodes) {
841
- for (let i = 0; i < child.childNodes.length; i++) {
842
- processedNodes.add(child.childNodes[i]);
827
+ const fragmentChildren = Array.from(child.childNodes);
828
+ for (const fragmentChild of fragmentChildren) {
829
+ processedNodes.add(fragmentChild);
843
830
  }
844
831
  }
845
832
  parent.appendChild(child);
833
+ } else if (child instanceof Node) {
834
+ if (child.parentNode && child.parentNode !== parent) {
835
+ child.parentNode.removeChild(child);
836
+ }
837
+ if (child.parentNode !== parent) {
838
+ parent.appendChild(child);
839
+ }
840
+ if (processedNodes) {
841
+ processedNodes.add(child);
842
+ }
846
843
  }
847
844
  }
848
- function buildNewChildrenMaps(flatNew) {
845
+ function buildNodeMaps(flatNodes) {
849
846
  const elementSet = /* @__PURE__ */ new Set();
850
847
  const cacheKeyMap = /* @__PURE__ */ new Map();
851
- for (const child of flatNew) {
852
- if (child instanceof HTMLElement || child instanceof SVGElement || child instanceof DocumentFragment) {
853
- elementSet.add(child);
854
- if (child instanceof HTMLElement || child instanceof SVGElement) {
855
- const cacheKey = getElementCacheKey(child);
856
- if (cacheKey) {
857
- cacheKeyMap.set(cacheKey, child);
848
+ const nodeSet = /* @__PURE__ */ new Set();
849
+ for (const child of flatNodes) {
850
+ if (child instanceof Node) {
851
+ nodeSet.add(child);
852
+ if (child instanceof HTMLElement || child instanceof SVGElement || child instanceof DocumentFragment) {
853
+ elementSet.add(child);
854
+ if (child instanceof HTMLElement || child instanceof SVGElement) {
855
+ const cacheKey = getElementCacheKey(child);
856
+ if (cacheKey) {
857
+ cacheKeyMap.set(cacheKey, child);
858
+ }
858
859
  }
859
860
  }
860
861
  }
861
862
  }
862
- return { elementSet, cacheKeyMap };
863
+ return { elementSet, cacheKeyMap, nodeSet };
863
864
  }
864
- function shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes) {
865
+ function shouldRemoveNode(node, _elementSet, _cacheKeyMap, processedNodes, nodeSet) {
866
+ if (processedNodes && processedNodes.has(node)) {
867
+ return false;
868
+ }
869
+ if (nodeSet && nodeSet.has(node)) {
870
+ return false;
871
+ }
865
872
  if (node.nodeType === Node.TEXT_NODE) {
866
873
  if (node.__wsxManaged === true) {
867
- if (processedNodes && processedNodes.has(node)) {
868
- return false;
869
- }
870
874
  return true;
871
875
  }
872
876
  const parent = node.parentNode;
@@ -876,29 +880,10 @@ function shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes) {
876
880
  }
877
881
  }
878
882
  return true;
879
- } else {
880
- if (shouldPreserveElement(node)) {
881
- return false;
882
- }
883
- }
884
- const isProcessed = processedNodes && processedNodes.has(node);
885
- if (isProcessed) {
886
- return false;
887
883
  }
888
884
  if (shouldPreserveElement(node)) {
889
885
  return false;
890
886
  }
891
- if (node instanceof HTMLElement || node instanceof SVGElement || node instanceof DocumentFragment) {
892
- if (elementSet.has(node)) {
893
- return false;
894
- }
895
- if (node instanceof HTMLElement || node instanceof SVGElement) {
896
- const cacheKey = getElementCacheKey(node);
897
- if (cacheKey && cacheKeyMap.has(cacheKey)) {
898
- return false;
899
- }
900
- }
901
- }
902
887
  return true;
903
888
  }
904
889
  function deduplicateCacheKeys(parent, cacheKeyMap) {
@@ -925,11 +910,11 @@ function deduplicateCacheKeys(parent, cacheKeyMap) {
925
910
  }
926
911
  }
927
912
  }
928
- function collectNodesToRemove(parent, elementSet, cacheKeyMap, processedNodes) {
913
+ function collectNodesToRemove(parent, elementSet, cacheKeyMap, processedNodes, nodeSet) {
929
914
  const nodesToRemove = [];
930
915
  for (let i = 0; i < parent.childNodes.length; i++) {
931
916
  const node = parent.childNodes[i];
932
- const removed = shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes);
917
+ const removed = shouldRemoveNode(node, elementSet, cacheKeyMap, processedNodes, nodeSet);
933
918
  if (removed) {
934
919
  nodesToRemove.push(node);
935
920
  }
@@ -1130,6 +1115,8 @@ function updateChildren(element, oldChildren, newChildren, _cacheManager) {
1130
1115
  const flatOld = flattenChildrenSafe(oldChildren);
1131
1116
  const flatNew = flattenChildrenSafe(newChildren);
1132
1117
  const preservedElements = collectPreservedElements(element);
1118
+ const { cacheKeyMap: oldKeyMap } = buildNodeMaps(flatOld);
1119
+ const newMaps = buildNodeMaps(flatNew);
1133
1120
  const minLength = Math.min(flatOld.length, flatNew.length);
1134
1121
  const domIndex = { value: 0 };
1135
1122
  const insertionIndex = { value: 0 };
@@ -1138,110 +1125,77 @@ function updateChildren(element, oldChildren, newChildren, _cacheManager) {
1138
1125
  const oldChild = flatOld[i];
1139
1126
  const newChild = flatNew[i];
1140
1127
  let oldNode = null;
1141
- if (oldChild instanceof HTMLElement || oldChild instanceof SVGElement) {
1142
- oldNode = findElementNode(oldChild, element);
1143
- if (oldNode && oldNode.parentNode === element) {
1144
- const nodeIndex = Array.from(element.childNodes).indexOf(oldNode);
1145
- if (nodeIndex !== -1 && nodeIndex >= domIndex.value) {
1146
- domIndex.value = nodeIndex + 1;
1128
+ if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1129
+ const key = getElementCacheKey(newChild);
1130
+ if (key) {
1131
+ const matchedOld = oldKeyMap.get(key);
1132
+ if (matchedOld && matchedOld.parentNode === element) {
1133
+ oldNode = matchedOld;
1147
1134
  }
1148
1135
  }
1149
- } else if (typeof oldChild === "string" || typeof oldChild === "number") {
1150
- if (shouldPreserveElement(element)) {
1151
- oldNode = null;
1152
- } else {
1136
+ }
1137
+ if (!oldNode) {
1138
+ if (oldChild instanceof HTMLElement || oldChild instanceof SVGElement) {
1139
+ oldNode = findElementNode(oldChild, element);
1140
+ } else if (typeof oldChild === "string" || typeof oldChild === "number" || oldChild instanceof Node) {
1153
1141
  oldNode = findTextNode(element, domIndex, processedNodes);
1154
- if (oldNode) {
1155
- const nodeIndex = Array.from(element.childNodes).indexOf(oldNode);
1156
- if (nodeIndex !== -1 && nodeIndex >= domIndex.value) {
1157
- domIndex.value = nodeIndex + 1;
1158
- }
1159
- }
1160
1142
  }
1161
1143
  }
1162
- if (typeof oldChild === "string" || typeof oldChild === "number") {
1163
- if (typeof newChild === "string" || typeof newChild === "number") {
1164
- const newText = String(newChild);
1165
- if (shouldPreserveElement(element)) {
1166
- continue;
1167
- }
1168
- const insertBeforeNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1169
- const updatedNode = updateOrCreateTextNode(
1170
- element,
1171
- oldNode,
1172
- newText,
1173
- insertBeforeNode
1174
- );
1175
- if (updatedNode) {
1176
- processedNodes.add(updatedNode);
1177
- insertionIndex.value++;
1178
- }
1179
- } else {
1180
- const targetNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1181
- if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1182
- if (oldNode && oldNode === targetNode && oldNode.parentNode === element) {
1183
- element.replaceChild(newChild, oldNode);
1184
- } else {
1185
- element.insertBefore(newChild, targetNode);
1186
- removeNodeIfNotPreserved(element, oldNode);
1187
- }
1188
- processedNodes.add(newChild);
1189
- insertionIndex.value++;
1190
- } else if (newChild instanceof DocumentFragment) {
1191
- if (processedNodes) {
1192
- for (let i2 = 0; i2 < newChild.childNodes.length; i2++) {
1193
- processedNodes.add(newChild.childNodes[i2]);
1194
- }
1195
- }
1196
- element.insertBefore(newChild, targetNode);
1197
- removeNodeIfNotPreserved(element, oldNode);
1198
- }
1199
- }
1200
- } else if (oldChild instanceof HTMLElement || oldChild instanceof SVGElement) {
1201
- if (oldNode && shouldPreserveElement(oldNode)) {
1202
- continue;
1144
+ if (oldNode && oldNode.parentNode === element) {
1145
+ const childrenArray = Array.from(element.childNodes);
1146
+ const nodeIndex = childrenArray.indexOf(oldNode);
1147
+ if (nodeIndex !== -1 && nodeIndex >= domIndex.value) {
1148
+ domIndex.value = nodeIndex + 1;
1203
1149
  }
1204
- if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1205
- const insertBeforeNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1206
- replaceOrInsertElementAtPosition(
1207
- element,
1208
- newChild,
1209
- oldNode,
1210
- insertBeforeNode,
1211
- processedNodes
1212
- );
1150
+ }
1151
+ const targetNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1152
+ const isNewTextChild = typeof newChild === "string" || typeof newChild === "number" || newChild instanceof Node && newChild.nodeType === Node.TEXT_NODE;
1153
+ if (isNewTextChild) {
1154
+ const newTextContent = newChild instanceof Node ? newChild.textContent || "" : String(newChild);
1155
+ if (shouldPreserveElement(element)) continue;
1156
+ const targetMatchingNode = newChild instanceof Node ? newChild : oldNode;
1157
+ const updatedNode = updateOrCreateTextNode(
1158
+ element,
1159
+ targetMatchingNode,
1160
+ newTextContent,
1161
+ targetNode
1162
+ );
1163
+ if (updatedNode) {
1164
+ processedNodes.add(updatedNode);
1213
1165
  insertionIndex.value++;
1214
- } else {
1215
- const targetNode = insertionIndex.value < element.childNodes.length ? element.childNodes[insertionIndex.value] : null;
1216
- if (typeof newChild === "string" || typeof newChild === "number") {
1217
- const newTextNode = document.createTextNode(String(newChild));
1218
- newTextNode.__wsxManaged = true;
1219
- if (oldNode && oldNode === targetNode && oldNode.parentNode === element) {
1220
- element.replaceChild(newTextNode, oldNode);
1221
- } else {
1222
- element.insertBefore(newTextNode, targetNode);
1223
- removeNodeIfNotPreserved(element, oldNode);
1224
- }
1225
- processedNodes.add(newTextNode);
1226
- insertionIndex.value++;
1227
- } else if (newChild instanceof DocumentFragment) {
1228
- if (processedNodes) {
1229
- for (let i2 = 0; i2 < newChild.childNodes.length; i2++) {
1230
- processedNodes.add(newChild.childNodes[i2]);
1231
- }
1232
- }
1233
- element.insertBefore(newChild, targetNode);
1234
- removeNodeIfNotPreserved(element, oldNode);
1235
- }
1236
1166
  }
1167
+ } else if (newChild instanceof HTMLElement || newChild instanceof SVGElement) {
1168
+ replaceOrInsertElementAtPosition(
1169
+ element,
1170
+ newChild,
1171
+ oldNode,
1172
+ targetNode,
1173
+ processedNodes
1174
+ );
1175
+ insertionIndex.value++;
1176
+ } else if (newChild instanceof DocumentFragment) {
1177
+ const fragmentChildren = Array.from(newChild.childNodes);
1178
+ for (const fc of fragmentChildren) {
1179
+ processedNodes.add(fc);
1180
+ }
1181
+ element.insertBefore(newChild, targetNode);
1182
+ if (oldNode && !processedNodes.has(oldNode)) {
1183
+ removeNodeIfNotPreserved(element, oldNode);
1184
+ }
1185
+ insertionIndex.value++;
1237
1186
  }
1238
1187
  }
1239
1188
  for (let i = minLength; i < flatNew.length; i++) {
1240
1189
  appendNewChild(element, flatNew[i], processedNodes);
1241
1190
  }
1242
- const { elementSet, cacheKeyMap } = buildNewChildrenMaps(flatNew);
1243
- deduplicateCacheKeys(element, cacheKeyMap);
1244
- const nodesToRemove = collectNodesToRemove(element, elementSet, cacheKeyMap, processedNodes);
1191
+ deduplicateCacheKeys(element, newMaps.cacheKeyMap);
1192
+ const nodesToRemove = collectNodesToRemove(
1193
+ element,
1194
+ newMaps.elementSet,
1195
+ newMaps.cacheKeyMap,
1196
+ processedNodes,
1197
+ newMaps.nodeSet
1198
+ );
1245
1199
  removeNodes(element, nodesToRemove, _cacheManager);
1246
1200
  reinsertPreservedElements(element, preservedElements);
1247
1201
  }
@@ -1360,6 +1314,8 @@ function Fragment(_props, children) {
1360
1314
  fragment.appendChild(child);
1361
1315
  } else if (child instanceof DocumentFragment) {
1362
1316
  fragment.appendChild(child);
1317
+ } else if (child instanceof Node) {
1318
+ fragment.appendChild(child);
1363
1319
  }
1364
1320
  });
1365
1321
  return fragment;
@@ -2,7 +2,7 @@ import {
2
2
  Fragment,
3
3
  jsx,
4
4
  jsxs
5
- } from "./chunk-2ER76KOQ.mjs";
5
+ } from "./chunk-PNIWQQN6.mjs";
6
6
  export {
7
7
  Fragment,
8
8
  jsx,