@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/slim.js
CHANGED
|
@@ -764,10 +764,17 @@ function effectScopeOper() {
|
|
|
764
764
|
}
|
|
765
765
|
function batch(fn) {
|
|
766
766
|
++batchDepth;
|
|
767
|
+
let hasError = false;
|
|
767
768
|
try {
|
|
768
769
|
return fn();
|
|
770
|
+
} catch (e) {
|
|
771
|
+
hasError = true;
|
|
772
|
+
throw e;
|
|
769
773
|
} finally {
|
|
770
|
-
|
|
774
|
+
--batchDepth;
|
|
775
|
+
if (!hasError && batchDepth === 0) {
|
|
776
|
+
flush();
|
|
777
|
+
}
|
|
771
778
|
}
|
|
772
779
|
}
|
|
773
780
|
function setActiveSub(sub) {
|
|
@@ -818,7 +825,7 @@ function effectRunDevtools(node) {
|
|
|
818
825
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
819
826
|
let current = source();
|
|
820
827
|
const observers = /* @__PURE__ */ new Map();
|
|
821
|
-
effect(() => {
|
|
828
|
+
const dispose = effect(() => {
|
|
822
829
|
const next = source();
|
|
823
830
|
if (equalityFn(current, next)) return;
|
|
824
831
|
const prevSig = observers.get(current);
|
|
@@ -827,6 +834,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
827
834
|
if (nextSig) nextSig(true);
|
|
828
835
|
current = next;
|
|
829
836
|
});
|
|
837
|
+
registerRootCleanup(() => {
|
|
838
|
+
dispose();
|
|
839
|
+
observers.clear();
|
|
840
|
+
});
|
|
830
841
|
return (key) => {
|
|
831
842
|
let sig = observers.get(key);
|
|
832
843
|
if (!sig) {
|
|
@@ -887,7 +898,8 @@ function createRenderEffect(fn) {
|
|
|
887
898
|
cleanup = maybeCleanup;
|
|
888
899
|
}
|
|
889
900
|
} catch (err) {
|
|
890
|
-
|
|
901
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
902
|
+
if (handled) {
|
|
891
903
|
return;
|
|
892
904
|
}
|
|
893
905
|
throw err;
|
|
@@ -1279,159 +1291,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1279
1291
|
// src/jsx.ts
|
|
1280
1292
|
var Fragment = Symbol("Fragment");
|
|
1281
1293
|
|
|
1282
|
-
// src/node-ops.ts
|
|
1283
|
-
function toNodeArray(node) {
|
|
1284
|
-
try {
|
|
1285
|
-
if (Array.isArray(node)) {
|
|
1286
|
-
let allNodes = true;
|
|
1287
|
-
for (const item of node) {
|
|
1288
|
-
let isItemNode = false;
|
|
1289
|
-
try {
|
|
1290
|
-
isItemNode = item instanceof Node;
|
|
1291
|
-
} catch {
|
|
1292
|
-
isItemNode = false;
|
|
1293
|
-
}
|
|
1294
|
-
if (!isItemNode) {
|
|
1295
|
-
allNodes = false;
|
|
1296
|
-
break;
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
if (allNodes) {
|
|
1300
|
-
return node;
|
|
1301
|
-
}
|
|
1302
|
-
const result = [];
|
|
1303
|
-
for (const item of node) {
|
|
1304
|
-
result.push(...toNodeArray(item));
|
|
1305
|
-
}
|
|
1306
|
-
return result;
|
|
1307
|
-
}
|
|
1308
|
-
if (node === null || node === void 0 || node === false) {
|
|
1309
|
-
return [];
|
|
1310
|
-
}
|
|
1311
|
-
} catch {
|
|
1312
|
-
return [];
|
|
1313
|
-
}
|
|
1314
|
-
let isNode = false;
|
|
1315
|
-
try {
|
|
1316
|
-
isNode = node instanceof Node;
|
|
1317
|
-
} catch {
|
|
1318
|
-
isNode = false;
|
|
1319
|
-
}
|
|
1320
|
-
if (isNode) {
|
|
1321
|
-
try {
|
|
1322
|
-
if (node instanceof DocumentFragment) {
|
|
1323
|
-
return Array.from(node.childNodes);
|
|
1324
|
-
}
|
|
1325
|
-
} catch {
|
|
1326
|
-
}
|
|
1327
|
-
return [node];
|
|
1328
|
-
}
|
|
1329
|
-
try {
|
|
1330
|
-
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
1331
|
-
return toNodeArray(node.marker);
|
|
1332
|
-
}
|
|
1333
|
-
} catch {
|
|
1334
|
-
}
|
|
1335
|
-
try {
|
|
1336
|
-
return [document.createTextNode(String(node))];
|
|
1337
|
-
} catch {
|
|
1338
|
-
return [document.createTextNode("")];
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
function insertNodesBefore(parent, nodes, anchor) {
|
|
1342
|
-
if (nodes.length === 0) return;
|
|
1343
|
-
if (nodes.length === 1) {
|
|
1344
|
-
const node = nodes[0];
|
|
1345
|
-
if (node === void 0 || node === null) return;
|
|
1346
|
-
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1347
|
-
parent.ownerDocument.adoptNode(node);
|
|
1348
|
-
}
|
|
1349
|
-
try {
|
|
1350
|
-
parent.insertBefore(node, anchor);
|
|
1351
|
-
} catch (e) {
|
|
1352
|
-
if (parent.ownerDocument) {
|
|
1353
|
-
try {
|
|
1354
|
-
const clone = parent.ownerDocument.importNode(node, true);
|
|
1355
|
-
parent.insertBefore(clone, anchor);
|
|
1356
|
-
return;
|
|
1357
|
-
} catch {
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
throw e;
|
|
1361
|
-
}
|
|
1362
|
-
return;
|
|
1363
|
-
}
|
|
1364
|
-
const doc = parent.ownerDocument;
|
|
1365
|
-
if (doc) {
|
|
1366
|
-
const frag = doc.createDocumentFragment();
|
|
1367
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
1368
|
-
const node = nodes[i];
|
|
1369
|
-
if (node === void 0 || node === null) continue;
|
|
1370
|
-
if (node.nodeType === 11) {
|
|
1371
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1372
|
-
for (let j = 0; j < childrenArr.length; j++) {
|
|
1373
|
-
frag.appendChild(childrenArr[j]);
|
|
1374
|
-
}
|
|
1375
|
-
} else {
|
|
1376
|
-
if (node.ownerDocument !== doc) {
|
|
1377
|
-
doc.adoptNode(node);
|
|
1378
|
-
}
|
|
1379
|
-
frag.appendChild(node);
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
parent.insertBefore(frag, anchor);
|
|
1383
|
-
return;
|
|
1384
|
-
}
|
|
1385
|
-
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
1386
|
-
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1387
|
-
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
1388
|
-
}
|
|
1389
|
-
try {
|
|
1390
|
-
parent.insertBefore(nodeToInsert, anchorNode);
|
|
1391
|
-
return nodeToInsert;
|
|
1392
|
-
} catch (e) {
|
|
1393
|
-
if (parent.ownerDocument) {
|
|
1394
|
-
try {
|
|
1395
|
-
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
1396
|
-
parent.insertBefore(clone, anchorNode);
|
|
1397
|
-
return clone;
|
|
1398
|
-
} catch {
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
throw e;
|
|
1402
|
-
}
|
|
1403
|
-
};
|
|
1404
|
-
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
1405
|
-
const node = nodes[i];
|
|
1406
|
-
if (node === void 0 || node === null) continue;
|
|
1407
|
-
const isFrag = node.nodeType === 11;
|
|
1408
|
-
if (isFrag) {
|
|
1409
|
-
const childrenArr = Array.from(node.childNodes);
|
|
1410
|
-
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
1411
|
-
const child = childrenArr[j];
|
|
1412
|
-
anchor = insertSingle(child, anchor);
|
|
1413
|
-
}
|
|
1414
|
-
} else {
|
|
1415
|
-
anchor = insertSingle(node, anchor);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
function removeNodes(nodes) {
|
|
1420
|
-
for (const node of nodes) {
|
|
1421
|
-
node.parentNode?.removeChild(node);
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
1294
|
// src/hooks.ts
|
|
1426
1295
|
var ctxStack = [];
|
|
1296
|
+
function assertRenderContext(ctx, hookName) {
|
|
1297
|
+
if (!ctx.rendering) {
|
|
1298
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1427
1301
|
function __fictUseContext() {
|
|
1428
1302
|
if (ctxStack.length === 0) {
|
|
1429
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1303
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1430
1304
|
ctxStack.push(ctx2);
|
|
1431
1305
|
return ctx2;
|
|
1432
1306
|
}
|
|
1433
1307
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1434
1308
|
ctx.cursor = 0;
|
|
1309
|
+
ctx.rendering = true;
|
|
1435
1310
|
return ctx;
|
|
1436
1311
|
}
|
|
1437
1312
|
function __fictPushContext() {
|
|
@@ -1446,6 +1321,7 @@ function __fictResetContext() {
|
|
|
1446
1321
|
ctxStack.length = 0;
|
|
1447
1322
|
}
|
|
1448
1323
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1324
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1449
1325
|
const index = slot ?? ctx.cursor++;
|
|
1450
1326
|
if (!ctx.slots[index]) {
|
|
1451
1327
|
ctx.slots[index] = signal(initial);
|
|
@@ -1453,6 +1329,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1453
1329
|
return ctx.slots[index];
|
|
1454
1330
|
}
|
|
1455
1331
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1332
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1456
1333
|
const index = slot ?? ctx.cursor++;
|
|
1457
1334
|
if (!ctx.slots[index]) {
|
|
1458
1335
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1460,6 +1337,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1460
1337
|
return ctx.slots[index];
|
|
1461
1338
|
}
|
|
1462
1339
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1340
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1463
1341
|
const index = slot ?? ctx.cursor++;
|
|
1464
1342
|
if (!ctx.slots[index]) {
|
|
1465
1343
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1468,9 +1346,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1468
1346
|
function __fictRender(ctx, fn) {
|
|
1469
1347
|
ctxStack.push(ctx);
|
|
1470
1348
|
ctx.cursor = 0;
|
|
1349
|
+
ctx.rendering = true;
|
|
1471
1350
|
try {
|
|
1472
1351
|
return fn();
|
|
1473
1352
|
} finally {
|
|
1353
|
+
ctx.rendering = false;
|
|
1474
1354
|
ctxStack.pop();
|
|
1475
1355
|
}
|
|
1476
1356
|
}
|
|
@@ -1673,6 +1553,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1673
1553
|
if (typeof handle.dispose === "function") {
|
|
1674
1554
|
registerRootCleanup(handle.dispose);
|
|
1675
1555
|
}
|
|
1556
|
+
if (typeof handle.flush === "function") {
|
|
1557
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1558
|
+
if (typeof queueMicrotask === "function") {
|
|
1559
|
+
queueMicrotask(runFlush);
|
|
1560
|
+
} else {
|
|
1561
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1676
1564
|
return createElement(handle.marker);
|
|
1677
1565
|
}
|
|
1678
1566
|
const nodeRecord = node;
|
|
@@ -1720,18 +1608,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1720
1608
|
}
|
|
1721
1609
|
});
|
|
1722
1610
|
const props = createPropsProxy(baseProps);
|
|
1611
|
+
__fictPushContext();
|
|
1723
1612
|
try {
|
|
1724
|
-
__fictPushContext();
|
|
1725
1613
|
const rendered = vnode.type(props);
|
|
1726
|
-
__fictPopContext();
|
|
1727
1614
|
return createElementWithContext(rendered, namespace);
|
|
1728
1615
|
} catch (err) {
|
|
1729
|
-
__fictPopContext();
|
|
1730
1616
|
if (handleSuspend(err)) {
|
|
1731
1617
|
return document.createComment("fict:suspend");
|
|
1732
1618
|
}
|
|
1733
1619
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1734
1620
|
throw err;
|
|
1621
|
+
} finally {
|
|
1622
|
+
__fictPopContext();
|
|
1735
1623
|
}
|
|
1736
1624
|
}
|
|
1737
1625
|
if (vnode.type === Fragment) {
|
|
@@ -2023,6 +1911,149 @@ function eventNameFromProp(key) {
|
|
|
2023
1911
|
return key.slice(2).toLowerCase();
|
|
2024
1912
|
}
|
|
2025
1913
|
|
|
1914
|
+
// src/node-ops.ts
|
|
1915
|
+
function toNodeArray(node) {
|
|
1916
|
+
try {
|
|
1917
|
+
if (Array.isArray(node)) {
|
|
1918
|
+
let allNodes = true;
|
|
1919
|
+
for (const item of node) {
|
|
1920
|
+
let isItemNode = false;
|
|
1921
|
+
try {
|
|
1922
|
+
isItemNode = item instanceof Node;
|
|
1923
|
+
} catch {
|
|
1924
|
+
isItemNode = false;
|
|
1925
|
+
}
|
|
1926
|
+
if (!isItemNode) {
|
|
1927
|
+
allNodes = false;
|
|
1928
|
+
break;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
if (allNodes) {
|
|
1932
|
+
return node;
|
|
1933
|
+
}
|
|
1934
|
+
const result = [];
|
|
1935
|
+
for (const item of node) {
|
|
1936
|
+
result.push(...toNodeArray(item));
|
|
1937
|
+
}
|
|
1938
|
+
return result;
|
|
1939
|
+
}
|
|
1940
|
+
if (node === null || node === void 0 || node === false) {
|
|
1941
|
+
return [];
|
|
1942
|
+
}
|
|
1943
|
+
} catch {
|
|
1944
|
+
return [];
|
|
1945
|
+
}
|
|
1946
|
+
let isNode = false;
|
|
1947
|
+
try {
|
|
1948
|
+
isNode = node instanceof Node;
|
|
1949
|
+
} catch {
|
|
1950
|
+
isNode = false;
|
|
1951
|
+
}
|
|
1952
|
+
if (isNode) {
|
|
1953
|
+
try {
|
|
1954
|
+
if (node instanceof DocumentFragment) {
|
|
1955
|
+
return Array.from(node.childNodes);
|
|
1956
|
+
}
|
|
1957
|
+
} catch {
|
|
1958
|
+
}
|
|
1959
|
+
return [node];
|
|
1960
|
+
}
|
|
1961
|
+
try {
|
|
1962
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
1963
|
+
return toNodeArray(node.marker);
|
|
1964
|
+
}
|
|
1965
|
+
} catch {
|
|
1966
|
+
}
|
|
1967
|
+
try {
|
|
1968
|
+
return [document.createTextNode(String(node))];
|
|
1969
|
+
} catch {
|
|
1970
|
+
return [document.createTextNode("")];
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
1974
|
+
if (nodes.length === 0) return;
|
|
1975
|
+
if (nodes.length === 1) {
|
|
1976
|
+
const node = nodes[0];
|
|
1977
|
+
if (node === void 0 || node === null) return;
|
|
1978
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
1979
|
+
parent.ownerDocument.adoptNode(node);
|
|
1980
|
+
}
|
|
1981
|
+
try {
|
|
1982
|
+
parent.insertBefore(node, anchor);
|
|
1983
|
+
} catch (e) {
|
|
1984
|
+
if (parent.ownerDocument) {
|
|
1985
|
+
try {
|
|
1986
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
1987
|
+
parent.insertBefore(clone, anchor);
|
|
1988
|
+
return;
|
|
1989
|
+
} catch {
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
throw e;
|
|
1993
|
+
}
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
const doc = parent.ownerDocument;
|
|
1997
|
+
if (doc) {
|
|
1998
|
+
const frag = doc.createDocumentFragment();
|
|
1999
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2000
|
+
const node = nodes[i];
|
|
2001
|
+
if (node === void 0 || node === null) continue;
|
|
2002
|
+
if (node.nodeType === 11) {
|
|
2003
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2004
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2005
|
+
frag.appendChild(childrenArr[j]);
|
|
2006
|
+
}
|
|
2007
|
+
} else {
|
|
2008
|
+
if (node.ownerDocument !== doc) {
|
|
2009
|
+
doc.adoptNode(node);
|
|
2010
|
+
}
|
|
2011
|
+
frag.appendChild(node);
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
parent.insertBefore(frag, anchor);
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2018
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2019
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2020
|
+
}
|
|
2021
|
+
try {
|
|
2022
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2023
|
+
return nodeToInsert;
|
|
2024
|
+
} catch (e) {
|
|
2025
|
+
if (parent.ownerDocument) {
|
|
2026
|
+
try {
|
|
2027
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2028
|
+
parent.insertBefore(clone, anchorNode);
|
|
2029
|
+
return clone;
|
|
2030
|
+
} catch {
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
throw e;
|
|
2034
|
+
}
|
|
2035
|
+
};
|
|
2036
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2037
|
+
const node = nodes[i];
|
|
2038
|
+
if (node === void 0 || node === null) continue;
|
|
2039
|
+
const isFrag = node.nodeType === 11;
|
|
2040
|
+
if (isFrag) {
|
|
2041
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2042
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2043
|
+
const child = childrenArr[j];
|
|
2044
|
+
anchor = insertSingle(child, anchor);
|
|
2045
|
+
}
|
|
2046
|
+
} else {
|
|
2047
|
+
anchor = insertSingle(node, anchor);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
function removeNodes(nodes) {
|
|
2052
|
+
for (const node of nodes) {
|
|
2053
|
+
node.parentNode?.removeChild(node);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2026
2057
|
// src/reconcile.ts
|
|
2027
2058
|
function reconcileArrays(parentNode, a, b) {
|
|
2028
2059
|
const bLength = b.length;
|
|
@@ -2250,7 +2281,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2250
2281
|
} finally {
|
|
2251
2282
|
setActiveSub(prevSub);
|
|
2252
2283
|
popRoot(prevRoot);
|
|
2253
|
-
flushOnMount(root);
|
|
2254
2284
|
}
|
|
2255
2285
|
return {
|
|
2256
2286
|
key,
|
|
@@ -2274,13 +2304,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2274
2304
|
const hostRoot = getCurrentRoot();
|
|
2275
2305
|
const fragment = document.createDocumentFragment();
|
|
2276
2306
|
fragment.append(container.startMarker, container.endMarker);
|
|
2277
|
-
let pendingItems = null;
|
|
2278
2307
|
let disposed = false;
|
|
2308
|
+
let effectDispose;
|
|
2309
|
+
let connectObserver = null;
|
|
2310
|
+
let effectStarted = false;
|
|
2311
|
+
let startScheduled = false;
|
|
2312
|
+
const getConnectedParent = () => {
|
|
2313
|
+
const endParent = container.endMarker.parentNode;
|
|
2314
|
+
const startParent = container.startMarker.parentNode;
|
|
2315
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2316
|
+
return endParent;
|
|
2317
|
+
}
|
|
2318
|
+
return null;
|
|
2319
|
+
};
|
|
2279
2320
|
const performDiff = () => {
|
|
2280
2321
|
if (disposed) return;
|
|
2322
|
+
const parent = getConnectedParent();
|
|
2323
|
+
if (!parent) return;
|
|
2281
2324
|
batch2(() => {
|
|
2282
|
-
const newItems = pendingItems || getItems();
|
|
2283
|
-
pendingItems = null;
|
|
2284
2325
|
const oldBlocks = container.blocks;
|
|
2285
2326
|
const newBlocks = container.nextBlocks;
|
|
2286
2327
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2289,20 +2330,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2289
2330
|
newBlocks.clear();
|
|
2290
2331
|
nextOrderedBlocks.length = 0;
|
|
2291
2332
|
orderedIndexByKey.clear();
|
|
2292
|
-
const
|
|
2293
|
-
const
|
|
2294
|
-
const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
|
|
2295
|
-
if (!parent) {
|
|
2296
|
-
pendingItems = newItems;
|
|
2297
|
-
queueMicrotask(performDiff);
|
|
2298
|
-
return;
|
|
2299
|
-
}
|
|
2333
|
+
const createdBlocks = [];
|
|
2334
|
+
const newItems = getItems();
|
|
2300
2335
|
if (newItems.length === 0) {
|
|
2301
2336
|
if (oldBlocks.size > 0) {
|
|
2302
2337
|
for (const block of oldBlocks.values()) {
|
|
2303
2338
|
destroyRoot(block.root);
|
|
2304
|
-
removeNodes(block.nodes);
|
|
2305
2339
|
}
|
|
2340
|
+
const range = document.createRange();
|
|
2341
|
+
range.setStartAfter(container.startMarker);
|
|
2342
|
+
range.setEndBefore(container.endMarker);
|
|
2343
|
+
range.deleteContents();
|
|
2306
2344
|
}
|
|
2307
2345
|
oldBlocks.clear();
|
|
2308
2346
|
newBlocks.clear();
|
|
@@ -2319,8 +2357,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2319
2357
|
const appendedBlocks = [];
|
|
2320
2358
|
newItems.forEach((item, index) => {
|
|
2321
2359
|
const key = keyFn(item, index);
|
|
2322
|
-
const existed = oldBlocks.has(key);
|
|
2323
2360
|
let block = oldBlocks.get(key);
|
|
2361
|
+
const existed = block !== void 0;
|
|
2324
2362
|
if (block) {
|
|
2325
2363
|
if (block.rawItem !== item) {
|
|
2326
2364
|
block.rawItem = item;
|
|
@@ -2331,38 +2369,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2331
2369
|
block.index(index);
|
|
2332
2370
|
}
|
|
2333
2371
|
}
|
|
2334
|
-
const existingBlock = newBlocks.get(key);
|
|
2335
|
-
if (existingBlock && existingBlock !== block) {
|
|
2336
|
-
destroyRoot(existingBlock.root);
|
|
2337
|
-
removeNodes(existingBlock.nodes);
|
|
2338
|
-
}
|
|
2339
2372
|
if (block) {
|
|
2340
2373
|
newBlocks.set(key, block);
|
|
2341
2374
|
oldBlocks.delete(key);
|
|
2342
2375
|
} else {
|
|
2343
|
-
const
|
|
2344
|
-
if (
|
|
2345
|
-
destroyRoot(
|
|
2346
|
-
removeNodes(
|
|
2376
|
+
const existingBlock = newBlocks.get(key);
|
|
2377
|
+
if (existingBlock) {
|
|
2378
|
+
destroyRoot(existingBlock.root);
|
|
2379
|
+
removeNodes(existingBlock.nodes);
|
|
2347
2380
|
}
|
|
2348
2381
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2382
|
+
createdBlocks.push(block);
|
|
2349
2383
|
}
|
|
2350
2384
|
const resolvedBlock = block;
|
|
2351
2385
|
newBlocks.set(key, resolvedBlock);
|
|
2352
2386
|
const position = orderedIndexByKey.get(key);
|
|
2353
2387
|
if (position !== void 0) {
|
|
2354
2388
|
appendCandidate = false;
|
|
2355
|
-
}
|
|
2356
|
-
if (appendCandidate) {
|
|
2357
|
-
if (index < prevCount) {
|
|
2358
|
-
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2359
|
-
appendCandidate = false;
|
|
2360
|
-
}
|
|
2361
|
-
} else if (existed) {
|
|
2362
|
-
appendCandidate = false;
|
|
2363
|
-
}
|
|
2364
|
-
}
|
|
2365
|
-
if (position !== void 0) {
|
|
2366
2389
|
const prior = nextOrderedBlocks[position];
|
|
2367
2390
|
if (prior && prior !== resolvedBlock) {
|
|
2368
2391
|
destroyRoot(prior.root);
|
|
@@ -2370,6 +2393,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2370
2393
|
}
|
|
2371
2394
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2372
2395
|
} else {
|
|
2396
|
+
if (appendCandidate) {
|
|
2397
|
+
if (index < prevCount) {
|
|
2398
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2399
|
+
appendCandidate = false;
|
|
2400
|
+
}
|
|
2401
|
+
} else if (existed) {
|
|
2402
|
+
appendCandidate = false;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2373
2405
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2374
2406
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2375
2407
|
}
|
|
@@ -2398,6 +2430,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2398
2430
|
container.nextBlocks = oldBlocks;
|
|
2399
2431
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2400
2432
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2433
|
+
for (const block of createdBlocks) {
|
|
2434
|
+
if (newBlocks.get(block.key) === block) {
|
|
2435
|
+
flushOnMount(block.root);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2401
2438
|
return;
|
|
2402
2439
|
}
|
|
2403
2440
|
if (oldBlocks.size > 0) {
|
|
@@ -2427,22 +2464,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2427
2464
|
container.nextBlocks = oldBlocks;
|
|
2428
2465
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2429
2466
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2467
|
+
for (const block of createdBlocks) {
|
|
2468
|
+
if (newBlocks.get(block.key) === block) {
|
|
2469
|
+
flushOnMount(block.root);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2430
2472
|
});
|
|
2431
2473
|
};
|
|
2432
|
-
const
|
|
2474
|
+
const disconnectObserver = () => {
|
|
2475
|
+
connectObserver?.disconnect();
|
|
2476
|
+
connectObserver = null;
|
|
2477
|
+
};
|
|
2478
|
+
const ensureEffectStarted = () => {
|
|
2479
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2480
|
+
const parent = getConnectedParent();
|
|
2481
|
+
if (!parent) return false;
|
|
2482
|
+
const start = () => {
|
|
2483
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2484
|
+
effectStarted = true;
|
|
2485
|
+
};
|
|
2486
|
+
if (hostRoot) {
|
|
2487
|
+
const prev = pushRoot(hostRoot);
|
|
2488
|
+
try {
|
|
2489
|
+
start();
|
|
2490
|
+
} finally {
|
|
2491
|
+
popRoot(prev);
|
|
2492
|
+
}
|
|
2493
|
+
} else {
|
|
2494
|
+
start();
|
|
2495
|
+
}
|
|
2496
|
+
return true;
|
|
2497
|
+
};
|
|
2498
|
+
const waitForConnection = () => {
|
|
2499
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2500
|
+
connectObserver = new MutationObserver(() => {
|
|
2501
|
+
if (disposed) return;
|
|
2502
|
+
if (getConnectedParent()) {
|
|
2503
|
+
disconnectObserver();
|
|
2504
|
+
if (ensureEffectStarted()) {
|
|
2505
|
+
flush();
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
});
|
|
2509
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2510
|
+
};
|
|
2511
|
+
const scheduleStart = () => {
|
|
2512
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2513
|
+
startScheduled = true;
|
|
2514
|
+
const run = () => {
|
|
2515
|
+
startScheduled = false;
|
|
2516
|
+
if (!ensureEffectStarted()) {
|
|
2517
|
+
waitForConnection();
|
|
2518
|
+
}
|
|
2519
|
+
};
|
|
2520
|
+
if (typeof queueMicrotask === "function") {
|
|
2521
|
+
queueMicrotask(run);
|
|
2522
|
+
} else {
|
|
2523
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2524
|
+
}
|
|
2525
|
+
};
|
|
2526
|
+
scheduleStart();
|
|
2433
2527
|
return {
|
|
2434
|
-
marker
|
|
2528
|
+
get marker() {
|
|
2529
|
+
scheduleStart();
|
|
2530
|
+
return fragment;
|
|
2531
|
+
},
|
|
2435
2532
|
startMarker: container.startMarker,
|
|
2436
2533
|
endMarker: container.endMarker,
|
|
2437
2534
|
// Flush pending items - call after markers are inserted into DOM
|
|
2438
2535
|
flush: () => {
|
|
2439
|
-
if (
|
|
2440
|
-
|
|
2536
|
+
if (disposed) return;
|
|
2537
|
+
scheduleStart();
|
|
2538
|
+
if (ensureEffectStarted()) {
|
|
2539
|
+
flush();
|
|
2540
|
+
} else {
|
|
2541
|
+
waitForConnection();
|
|
2441
2542
|
}
|
|
2442
2543
|
},
|
|
2443
2544
|
dispose: () => {
|
|
2444
2545
|
disposed = true;
|
|
2445
2546
|
effectDispose?.();
|
|
2547
|
+
disconnectObserver();
|
|
2446
2548
|
container.dispose();
|
|
2447
2549
|
}
|
|
2448
2550
|
};
|
|
@@ -2614,8 +2716,17 @@ function createClassBinding(el, value) {
|
|
|
2614
2716
|
}
|
|
2615
2717
|
function bindClass(el, getValue) {
|
|
2616
2718
|
let prev = {};
|
|
2719
|
+
let prevString;
|
|
2617
2720
|
return createRenderEffect(() => {
|
|
2618
2721
|
const next = getValue();
|
|
2722
|
+
if (typeof next === "string") {
|
|
2723
|
+
if (next === prevString) return;
|
|
2724
|
+
prevString = next;
|
|
2725
|
+
el.className = next;
|
|
2726
|
+
prev = {};
|
|
2727
|
+
return;
|
|
2728
|
+
}
|
|
2729
|
+
prevString = void 0;
|
|
2619
2730
|
prev = applyClass(el, next, prev);
|
|
2620
2731
|
});
|
|
2621
2732
|
}
|
|
@@ -2841,11 +2952,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
2841
2952
|
}
|
|
2842
2953
|
}
|
|
2843
2954
|
function globalEventHandler(e) {
|
|
2844
|
-
|
|
2955
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
2956
|
+
const asElement = (value) => {
|
|
2957
|
+
const n = asNode(value);
|
|
2958
|
+
if (!n) return null;
|
|
2959
|
+
if (n.nodeType === 1) return n;
|
|
2960
|
+
return n.parentElement;
|
|
2961
|
+
};
|
|
2962
|
+
let node = asElement(e.target);
|
|
2845
2963
|
const key = `$$${e.type}`;
|
|
2846
2964
|
const dataKey = `${key}Data`;
|
|
2847
2965
|
const oriTarget = e.target;
|
|
2848
2966
|
const oriCurrentTarget = e.currentTarget;
|
|
2967
|
+
let lastHandled = null;
|
|
2849
2968
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
2850
2969
|
configurable: true,
|
|
2851
2970
|
value
|
|
@@ -2868,23 +2987,28 @@ function globalEventHandler(e) {
|
|
|
2868
2987
|
const rawData = node[dataKey];
|
|
2869
2988
|
const hasData = rawData !== void 0;
|
|
2870
2989
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2990
|
+
batch2(() => {
|
|
2991
|
+
if (typeof handler === "function") {
|
|
2992
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
2993
|
+
} else if (Array.isArray(handler)) {
|
|
2994
|
+
const tupleData = resolveData(handler[1]);
|
|
2995
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
2996
|
+
}
|
|
2997
|
+
});
|
|
2877
2998
|
if (e.cancelBubble) return false;
|
|
2878
2999
|
}
|
|
2879
3000
|
const shadowHost = node.host;
|
|
2880
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3001
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3002
|
+
const targetNode = asNode(e.target);
|
|
3003
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3004
|
+
})()) {
|
|
2881
3005
|
retarget(shadowHost);
|
|
2882
3006
|
}
|
|
2883
3007
|
return true;
|
|
2884
3008
|
};
|
|
2885
3009
|
const walkUpTree = () => {
|
|
2886
3010
|
while (handleNode() && node) {
|
|
2887
|
-
node = node._$host || node.parentNode || node.host;
|
|
3011
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
2888
3012
|
}
|
|
2889
3013
|
};
|
|
2890
3014
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -2897,8 +3021,11 @@ function globalEventHandler(e) {
|
|
|
2897
3021
|
const path = e.composedPath();
|
|
2898
3022
|
retarget(path[0]);
|
|
2899
3023
|
for (let i = 0; i < path.length - 2; i++) {
|
|
2900
|
-
|
|
3024
|
+
const nextNode = asElement(path[i]);
|
|
3025
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3026
|
+
node = nextNode;
|
|
2901
3027
|
if (!handleNode()) break;
|
|
3028
|
+
lastHandled = node;
|
|
2902
3029
|
if (node._$host) {
|
|
2903
3030
|
node = node._$host;
|
|
2904
3031
|
walkUpTree();
|