@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.cjs
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,17 @@ function effectScopeOper() {
|
|
|
807
869
|
}
|
|
808
870
|
function batch(fn) {
|
|
809
871
|
++batchDepth;
|
|
872
|
+
let hasError = false;
|
|
810
873
|
try {
|
|
811
874
|
return fn();
|
|
875
|
+
} catch (e) {
|
|
876
|
+
hasError = true;
|
|
877
|
+
throw e;
|
|
812
878
|
} finally {
|
|
813
|
-
|
|
879
|
+
--batchDepth;
|
|
880
|
+
if (!hasError && batchDepth === 0) {
|
|
881
|
+
flush();
|
|
882
|
+
}
|
|
814
883
|
}
|
|
815
884
|
}
|
|
816
885
|
function setActiveSub(sub) {
|
|
@@ -866,7 +935,7 @@ function effectRunDevtools(node) {
|
|
|
866
935
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
867
936
|
let current = source();
|
|
868
937
|
const observers = /* @__PURE__ */ new Map();
|
|
869
|
-
effect(() => {
|
|
938
|
+
const dispose = effect(() => {
|
|
870
939
|
const next = source();
|
|
871
940
|
if (equalityFn(current, next)) return;
|
|
872
941
|
const prevSig = observers.get(current);
|
|
@@ -875,6 +944,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
875
944
|
if (nextSig) nextSig(true);
|
|
876
945
|
current = next;
|
|
877
946
|
});
|
|
947
|
+
registerRootCleanup(() => {
|
|
948
|
+
dispose();
|
|
949
|
+
observers.clear();
|
|
950
|
+
});
|
|
878
951
|
return (key) => {
|
|
879
952
|
let sig = observers.get(key);
|
|
880
953
|
if (!sig) {
|
|
@@ -1021,8 +1094,11 @@ var $memo = createMemo;
|
|
|
1021
1094
|
function createEffect(fn) {
|
|
1022
1095
|
let cleanups = [];
|
|
1023
1096
|
const rootForError = getCurrentRoot();
|
|
1024
|
-
const
|
|
1097
|
+
const doCleanup = () => {
|
|
1025
1098
|
runCleanupList(cleanups);
|
|
1099
|
+
cleanups = [];
|
|
1100
|
+
};
|
|
1101
|
+
const run = () => {
|
|
1026
1102
|
const bucket = [];
|
|
1027
1103
|
withEffectCleanups(bucket, () => {
|
|
1028
1104
|
try {
|
|
@@ -1039,7 +1115,7 @@ function createEffect(fn) {
|
|
|
1039
1115
|
});
|
|
1040
1116
|
cleanups = bucket;
|
|
1041
1117
|
};
|
|
1042
|
-
const disposeEffect =
|
|
1118
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1043
1119
|
const teardown = () => {
|
|
1044
1120
|
runCleanupList(cleanups);
|
|
1045
1121
|
disposeEffect();
|
|
@@ -1051,24 +1127,27 @@ var $effect = createEffect;
|
|
|
1051
1127
|
function createRenderEffect(fn) {
|
|
1052
1128
|
let cleanup;
|
|
1053
1129
|
const rootForError = getCurrentRoot();
|
|
1054
|
-
const
|
|
1130
|
+
const doCleanup = () => {
|
|
1055
1131
|
if (cleanup) {
|
|
1056
1132
|
cleanup();
|
|
1057
1133
|
cleanup = void 0;
|
|
1058
1134
|
}
|
|
1135
|
+
};
|
|
1136
|
+
const run = () => {
|
|
1059
1137
|
try {
|
|
1060
1138
|
const maybeCleanup = fn();
|
|
1061
1139
|
if (typeof maybeCleanup === "function") {
|
|
1062
1140
|
cleanup = maybeCleanup;
|
|
1063
1141
|
}
|
|
1064
1142
|
} catch (err) {
|
|
1065
|
-
|
|
1143
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1144
|
+
if (handled) {
|
|
1066
1145
|
return;
|
|
1067
1146
|
}
|
|
1068
1147
|
throw err;
|
|
1069
1148
|
}
|
|
1070
1149
|
};
|
|
1071
|
-
const disposeEffect =
|
|
1150
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1072
1151
|
const teardown = () => {
|
|
1073
1152
|
if (cleanup) {
|
|
1074
1153
|
cleanup();
|
|
@@ -1454,159 +1533,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1454
1533
|
// src/jsx.ts
|
|
1455
1534
|
var Fragment = Symbol("Fragment");
|
|
1456
1535
|
|
|
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
1536
|
// src/hooks.ts
|
|
1601
1537
|
var ctxStack = [];
|
|
1538
|
+
function assertRenderContext(ctx, hookName) {
|
|
1539
|
+
if (!ctx.rendering) {
|
|
1540
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1602
1543
|
function __fictUseContext() {
|
|
1603
1544
|
if (ctxStack.length === 0) {
|
|
1604
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1545
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1605
1546
|
ctxStack.push(ctx2);
|
|
1606
1547
|
return ctx2;
|
|
1607
1548
|
}
|
|
1608
1549
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1609
1550
|
ctx.cursor = 0;
|
|
1551
|
+
ctx.rendering = true;
|
|
1610
1552
|
return ctx;
|
|
1611
1553
|
}
|
|
1612
1554
|
function __fictPushContext() {
|
|
@@ -1621,6 +1563,7 @@ function __fictResetContext() {
|
|
|
1621
1563
|
ctxStack.length = 0;
|
|
1622
1564
|
}
|
|
1623
1565
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1566
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1624
1567
|
const index = slot ?? ctx.cursor++;
|
|
1625
1568
|
if (!ctx.slots[index]) {
|
|
1626
1569
|
ctx.slots[index] = signal(initial);
|
|
@@ -1628,6 +1571,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1628
1571
|
return ctx.slots[index];
|
|
1629
1572
|
}
|
|
1630
1573
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1574
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1631
1575
|
const index = slot ?? ctx.cursor++;
|
|
1632
1576
|
if (!ctx.slots[index]) {
|
|
1633
1577
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1635,6 +1579,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1635
1579
|
return ctx.slots[index];
|
|
1636
1580
|
}
|
|
1637
1581
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1582
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1638
1583
|
const index = slot ?? ctx.cursor++;
|
|
1639
1584
|
if (!ctx.slots[index]) {
|
|
1640
1585
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1643,9 +1588,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1643
1588
|
function __fictRender(ctx, fn) {
|
|
1644
1589
|
ctxStack.push(ctx);
|
|
1645
1590
|
ctx.cursor = 0;
|
|
1591
|
+
ctx.rendering = true;
|
|
1646
1592
|
try {
|
|
1647
1593
|
return fn();
|
|
1648
1594
|
} finally {
|
|
1595
|
+
ctx.rendering = false;
|
|
1649
1596
|
ctxStack.pop();
|
|
1650
1597
|
}
|
|
1651
1598
|
}
|
|
@@ -1886,6 +1833,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1886
1833
|
if (typeof handle.dispose === "function") {
|
|
1887
1834
|
registerRootCleanup(handle.dispose);
|
|
1888
1835
|
}
|
|
1836
|
+
if (typeof handle.flush === "function") {
|
|
1837
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1838
|
+
if (typeof queueMicrotask === "function") {
|
|
1839
|
+
queueMicrotask(runFlush);
|
|
1840
|
+
} else {
|
|
1841
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1889
1844
|
return createElement(handle.marker);
|
|
1890
1845
|
}
|
|
1891
1846
|
const nodeRecord = node;
|
|
@@ -1933,18 +1888,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1933
1888
|
}
|
|
1934
1889
|
});
|
|
1935
1890
|
const props = createPropsProxy(baseProps);
|
|
1891
|
+
__fictPushContext();
|
|
1936
1892
|
try {
|
|
1937
|
-
__fictPushContext();
|
|
1938
1893
|
const rendered = vnode.type(props);
|
|
1939
|
-
__fictPopContext();
|
|
1940
1894
|
return createElementWithContext(rendered, namespace);
|
|
1941
1895
|
} catch (err) {
|
|
1942
|
-
__fictPopContext();
|
|
1943
1896
|
if (handleSuspend(err)) {
|
|
1944
1897
|
return document.createComment("fict:suspend");
|
|
1945
1898
|
}
|
|
1946
1899
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1947
1900
|
throw err;
|
|
1901
|
+
} finally {
|
|
1902
|
+
__fictPopContext();
|
|
1948
1903
|
}
|
|
1949
1904
|
}
|
|
1950
1905
|
if (vnode.type === Fragment) {
|
|
@@ -2236,6 +2191,149 @@ function eventNameFromProp(key) {
|
|
|
2236
2191
|
return key.slice(2).toLowerCase();
|
|
2237
2192
|
}
|
|
2238
2193
|
|
|
2194
|
+
// src/node-ops.ts
|
|
2195
|
+
function toNodeArray(node) {
|
|
2196
|
+
try {
|
|
2197
|
+
if (Array.isArray(node)) {
|
|
2198
|
+
let allNodes = true;
|
|
2199
|
+
for (const item of node) {
|
|
2200
|
+
let isItemNode = false;
|
|
2201
|
+
try {
|
|
2202
|
+
isItemNode = item instanceof Node;
|
|
2203
|
+
} catch {
|
|
2204
|
+
isItemNode = false;
|
|
2205
|
+
}
|
|
2206
|
+
if (!isItemNode) {
|
|
2207
|
+
allNodes = false;
|
|
2208
|
+
break;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
if (allNodes) {
|
|
2212
|
+
return node;
|
|
2213
|
+
}
|
|
2214
|
+
const result = [];
|
|
2215
|
+
for (const item of node) {
|
|
2216
|
+
result.push(...toNodeArray(item));
|
|
2217
|
+
}
|
|
2218
|
+
return result;
|
|
2219
|
+
}
|
|
2220
|
+
if (node === null || node === void 0 || node === false) {
|
|
2221
|
+
return [];
|
|
2222
|
+
}
|
|
2223
|
+
} catch {
|
|
2224
|
+
return [];
|
|
2225
|
+
}
|
|
2226
|
+
let isNode = false;
|
|
2227
|
+
try {
|
|
2228
|
+
isNode = node instanceof Node;
|
|
2229
|
+
} catch {
|
|
2230
|
+
isNode = false;
|
|
2231
|
+
}
|
|
2232
|
+
if (isNode) {
|
|
2233
|
+
try {
|
|
2234
|
+
if (node instanceof DocumentFragment) {
|
|
2235
|
+
return Array.from(node.childNodes);
|
|
2236
|
+
}
|
|
2237
|
+
} catch {
|
|
2238
|
+
}
|
|
2239
|
+
return [node];
|
|
2240
|
+
}
|
|
2241
|
+
try {
|
|
2242
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
2243
|
+
return toNodeArray(node.marker);
|
|
2244
|
+
}
|
|
2245
|
+
} catch {
|
|
2246
|
+
}
|
|
2247
|
+
try {
|
|
2248
|
+
return [document.createTextNode(String(node))];
|
|
2249
|
+
} catch {
|
|
2250
|
+
return [document.createTextNode("")];
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
2254
|
+
if (nodes.length === 0) return;
|
|
2255
|
+
if (nodes.length === 1) {
|
|
2256
|
+
const node = nodes[0];
|
|
2257
|
+
if (node === void 0 || node === null) return;
|
|
2258
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2259
|
+
parent.ownerDocument.adoptNode(node);
|
|
2260
|
+
}
|
|
2261
|
+
try {
|
|
2262
|
+
parent.insertBefore(node, anchor);
|
|
2263
|
+
} catch (e) {
|
|
2264
|
+
if (parent.ownerDocument) {
|
|
2265
|
+
try {
|
|
2266
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
2267
|
+
parent.insertBefore(clone, anchor);
|
|
2268
|
+
return;
|
|
2269
|
+
} catch {
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
throw e;
|
|
2273
|
+
}
|
|
2274
|
+
return;
|
|
2275
|
+
}
|
|
2276
|
+
const doc = parent.ownerDocument;
|
|
2277
|
+
if (doc) {
|
|
2278
|
+
const frag = doc.createDocumentFragment();
|
|
2279
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2280
|
+
const node = nodes[i];
|
|
2281
|
+
if (node === void 0 || node === null) continue;
|
|
2282
|
+
if (node.nodeType === 11) {
|
|
2283
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2284
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2285
|
+
frag.appendChild(childrenArr[j]);
|
|
2286
|
+
}
|
|
2287
|
+
} else {
|
|
2288
|
+
if (node.ownerDocument !== doc) {
|
|
2289
|
+
doc.adoptNode(node);
|
|
2290
|
+
}
|
|
2291
|
+
frag.appendChild(node);
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
parent.insertBefore(frag, anchor);
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2298
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2299
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2300
|
+
}
|
|
2301
|
+
try {
|
|
2302
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2303
|
+
return nodeToInsert;
|
|
2304
|
+
} catch (e) {
|
|
2305
|
+
if (parent.ownerDocument) {
|
|
2306
|
+
try {
|
|
2307
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2308
|
+
parent.insertBefore(clone, anchorNode);
|
|
2309
|
+
return clone;
|
|
2310
|
+
} catch {
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
throw e;
|
|
2314
|
+
}
|
|
2315
|
+
};
|
|
2316
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2317
|
+
const node = nodes[i];
|
|
2318
|
+
if (node === void 0 || node === null) continue;
|
|
2319
|
+
const isFrag = node.nodeType === 11;
|
|
2320
|
+
if (isFrag) {
|
|
2321
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2322
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2323
|
+
const child = childrenArr[j];
|
|
2324
|
+
anchor = insertSingle(child, anchor);
|
|
2325
|
+
}
|
|
2326
|
+
} else {
|
|
2327
|
+
anchor = insertSingle(node, anchor);
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
function removeNodes(nodes) {
|
|
2332
|
+
for (const node of nodes) {
|
|
2333
|
+
node.parentNode?.removeChild(node);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2239
2337
|
// src/reconcile.ts
|
|
2240
2338
|
function reconcileArrays(parentNode, a, b) {
|
|
2241
2339
|
const bLength = b.length;
|
|
@@ -2463,7 +2561,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2463
2561
|
} finally {
|
|
2464
2562
|
setActiveSub(prevSub);
|
|
2465
2563
|
popRoot(prevRoot);
|
|
2466
|
-
flushOnMount(root);
|
|
2467
2564
|
}
|
|
2468
2565
|
return {
|
|
2469
2566
|
key,
|
|
@@ -2495,13 +2592,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2495
2592
|
const hostRoot = getCurrentRoot();
|
|
2496
2593
|
const fragment = document.createDocumentFragment();
|
|
2497
2594
|
fragment.append(container.startMarker, container.endMarker);
|
|
2498
|
-
let pendingItems = null;
|
|
2499
2595
|
let disposed = false;
|
|
2596
|
+
let effectDispose;
|
|
2597
|
+
let connectObserver = null;
|
|
2598
|
+
let effectStarted = false;
|
|
2599
|
+
let startScheduled = false;
|
|
2600
|
+
const getConnectedParent = () => {
|
|
2601
|
+
const endParent = container.endMarker.parentNode;
|
|
2602
|
+
const startParent = container.startMarker.parentNode;
|
|
2603
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2604
|
+
return endParent;
|
|
2605
|
+
}
|
|
2606
|
+
return null;
|
|
2607
|
+
};
|
|
2500
2608
|
const performDiff = () => {
|
|
2501
2609
|
if (disposed) return;
|
|
2610
|
+
const parent = getConnectedParent();
|
|
2611
|
+
if (!parent) return;
|
|
2502
2612
|
batch2(() => {
|
|
2503
|
-
const newItems = pendingItems || getItems();
|
|
2504
|
-
pendingItems = null;
|
|
2505
2613
|
const oldBlocks = container.blocks;
|
|
2506
2614
|
const newBlocks = container.nextBlocks;
|
|
2507
2615
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2510,20 +2618,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2510
2618
|
newBlocks.clear();
|
|
2511
2619
|
nextOrderedBlocks.length = 0;
|
|
2512
2620
|
orderedIndexByKey.clear();
|
|
2513
|
-
const
|
|
2514
|
-
const
|
|
2515
|
-
const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
|
|
2516
|
-
if (!parent) {
|
|
2517
|
-
pendingItems = newItems;
|
|
2518
|
-
queueMicrotask(performDiff);
|
|
2519
|
-
return;
|
|
2520
|
-
}
|
|
2621
|
+
const createdBlocks = [];
|
|
2622
|
+
const newItems = getItems();
|
|
2521
2623
|
if (newItems.length === 0) {
|
|
2522
2624
|
if (oldBlocks.size > 0) {
|
|
2523
2625
|
for (const block of oldBlocks.values()) {
|
|
2524
2626
|
destroyRoot(block.root);
|
|
2525
|
-
removeNodes(block.nodes);
|
|
2526
2627
|
}
|
|
2628
|
+
const range = document.createRange();
|
|
2629
|
+
range.setStartAfter(container.startMarker);
|
|
2630
|
+
range.setEndBefore(container.endMarker);
|
|
2631
|
+
range.deleteContents();
|
|
2527
2632
|
}
|
|
2528
2633
|
oldBlocks.clear();
|
|
2529
2634
|
newBlocks.clear();
|
|
@@ -2540,8 +2645,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2540
2645
|
const appendedBlocks = [];
|
|
2541
2646
|
newItems.forEach((item, index) => {
|
|
2542
2647
|
const key = keyFn(item, index);
|
|
2543
|
-
const existed = oldBlocks.has(key);
|
|
2544
2648
|
let block = oldBlocks.get(key);
|
|
2649
|
+
const existed = block !== void 0;
|
|
2545
2650
|
if (block) {
|
|
2546
2651
|
if (block.rawItem !== item) {
|
|
2547
2652
|
block.rawItem = item;
|
|
@@ -2552,38 +2657,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2552
2657
|
block.index(index);
|
|
2553
2658
|
}
|
|
2554
2659
|
}
|
|
2555
|
-
const existingBlock = newBlocks.get(key);
|
|
2556
|
-
if (existingBlock && existingBlock !== block) {
|
|
2557
|
-
destroyRoot(existingBlock.root);
|
|
2558
|
-
removeNodes(existingBlock.nodes);
|
|
2559
|
-
}
|
|
2560
2660
|
if (block) {
|
|
2561
2661
|
newBlocks.set(key, block);
|
|
2562
2662
|
oldBlocks.delete(key);
|
|
2563
2663
|
} else {
|
|
2564
|
-
const
|
|
2565
|
-
if (
|
|
2566
|
-
destroyRoot(
|
|
2567
|
-
removeNodes(
|
|
2664
|
+
const existingBlock = newBlocks.get(key);
|
|
2665
|
+
if (existingBlock) {
|
|
2666
|
+
destroyRoot(existingBlock.root);
|
|
2667
|
+
removeNodes(existingBlock.nodes);
|
|
2568
2668
|
}
|
|
2569
2669
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2670
|
+
createdBlocks.push(block);
|
|
2570
2671
|
}
|
|
2571
2672
|
const resolvedBlock = block;
|
|
2572
2673
|
newBlocks.set(key, resolvedBlock);
|
|
2573
2674
|
const position = orderedIndexByKey.get(key);
|
|
2574
2675
|
if (position !== void 0) {
|
|
2575
2676
|
appendCandidate = false;
|
|
2576
|
-
}
|
|
2577
|
-
if (appendCandidate) {
|
|
2578
|
-
if (index < prevCount) {
|
|
2579
|
-
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2580
|
-
appendCandidate = false;
|
|
2581
|
-
}
|
|
2582
|
-
} else if (existed) {
|
|
2583
|
-
appendCandidate = false;
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
|
-
if (position !== void 0) {
|
|
2587
2677
|
const prior = nextOrderedBlocks[position];
|
|
2588
2678
|
if (prior && prior !== resolvedBlock) {
|
|
2589
2679
|
destroyRoot(prior.root);
|
|
@@ -2591,6 +2681,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2591
2681
|
}
|
|
2592
2682
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2593
2683
|
} else {
|
|
2684
|
+
if (appendCandidate) {
|
|
2685
|
+
if (index < prevCount) {
|
|
2686
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2687
|
+
appendCandidate = false;
|
|
2688
|
+
}
|
|
2689
|
+
} else if (existed) {
|
|
2690
|
+
appendCandidate = false;
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2594
2693
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2595
2694
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2596
2695
|
}
|
|
@@ -2619,6 +2718,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2619
2718
|
container.nextBlocks = oldBlocks;
|
|
2620
2719
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2621
2720
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2721
|
+
for (const block of createdBlocks) {
|
|
2722
|
+
if (newBlocks.get(block.key) === block) {
|
|
2723
|
+
flushOnMount(block.root);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2622
2726
|
return;
|
|
2623
2727
|
}
|
|
2624
2728
|
if (oldBlocks.size > 0) {
|
|
@@ -2648,22 +2752,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2648
2752
|
container.nextBlocks = oldBlocks;
|
|
2649
2753
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2650
2754
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2755
|
+
for (const block of createdBlocks) {
|
|
2756
|
+
if (newBlocks.get(block.key) === block) {
|
|
2757
|
+
flushOnMount(block.root);
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2651
2760
|
});
|
|
2652
2761
|
};
|
|
2653
|
-
const
|
|
2762
|
+
const disconnectObserver = () => {
|
|
2763
|
+
connectObserver?.disconnect();
|
|
2764
|
+
connectObserver = null;
|
|
2765
|
+
};
|
|
2766
|
+
const ensureEffectStarted = () => {
|
|
2767
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2768
|
+
const parent = getConnectedParent();
|
|
2769
|
+
if (!parent) return false;
|
|
2770
|
+
const start = () => {
|
|
2771
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2772
|
+
effectStarted = true;
|
|
2773
|
+
};
|
|
2774
|
+
if (hostRoot) {
|
|
2775
|
+
const prev = pushRoot(hostRoot);
|
|
2776
|
+
try {
|
|
2777
|
+
start();
|
|
2778
|
+
} finally {
|
|
2779
|
+
popRoot(prev);
|
|
2780
|
+
}
|
|
2781
|
+
} else {
|
|
2782
|
+
start();
|
|
2783
|
+
}
|
|
2784
|
+
return true;
|
|
2785
|
+
};
|
|
2786
|
+
const waitForConnection = () => {
|
|
2787
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2788
|
+
connectObserver = new MutationObserver(() => {
|
|
2789
|
+
if (disposed) return;
|
|
2790
|
+
if (getConnectedParent()) {
|
|
2791
|
+
disconnectObserver();
|
|
2792
|
+
if (ensureEffectStarted()) {
|
|
2793
|
+
flush();
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
});
|
|
2797
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2798
|
+
};
|
|
2799
|
+
const scheduleStart = () => {
|
|
2800
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2801
|
+
startScheduled = true;
|
|
2802
|
+
const run = () => {
|
|
2803
|
+
startScheduled = false;
|
|
2804
|
+
if (!ensureEffectStarted()) {
|
|
2805
|
+
waitForConnection();
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
if (typeof queueMicrotask === "function") {
|
|
2809
|
+
queueMicrotask(run);
|
|
2810
|
+
} else {
|
|
2811
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2812
|
+
}
|
|
2813
|
+
};
|
|
2814
|
+
scheduleStart();
|
|
2654
2815
|
return {
|
|
2655
|
-
marker
|
|
2816
|
+
get marker() {
|
|
2817
|
+
scheduleStart();
|
|
2818
|
+
return fragment;
|
|
2819
|
+
},
|
|
2656
2820
|
startMarker: container.startMarker,
|
|
2657
2821
|
endMarker: container.endMarker,
|
|
2658
2822
|
// Flush pending items - call after markers are inserted into DOM
|
|
2659
2823
|
flush: () => {
|
|
2660
|
-
if (
|
|
2661
|
-
|
|
2824
|
+
if (disposed) return;
|
|
2825
|
+
scheduleStart();
|
|
2826
|
+
if (ensureEffectStarted()) {
|
|
2827
|
+
flush();
|
|
2828
|
+
} else {
|
|
2829
|
+
waitForConnection();
|
|
2662
2830
|
}
|
|
2663
2831
|
},
|
|
2664
2832
|
dispose: () => {
|
|
2665
2833
|
disposed = true;
|
|
2666
2834
|
effectDispose?.();
|
|
2835
|
+
disconnectObserver();
|
|
2667
2836
|
container.dispose();
|
|
2668
2837
|
}
|
|
2669
2838
|
};
|
|
@@ -2863,8 +3032,17 @@ function createClassBinding(el, value) {
|
|
|
2863
3032
|
}
|
|
2864
3033
|
function bindClass(el, getValue) {
|
|
2865
3034
|
let prev = {};
|
|
3035
|
+
let prevString;
|
|
2866
3036
|
return createRenderEffect(() => {
|
|
2867
3037
|
const next = getValue();
|
|
3038
|
+
if (typeof next === "string") {
|
|
3039
|
+
if (next === prevString) return;
|
|
3040
|
+
prevString = next;
|
|
3041
|
+
el.className = next;
|
|
3042
|
+
prev = {};
|
|
3043
|
+
return;
|
|
3044
|
+
}
|
|
3045
|
+
prevString = void 0;
|
|
2868
3046
|
prev = applyClass(el, next, prev);
|
|
2869
3047
|
});
|
|
2870
3048
|
}
|
|
@@ -3093,11 +3271,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
3093
3271
|
}
|
|
3094
3272
|
}
|
|
3095
3273
|
function globalEventHandler(e) {
|
|
3096
|
-
|
|
3274
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
3275
|
+
const asElement = (value) => {
|
|
3276
|
+
const n = asNode(value);
|
|
3277
|
+
if (!n) return null;
|
|
3278
|
+
if (n.nodeType === 1) return n;
|
|
3279
|
+
return n.parentElement;
|
|
3280
|
+
};
|
|
3281
|
+
let node = asElement(e.target);
|
|
3097
3282
|
const key = `$$${e.type}`;
|
|
3098
3283
|
const dataKey = `${key}Data`;
|
|
3099
3284
|
const oriTarget = e.target;
|
|
3100
3285
|
const oriCurrentTarget = e.currentTarget;
|
|
3286
|
+
let lastHandled = null;
|
|
3101
3287
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
3102
3288
|
configurable: true,
|
|
3103
3289
|
value
|
|
@@ -3120,23 +3306,28 @@ function globalEventHandler(e) {
|
|
|
3120
3306
|
const rawData = node[dataKey];
|
|
3121
3307
|
const hasData = rawData !== void 0;
|
|
3122
3308
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3309
|
+
batch2(() => {
|
|
3310
|
+
if (typeof handler === "function") {
|
|
3311
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
3312
|
+
} else if (Array.isArray(handler)) {
|
|
3313
|
+
const tupleData = resolveData(handler[1]);
|
|
3314
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
3315
|
+
}
|
|
3316
|
+
});
|
|
3129
3317
|
if (e.cancelBubble) return false;
|
|
3130
3318
|
}
|
|
3131
3319
|
const shadowHost = node.host;
|
|
3132
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3320
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3321
|
+
const targetNode = asNode(e.target);
|
|
3322
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3323
|
+
})()) {
|
|
3133
3324
|
retarget(shadowHost);
|
|
3134
3325
|
}
|
|
3135
3326
|
return true;
|
|
3136
3327
|
};
|
|
3137
3328
|
const walkUpTree = () => {
|
|
3138
3329
|
while (handleNode() && node) {
|
|
3139
|
-
node = node._$host || node.parentNode || node.host;
|
|
3330
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
3140
3331
|
}
|
|
3141
3332
|
};
|
|
3142
3333
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -3149,8 +3340,11 @@ function globalEventHandler(e) {
|
|
|
3149
3340
|
const path = e.composedPath();
|
|
3150
3341
|
retarget(path[0]);
|
|
3151
3342
|
for (let i = 0; i < path.length - 2; i++) {
|
|
3152
|
-
|
|
3343
|
+
const nextNode = asElement(path[i]);
|
|
3344
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3345
|
+
node = nextNode;
|
|
3153
3346
|
if (!handleNode()) break;
|
|
3347
|
+
lastHandled = node;
|
|
3154
3348
|
if (node._$host) {
|
|
3155
3349
|
node = node._$host;
|
|
3156
3350
|
walkUpTree();
|