@fictjs/runtime 0.0.9 → 0.0.10
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 +325 -198
- 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 +327 -198
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +325 -198
- package/dist/index.js.map +1 -1
- package/dist/slim.cjs +325 -198
- 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 +325 -198
- 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 +2 -1
- package/src/hooks.ts +14 -1
- package/src/list-helpers.ts +125 -47
- package/src/signal.ts +16 -2
package/dist/index.cjs
CHANGED
|
@@ -807,10 +807,17 @@ function effectScopeOper() {
|
|
|
807
807
|
}
|
|
808
808
|
function batch(fn) {
|
|
809
809
|
++batchDepth;
|
|
810
|
+
let hasError = false;
|
|
810
811
|
try {
|
|
811
812
|
return fn();
|
|
813
|
+
} catch (e) {
|
|
814
|
+
hasError = true;
|
|
815
|
+
throw e;
|
|
812
816
|
} finally {
|
|
813
|
-
|
|
817
|
+
--batchDepth;
|
|
818
|
+
if (!hasError && batchDepth === 0) {
|
|
819
|
+
flush();
|
|
820
|
+
}
|
|
814
821
|
}
|
|
815
822
|
}
|
|
816
823
|
function setActiveSub(sub) {
|
|
@@ -866,7 +873,7 @@ function effectRunDevtools(node) {
|
|
|
866
873
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
867
874
|
let current = source();
|
|
868
875
|
const observers = /* @__PURE__ */ new Map();
|
|
869
|
-
effect(() => {
|
|
876
|
+
const dispose = effect(() => {
|
|
870
877
|
const next = source();
|
|
871
878
|
if (equalityFn(current, next)) return;
|
|
872
879
|
const prevSig = observers.get(current);
|
|
@@ -875,6 +882,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
875
882
|
if (nextSig) nextSig(true);
|
|
876
883
|
current = next;
|
|
877
884
|
});
|
|
885
|
+
registerRootCleanup(() => {
|
|
886
|
+
dispose();
|
|
887
|
+
observers.clear();
|
|
888
|
+
});
|
|
878
889
|
return (key) => {
|
|
879
890
|
let sig = observers.get(key);
|
|
880
891
|
if (!sig) {
|
|
@@ -1062,7 +1073,8 @@ function createRenderEffect(fn) {
|
|
|
1062
1073
|
cleanup = maybeCleanup;
|
|
1063
1074
|
}
|
|
1064
1075
|
} catch (err) {
|
|
1065
|
-
|
|
1076
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1077
|
+
if (handled) {
|
|
1066
1078
|
return;
|
|
1067
1079
|
}
|
|
1068
1080
|
throw err;
|
|
@@ -1454,159 +1466,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1454
1466
|
// src/jsx.ts
|
|
1455
1467
|
var Fragment = Symbol("Fragment");
|
|
1456
1468
|
|
|
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
1469
|
// src/hooks.ts
|
|
1601
1470
|
var ctxStack = [];
|
|
1471
|
+
function assertRenderContext(ctx, hookName) {
|
|
1472
|
+
if (!ctx.rendering) {
|
|
1473
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1602
1476
|
function __fictUseContext() {
|
|
1603
1477
|
if (ctxStack.length === 0) {
|
|
1604
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1478
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1605
1479
|
ctxStack.push(ctx2);
|
|
1606
1480
|
return ctx2;
|
|
1607
1481
|
}
|
|
1608
1482
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1609
1483
|
ctx.cursor = 0;
|
|
1484
|
+
ctx.rendering = true;
|
|
1610
1485
|
return ctx;
|
|
1611
1486
|
}
|
|
1612
1487
|
function __fictPushContext() {
|
|
@@ -1621,6 +1496,7 @@ function __fictResetContext() {
|
|
|
1621
1496
|
ctxStack.length = 0;
|
|
1622
1497
|
}
|
|
1623
1498
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1499
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1624
1500
|
const index = slot ?? ctx.cursor++;
|
|
1625
1501
|
if (!ctx.slots[index]) {
|
|
1626
1502
|
ctx.slots[index] = signal(initial);
|
|
@@ -1628,6 +1504,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1628
1504
|
return ctx.slots[index];
|
|
1629
1505
|
}
|
|
1630
1506
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1507
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1631
1508
|
const index = slot ?? ctx.cursor++;
|
|
1632
1509
|
if (!ctx.slots[index]) {
|
|
1633
1510
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1635,6 +1512,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1635
1512
|
return ctx.slots[index];
|
|
1636
1513
|
}
|
|
1637
1514
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1515
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1638
1516
|
const index = slot ?? ctx.cursor++;
|
|
1639
1517
|
if (!ctx.slots[index]) {
|
|
1640
1518
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1643,9 +1521,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1643
1521
|
function __fictRender(ctx, fn) {
|
|
1644
1522
|
ctxStack.push(ctx);
|
|
1645
1523
|
ctx.cursor = 0;
|
|
1524
|
+
ctx.rendering = true;
|
|
1646
1525
|
try {
|
|
1647
1526
|
return fn();
|
|
1648
1527
|
} finally {
|
|
1528
|
+
ctx.rendering = false;
|
|
1649
1529
|
ctxStack.pop();
|
|
1650
1530
|
}
|
|
1651
1531
|
}
|
|
@@ -1886,6 +1766,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1886
1766
|
if (typeof handle.dispose === "function") {
|
|
1887
1767
|
registerRootCleanup(handle.dispose);
|
|
1888
1768
|
}
|
|
1769
|
+
if (typeof handle.flush === "function") {
|
|
1770
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1771
|
+
if (typeof queueMicrotask === "function") {
|
|
1772
|
+
queueMicrotask(runFlush);
|
|
1773
|
+
} else {
|
|
1774
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1889
1777
|
return createElement(handle.marker);
|
|
1890
1778
|
}
|
|
1891
1779
|
const nodeRecord = node;
|
|
@@ -1933,18 +1821,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1933
1821
|
}
|
|
1934
1822
|
});
|
|
1935
1823
|
const props = createPropsProxy(baseProps);
|
|
1824
|
+
__fictPushContext();
|
|
1936
1825
|
try {
|
|
1937
|
-
__fictPushContext();
|
|
1938
1826
|
const rendered = vnode.type(props);
|
|
1939
|
-
__fictPopContext();
|
|
1940
1827
|
return createElementWithContext(rendered, namespace);
|
|
1941
1828
|
} catch (err) {
|
|
1942
|
-
__fictPopContext();
|
|
1943
1829
|
if (handleSuspend(err)) {
|
|
1944
1830
|
return document.createComment("fict:suspend");
|
|
1945
1831
|
}
|
|
1946
1832
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1947
1833
|
throw err;
|
|
1834
|
+
} finally {
|
|
1835
|
+
__fictPopContext();
|
|
1948
1836
|
}
|
|
1949
1837
|
}
|
|
1950
1838
|
if (vnode.type === Fragment) {
|
|
@@ -2236,6 +2124,149 @@ function eventNameFromProp(key) {
|
|
|
2236
2124
|
return key.slice(2).toLowerCase();
|
|
2237
2125
|
}
|
|
2238
2126
|
|
|
2127
|
+
// src/node-ops.ts
|
|
2128
|
+
function toNodeArray(node) {
|
|
2129
|
+
try {
|
|
2130
|
+
if (Array.isArray(node)) {
|
|
2131
|
+
let allNodes = true;
|
|
2132
|
+
for (const item of node) {
|
|
2133
|
+
let isItemNode = false;
|
|
2134
|
+
try {
|
|
2135
|
+
isItemNode = item instanceof Node;
|
|
2136
|
+
} catch {
|
|
2137
|
+
isItemNode = false;
|
|
2138
|
+
}
|
|
2139
|
+
if (!isItemNode) {
|
|
2140
|
+
allNodes = false;
|
|
2141
|
+
break;
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (allNodes) {
|
|
2145
|
+
return node;
|
|
2146
|
+
}
|
|
2147
|
+
const result = [];
|
|
2148
|
+
for (const item of node) {
|
|
2149
|
+
result.push(...toNodeArray(item));
|
|
2150
|
+
}
|
|
2151
|
+
return result;
|
|
2152
|
+
}
|
|
2153
|
+
if (node === null || node === void 0 || node === false) {
|
|
2154
|
+
return [];
|
|
2155
|
+
}
|
|
2156
|
+
} catch {
|
|
2157
|
+
return [];
|
|
2158
|
+
}
|
|
2159
|
+
let isNode = false;
|
|
2160
|
+
try {
|
|
2161
|
+
isNode = node instanceof Node;
|
|
2162
|
+
} catch {
|
|
2163
|
+
isNode = false;
|
|
2164
|
+
}
|
|
2165
|
+
if (isNode) {
|
|
2166
|
+
try {
|
|
2167
|
+
if (node instanceof DocumentFragment) {
|
|
2168
|
+
return Array.from(node.childNodes);
|
|
2169
|
+
}
|
|
2170
|
+
} catch {
|
|
2171
|
+
}
|
|
2172
|
+
return [node];
|
|
2173
|
+
}
|
|
2174
|
+
try {
|
|
2175
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
2176
|
+
return toNodeArray(node.marker);
|
|
2177
|
+
}
|
|
2178
|
+
} catch {
|
|
2179
|
+
}
|
|
2180
|
+
try {
|
|
2181
|
+
return [document.createTextNode(String(node))];
|
|
2182
|
+
} catch {
|
|
2183
|
+
return [document.createTextNode("")];
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
2187
|
+
if (nodes.length === 0) return;
|
|
2188
|
+
if (nodes.length === 1) {
|
|
2189
|
+
const node = nodes[0];
|
|
2190
|
+
if (node === void 0 || node === null) return;
|
|
2191
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2192
|
+
parent.ownerDocument.adoptNode(node);
|
|
2193
|
+
}
|
|
2194
|
+
try {
|
|
2195
|
+
parent.insertBefore(node, anchor);
|
|
2196
|
+
} catch (e) {
|
|
2197
|
+
if (parent.ownerDocument) {
|
|
2198
|
+
try {
|
|
2199
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
2200
|
+
parent.insertBefore(clone, anchor);
|
|
2201
|
+
return;
|
|
2202
|
+
} catch {
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
throw e;
|
|
2206
|
+
}
|
|
2207
|
+
return;
|
|
2208
|
+
}
|
|
2209
|
+
const doc = parent.ownerDocument;
|
|
2210
|
+
if (doc) {
|
|
2211
|
+
const frag = doc.createDocumentFragment();
|
|
2212
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2213
|
+
const node = nodes[i];
|
|
2214
|
+
if (node === void 0 || node === null) continue;
|
|
2215
|
+
if (node.nodeType === 11) {
|
|
2216
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2217
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2218
|
+
frag.appendChild(childrenArr[j]);
|
|
2219
|
+
}
|
|
2220
|
+
} else {
|
|
2221
|
+
if (node.ownerDocument !== doc) {
|
|
2222
|
+
doc.adoptNode(node);
|
|
2223
|
+
}
|
|
2224
|
+
frag.appendChild(node);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
parent.insertBefore(frag, anchor);
|
|
2228
|
+
return;
|
|
2229
|
+
}
|
|
2230
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2231
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2232
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2233
|
+
}
|
|
2234
|
+
try {
|
|
2235
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2236
|
+
return nodeToInsert;
|
|
2237
|
+
} catch (e) {
|
|
2238
|
+
if (parent.ownerDocument) {
|
|
2239
|
+
try {
|
|
2240
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2241
|
+
parent.insertBefore(clone, anchorNode);
|
|
2242
|
+
return clone;
|
|
2243
|
+
} catch {
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
throw e;
|
|
2247
|
+
}
|
|
2248
|
+
};
|
|
2249
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2250
|
+
const node = nodes[i];
|
|
2251
|
+
if (node === void 0 || node === null) continue;
|
|
2252
|
+
const isFrag = node.nodeType === 11;
|
|
2253
|
+
if (isFrag) {
|
|
2254
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2255
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2256
|
+
const child = childrenArr[j];
|
|
2257
|
+
anchor = insertSingle(child, anchor);
|
|
2258
|
+
}
|
|
2259
|
+
} else {
|
|
2260
|
+
anchor = insertSingle(node, anchor);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
function removeNodes(nodes) {
|
|
2265
|
+
for (const node of nodes) {
|
|
2266
|
+
node.parentNode?.removeChild(node);
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2239
2270
|
// src/reconcile.ts
|
|
2240
2271
|
function reconcileArrays(parentNode, a, b) {
|
|
2241
2272
|
const bLength = b.length;
|
|
@@ -2463,7 +2494,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2463
2494
|
} finally {
|
|
2464
2495
|
setActiveSub(prevSub);
|
|
2465
2496
|
popRoot(prevRoot);
|
|
2466
|
-
flushOnMount(root);
|
|
2467
2497
|
}
|
|
2468
2498
|
return {
|
|
2469
2499
|
key,
|
|
@@ -2495,13 +2525,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2495
2525
|
const hostRoot = getCurrentRoot();
|
|
2496
2526
|
const fragment = document.createDocumentFragment();
|
|
2497
2527
|
fragment.append(container.startMarker, container.endMarker);
|
|
2498
|
-
let pendingItems = null;
|
|
2499
2528
|
let disposed = false;
|
|
2529
|
+
let effectDispose;
|
|
2530
|
+
let connectObserver = null;
|
|
2531
|
+
let effectStarted = false;
|
|
2532
|
+
let startScheduled = false;
|
|
2533
|
+
const getConnectedParent = () => {
|
|
2534
|
+
const endParent = container.endMarker.parentNode;
|
|
2535
|
+
const startParent = container.startMarker.parentNode;
|
|
2536
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2537
|
+
return endParent;
|
|
2538
|
+
}
|
|
2539
|
+
return null;
|
|
2540
|
+
};
|
|
2500
2541
|
const performDiff = () => {
|
|
2501
2542
|
if (disposed) return;
|
|
2543
|
+
const parent = getConnectedParent();
|
|
2544
|
+
if (!parent) return;
|
|
2502
2545
|
batch2(() => {
|
|
2503
|
-
const newItems = pendingItems || getItems();
|
|
2504
|
-
pendingItems = null;
|
|
2505
2546
|
const oldBlocks = container.blocks;
|
|
2506
2547
|
const newBlocks = container.nextBlocks;
|
|
2507
2548
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2510,20 +2551,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2510
2551
|
newBlocks.clear();
|
|
2511
2552
|
nextOrderedBlocks.length = 0;
|
|
2512
2553
|
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
|
-
}
|
|
2554
|
+
const createdBlocks = [];
|
|
2555
|
+
const newItems = getItems();
|
|
2521
2556
|
if (newItems.length === 0) {
|
|
2522
2557
|
if (oldBlocks.size > 0) {
|
|
2523
2558
|
for (const block of oldBlocks.values()) {
|
|
2524
2559
|
destroyRoot(block.root);
|
|
2525
|
-
removeNodes(block.nodes);
|
|
2526
2560
|
}
|
|
2561
|
+
const range = document.createRange();
|
|
2562
|
+
range.setStartAfter(container.startMarker);
|
|
2563
|
+
range.setEndBefore(container.endMarker);
|
|
2564
|
+
range.deleteContents();
|
|
2527
2565
|
}
|
|
2528
2566
|
oldBlocks.clear();
|
|
2529
2567
|
newBlocks.clear();
|
|
@@ -2540,8 +2578,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2540
2578
|
const appendedBlocks = [];
|
|
2541
2579
|
newItems.forEach((item, index) => {
|
|
2542
2580
|
const key = keyFn(item, index);
|
|
2543
|
-
const existed = oldBlocks.has(key);
|
|
2544
2581
|
let block = oldBlocks.get(key);
|
|
2582
|
+
const existed = block !== void 0;
|
|
2545
2583
|
if (block) {
|
|
2546
2584
|
if (block.rawItem !== item) {
|
|
2547
2585
|
block.rawItem = item;
|
|
@@ -2552,38 +2590,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2552
2590
|
block.index(index);
|
|
2553
2591
|
}
|
|
2554
2592
|
}
|
|
2555
|
-
const existingBlock = newBlocks.get(key);
|
|
2556
|
-
if (existingBlock && existingBlock !== block) {
|
|
2557
|
-
destroyRoot(existingBlock.root);
|
|
2558
|
-
removeNodes(existingBlock.nodes);
|
|
2559
|
-
}
|
|
2560
2593
|
if (block) {
|
|
2561
2594
|
newBlocks.set(key, block);
|
|
2562
2595
|
oldBlocks.delete(key);
|
|
2563
2596
|
} else {
|
|
2564
|
-
const
|
|
2565
|
-
if (
|
|
2566
|
-
destroyRoot(
|
|
2567
|
-
removeNodes(
|
|
2597
|
+
const existingBlock = newBlocks.get(key);
|
|
2598
|
+
if (existingBlock) {
|
|
2599
|
+
destroyRoot(existingBlock.root);
|
|
2600
|
+
removeNodes(existingBlock.nodes);
|
|
2568
2601
|
}
|
|
2569
2602
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2603
|
+
createdBlocks.push(block);
|
|
2570
2604
|
}
|
|
2571
2605
|
const resolvedBlock = block;
|
|
2572
2606
|
newBlocks.set(key, resolvedBlock);
|
|
2573
2607
|
const position = orderedIndexByKey.get(key);
|
|
2574
2608
|
if (position !== void 0) {
|
|
2575
2609
|
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
2610
|
const prior = nextOrderedBlocks[position];
|
|
2588
2611
|
if (prior && prior !== resolvedBlock) {
|
|
2589
2612
|
destroyRoot(prior.root);
|
|
@@ -2591,6 +2614,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2591
2614
|
}
|
|
2592
2615
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2593
2616
|
} else {
|
|
2617
|
+
if (appendCandidate) {
|
|
2618
|
+
if (index < prevCount) {
|
|
2619
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2620
|
+
appendCandidate = false;
|
|
2621
|
+
}
|
|
2622
|
+
} else if (existed) {
|
|
2623
|
+
appendCandidate = false;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2594
2626
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2595
2627
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2596
2628
|
}
|
|
@@ -2619,6 +2651,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2619
2651
|
container.nextBlocks = oldBlocks;
|
|
2620
2652
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2621
2653
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2654
|
+
for (const block of createdBlocks) {
|
|
2655
|
+
if (newBlocks.get(block.key) === block) {
|
|
2656
|
+
flushOnMount(block.root);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2622
2659
|
return;
|
|
2623
2660
|
}
|
|
2624
2661
|
if (oldBlocks.size > 0) {
|
|
@@ -2648,22 +2685,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2648
2685
|
container.nextBlocks = oldBlocks;
|
|
2649
2686
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2650
2687
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2688
|
+
for (const block of createdBlocks) {
|
|
2689
|
+
if (newBlocks.get(block.key) === block) {
|
|
2690
|
+
flushOnMount(block.root);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2651
2693
|
});
|
|
2652
2694
|
};
|
|
2653
|
-
const
|
|
2695
|
+
const disconnectObserver = () => {
|
|
2696
|
+
connectObserver?.disconnect();
|
|
2697
|
+
connectObserver = null;
|
|
2698
|
+
};
|
|
2699
|
+
const ensureEffectStarted = () => {
|
|
2700
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2701
|
+
const parent = getConnectedParent();
|
|
2702
|
+
if (!parent) return false;
|
|
2703
|
+
const start = () => {
|
|
2704
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2705
|
+
effectStarted = true;
|
|
2706
|
+
};
|
|
2707
|
+
if (hostRoot) {
|
|
2708
|
+
const prev = pushRoot(hostRoot);
|
|
2709
|
+
try {
|
|
2710
|
+
start();
|
|
2711
|
+
} finally {
|
|
2712
|
+
popRoot(prev);
|
|
2713
|
+
}
|
|
2714
|
+
} else {
|
|
2715
|
+
start();
|
|
2716
|
+
}
|
|
2717
|
+
return true;
|
|
2718
|
+
};
|
|
2719
|
+
const waitForConnection = () => {
|
|
2720
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2721
|
+
connectObserver = new MutationObserver(() => {
|
|
2722
|
+
if (disposed) return;
|
|
2723
|
+
if (getConnectedParent()) {
|
|
2724
|
+
disconnectObserver();
|
|
2725
|
+
if (ensureEffectStarted()) {
|
|
2726
|
+
flush();
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
});
|
|
2730
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2731
|
+
};
|
|
2732
|
+
const scheduleStart = () => {
|
|
2733
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2734
|
+
startScheduled = true;
|
|
2735
|
+
const run = () => {
|
|
2736
|
+
startScheduled = false;
|
|
2737
|
+
if (!ensureEffectStarted()) {
|
|
2738
|
+
waitForConnection();
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
if (typeof queueMicrotask === "function") {
|
|
2742
|
+
queueMicrotask(run);
|
|
2743
|
+
} else {
|
|
2744
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
scheduleStart();
|
|
2654
2748
|
return {
|
|
2655
|
-
marker
|
|
2749
|
+
get marker() {
|
|
2750
|
+
scheduleStart();
|
|
2751
|
+
return fragment;
|
|
2752
|
+
},
|
|
2656
2753
|
startMarker: container.startMarker,
|
|
2657
2754
|
endMarker: container.endMarker,
|
|
2658
2755
|
// Flush pending items - call after markers are inserted into DOM
|
|
2659
2756
|
flush: () => {
|
|
2660
|
-
if (
|
|
2661
|
-
|
|
2757
|
+
if (disposed) return;
|
|
2758
|
+
scheduleStart();
|
|
2759
|
+
if (ensureEffectStarted()) {
|
|
2760
|
+
flush();
|
|
2761
|
+
} else {
|
|
2762
|
+
waitForConnection();
|
|
2662
2763
|
}
|
|
2663
2764
|
},
|
|
2664
2765
|
dispose: () => {
|
|
2665
2766
|
disposed = true;
|
|
2666
2767
|
effectDispose?.();
|
|
2768
|
+
disconnectObserver();
|
|
2667
2769
|
container.dispose();
|
|
2668
2770
|
}
|
|
2669
2771
|
};
|
|
@@ -2863,8 +2965,17 @@ function createClassBinding(el, value) {
|
|
|
2863
2965
|
}
|
|
2864
2966
|
function bindClass(el, getValue) {
|
|
2865
2967
|
let prev = {};
|
|
2968
|
+
let prevString;
|
|
2866
2969
|
return createRenderEffect(() => {
|
|
2867
2970
|
const next = getValue();
|
|
2971
|
+
if (typeof next === "string") {
|
|
2972
|
+
if (next === prevString) return;
|
|
2973
|
+
prevString = next;
|
|
2974
|
+
el.className = next;
|
|
2975
|
+
prev = {};
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
prevString = void 0;
|
|
2868
2979
|
prev = applyClass(el, next, prev);
|
|
2869
2980
|
});
|
|
2870
2981
|
}
|
|
@@ -3093,11 +3204,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
3093
3204
|
}
|
|
3094
3205
|
}
|
|
3095
3206
|
function globalEventHandler(e) {
|
|
3096
|
-
|
|
3207
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
3208
|
+
const asElement = (value) => {
|
|
3209
|
+
const n = asNode(value);
|
|
3210
|
+
if (!n) return null;
|
|
3211
|
+
if (n.nodeType === 1) return n;
|
|
3212
|
+
return n.parentElement;
|
|
3213
|
+
};
|
|
3214
|
+
let node = asElement(e.target);
|
|
3097
3215
|
const key = `$$${e.type}`;
|
|
3098
3216
|
const dataKey = `${key}Data`;
|
|
3099
3217
|
const oriTarget = e.target;
|
|
3100
3218
|
const oriCurrentTarget = e.currentTarget;
|
|
3219
|
+
let lastHandled = null;
|
|
3101
3220
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
3102
3221
|
configurable: true,
|
|
3103
3222
|
value
|
|
@@ -3120,23 +3239,28 @@ function globalEventHandler(e) {
|
|
|
3120
3239
|
const rawData = node[dataKey];
|
|
3121
3240
|
const hasData = rawData !== void 0;
|
|
3122
3241
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3242
|
+
batch2(() => {
|
|
3243
|
+
if (typeof handler === "function") {
|
|
3244
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
3245
|
+
} else if (Array.isArray(handler)) {
|
|
3246
|
+
const tupleData = resolveData(handler[1]);
|
|
3247
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
3248
|
+
}
|
|
3249
|
+
});
|
|
3129
3250
|
if (e.cancelBubble) return false;
|
|
3130
3251
|
}
|
|
3131
3252
|
const shadowHost = node.host;
|
|
3132
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3253
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3254
|
+
const targetNode = asNode(e.target);
|
|
3255
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3256
|
+
})()) {
|
|
3133
3257
|
retarget(shadowHost);
|
|
3134
3258
|
}
|
|
3135
3259
|
return true;
|
|
3136
3260
|
};
|
|
3137
3261
|
const walkUpTree = () => {
|
|
3138
3262
|
while (handleNode() && node) {
|
|
3139
|
-
node = node._$host || node.parentNode || node.host;
|
|
3263
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
3140
3264
|
}
|
|
3141
3265
|
};
|
|
3142
3266
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -3149,8 +3273,11 @@ function globalEventHandler(e) {
|
|
|
3149
3273
|
const path = e.composedPath();
|
|
3150
3274
|
retarget(path[0]);
|
|
3151
3275
|
for (let i = 0; i < path.length - 2; i++) {
|
|
3152
|
-
|
|
3276
|
+
const nextNode = asElement(path[i]);
|
|
3277
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3278
|
+
node = nextNode;
|
|
3153
3279
|
if (!handleNode()) break;
|
|
3280
|
+
lastHandled = node;
|
|
3154
3281
|
if (node._$host) {
|
|
3155
3282
|
node = node._$host;
|
|
3156
3283
|
walkUpTree();
|