@fictjs/runtime 0.0.9 → 0.0.11
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.cjs +398 -204
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.dev.js +400 -204
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +398 -204
- package/dist/index.js.map +1 -1
- package/dist/slim.cjs +398 -204
- package/dist/slim.cjs.map +1 -1
- package/dist/slim.d.cts +1 -0
- package/dist/slim.d.ts +1 -0
- package/dist/slim.js +398 -204
- package/dist/slim.js.map +1 -1
- package/package.json +1 -1
- package/src/binding.ts +41 -13
- package/src/dom.ts +16 -6
- package/src/effect.ts +18 -6
- package/src/hooks.ts +14 -1
- package/src/list-helpers.ts +125 -47
- package/src/signal.ts +102 -4
package/dist/index.dev.js
CHANGED
|
@@ -348,6 +348,7 @@ var isInTransition = false;
|
|
|
348
348
|
var enqueueMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
349
349
|
Promise.resolve().then(fn);
|
|
350
350
|
};
|
|
351
|
+
var inCleanup = false;
|
|
351
352
|
function link(dep, sub, version) {
|
|
352
353
|
const prevDep = sub.depsTail;
|
|
353
354
|
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
@@ -593,7 +594,15 @@ function updateComputed(c) {
|
|
|
593
594
|
}
|
|
594
595
|
function runEffect(e) {
|
|
595
596
|
const flags = e.flags;
|
|
596
|
-
if (flags & Dirty
|
|
597
|
+
if (flags & Dirty) {
|
|
598
|
+
if (e.runCleanup) {
|
|
599
|
+
inCleanup = true;
|
|
600
|
+
try {
|
|
601
|
+
e.runCleanup();
|
|
602
|
+
} finally {
|
|
603
|
+
inCleanup = false;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
597
606
|
++cycle;
|
|
598
607
|
effectRunDevtools(e);
|
|
599
608
|
e.depsTail = void 0;
|
|
@@ -610,6 +619,35 @@ function runEffect(e) {
|
|
|
610
619
|
e.flags = Watching;
|
|
611
620
|
throw err;
|
|
612
621
|
}
|
|
622
|
+
} else if (flags & Pending && e.deps) {
|
|
623
|
+
if (e.runCleanup) {
|
|
624
|
+
inCleanup = true;
|
|
625
|
+
try {
|
|
626
|
+
e.runCleanup();
|
|
627
|
+
} finally {
|
|
628
|
+
inCleanup = false;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (checkDirty(e.deps, e)) {
|
|
632
|
+
++cycle;
|
|
633
|
+
effectRunDevtools(e);
|
|
634
|
+
e.depsTail = void 0;
|
|
635
|
+
e.flags = WatchingRunning;
|
|
636
|
+
const prevSub = activeSub;
|
|
637
|
+
activeSub = e;
|
|
638
|
+
try {
|
|
639
|
+
e.fn();
|
|
640
|
+
activeSub = prevSub;
|
|
641
|
+
e.flags = Watching;
|
|
642
|
+
purgeDeps(e);
|
|
643
|
+
} catch (err) {
|
|
644
|
+
activeSub = prevSub;
|
|
645
|
+
e.flags = Watching;
|
|
646
|
+
throw err;
|
|
647
|
+
}
|
|
648
|
+
} else {
|
|
649
|
+
e.flags = Watching;
|
|
650
|
+
}
|
|
613
651
|
} else {
|
|
614
652
|
e.flags = Watching;
|
|
615
653
|
}
|
|
@@ -705,7 +743,7 @@ function signalOper(value) {
|
|
|
705
743
|
return;
|
|
706
744
|
}
|
|
707
745
|
const flags = this.flags;
|
|
708
|
-
if (flags & Dirty) {
|
|
746
|
+
if (flags & Dirty && !inCleanup) {
|
|
709
747
|
if (updateSignal(this)) {
|
|
710
748
|
const subs = this.subs;
|
|
711
749
|
if (subs !== void 0) shallowPropagate(subs);
|
|
@@ -787,6 +825,30 @@ function effect(fn) {
|
|
|
787
825
|
}
|
|
788
826
|
return effectOper.bind(e);
|
|
789
827
|
}
|
|
828
|
+
function effectWithCleanup(fn, cleanupRunner) {
|
|
829
|
+
const e = {
|
|
830
|
+
fn,
|
|
831
|
+
subs: void 0,
|
|
832
|
+
subsTail: void 0,
|
|
833
|
+
deps: void 0,
|
|
834
|
+
depsTail: void 0,
|
|
835
|
+
flags: WatchingRunning,
|
|
836
|
+
runCleanup: cleanupRunner,
|
|
837
|
+
__id: void 0
|
|
838
|
+
};
|
|
839
|
+
registerEffectDevtools(e);
|
|
840
|
+
const prevSub = activeSub;
|
|
841
|
+
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
842
|
+
activeSub = e;
|
|
843
|
+
try {
|
|
844
|
+
effectRunDevtools(e);
|
|
845
|
+
fn();
|
|
846
|
+
} finally {
|
|
847
|
+
activeSub = prevSub;
|
|
848
|
+
e.flags &= ~Running;
|
|
849
|
+
}
|
|
850
|
+
return effectOper.bind(e);
|
|
851
|
+
}
|
|
790
852
|
function effectOper() {
|
|
791
853
|
disposeNode(this);
|
|
792
854
|
}
|
|
@@ -807,10 +869,19 @@ function effectScopeOper() {
|
|
|
807
869
|
}
|
|
808
870
|
function batch(fn) {
|
|
809
871
|
++batchDepth;
|
|
872
|
+
let _error;
|
|
873
|
+
let hasError = false;
|
|
810
874
|
try {
|
|
811
875
|
return fn();
|
|
876
|
+
} catch (e) {
|
|
877
|
+
_error = e;
|
|
878
|
+
hasError = true;
|
|
879
|
+
throw e;
|
|
812
880
|
} finally {
|
|
813
|
-
|
|
881
|
+
--batchDepth;
|
|
882
|
+
if (!hasError && batchDepth === 0) {
|
|
883
|
+
flush();
|
|
884
|
+
}
|
|
814
885
|
}
|
|
815
886
|
}
|
|
816
887
|
function setActiveSub(sub) {
|
|
@@ -866,7 +937,7 @@ function effectRunDevtools(node) {
|
|
|
866
937
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
867
938
|
let current = source();
|
|
868
939
|
const observers = /* @__PURE__ */ new Map();
|
|
869
|
-
effect(() => {
|
|
940
|
+
const dispose = effect(() => {
|
|
870
941
|
const next = source();
|
|
871
942
|
if (equalityFn(current, next)) return;
|
|
872
943
|
const prevSig = observers.get(current);
|
|
@@ -875,6 +946,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
875
946
|
if (nextSig) nextSig(true);
|
|
876
947
|
current = next;
|
|
877
948
|
});
|
|
949
|
+
registerRootCleanup(() => {
|
|
950
|
+
dispose();
|
|
951
|
+
observers.clear();
|
|
952
|
+
});
|
|
878
953
|
return (key) => {
|
|
879
954
|
let sig = observers.get(key);
|
|
880
955
|
if (!sig) {
|
|
@@ -1021,8 +1096,11 @@ var $memo = createMemo;
|
|
|
1021
1096
|
function createEffect(fn) {
|
|
1022
1097
|
let cleanups = [];
|
|
1023
1098
|
const rootForError = getCurrentRoot();
|
|
1024
|
-
const
|
|
1099
|
+
const doCleanup = () => {
|
|
1025
1100
|
runCleanupList(cleanups);
|
|
1101
|
+
cleanups = [];
|
|
1102
|
+
};
|
|
1103
|
+
const run = () => {
|
|
1026
1104
|
const bucket = [];
|
|
1027
1105
|
withEffectCleanups(bucket, () => {
|
|
1028
1106
|
try {
|
|
@@ -1039,7 +1117,7 @@ function createEffect(fn) {
|
|
|
1039
1117
|
});
|
|
1040
1118
|
cleanups = bucket;
|
|
1041
1119
|
};
|
|
1042
|
-
const disposeEffect =
|
|
1120
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1043
1121
|
const teardown = () => {
|
|
1044
1122
|
runCleanupList(cleanups);
|
|
1045
1123
|
disposeEffect();
|
|
@@ -1051,24 +1129,27 @@ var $effect = createEffect;
|
|
|
1051
1129
|
function createRenderEffect(fn) {
|
|
1052
1130
|
let cleanup;
|
|
1053
1131
|
const rootForError = getCurrentRoot();
|
|
1054
|
-
const
|
|
1132
|
+
const doCleanup = () => {
|
|
1055
1133
|
if (cleanup) {
|
|
1056
1134
|
cleanup();
|
|
1057
1135
|
cleanup = void 0;
|
|
1058
1136
|
}
|
|
1137
|
+
};
|
|
1138
|
+
const run = () => {
|
|
1059
1139
|
try {
|
|
1060
1140
|
const maybeCleanup = fn();
|
|
1061
1141
|
if (typeof maybeCleanup === "function") {
|
|
1062
1142
|
cleanup = maybeCleanup;
|
|
1063
1143
|
}
|
|
1064
1144
|
} catch (err) {
|
|
1065
|
-
|
|
1145
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1146
|
+
if (handled) {
|
|
1066
1147
|
return;
|
|
1067
1148
|
}
|
|
1068
1149
|
throw err;
|
|
1069
1150
|
}
|
|
1070
1151
|
};
|
|
1071
|
-
const disposeEffect =
|
|
1152
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1072
1153
|
const teardown = () => {
|
|
1073
1154
|
if (cleanup) {
|
|
1074
1155
|
cleanup();
|
|
@@ -1454,159 +1535,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1454
1535
|
// src/jsx.ts
|
|
1455
1536
|
var Fragment = Symbol("Fragment");
|
|
1456
1537
|
|
|
1457
|
-
// src/node-ops.ts
|
|
1458
|
-
function toNodeArray(node) {
|
|
1459
|
-
try {
|
|
1460
|
-
if (Array.isArray(node)) {
|
|
1461
|
-
let allNodes = true;
|
|
1462
|
-
for (const item of node) {
|
|
1463
|
-
let isItemNode = false;
|
|
1464
|
-
try {
|
|
1465
|
-
isItemNode = item instanceof Node;
|
|
1466
|
-
} catch {
|
|
1467
|
-
isItemNode = false;
|
|
1468
|
-
}
|
|
1469
|
-
if (!isItemNode) {
|
|
1470
|
-
allNodes = false;
|
|
1471
|
-
break;
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
if (allNodes) {
|
|
1475
|
-
return node;
|
|
1476
|
-
}
|
|
1477
|
-
const result = [];
|
|
1478
|
-
for (const item of node) {
|
|
1479
|
-
result.push(...toNodeArray(item));
|
|
1480
|
-
}
|
|
1481
|
-
return result;
|
|
1482
|
-
}
|
|
1483
|
-
if (node === null || node === void 0 || node === false) {
|
|
1484
|
-
return [];
|
|
1485
|
-
}
|
|
1486
|
-
} catch {
|
|
1487
|
-
return [];
|
|
1488
|
-
}
|
|
1489
|
-
let isNode = false;
|
|
1490
|
-
try {
|
|
1491
|
-
isNode = node instanceof Node;
|
|
1492
|
-
} catch {
|
|
1493
|
-
isNode = false;
|
|
1494
|
-
}
|
|
1495
|
-
if (isNode) {
|
|
1496
|
-
try {
|
|
1497
|
-
if (node instanceof DocumentFragment) {
|
|
1498
|
-
return Array.from(node.childNodes);
|
|
1499
|
-
}
|
|
1500
|
-
} catch {
|
|
1501
|
-
}
|
|
1502
|
-
return [node];
|
|
1503
|
-
}
|
|
1504
|
-
try {
|
|
1505
|
-
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
1506
|
-
return toNodeArray(node.marker);
|
|
1507
|
-
}
|
|
1508
|
-
} catch {
|
|
1509
|
-
}
|
|
1510
|
-
try {
|
|
1511
|
-
return [document.createTextNode(String(node))];
|
|
1512
|
-
} catch {
|
|
1513
|
-
return [document.createTextNode("")];
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
function insertNodesBefore(parent, nodes, anchor) {
|
|
1517
|
-
if (nodes.length === 0) return;
|
|
1518
|
-
if (nodes.length === 1) {
|
|
1519
|
-
const node = nodes[0];
|
|
1520
|
-
if (node === void 0 || node === null) return;
|
|
1521
|
-
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1522
|
-
parent.ownerDocument.adoptNode(node);
|
|
1523
|
-
}
|
|
1524
|
-
try {
|
|
1525
|
-
parent.insertBefore(node, anchor);
|
|
1526
|
-
} catch (e) {
|
|
1527
|
-
if (parent.ownerDocument) {
|
|
1528
|
-
try {
|
|
1529
|
-
const clone = parent.ownerDocument.importNode(node, true);
|
|
1530
|
-
parent.insertBefore(clone, anchor);
|
|
1531
|
-
return;
|
|
1532
|
-
} catch {
|
|
1533
|
-
}
|
|
1534
|
-
}
|
|
1535
|
-
throw e;
|
|
1536
|
-
}
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
|
-
const doc = parent.ownerDocument;
|
|
1540
|
-
if (doc) {
|
|
1541
|
-
const frag = doc.createDocumentFragment();
|
|
1542
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
1543
|
-
const node = nodes[i];
|
|
1544
|
-
if (node === void 0 || node === null) continue;
|
|
1545
|
-
if (node.nodeType === 11) {
|
|
1546
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1547
|
-
for (let j = 0; j < childrenArr.length; j++) {
|
|
1548
|
-
frag.appendChild(childrenArr[j]);
|
|
1549
|
-
}
|
|
1550
|
-
} else {
|
|
1551
|
-
if (node.ownerDocument !== doc) {
|
|
1552
|
-
doc.adoptNode(node);
|
|
1553
|
-
}
|
|
1554
|
-
frag.appendChild(node);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
parent.insertBefore(frag, anchor);
|
|
1558
|
-
return;
|
|
1559
|
-
}
|
|
1560
|
-
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
1561
|
-
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1562
|
-
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
1563
|
-
}
|
|
1564
|
-
try {
|
|
1565
|
-
parent.insertBefore(nodeToInsert, anchorNode);
|
|
1566
|
-
return nodeToInsert;
|
|
1567
|
-
} catch (e) {
|
|
1568
|
-
if (parent.ownerDocument) {
|
|
1569
|
-
try {
|
|
1570
|
-
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
1571
|
-
parent.insertBefore(clone, anchorNode);
|
|
1572
|
-
return clone;
|
|
1573
|
-
} catch {
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
throw e;
|
|
1577
|
-
}
|
|
1578
|
-
};
|
|
1579
|
-
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
1580
|
-
const node = nodes[i];
|
|
1581
|
-
if (node === void 0 || node === null) continue;
|
|
1582
|
-
const isFrag = node.nodeType === 11;
|
|
1583
|
-
if (isFrag) {
|
|
1584
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1585
|
-
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
1586
|
-
const child = childrenArr[j];
|
|
1587
|
-
anchor = insertSingle(child, anchor);
|
|
1588
|
-
}
|
|
1589
|
-
} else {
|
|
1590
|
-
anchor = insertSingle(node, anchor);
|
|
1591
|
-
}
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
function removeNodes(nodes) {
|
|
1595
|
-
for (const node of nodes) {
|
|
1596
|
-
node.parentNode?.removeChild(node);
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
1538
|
// src/hooks.ts
|
|
1601
1539
|
var ctxStack = [];
|
|
1540
|
+
function assertRenderContext(ctx, hookName) {
|
|
1541
|
+
if (!ctx.rendering) {
|
|
1542
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1602
1545
|
function __fictUseContext() {
|
|
1603
1546
|
if (ctxStack.length === 0) {
|
|
1604
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1547
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1605
1548
|
ctxStack.push(ctx2);
|
|
1606
1549
|
return ctx2;
|
|
1607
1550
|
}
|
|
1608
1551
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1609
1552
|
ctx.cursor = 0;
|
|
1553
|
+
ctx.rendering = true;
|
|
1610
1554
|
return ctx;
|
|
1611
1555
|
}
|
|
1612
1556
|
function __fictPushContext() {
|
|
@@ -1621,6 +1565,7 @@ function __fictResetContext() {
|
|
|
1621
1565
|
ctxStack.length = 0;
|
|
1622
1566
|
}
|
|
1623
1567
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1568
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1624
1569
|
const index = slot ?? ctx.cursor++;
|
|
1625
1570
|
if (!ctx.slots[index]) {
|
|
1626
1571
|
ctx.slots[index] = signal(initial);
|
|
@@ -1628,6 +1573,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1628
1573
|
return ctx.slots[index];
|
|
1629
1574
|
}
|
|
1630
1575
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1576
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1631
1577
|
const index = slot ?? ctx.cursor++;
|
|
1632
1578
|
if (!ctx.slots[index]) {
|
|
1633
1579
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1635,6 +1581,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1635
1581
|
return ctx.slots[index];
|
|
1636
1582
|
}
|
|
1637
1583
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1584
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1638
1585
|
const index = slot ?? ctx.cursor++;
|
|
1639
1586
|
if (!ctx.slots[index]) {
|
|
1640
1587
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1643,9 +1590,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1643
1590
|
function __fictRender(ctx, fn) {
|
|
1644
1591
|
ctxStack.push(ctx);
|
|
1645
1592
|
ctx.cursor = 0;
|
|
1593
|
+
ctx.rendering = true;
|
|
1646
1594
|
try {
|
|
1647
1595
|
return fn();
|
|
1648
1596
|
} finally {
|
|
1597
|
+
ctx.rendering = false;
|
|
1649
1598
|
ctxStack.pop();
|
|
1650
1599
|
}
|
|
1651
1600
|
}
|
|
@@ -1886,6 +1835,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1886
1835
|
if (typeof handle.dispose === "function") {
|
|
1887
1836
|
registerRootCleanup(handle.dispose);
|
|
1888
1837
|
}
|
|
1838
|
+
if (typeof handle.flush === "function") {
|
|
1839
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1840
|
+
if (typeof queueMicrotask === "function") {
|
|
1841
|
+
queueMicrotask(runFlush);
|
|
1842
|
+
} else {
|
|
1843
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1889
1846
|
return createElement(handle.marker);
|
|
1890
1847
|
}
|
|
1891
1848
|
const nodeRecord = node;
|
|
@@ -1933,18 +1890,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1933
1890
|
}
|
|
1934
1891
|
});
|
|
1935
1892
|
const props = createPropsProxy(baseProps);
|
|
1893
|
+
__fictPushContext();
|
|
1936
1894
|
try {
|
|
1937
|
-
__fictPushContext();
|
|
1938
1895
|
const rendered = vnode.type(props);
|
|
1939
|
-
__fictPopContext();
|
|
1940
1896
|
return createElementWithContext(rendered, namespace);
|
|
1941
1897
|
} catch (err) {
|
|
1942
|
-
__fictPopContext();
|
|
1943
1898
|
if (handleSuspend(err)) {
|
|
1944
1899
|
return document.createComment("fict:suspend");
|
|
1945
1900
|
}
|
|
1946
1901
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1947
1902
|
throw err;
|
|
1903
|
+
} finally {
|
|
1904
|
+
__fictPopContext();
|
|
1948
1905
|
}
|
|
1949
1906
|
}
|
|
1950
1907
|
if (vnode.type === Fragment) {
|
|
@@ -2240,6 +2197,149 @@ function eventNameFromProp(key) {
|
|
|
2240
2197
|
return key.slice(2).toLowerCase();
|
|
2241
2198
|
}
|
|
2242
2199
|
|
|
2200
|
+
// src/node-ops.ts
|
|
2201
|
+
function toNodeArray(node) {
|
|
2202
|
+
try {
|
|
2203
|
+
if (Array.isArray(node)) {
|
|
2204
|
+
let allNodes = true;
|
|
2205
|
+
for (const item of node) {
|
|
2206
|
+
let isItemNode = false;
|
|
2207
|
+
try {
|
|
2208
|
+
isItemNode = item instanceof Node;
|
|
2209
|
+
} catch {
|
|
2210
|
+
isItemNode = false;
|
|
2211
|
+
}
|
|
2212
|
+
if (!isItemNode) {
|
|
2213
|
+
allNodes = false;
|
|
2214
|
+
break;
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
if (allNodes) {
|
|
2218
|
+
return node;
|
|
2219
|
+
}
|
|
2220
|
+
const result = [];
|
|
2221
|
+
for (const item of node) {
|
|
2222
|
+
result.push(...toNodeArray(item));
|
|
2223
|
+
}
|
|
2224
|
+
return result;
|
|
2225
|
+
}
|
|
2226
|
+
if (node === null || node === void 0 || node === false) {
|
|
2227
|
+
return [];
|
|
2228
|
+
}
|
|
2229
|
+
} catch {
|
|
2230
|
+
return [];
|
|
2231
|
+
}
|
|
2232
|
+
let isNode = false;
|
|
2233
|
+
try {
|
|
2234
|
+
isNode = node instanceof Node;
|
|
2235
|
+
} catch {
|
|
2236
|
+
isNode = false;
|
|
2237
|
+
}
|
|
2238
|
+
if (isNode) {
|
|
2239
|
+
try {
|
|
2240
|
+
if (node instanceof DocumentFragment) {
|
|
2241
|
+
return Array.from(node.childNodes);
|
|
2242
|
+
}
|
|
2243
|
+
} catch {
|
|
2244
|
+
}
|
|
2245
|
+
return [node];
|
|
2246
|
+
}
|
|
2247
|
+
try {
|
|
2248
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
2249
|
+
return toNodeArray(node.marker);
|
|
2250
|
+
}
|
|
2251
|
+
} catch {
|
|
2252
|
+
}
|
|
2253
|
+
try {
|
|
2254
|
+
return [document.createTextNode(String(node))];
|
|
2255
|
+
} catch {
|
|
2256
|
+
return [document.createTextNode("")];
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
2260
|
+
if (nodes.length === 0) return;
|
|
2261
|
+
if (nodes.length === 1) {
|
|
2262
|
+
const node = nodes[0];
|
|
2263
|
+
if (node === void 0 || node === null) return;
|
|
2264
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2265
|
+
parent.ownerDocument.adoptNode(node);
|
|
2266
|
+
}
|
|
2267
|
+
try {
|
|
2268
|
+
parent.insertBefore(node, anchor);
|
|
2269
|
+
} catch (e) {
|
|
2270
|
+
if (parent.ownerDocument) {
|
|
2271
|
+
try {
|
|
2272
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
2273
|
+
parent.insertBefore(clone, anchor);
|
|
2274
|
+
return;
|
|
2275
|
+
} catch {
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
throw e;
|
|
2279
|
+
}
|
|
2280
|
+
return;
|
|
2281
|
+
}
|
|
2282
|
+
const doc = parent.ownerDocument;
|
|
2283
|
+
if (doc) {
|
|
2284
|
+
const frag = doc.createDocumentFragment();
|
|
2285
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2286
|
+
const node = nodes[i];
|
|
2287
|
+
if (node === void 0 || node === null) continue;
|
|
2288
|
+
if (node.nodeType === 11) {
|
|
2289
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2290
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2291
|
+
frag.appendChild(childrenArr[j]);
|
|
2292
|
+
}
|
|
2293
|
+
} else {
|
|
2294
|
+
if (node.ownerDocument !== doc) {
|
|
2295
|
+
doc.adoptNode(node);
|
|
2296
|
+
}
|
|
2297
|
+
frag.appendChild(node);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
parent.insertBefore(frag, anchor);
|
|
2301
|
+
return;
|
|
2302
|
+
}
|
|
2303
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2304
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2305
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2306
|
+
}
|
|
2307
|
+
try {
|
|
2308
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2309
|
+
return nodeToInsert;
|
|
2310
|
+
} catch (e) {
|
|
2311
|
+
if (parent.ownerDocument) {
|
|
2312
|
+
try {
|
|
2313
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2314
|
+
parent.insertBefore(clone, anchorNode);
|
|
2315
|
+
return clone;
|
|
2316
|
+
} catch {
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
throw e;
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2322
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2323
|
+
const node = nodes[i];
|
|
2324
|
+
if (node === void 0 || node === null) continue;
|
|
2325
|
+
const isFrag = node.nodeType === 11;
|
|
2326
|
+
if (isFrag) {
|
|
2327
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2328
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2329
|
+
const child = childrenArr[j];
|
|
2330
|
+
anchor = insertSingle(child, anchor);
|
|
2331
|
+
}
|
|
2332
|
+
} else {
|
|
2333
|
+
anchor = insertSingle(node, anchor);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
function removeNodes(nodes) {
|
|
2338
|
+
for (const node of nodes) {
|
|
2339
|
+
node.parentNode?.removeChild(node);
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2243
2343
|
// src/reconcile.ts
|
|
2244
2344
|
function reconcileArrays(parentNode, a, b) {
|
|
2245
2345
|
const bLength = b.length;
|
|
@@ -2467,7 +2567,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2467
2567
|
} finally {
|
|
2468
2568
|
setActiveSub(prevSub);
|
|
2469
2569
|
popRoot(prevRoot);
|
|
2470
|
-
flushOnMount(root);
|
|
2471
2570
|
}
|
|
2472
2571
|
return {
|
|
2473
2572
|
key,
|
|
@@ -2499,13 +2598,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2499
2598
|
const hostRoot = getCurrentRoot();
|
|
2500
2599
|
const fragment = document.createDocumentFragment();
|
|
2501
2600
|
fragment.append(container.startMarker, container.endMarker);
|
|
2502
|
-
let pendingItems = null;
|
|
2503
2601
|
let disposed = false;
|
|
2602
|
+
let effectDispose;
|
|
2603
|
+
let connectObserver = null;
|
|
2604
|
+
let effectStarted = false;
|
|
2605
|
+
let startScheduled = false;
|
|
2606
|
+
const getConnectedParent = () => {
|
|
2607
|
+
const endParent = container.endMarker.parentNode;
|
|
2608
|
+
const startParent = container.startMarker.parentNode;
|
|
2609
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2610
|
+
return endParent;
|
|
2611
|
+
}
|
|
2612
|
+
return null;
|
|
2613
|
+
};
|
|
2504
2614
|
const performDiff = () => {
|
|
2505
2615
|
if (disposed) return;
|
|
2616
|
+
const parent = getConnectedParent();
|
|
2617
|
+
if (!parent) return;
|
|
2506
2618
|
batch2(() => {
|
|
2507
|
-
const newItems = pendingItems || getItems();
|
|
2508
|
-
pendingItems = null;
|
|
2509
2619
|
const oldBlocks = container.blocks;
|
|
2510
2620
|
const newBlocks = container.nextBlocks;
|
|
2511
2621
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2514,20 +2624,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2514
2624
|
newBlocks.clear();
|
|
2515
2625
|
nextOrderedBlocks.length = 0;
|
|
2516
2626
|
orderedIndexByKey.clear();
|
|
2517
|
-
const
|
|
2518
|
-
const
|
|
2519
|
-
const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
|
|
2520
|
-
if (!parent) {
|
|
2521
|
-
pendingItems = newItems;
|
|
2522
|
-
queueMicrotask(performDiff);
|
|
2523
|
-
return;
|
|
2524
|
-
}
|
|
2627
|
+
const createdBlocks = [];
|
|
2628
|
+
const newItems = getItems();
|
|
2525
2629
|
if (newItems.length === 0) {
|
|
2526
2630
|
if (oldBlocks.size > 0) {
|
|
2527
2631
|
for (const block of oldBlocks.values()) {
|
|
2528
2632
|
destroyRoot(block.root);
|
|
2529
|
-
removeNodes(block.nodes);
|
|
2530
2633
|
}
|
|
2634
|
+
const range = document.createRange();
|
|
2635
|
+
range.setStartAfter(container.startMarker);
|
|
2636
|
+
range.setEndBefore(container.endMarker);
|
|
2637
|
+
range.deleteContents();
|
|
2531
2638
|
}
|
|
2532
2639
|
oldBlocks.clear();
|
|
2533
2640
|
newBlocks.clear();
|
|
@@ -2544,8 +2651,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2544
2651
|
const appendedBlocks = [];
|
|
2545
2652
|
newItems.forEach((item, index) => {
|
|
2546
2653
|
const key = keyFn(item, index);
|
|
2547
|
-
const existed = oldBlocks.has(key);
|
|
2548
2654
|
let block = oldBlocks.get(key);
|
|
2655
|
+
const existed = block !== void 0;
|
|
2549
2656
|
if (block) {
|
|
2550
2657
|
if (block.rawItem !== item) {
|
|
2551
2658
|
block.rawItem = item;
|
|
@@ -2556,38 +2663,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2556
2663
|
block.index(index);
|
|
2557
2664
|
}
|
|
2558
2665
|
}
|
|
2559
|
-
const existingBlock = newBlocks.get(key);
|
|
2560
|
-
if (existingBlock && existingBlock !== block) {
|
|
2561
|
-
destroyRoot(existingBlock.root);
|
|
2562
|
-
removeNodes(existingBlock.nodes);
|
|
2563
|
-
}
|
|
2564
2666
|
if (block) {
|
|
2565
2667
|
newBlocks.set(key, block);
|
|
2566
2668
|
oldBlocks.delete(key);
|
|
2567
2669
|
} else {
|
|
2568
|
-
const
|
|
2569
|
-
if (
|
|
2570
|
-
destroyRoot(
|
|
2571
|
-
removeNodes(
|
|
2670
|
+
const existingBlock = newBlocks.get(key);
|
|
2671
|
+
if (existingBlock) {
|
|
2672
|
+
destroyRoot(existingBlock.root);
|
|
2673
|
+
removeNodes(existingBlock.nodes);
|
|
2572
2674
|
}
|
|
2573
2675
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2676
|
+
createdBlocks.push(block);
|
|
2574
2677
|
}
|
|
2575
2678
|
const resolvedBlock = block;
|
|
2576
2679
|
newBlocks.set(key, resolvedBlock);
|
|
2577
2680
|
const position = orderedIndexByKey.get(key);
|
|
2578
2681
|
if (position !== void 0) {
|
|
2579
2682
|
appendCandidate = false;
|
|
2580
|
-
}
|
|
2581
|
-
if (appendCandidate) {
|
|
2582
|
-
if (index < prevCount) {
|
|
2583
|
-
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2584
|
-
appendCandidate = false;
|
|
2585
|
-
}
|
|
2586
|
-
} else if (existed) {
|
|
2587
|
-
appendCandidate = false;
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
if (position !== void 0) {
|
|
2591
2683
|
const prior = nextOrderedBlocks[position];
|
|
2592
2684
|
if (prior && prior !== resolvedBlock) {
|
|
2593
2685
|
destroyRoot(prior.root);
|
|
@@ -2595,6 +2687,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2595
2687
|
}
|
|
2596
2688
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2597
2689
|
} else {
|
|
2690
|
+
if (appendCandidate) {
|
|
2691
|
+
if (index < prevCount) {
|
|
2692
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2693
|
+
appendCandidate = false;
|
|
2694
|
+
}
|
|
2695
|
+
} else if (existed) {
|
|
2696
|
+
appendCandidate = false;
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2598
2699
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2599
2700
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2600
2701
|
}
|
|
@@ -2623,6 +2724,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2623
2724
|
container.nextBlocks = oldBlocks;
|
|
2624
2725
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2625
2726
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2727
|
+
for (const block of createdBlocks) {
|
|
2728
|
+
if (newBlocks.get(block.key) === block) {
|
|
2729
|
+
flushOnMount(block.root);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2626
2732
|
return;
|
|
2627
2733
|
}
|
|
2628
2734
|
if (oldBlocks.size > 0) {
|
|
@@ -2652,22 +2758,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2652
2758
|
container.nextBlocks = oldBlocks;
|
|
2653
2759
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2654
2760
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2761
|
+
for (const block of createdBlocks) {
|
|
2762
|
+
if (newBlocks.get(block.key) === block) {
|
|
2763
|
+
flushOnMount(block.root);
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2655
2766
|
});
|
|
2656
2767
|
};
|
|
2657
|
-
const
|
|
2768
|
+
const disconnectObserver = () => {
|
|
2769
|
+
connectObserver?.disconnect();
|
|
2770
|
+
connectObserver = null;
|
|
2771
|
+
};
|
|
2772
|
+
const ensureEffectStarted = () => {
|
|
2773
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2774
|
+
const parent = getConnectedParent();
|
|
2775
|
+
if (!parent) return false;
|
|
2776
|
+
const start = () => {
|
|
2777
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2778
|
+
effectStarted = true;
|
|
2779
|
+
};
|
|
2780
|
+
if (hostRoot) {
|
|
2781
|
+
const prev = pushRoot(hostRoot);
|
|
2782
|
+
try {
|
|
2783
|
+
start();
|
|
2784
|
+
} finally {
|
|
2785
|
+
popRoot(prev);
|
|
2786
|
+
}
|
|
2787
|
+
} else {
|
|
2788
|
+
start();
|
|
2789
|
+
}
|
|
2790
|
+
return true;
|
|
2791
|
+
};
|
|
2792
|
+
const waitForConnection = () => {
|
|
2793
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2794
|
+
connectObserver = new MutationObserver(() => {
|
|
2795
|
+
if (disposed) return;
|
|
2796
|
+
if (getConnectedParent()) {
|
|
2797
|
+
disconnectObserver();
|
|
2798
|
+
if (ensureEffectStarted()) {
|
|
2799
|
+
flush();
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
});
|
|
2803
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2804
|
+
};
|
|
2805
|
+
const scheduleStart = () => {
|
|
2806
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2807
|
+
startScheduled = true;
|
|
2808
|
+
const run = () => {
|
|
2809
|
+
startScheduled = false;
|
|
2810
|
+
if (!ensureEffectStarted()) {
|
|
2811
|
+
waitForConnection();
|
|
2812
|
+
}
|
|
2813
|
+
};
|
|
2814
|
+
if (typeof queueMicrotask === "function") {
|
|
2815
|
+
queueMicrotask(run);
|
|
2816
|
+
} else {
|
|
2817
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
scheduleStart();
|
|
2658
2821
|
return {
|
|
2659
|
-
marker
|
|
2822
|
+
get marker() {
|
|
2823
|
+
scheduleStart();
|
|
2824
|
+
return fragment;
|
|
2825
|
+
},
|
|
2660
2826
|
startMarker: container.startMarker,
|
|
2661
2827
|
endMarker: container.endMarker,
|
|
2662
2828
|
// Flush pending items - call after markers are inserted into DOM
|
|
2663
2829
|
flush: () => {
|
|
2664
|
-
if (
|
|
2665
|
-
|
|
2830
|
+
if (disposed) return;
|
|
2831
|
+
scheduleStart();
|
|
2832
|
+
if (ensureEffectStarted()) {
|
|
2833
|
+
flush();
|
|
2834
|
+
} else {
|
|
2835
|
+
waitForConnection();
|
|
2666
2836
|
}
|
|
2667
2837
|
},
|
|
2668
2838
|
dispose: () => {
|
|
2669
2839
|
disposed = true;
|
|
2670
2840
|
effectDispose?.();
|
|
2841
|
+
disconnectObserver();
|
|
2671
2842
|
container.dispose();
|
|
2672
2843
|
}
|
|
2673
2844
|
};
|
|
@@ -2870,8 +3041,17 @@ function createClassBinding(el, value) {
|
|
|
2870
3041
|
}
|
|
2871
3042
|
function bindClass(el, getValue) {
|
|
2872
3043
|
let prev = {};
|
|
3044
|
+
let prevString;
|
|
2873
3045
|
return createRenderEffect(() => {
|
|
2874
3046
|
const next = getValue();
|
|
3047
|
+
if (typeof next === "string") {
|
|
3048
|
+
if (next === prevString) return;
|
|
3049
|
+
prevString = next;
|
|
3050
|
+
el.className = next;
|
|
3051
|
+
prev = {};
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
prevString = void 0;
|
|
2875
3055
|
prev = applyClass(el, next, prev);
|
|
2876
3056
|
});
|
|
2877
3057
|
}
|
|
@@ -3100,11 +3280,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
3100
3280
|
}
|
|
3101
3281
|
}
|
|
3102
3282
|
function globalEventHandler(e) {
|
|
3103
|
-
|
|
3283
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
3284
|
+
const asElement = (value) => {
|
|
3285
|
+
const n = asNode(value);
|
|
3286
|
+
if (!n) return null;
|
|
3287
|
+
if (n.nodeType === 1) return n;
|
|
3288
|
+
return n.parentElement;
|
|
3289
|
+
};
|
|
3290
|
+
let node = asElement(e.target);
|
|
3104
3291
|
const key = `$$${e.type}`;
|
|
3105
3292
|
const dataKey = `${key}Data`;
|
|
3106
3293
|
const oriTarget = e.target;
|
|
3107
3294
|
const oriCurrentTarget = e.currentTarget;
|
|
3295
|
+
let lastHandled = null;
|
|
3108
3296
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
3109
3297
|
configurable: true,
|
|
3110
3298
|
value
|
|
@@ -3127,23 +3315,28 @@ function globalEventHandler(e) {
|
|
|
3127
3315
|
const rawData = node[dataKey];
|
|
3128
3316
|
const hasData = rawData !== void 0;
|
|
3129
3317
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3318
|
+
batch2(() => {
|
|
3319
|
+
if (typeof handler === "function") {
|
|
3320
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
3321
|
+
} else if (Array.isArray(handler)) {
|
|
3322
|
+
const tupleData = resolveData(handler[1]);
|
|
3323
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
3324
|
+
}
|
|
3325
|
+
});
|
|
3136
3326
|
if (e.cancelBubble) return false;
|
|
3137
3327
|
}
|
|
3138
3328
|
const shadowHost = node.host;
|
|
3139
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3329
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3330
|
+
const targetNode = asNode(e.target);
|
|
3331
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3332
|
+
})()) {
|
|
3140
3333
|
retarget(shadowHost);
|
|
3141
3334
|
}
|
|
3142
3335
|
return true;
|
|
3143
3336
|
};
|
|
3144
3337
|
const walkUpTree = () => {
|
|
3145
3338
|
while (handleNode() && node) {
|
|
3146
|
-
node = node._$host || node.parentNode || node.host;
|
|
3339
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
3147
3340
|
}
|
|
3148
3341
|
};
|
|
3149
3342
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -3156,8 +3349,11 @@ function globalEventHandler(e) {
|
|
|
3156
3349
|
const path = e.composedPath();
|
|
3157
3350
|
retarget(path[0]);
|
|
3158
3351
|
for (let i = 0; i < path.length - 2; i++) {
|
|
3159
|
-
|
|
3352
|
+
const nextNode = asElement(path[i]);
|
|
3353
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3354
|
+
node = nextNode;
|
|
3160
3355
|
if (!handleNode()) break;
|
|
3356
|
+
lastHandled = node;
|
|
3161
3357
|
if (node._$host) {
|
|
3162
3358
|
node = node._$host;
|
|
3163
3359
|
walkUpTree();
|