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