what-core 0.6.0 → 0.6.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.
- package/dist/index.js +115 -50
- package/dist/index.js.map +2 -2
- package/dist/index.min.js +6 -6
- package/dist/index.min.js.map +3 -3
- package/dist/render.js +98 -49
- package/dist/render.js.map +2 -2
- package/dist/render.min.js +1 -1
- package/dist/render.min.js.map +3 -3
- package/dist/testing.js +100 -47
- package/dist/testing.js.map +2 -2
- package/dist/testing.min.js +1 -1
- package/dist/testing.min.js.map +3 -3
- package/package.json +1 -1
- package/src/dom.js +60 -20
- package/src/reactive.js +78 -40
- package/src/render.js +20 -0
package/dist/render.js
CHANGED
|
@@ -285,40 +285,47 @@ function scheduleMicrotask() {
|
|
|
285
285
|
});
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
|
+
var isFlushing = false;
|
|
288
289
|
function flush() {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
batch2
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
if (!e.
|
|
304
|
-
|
|
290
|
+
if (isFlushing) return;
|
|
291
|
+
isFlushing = true;
|
|
292
|
+
try {
|
|
293
|
+
let iterations = 0;
|
|
294
|
+
while (pendingEffects.length > 0 && iterations < 25) {
|
|
295
|
+
const batch2 = pendingEffects;
|
|
296
|
+
pendingEffects = [];
|
|
297
|
+
if (batch2.length > 1 && pendingNeedSort) {
|
|
298
|
+
batch2.sort((a, b) => a._level - b._level);
|
|
299
|
+
}
|
|
300
|
+
pendingNeedSort = false;
|
|
301
|
+
for (let i = 0; i < batch2.length; i++) {
|
|
302
|
+
const e = batch2[i];
|
|
303
|
+
e._pending = false;
|
|
304
|
+
if (!e.disposed && !e._onNotify) {
|
|
305
|
+
const prevDepsLen = e.deps.length;
|
|
306
|
+
_runEffect(e);
|
|
307
|
+
if (!e._computed && e.deps.length !== prevDepsLen) {
|
|
308
|
+
_updateLevel(e);
|
|
309
|
+
}
|
|
305
310
|
}
|
|
306
311
|
}
|
|
312
|
+
iterations++;
|
|
307
313
|
}
|
|
308
|
-
iterations
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
314
|
+
if (iterations >= 25) {
|
|
315
|
+
for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
|
|
316
|
+
pendingEffects.length = 0;
|
|
317
|
+
if (__DEV__) {
|
|
318
|
+
const remaining = pendingEffects.slice(0, 3);
|
|
319
|
+
const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
|
|
320
|
+
console.warn(
|
|
321
|
+
`[what] Possible infinite effect loop detected (25 iterations). Likely cause: an effect writes to a signal it also reads, creating a cycle. Use untrack() to read signals without subscribing. Looping effects: ${effectNames.join(", ")}`
|
|
322
|
+
);
|
|
323
|
+
} else {
|
|
324
|
+
console.warn("[what] Possible infinite effect loop detected");
|
|
325
|
+
}
|
|
319
326
|
}
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
} finally {
|
|
328
|
+
isFlushing = false;
|
|
322
329
|
}
|
|
323
330
|
}
|
|
324
331
|
function untrack(fn) {
|
|
@@ -718,8 +725,8 @@ function createComponent(vnode, parent, isSvg) {
|
|
|
718
725
|
function createErrorBoundary(vnode, parent) {
|
|
719
726
|
const { errorState, handleError, fallback, reset } = vnode.props;
|
|
720
727
|
const children = vnode.children;
|
|
721
|
-
const
|
|
722
|
-
|
|
728
|
+
const startComment = document.createComment("eb:start");
|
|
729
|
+
const endComment = document.createComment("eb:end");
|
|
723
730
|
const boundaryCtx = {
|
|
724
731
|
hooks: [],
|
|
725
732
|
hookIndex: 0,
|
|
@@ -728,15 +735,24 @@ function createErrorBoundary(vnode, parent) {
|
|
|
728
735
|
mounted: false,
|
|
729
736
|
disposed: false,
|
|
730
737
|
_parentCtx: componentStack[componentStack.length - 1] || null,
|
|
731
|
-
_errorBoundary: handleError
|
|
738
|
+
_errorBoundary: handleError,
|
|
739
|
+
_startComment: startComment,
|
|
740
|
+
_endComment: endComment
|
|
732
741
|
};
|
|
733
|
-
|
|
742
|
+
_commentCtxMap.set(startComment, boundaryCtx);
|
|
743
|
+
const container = document.createDocumentFragment();
|
|
744
|
+
container._componentCtx = boundaryCtx;
|
|
745
|
+
container.appendChild(startComment);
|
|
746
|
+
container.appendChild(endComment);
|
|
734
747
|
const dispose = effect(() => {
|
|
735
748
|
const error = errorState();
|
|
736
749
|
componentStack.push(boundaryCtx);
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
750
|
+
if (startComment.parentNode) {
|
|
751
|
+
while (startComment.nextSibling && startComment.nextSibling !== endComment) {
|
|
752
|
+
const old = startComment.nextSibling;
|
|
753
|
+
disposeTree(old);
|
|
754
|
+
old.parentNode.removeChild(old);
|
|
755
|
+
}
|
|
740
756
|
}
|
|
741
757
|
let vnodes;
|
|
742
758
|
if (error) {
|
|
@@ -746,19 +762,25 @@ function createErrorBoundary(vnode, parent) {
|
|
|
746
762
|
}
|
|
747
763
|
vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];
|
|
748
764
|
for (const v of vnodes) {
|
|
749
|
-
const node = createDOM(v,
|
|
750
|
-
if (node)
|
|
765
|
+
const node = createDOM(v, parent);
|
|
766
|
+
if (node) {
|
|
767
|
+
if (endComment.parentNode) {
|
|
768
|
+
endComment.parentNode.insertBefore(node, endComment);
|
|
769
|
+
} else {
|
|
770
|
+
container.insertBefore(node, endComment);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
751
773
|
}
|
|
752
774
|
componentStack.pop();
|
|
753
775
|
});
|
|
754
776
|
boundaryCtx.effects.push(dispose);
|
|
755
|
-
return
|
|
777
|
+
return container;
|
|
756
778
|
}
|
|
757
779
|
function createSuspenseBoundary(vnode, parent) {
|
|
758
780
|
const { boundary, fallback, loading } = vnode.props;
|
|
759
781
|
const children = vnode.children;
|
|
760
|
-
const
|
|
761
|
-
|
|
782
|
+
const startComment = document.createComment("sb:start");
|
|
783
|
+
const endComment = document.createComment("sb:end");
|
|
762
784
|
const boundaryCtx = {
|
|
763
785
|
hooks: [],
|
|
764
786
|
hookIndex: 0,
|
|
@@ -766,26 +788,41 @@ function createSuspenseBoundary(vnode, parent) {
|
|
|
766
788
|
cleanups: [],
|
|
767
789
|
mounted: false,
|
|
768
790
|
disposed: false,
|
|
769
|
-
_parentCtx: componentStack[componentStack.length - 1] || null
|
|
791
|
+
_parentCtx: componentStack[componentStack.length - 1] || null,
|
|
792
|
+
_startComment: startComment,
|
|
793
|
+
_endComment: endComment
|
|
770
794
|
};
|
|
771
|
-
|
|
795
|
+
_commentCtxMap.set(startComment, boundaryCtx);
|
|
796
|
+
const container = document.createDocumentFragment();
|
|
797
|
+
container._componentCtx = boundaryCtx;
|
|
798
|
+
container.appendChild(startComment);
|
|
799
|
+
container.appendChild(endComment);
|
|
772
800
|
const dispose = effect(() => {
|
|
773
801
|
const isLoading = loading();
|
|
774
802
|
const vnodes = isLoading ? [fallback] : children;
|
|
775
803
|
const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];
|
|
776
804
|
componentStack.push(boundaryCtx);
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
805
|
+
if (startComment.parentNode) {
|
|
806
|
+
while (startComment.nextSibling && startComment.nextSibling !== endComment) {
|
|
807
|
+
const old = startComment.nextSibling;
|
|
808
|
+
disposeTree(old);
|
|
809
|
+
old.parentNode.removeChild(old);
|
|
810
|
+
}
|
|
780
811
|
}
|
|
781
812
|
for (const v of normalized) {
|
|
782
|
-
const node = createDOM(v,
|
|
783
|
-
if (node)
|
|
813
|
+
const node = createDOM(v, parent);
|
|
814
|
+
if (node) {
|
|
815
|
+
if (endComment.parentNode) {
|
|
816
|
+
endComment.parentNode.insertBefore(node, endComment);
|
|
817
|
+
} else {
|
|
818
|
+
container.insertBefore(node, endComment);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
784
821
|
}
|
|
785
822
|
componentStack.pop();
|
|
786
823
|
});
|
|
787
824
|
boundaryCtx.effects.push(dispose);
|
|
788
|
-
return
|
|
825
|
+
return container;
|
|
789
826
|
}
|
|
790
827
|
function createPortalDOM(vnode, parent) {
|
|
791
828
|
const { container } = vnode.props;
|
|
@@ -1135,6 +1172,12 @@ function sameNodeArray(a, b) {
|
|
|
1135
1172
|
return true;
|
|
1136
1173
|
}
|
|
1137
1174
|
function reconcileInsert(parent, value, current, marker) {
|
|
1175
|
+
if (!parent || typeof parent.insertBefore !== "function") {
|
|
1176
|
+
if (__DEV__) {
|
|
1177
|
+
console.warn("[what] reconcileInsert called with invalid parent:", parent);
|
|
1178
|
+
}
|
|
1179
|
+
return current;
|
|
1180
|
+
}
|
|
1138
1181
|
const targetMarker = marker || null;
|
|
1139
1182
|
if (value == null || typeof value === "boolean") {
|
|
1140
1183
|
const oldNodes2 = asNodeArray(current);
|
|
@@ -1648,6 +1691,12 @@ function spread(el, props) {
|
|
|
1648
1691
|
}
|
|
1649
1692
|
}
|
|
1650
1693
|
function setProp2(el, key, value) {
|
|
1694
|
+
if (key === "ref") {
|
|
1695
|
+
if (typeof value === "function") value(el);
|
|
1696
|
+
else if (value && typeof value === "object") value.current = el;
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
if (key === "key") return;
|
|
1651
1700
|
if (URL_ATTRS.has(key) || URL_ATTRS.has(key.toLowerCase())) {
|
|
1652
1701
|
if (!isSafeUrl(value)) {
|
|
1653
1702
|
if (typeof console !== "undefined") {
|