@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.js
CHANGED
|
@@ -346,6 +346,7 @@ var isInTransition = false;
|
|
|
346
346
|
var enqueueMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
347
347
|
Promise.resolve().then(fn);
|
|
348
348
|
};
|
|
349
|
+
var inCleanup = false;
|
|
349
350
|
function link(dep, sub, version) {
|
|
350
351
|
const prevDep = sub.depsTail;
|
|
351
352
|
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
@@ -591,7 +592,15 @@ function updateComputed(c) {
|
|
|
591
592
|
}
|
|
592
593
|
function runEffect(e) {
|
|
593
594
|
const flags = e.flags;
|
|
594
|
-
if (flags & Dirty
|
|
595
|
+
if (flags & Dirty) {
|
|
596
|
+
if (e.runCleanup) {
|
|
597
|
+
inCleanup = true;
|
|
598
|
+
try {
|
|
599
|
+
e.runCleanup();
|
|
600
|
+
} finally {
|
|
601
|
+
inCleanup = false;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
595
604
|
++cycle;
|
|
596
605
|
effectRunDevtools(e);
|
|
597
606
|
e.depsTail = void 0;
|
|
@@ -608,6 +617,35 @@ function runEffect(e) {
|
|
|
608
617
|
e.flags = Watching;
|
|
609
618
|
throw err;
|
|
610
619
|
}
|
|
620
|
+
} else if (flags & Pending && e.deps) {
|
|
621
|
+
if (e.runCleanup) {
|
|
622
|
+
inCleanup = true;
|
|
623
|
+
try {
|
|
624
|
+
e.runCleanup();
|
|
625
|
+
} finally {
|
|
626
|
+
inCleanup = false;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (checkDirty(e.deps, e)) {
|
|
630
|
+
++cycle;
|
|
631
|
+
effectRunDevtools(e);
|
|
632
|
+
e.depsTail = void 0;
|
|
633
|
+
e.flags = WatchingRunning;
|
|
634
|
+
const prevSub = activeSub;
|
|
635
|
+
activeSub = e;
|
|
636
|
+
try {
|
|
637
|
+
e.fn();
|
|
638
|
+
activeSub = prevSub;
|
|
639
|
+
e.flags = Watching;
|
|
640
|
+
purgeDeps(e);
|
|
641
|
+
} catch (err) {
|
|
642
|
+
activeSub = prevSub;
|
|
643
|
+
e.flags = Watching;
|
|
644
|
+
throw err;
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
e.flags = Watching;
|
|
648
|
+
}
|
|
611
649
|
} else {
|
|
612
650
|
e.flags = Watching;
|
|
613
651
|
}
|
|
@@ -703,7 +741,7 @@ function signalOper(value) {
|
|
|
703
741
|
return;
|
|
704
742
|
}
|
|
705
743
|
const flags = this.flags;
|
|
706
|
-
if (flags & Dirty) {
|
|
744
|
+
if (flags & Dirty && !inCleanup) {
|
|
707
745
|
if (updateSignal(this)) {
|
|
708
746
|
const subs = this.subs;
|
|
709
747
|
if (subs !== void 0) shallowPropagate(subs);
|
|
@@ -785,6 +823,30 @@ function effect(fn) {
|
|
|
785
823
|
}
|
|
786
824
|
return effectOper.bind(e);
|
|
787
825
|
}
|
|
826
|
+
function effectWithCleanup(fn, cleanupRunner) {
|
|
827
|
+
const e = {
|
|
828
|
+
fn,
|
|
829
|
+
subs: void 0,
|
|
830
|
+
subsTail: void 0,
|
|
831
|
+
deps: void 0,
|
|
832
|
+
depsTail: void 0,
|
|
833
|
+
flags: WatchingRunning,
|
|
834
|
+
runCleanup: cleanupRunner,
|
|
835
|
+
__id: void 0
|
|
836
|
+
};
|
|
837
|
+
registerEffectDevtools(e);
|
|
838
|
+
const prevSub = activeSub;
|
|
839
|
+
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
840
|
+
activeSub = e;
|
|
841
|
+
try {
|
|
842
|
+
effectRunDevtools(e);
|
|
843
|
+
fn();
|
|
844
|
+
} finally {
|
|
845
|
+
activeSub = prevSub;
|
|
846
|
+
e.flags &= ~Running;
|
|
847
|
+
}
|
|
848
|
+
return effectOper.bind(e);
|
|
849
|
+
}
|
|
788
850
|
function effectOper() {
|
|
789
851
|
disposeNode(this);
|
|
790
852
|
}
|
|
@@ -805,10 +867,17 @@ function effectScopeOper() {
|
|
|
805
867
|
}
|
|
806
868
|
function batch(fn) {
|
|
807
869
|
++batchDepth;
|
|
870
|
+
let hasError = false;
|
|
808
871
|
try {
|
|
809
872
|
return fn();
|
|
873
|
+
} catch (e) {
|
|
874
|
+
hasError = true;
|
|
875
|
+
throw e;
|
|
810
876
|
} finally {
|
|
811
|
-
|
|
877
|
+
--batchDepth;
|
|
878
|
+
if (!hasError && batchDepth === 0) {
|
|
879
|
+
flush();
|
|
880
|
+
}
|
|
812
881
|
}
|
|
813
882
|
}
|
|
814
883
|
function setActiveSub(sub) {
|
|
@@ -864,7 +933,7 @@ function effectRunDevtools(node) {
|
|
|
864
933
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
865
934
|
let current = source();
|
|
866
935
|
const observers = /* @__PURE__ */ new Map();
|
|
867
|
-
effect(() => {
|
|
936
|
+
const dispose = effect(() => {
|
|
868
937
|
const next = source();
|
|
869
938
|
if (equalityFn(current, next)) return;
|
|
870
939
|
const prevSig = observers.get(current);
|
|
@@ -873,6 +942,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
873
942
|
if (nextSig) nextSig(true);
|
|
874
943
|
current = next;
|
|
875
944
|
});
|
|
945
|
+
registerRootCleanup(() => {
|
|
946
|
+
dispose();
|
|
947
|
+
observers.clear();
|
|
948
|
+
});
|
|
876
949
|
return (key) => {
|
|
877
950
|
let sig = observers.get(key);
|
|
878
951
|
if (!sig) {
|
|
@@ -1019,8 +1092,11 @@ var $memo = createMemo;
|
|
|
1019
1092
|
function createEffect(fn) {
|
|
1020
1093
|
let cleanups = [];
|
|
1021
1094
|
const rootForError = getCurrentRoot();
|
|
1022
|
-
const
|
|
1095
|
+
const doCleanup = () => {
|
|
1023
1096
|
runCleanupList(cleanups);
|
|
1097
|
+
cleanups = [];
|
|
1098
|
+
};
|
|
1099
|
+
const run = () => {
|
|
1024
1100
|
const bucket = [];
|
|
1025
1101
|
withEffectCleanups(bucket, () => {
|
|
1026
1102
|
try {
|
|
@@ -1037,7 +1113,7 @@ function createEffect(fn) {
|
|
|
1037
1113
|
});
|
|
1038
1114
|
cleanups = bucket;
|
|
1039
1115
|
};
|
|
1040
|
-
const disposeEffect =
|
|
1116
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1041
1117
|
const teardown = () => {
|
|
1042
1118
|
runCleanupList(cleanups);
|
|
1043
1119
|
disposeEffect();
|
|
@@ -1049,24 +1125,27 @@ var $effect = createEffect;
|
|
|
1049
1125
|
function createRenderEffect(fn) {
|
|
1050
1126
|
let cleanup;
|
|
1051
1127
|
const rootForError = getCurrentRoot();
|
|
1052
|
-
const
|
|
1128
|
+
const doCleanup = () => {
|
|
1053
1129
|
if (cleanup) {
|
|
1054
1130
|
cleanup();
|
|
1055
1131
|
cleanup = void 0;
|
|
1056
1132
|
}
|
|
1133
|
+
};
|
|
1134
|
+
const run = () => {
|
|
1057
1135
|
try {
|
|
1058
1136
|
const maybeCleanup = fn();
|
|
1059
1137
|
if (typeof maybeCleanup === "function") {
|
|
1060
1138
|
cleanup = maybeCleanup;
|
|
1061
1139
|
}
|
|
1062
1140
|
} catch (err) {
|
|
1063
|
-
|
|
1141
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1142
|
+
if (handled) {
|
|
1064
1143
|
return;
|
|
1065
1144
|
}
|
|
1066
1145
|
throw err;
|
|
1067
1146
|
}
|
|
1068
1147
|
};
|
|
1069
|
-
const disposeEffect =
|
|
1148
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
1070
1149
|
const teardown = () => {
|
|
1071
1150
|
if (cleanup) {
|
|
1072
1151
|
cleanup();
|
|
@@ -1452,159 +1531,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1452
1531
|
// src/jsx.ts
|
|
1453
1532
|
var Fragment = Symbol("Fragment");
|
|
1454
1533
|
|
|
1455
|
-
// src/node-ops.ts
|
|
1456
|
-
function toNodeArray(node) {
|
|
1457
|
-
try {
|
|
1458
|
-
if (Array.isArray(node)) {
|
|
1459
|
-
let allNodes = true;
|
|
1460
|
-
for (const item of node) {
|
|
1461
|
-
let isItemNode = false;
|
|
1462
|
-
try {
|
|
1463
|
-
isItemNode = item instanceof Node;
|
|
1464
|
-
} catch {
|
|
1465
|
-
isItemNode = false;
|
|
1466
|
-
}
|
|
1467
|
-
if (!isItemNode) {
|
|
1468
|
-
allNodes = false;
|
|
1469
|
-
break;
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
if (allNodes) {
|
|
1473
|
-
return node;
|
|
1474
|
-
}
|
|
1475
|
-
const result = [];
|
|
1476
|
-
for (const item of node) {
|
|
1477
|
-
result.push(...toNodeArray(item));
|
|
1478
|
-
}
|
|
1479
|
-
return result;
|
|
1480
|
-
}
|
|
1481
|
-
if (node === null || node === void 0 || node === false) {
|
|
1482
|
-
return [];
|
|
1483
|
-
}
|
|
1484
|
-
} catch {
|
|
1485
|
-
return [];
|
|
1486
|
-
}
|
|
1487
|
-
let isNode = false;
|
|
1488
|
-
try {
|
|
1489
|
-
isNode = node instanceof Node;
|
|
1490
|
-
} catch {
|
|
1491
|
-
isNode = false;
|
|
1492
|
-
}
|
|
1493
|
-
if (isNode) {
|
|
1494
|
-
try {
|
|
1495
|
-
if (node instanceof DocumentFragment) {
|
|
1496
|
-
return Array.from(node.childNodes);
|
|
1497
|
-
}
|
|
1498
|
-
} catch {
|
|
1499
|
-
}
|
|
1500
|
-
return [node];
|
|
1501
|
-
}
|
|
1502
|
-
try {
|
|
1503
|
-
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
1504
|
-
return toNodeArray(node.marker);
|
|
1505
|
-
}
|
|
1506
|
-
} catch {
|
|
1507
|
-
}
|
|
1508
|
-
try {
|
|
1509
|
-
return [document.createTextNode(String(node))];
|
|
1510
|
-
} catch {
|
|
1511
|
-
return [document.createTextNode("")];
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
function insertNodesBefore(parent, nodes, anchor) {
|
|
1515
|
-
if (nodes.length === 0) return;
|
|
1516
|
-
if (nodes.length === 1) {
|
|
1517
|
-
const node = nodes[0];
|
|
1518
|
-
if (node === void 0 || node === null) return;
|
|
1519
|
-
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1520
|
-
parent.ownerDocument.adoptNode(node);
|
|
1521
|
-
}
|
|
1522
|
-
try {
|
|
1523
|
-
parent.insertBefore(node, anchor);
|
|
1524
|
-
} catch (e) {
|
|
1525
|
-
if (parent.ownerDocument) {
|
|
1526
|
-
try {
|
|
1527
|
-
const clone = parent.ownerDocument.importNode(node, true);
|
|
1528
|
-
parent.insertBefore(clone, anchor);
|
|
1529
|
-
return;
|
|
1530
|
-
} catch {
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
throw e;
|
|
1534
|
-
}
|
|
1535
|
-
return;
|
|
1536
|
-
}
|
|
1537
|
-
const doc = parent.ownerDocument;
|
|
1538
|
-
if (doc) {
|
|
1539
|
-
const frag = doc.createDocumentFragment();
|
|
1540
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
1541
|
-
const node = nodes[i];
|
|
1542
|
-
if (node === void 0 || node === null) continue;
|
|
1543
|
-
if (node.nodeType === 11) {
|
|
1544
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1545
|
-
for (let j = 0; j < childrenArr.length; j++) {
|
|
1546
|
-
frag.appendChild(childrenArr[j]);
|
|
1547
|
-
}
|
|
1548
|
-
} else {
|
|
1549
|
-
if (node.ownerDocument !== doc) {
|
|
1550
|
-
doc.adoptNode(node);
|
|
1551
|
-
}
|
|
1552
|
-
frag.appendChild(node);
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
parent.insertBefore(frag, anchor);
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
1559
|
-
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1560
|
-
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
1561
|
-
}
|
|
1562
|
-
try {
|
|
1563
|
-
parent.insertBefore(nodeToInsert, anchorNode);
|
|
1564
|
-
return nodeToInsert;
|
|
1565
|
-
} catch (e) {
|
|
1566
|
-
if (parent.ownerDocument) {
|
|
1567
|
-
try {
|
|
1568
|
-
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
1569
|
-
parent.insertBefore(clone, anchorNode);
|
|
1570
|
-
return clone;
|
|
1571
|
-
} catch {
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
throw e;
|
|
1575
|
-
}
|
|
1576
|
-
};
|
|
1577
|
-
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
1578
|
-
const node = nodes[i];
|
|
1579
|
-
if (node === void 0 || node === null) continue;
|
|
1580
|
-
const isFrag = node.nodeType === 11;
|
|
1581
|
-
if (isFrag) {
|
|
1582
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1583
|
-
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
1584
|
-
const child = childrenArr[j];
|
|
1585
|
-
anchor = insertSingle(child, anchor);
|
|
1586
|
-
}
|
|
1587
|
-
} else {
|
|
1588
|
-
anchor = insertSingle(node, anchor);
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
function removeNodes(nodes) {
|
|
1593
|
-
for (const node of nodes) {
|
|
1594
|
-
node.parentNode?.removeChild(node);
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
1534
|
// src/hooks.ts
|
|
1599
1535
|
var ctxStack = [];
|
|
1536
|
+
function assertRenderContext(ctx, hookName) {
|
|
1537
|
+
if (!ctx.rendering) {
|
|
1538
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1600
1541
|
function __fictUseContext() {
|
|
1601
1542
|
if (ctxStack.length === 0) {
|
|
1602
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1543
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1603
1544
|
ctxStack.push(ctx2);
|
|
1604
1545
|
return ctx2;
|
|
1605
1546
|
}
|
|
1606
1547
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1607
1548
|
ctx.cursor = 0;
|
|
1549
|
+
ctx.rendering = true;
|
|
1608
1550
|
return ctx;
|
|
1609
1551
|
}
|
|
1610
1552
|
function __fictPushContext() {
|
|
@@ -1619,6 +1561,7 @@ function __fictResetContext() {
|
|
|
1619
1561
|
ctxStack.length = 0;
|
|
1620
1562
|
}
|
|
1621
1563
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1564
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1622
1565
|
const index = slot ?? ctx.cursor++;
|
|
1623
1566
|
if (!ctx.slots[index]) {
|
|
1624
1567
|
ctx.slots[index] = signal(initial);
|
|
@@ -1626,6 +1569,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1626
1569
|
return ctx.slots[index];
|
|
1627
1570
|
}
|
|
1628
1571
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1572
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1629
1573
|
const index = slot ?? ctx.cursor++;
|
|
1630
1574
|
if (!ctx.slots[index]) {
|
|
1631
1575
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1633,6 +1577,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1633
1577
|
return ctx.slots[index];
|
|
1634
1578
|
}
|
|
1635
1579
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1580
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1636
1581
|
const index = slot ?? ctx.cursor++;
|
|
1637
1582
|
if (!ctx.slots[index]) {
|
|
1638
1583
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1641,9 +1586,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1641
1586
|
function __fictRender(ctx, fn) {
|
|
1642
1587
|
ctxStack.push(ctx);
|
|
1643
1588
|
ctx.cursor = 0;
|
|
1589
|
+
ctx.rendering = true;
|
|
1644
1590
|
try {
|
|
1645
1591
|
return fn();
|
|
1646
1592
|
} finally {
|
|
1593
|
+
ctx.rendering = false;
|
|
1647
1594
|
ctxStack.pop();
|
|
1648
1595
|
}
|
|
1649
1596
|
}
|
|
@@ -1884,6 +1831,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1884
1831
|
if (typeof handle.dispose === "function") {
|
|
1885
1832
|
registerRootCleanup(handle.dispose);
|
|
1886
1833
|
}
|
|
1834
|
+
if (typeof handle.flush === "function") {
|
|
1835
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1836
|
+
if (typeof queueMicrotask === "function") {
|
|
1837
|
+
queueMicrotask(runFlush);
|
|
1838
|
+
} else {
|
|
1839
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1887
1842
|
return createElement(handle.marker);
|
|
1888
1843
|
}
|
|
1889
1844
|
const nodeRecord = node;
|
|
@@ -1931,18 +1886,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1931
1886
|
}
|
|
1932
1887
|
});
|
|
1933
1888
|
const props = createPropsProxy(baseProps);
|
|
1889
|
+
__fictPushContext();
|
|
1934
1890
|
try {
|
|
1935
|
-
__fictPushContext();
|
|
1936
1891
|
const rendered = vnode.type(props);
|
|
1937
|
-
__fictPopContext();
|
|
1938
1892
|
return createElementWithContext(rendered, namespace);
|
|
1939
1893
|
} catch (err) {
|
|
1940
|
-
__fictPopContext();
|
|
1941
1894
|
if (handleSuspend(err)) {
|
|
1942
1895
|
return document.createComment("fict:suspend");
|
|
1943
1896
|
}
|
|
1944
1897
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1945
1898
|
throw err;
|
|
1899
|
+
} finally {
|
|
1900
|
+
__fictPopContext();
|
|
1946
1901
|
}
|
|
1947
1902
|
}
|
|
1948
1903
|
if (vnode.type === Fragment) {
|
|
@@ -2234,6 +2189,149 @@ function eventNameFromProp(key) {
|
|
|
2234
2189
|
return key.slice(2).toLowerCase();
|
|
2235
2190
|
}
|
|
2236
2191
|
|
|
2192
|
+
// src/node-ops.ts
|
|
2193
|
+
function toNodeArray(node) {
|
|
2194
|
+
try {
|
|
2195
|
+
if (Array.isArray(node)) {
|
|
2196
|
+
let allNodes = true;
|
|
2197
|
+
for (const item of node) {
|
|
2198
|
+
let isItemNode = false;
|
|
2199
|
+
try {
|
|
2200
|
+
isItemNode = item instanceof Node;
|
|
2201
|
+
} catch {
|
|
2202
|
+
isItemNode = false;
|
|
2203
|
+
}
|
|
2204
|
+
if (!isItemNode) {
|
|
2205
|
+
allNodes = false;
|
|
2206
|
+
break;
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
if (allNodes) {
|
|
2210
|
+
return node;
|
|
2211
|
+
}
|
|
2212
|
+
const result = [];
|
|
2213
|
+
for (const item of node) {
|
|
2214
|
+
result.push(...toNodeArray(item));
|
|
2215
|
+
}
|
|
2216
|
+
return result;
|
|
2217
|
+
}
|
|
2218
|
+
if (node === null || node === void 0 || node === false) {
|
|
2219
|
+
return [];
|
|
2220
|
+
}
|
|
2221
|
+
} catch {
|
|
2222
|
+
return [];
|
|
2223
|
+
}
|
|
2224
|
+
let isNode = false;
|
|
2225
|
+
try {
|
|
2226
|
+
isNode = node instanceof Node;
|
|
2227
|
+
} catch {
|
|
2228
|
+
isNode = false;
|
|
2229
|
+
}
|
|
2230
|
+
if (isNode) {
|
|
2231
|
+
try {
|
|
2232
|
+
if (node instanceof DocumentFragment) {
|
|
2233
|
+
return Array.from(node.childNodes);
|
|
2234
|
+
}
|
|
2235
|
+
} catch {
|
|
2236
|
+
}
|
|
2237
|
+
return [node];
|
|
2238
|
+
}
|
|
2239
|
+
try {
|
|
2240
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
2241
|
+
return toNodeArray(node.marker);
|
|
2242
|
+
}
|
|
2243
|
+
} catch {
|
|
2244
|
+
}
|
|
2245
|
+
try {
|
|
2246
|
+
return [document.createTextNode(String(node))];
|
|
2247
|
+
} catch {
|
|
2248
|
+
return [document.createTextNode("")];
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
2252
|
+
if (nodes.length === 0) return;
|
|
2253
|
+
if (nodes.length === 1) {
|
|
2254
|
+
const node = nodes[0];
|
|
2255
|
+
if (node === void 0 || node === null) return;
|
|
2256
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2257
|
+
parent.ownerDocument.adoptNode(node);
|
|
2258
|
+
}
|
|
2259
|
+
try {
|
|
2260
|
+
parent.insertBefore(node, anchor);
|
|
2261
|
+
} catch (e) {
|
|
2262
|
+
if (parent.ownerDocument) {
|
|
2263
|
+
try {
|
|
2264
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
2265
|
+
parent.insertBefore(clone, anchor);
|
|
2266
|
+
return;
|
|
2267
|
+
} catch {
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
throw e;
|
|
2271
|
+
}
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
const doc = parent.ownerDocument;
|
|
2275
|
+
if (doc) {
|
|
2276
|
+
const frag = doc.createDocumentFragment();
|
|
2277
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2278
|
+
const node = nodes[i];
|
|
2279
|
+
if (node === void 0 || node === null) continue;
|
|
2280
|
+
if (node.nodeType === 11) {
|
|
2281
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2282
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2283
|
+
frag.appendChild(childrenArr[j]);
|
|
2284
|
+
}
|
|
2285
|
+
} else {
|
|
2286
|
+
if (node.ownerDocument !== doc) {
|
|
2287
|
+
doc.adoptNode(node);
|
|
2288
|
+
}
|
|
2289
|
+
frag.appendChild(node);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
parent.insertBefore(frag, anchor);
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2296
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2297
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2298
|
+
}
|
|
2299
|
+
try {
|
|
2300
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2301
|
+
return nodeToInsert;
|
|
2302
|
+
} catch (e) {
|
|
2303
|
+
if (parent.ownerDocument) {
|
|
2304
|
+
try {
|
|
2305
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2306
|
+
parent.insertBefore(clone, anchorNode);
|
|
2307
|
+
return clone;
|
|
2308
|
+
} catch {
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
throw e;
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2315
|
+
const node = nodes[i];
|
|
2316
|
+
if (node === void 0 || node === null) continue;
|
|
2317
|
+
const isFrag = node.nodeType === 11;
|
|
2318
|
+
if (isFrag) {
|
|
2319
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2320
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2321
|
+
const child = childrenArr[j];
|
|
2322
|
+
anchor = insertSingle(child, anchor);
|
|
2323
|
+
}
|
|
2324
|
+
} else {
|
|
2325
|
+
anchor = insertSingle(node, anchor);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
function removeNodes(nodes) {
|
|
2330
|
+
for (const node of nodes) {
|
|
2331
|
+
node.parentNode?.removeChild(node);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2237
2335
|
// src/reconcile.ts
|
|
2238
2336
|
function reconcileArrays(parentNode, a, b) {
|
|
2239
2337
|
const bLength = b.length;
|
|
@@ -2461,7 +2559,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2461
2559
|
} finally {
|
|
2462
2560
|
setActiveSub(prevSub);
|
|
2463
2561
|
popRoot(prevRoot);
|
|
2464
|
-
flushOnMount(root);
|
|
2465
2562
|
}
|
|
2466
2563
|
return {
|
|
2467
2564
|
key,
|
|
@@ -2493,13 +2590,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2493
2590
|
const hostRoot = getCurrentRoot();
|
|
2494
2591
|
const fragment = document.createDocumentFragment();
|
|
2495
2592
|
fragment.append(container.startMarker, container.endMarker);
|
|
2496
|
-
let pendingItems = null;
|
|
2497
2593
|
let disposed = false;
|
|
2594
|
+
let effectDispose;
|
|
2595
|
+
let connectObserver = null;
|
|
2596
|
+
let effectStarted = false;
|
|
2597
|
+
let startScheduled = false;
|
|
2598
|
+
const getConnectedParent = () => {
|
|
2599
|
+
const endParent = container.endMarker.parentNode;
|
|
2600
|
+
const startParent = container.startMarker.parentNode;
|
|
2601
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2602
|
+
return endParent;
|
|
2603
|
+
}
|
|
2604
|
+
return null;
|
|
2605
|
+
};
|
|
2498
2606
|
const performDiff = () => {
|
|
2499
2607
|
if (disposed) return;
|
|
2608
|
+
const parent = getConnectedParent();
|
|
2609
|
+
if (!parent) return;
|
|
2500
2610
|
batch2(() => {
|
|
2501
|
-
const newItems = pendingItems || getItems();
|
|
2502
|
-
pendingItems = null;
|
|
2503
2611
|
const oldBlocks = container.blocks;
|
|
2504
2612
|
const newBlocks = container.nextBlocks;
|
|
2505
2613
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2508,20 +2616,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2508
2616
|
newBlocks.clear();
|
|
2509
2617
|
nextOrderedBlocks.length = 0;
|
|
2510
2618
|
orderedIndexByKey.clear();
|
|
2511
|
-
const
|
|
2512
|
-
const
|
|
2513
|
-
const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
|
|
2514
|
-
if (!parent) {
|
|
2515
|
-
pendingItems = newItems;
|
|
2516
|
-
queueMicrotask(performDiff);
|
|
2517
|
-
return;
|
|
2518
|
-
}
|
|
2619
|
+
const createdBlocks = [];
|
|
2620
|
+
const newItems = getItems();
|
|
2519
2621
|
if (newItems.length === 0) {
|
|
2520
2622
|
if (oldBlocks.size > 0) {
|
|
2521
2623
|
for (const block of oldBlocks.values()) {
|
|
2522
2624
|
destroyRoot(block.root);
|
|
2523
|
-
removeNodes(block.nodes);
|
|
2524
2625
|
}
|
|
2626
|
+
const range = document.createRange();
|
|
2627
|
+
range.setStartAfter(container.startMarker);
|
|
2628
|
+
range.setEndBefore(container.endMarker);
|
|
2629
|
+
range.deleteContents();
|
|
2525
2630
|
}
|
|
2526
2631
|
oldBlocks.clear();
|
|
2527
2632
|
newBlocks.clear();
|
|
@@ -2538,8 +2643,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2538
2643
|
const appendedBlocks = [];
|
|
2539
2644
|
newItems.forEach((item, index) => {
|
|
2540
2645
|
const key = keyFn(item, index);
|
|
2541
|
-
const existed = oldBlocks.has(key);
|
|
2542
2646
|
let block = oldBlocks.get(key);
|
|
2647
|
+
const existed = block !== void 0;
|
|
2543
2648
|
if (block) {
|
|
2544
2649
|
if (block.rawItem !== item) {
|
|
2545
2650
|
block.rawItem = item;
|
|
@@ -2550,38 +2655,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2550
2655
|
block.index(index);
|
|
2551
2656
|
}
|
|
2552
2657
|
}
|
|
2553
|
-
const existingBlock = newBlocks.get(key);
|
|
2554
|
-
if (existingBlock && existingBlock !== block) {
|
|
2555
|
-
destroyRoot(existingBlock.root);
|
|
2556
|
-
removeNodes(existingBlock.nodes);
|
|
2557
|
-
}
|
|
2558
2658
|
if (block) {
|
|
2559
2659
|
newBlocks.set(key, block);
|
|
2560
2660
|
oldBlocks.delete(key);
|
|
2561
2661
|
} else {
|
|
2562
|
-
const
|
|
2563
|
-
if (
|
|
2564
|
-
destroyRoot(
|
|
2565
|
-
removeNodes(
|
|
2662
|
+
const existingBlock = newBlocks.get(key);
|
|
2663
|
+
if (existingBlock) {
|
|
2664
|
+
destroyRoot(existingBlock.root);
|
|
2665
|
+
removeNodes(existingBlock.nodes);
|
|
2566
2666
|
}
|
|
2567
2667
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2668
|
+
createdBlocks.push(block);
|
|
2568
2669
|
}
|
|
2569
2670
|
const resolvedBlock = block;
|
|
2570
2671
|
newBlocks.set(key, resolvedBlock);
|
|
2571
2672
|
const position = orderedIndexByKey.get(key);
|
|
2572
2673
|
if (position !== void 0) {
|
|
2573
2674
|
appendCandidate = false;
|
|
2574
|
-
}
|
|
2575
|
-
if (appendCandidate) {
|
|
2576
|
-
if (index < prevCount) {
|
|
2577
|
-
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2578
|
-
appendCandidate = false;
|
|
2579
|
-
}
|
|
2580
|
-
} else if (existed) {
|
|
2581
|
-
appendCandidate = false;
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
|
-
if (position !== void 0) {
|
|
2585
2675
|
const prior = nextOrderedBlocks[position];
|
|
2586
2676
|
if (prior && prior !== resolvedBlock) {
|
|
2587
2677
|
destroyRoot(prior.root);
|
|
@@ -2589,6 +2679,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2589
2679
|
}
|
|
2590
2680
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2591
2681
|
} else {
|
|
2682
|
+
if (appendCandidate) {
|
|
2683
|
+
if (index < prevCount) {
|
|
2684
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2685
|
+
appendCandidate = false;
|
|
2686
|
+
}
|
|
2687
|
+
} else if (existed) {
|
|
2688
|
+
appendCandidate = false;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2592
2691
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2593
2692
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2594
2693
|
}
|
|
@@ -2617,6 +2716,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2617
2716
|
container.nextBlocks = oldBlocks;
|
|
2618
2717
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2619
2718
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2719
|
+
for (const block of createdBlocks) {
|
|
2720
|
+
if (newBlocks.get(block.key) === block) {
|
|
2721
|
+
flushOnMount(block.root);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2620
2724
|
return;
|
|
2621
2725
|
}
|
|
2622
2726
|
if (oldBlocks.size > 0) {
|
|
@@ -2646,22 +2750,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2646
2750
|
container.nextBlocks = oldBlocks;
|
|
2647
2751
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2648
2752
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2753
|
+
for (const block of createdBlocks) {
|
|
2754
|
+
if (newBlocks.get(block.key) === block) {
|
|
2755
|
+
flushOnMount(block.root);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2649
2758
|
});
|
|
2650
2759
|
};
|
|
2651
|
-
const
|
|
2760
|
+
const disconnectObserver = () => {
|
|
2761
|
+
connectObserver?.disconnect();
|
|
2762
|
+
connectObserver = null;
|
|
2763
|
+
};
|
|
2764
|
+
const ensureEffectStarted = () => {
|
|
2765
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2766
|
+
const parent = getConnectedParent();
|
|
2767
|
+
if (!parent) return false;
|
|
2768
|
+
const start = () => {
|
|
2769
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2770
|
+
effectStarted = true;
|
|
2771
|
+
};
|
|
2772
|
+
if (hostRoot) {
|
|
2773
|
+
const prev = pushRoot(hostRoot);
|
|
2774
|
+
try {
|
|
2775
|
+
start();
|
|
2776
|
+
} finally {
|
|
2777
|
+
popRoot(prev);
|
|
2778
|
+
}
|
|
2779
|
+
} else {
|
|
2780
|
+
start();
|
|
2781
|
+
}
|
|
2782
|
+
return true;
|
|
2783
|
+
};
|
|
2784
|
+
const waitForConnection = () => {
|
|
2785
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2786
|
+
connectObserver = new MutationObserver(() => {
|
|
2787
|
+
if (disposed) return;
|
|
2788
|
+
if (getConnectedParent()) {
|
|
2789
|
+
disconnectObserver();
|
|
2790
|
+
if (ensureEffectStarted()) {
|
|
2791
|
+
flush();
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
});
|
|
2795
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2796
|
+
};
|
|
2797
|
+
const scheduleStart = () => {
|
|
2798
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2799
|
+
startScheduled = true;
|
|
2800
|
+
const run = () => {
|
|
2801
|
+
startScheduled = false;
|
|
2802
|
+
if (!ensureEffectStarted()) {
|
|
2803
|
+
waitForConnection();
|
|
2804
|
+
}
|
|
2805
|
+
};
|
|
2806
|
+
if (typeof queueMicrotask === "function") {
|
|
2807
|
+
queueMicrotask(run);
|
|
2808
|
+
} else {
|
|
2809
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2810
|
+
}
|
|
2811
|
+
};
|
|
2812
|
+
scheduleStart();
|
|
2652
2813
|
return {
|
|
2653
|
-
marker
|
|
2814
|
+
get marker() {
|
|
2815
|
+
scheduleStart();
|
|
2816
|
+
return fragment;
|
|
2817
|
+
},
|
|
2654
2818
|
startMarker: container.startMarker,
|
|
2655
2819
|
endMarker: container.endMarker,
|
|
2656
2820
|
// Flush pending items - call after markers are inserted into DOM
|
|
2657
2821
|
flush: () => {
|
|
2658
|
-
if (
|
|
2659
|
-
|
|
2822
|
+
if (disposed) return;
|
|
2823
|
+
scheduleStart();
|
|
2824
|
+
if (ensureEffectStarted()) {
|
|
2825
|
+
flush();
|
|
2826
|
+
} else {
|
|
2827
|
+
waitForConnection();
|
|
2660
2828
|
}
|
|
2661
2829
|
},
|
|
2662
2830
|
dispose: () => {
|
|
2663
2831
|
disposed = true;
|
|
2664
2832
|
effectDispose?.();
|
|
2833
|
+
disconnectObserver();
|
|
2665
2834
|
container.dispose();
|
|
2666
2835
|
}
|
|
2667
2836
|
};
|
|
@@ -2861,8 +3030,17 @@ function createClassBinding(el, value) {
|
|
|
2861
3030
|
}
|
|
2862
3031
|
function bindClass(el, getValue) {
|
|
2863
3032
|
let prev = {};
|
|
3033
|
+
let prevString;
|
|
2864
3034
|
return createRenderEffect(() => {
|
|
2865
3035
|
const next = getValue();
|
|
3036
|
+
if (typeof next === "string") {
|
|
3037
|
+
if (next === prevString) return;
|
|
3038
|
+
prevString = next;
|
|
3039
|
+
el.className = next;
|
|
3040
|
+
prev = {};
|
|
3041
|
+
return;
|
|
3042
|
+
}
|
|
3043
|
+
prevString = void 0;
|
|
2866
3044
|
prev = applyClass(el, next, prev);
|
|
2867
3045
|
});
|
|
2868
3046
|
}
|
|
@@ -3091,11 +3269,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
3091
3269
|
}
|
|
3092
3270
|
}
|
|
3093
3271
|
function globalEventHandler(e) {
|
|
3094
|
-
|
|
3272
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
3273
|
+
const asElement = (value) => {
|
|
3274
|
+
const n = asNode(value);
|
|
3275
|
+
if (!n) return null;
|
|
3276
|
+
if (n.nodeType === 1) return n;
|
|
3277
|
+
return n.parentElement;
|
|
3278
|
+
};
|
|
3279
|
+
let node = asElement(e.target);
|
|
3095
3280
|
const key = `$$${e.type}`;
|
|
3096
3281
|
const dataKey = `${key}Data`;
|
|
3097
3282
|
const oriTarget = e.target;
|
|
3098
3283
|
const oriCurrentTarget = e.currentTarget;
|
|
3284
|
+
let lastHandled = null;
|
|
3099
3285
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
3100
3286
|
configurable: true,
|
|
3101
3287
|
value
|
|
@@ -3118,23 +3304,28 @@ function globalEventHandler(e) {
|
|
|
3118
3304
|
const rawData = node[dataKey];
|
|
3119
3305
|
const hasData = rawData !== void 0;
|
|
3120
3306
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3307
|
+
batch2(() => {
|
|
3308
|
+
if (typeof handler === "function") {
|
|
3309
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
3310
|
+
} else if (Array.isArray(handler)) {
|
|
3311
|
+
const tupleData = resolveData(handler[1]);
|
|
3312
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
3313
|
+
}
|
|
3314
|
+
});
|
|
3127
3315
|
if (e.cancelBubble) return false;
|
|
3128
3316
|
}
|
|
3129
3317
|
const shadowHost = node.host;
|
|
3130
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3318
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3319
|
+
const targetNode = asNode(e.target);
|
|
3320
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3321
|
+
})()) {
|
|
3131
3322
|
retarget(shadowHost);
|
|
3132
3323
|
}
|
|
3133
3324
|
return true;
|
|
3134
3325
|
};
|
|
3135
3326
|
const walkUpTree = () => {
|
|
3136
3327
|
while (handleNode() && node) {
|
|
3137
|
-
node = node._$host || node.parentNode || node.host;
|
|
3328
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
3138
3329
|
}
|
|
3139
3330
|
};
|
|
3140
3331
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -3147,8 +3338,11 @@ function globalEventHandler(e) {
|
|
|
3147
3338
|
const path = e.composedPath();
|
|
3148
3339
|
retarget(path[0]);
|
|
3149
3340
|
for (let i = 0; i < path.length - 2; i++) {
|
|
3150
|
-
|
|
3341
|
+
const nextNode = asElement(path[i]);
|
|
3342
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3343
|
+
node = nextNode;
|
|
3151
3344
|
if (!handleNode()) break;
|
|
3345
|
+
lastHandled = node;
|
|
3152
3346
|
if (node._$host) {
|
|
3153
3347
|
node = node._$host;
|
|
3154
3348
|
walkUpTree();
|