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