@fictjs/runtime 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +398 -204
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.dev.js +400 -204
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +398 -204
- package/dist/index.js.map +1 -1
- package/dist/slim.cjs +398 -204
- package/dist/slim.cjs.map +1 -1
- package/dist/slim.d.cts +1 -0
- package/dist/slim.d.ts +1 -0
- package/dist/slim.js +398 -204
- package/dist/slim.js.map +1 -1
- package/package.json +1 -1
- package/src/binding.ts +41 -13
- package/src/dom.ts +16 -6
- package/src/effect.ts +18 -6
- package/src/hooks.ts +14 -1
- package/src/list-helpers.ts +125 -47
- package/src/signal.ts +102 -4
package/dist/slim.cjs
CHANGED
|
@@ -307,6 +307,7 @@ var lowPriorityQueue = [];
|
|
|
307
307
|
var enqueueMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
308
308
|
Promise.resolve().then(fn);
|
|
309
309
|
};
|
|
310
|
+
var inCleanup = false;
|
|
310
311
|
function link(dep, sub, version) {
|
|
311
312
|
const prevDep = sub.depsTail;
|
|
312
313
|
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
@@ -552,7 +553,15 @@ function updateComputed(c) {
|
|
|
552
553
|
}
|
|
553
554
|
function runEffect(e) {
|
|
554
555
|
const flags = e.flags;
|
|
555
|
-
if (flags & Dirty
|
|
556
|
+
if (flags & Dirty) {
|
|
557
|
+
if (e.runCleanup) {
|
|
558
|
+
inCleanup = true;
|
|
559
|
+
try {
|
|
560
|
+
e.runCleanup();
|
|
561
|
+
} finally {
|
|
562
|
+
inCleanup = false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
556
565
|
++cycle;
|
|
557
566
|
effectRunDevtools(e);
|
|
558
567
|
e.depsTail = void 0;
|
|
@@ -569,6 +578,35 @@ function runEffect(e) {
|
|
|
569
578
|
e.flags = Watching;
|
|
570
579
|
throw err;
|
|
571
580
|
}
|
|
581
|
+
} else if (flags & Pending && e.deps) {
|
|
582
|
+
if (e.runCleanup) {
|
|
583
|
+
inCleanup = true;
|
|
584
|
+
try {
|
|
585
|
+
e.runCleanup();
|
|
586
|
+
} finally {
|
|
587
|
+
inCleanup = false;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (checkDirty(e.deps, e)) {
|
|
591
|
+
++cycle;
|
|
592
|
+
effectRunDevtools(e);
|
|
593
|
+
e.depsTail = void 0;
|
|
594
|
+
e.flags = WatchingRunning;
|
|
595
|
+
const prevSub = activeSub;
|
|
596
|
+
activeSub = e;
|
|
597
|
+
try {
|
|
598
|
+
e.fn();
|
|
599
|
+
activeSub = prevSub;
|
|
600
|
+
e.flags = Watching;
|
|
601
|
+
purgeDeps(e);
|
|
602
|
+
} catch (err) {
|
|
603
|
+
activeSub = prevSub;
|
|
604
|
+
e.flags = Watching;
|
|
605
|
+
throw err;
|
|
606
|
+
}
|
|
607
|
+
} else {
|
|
608
|
+
e.flags = Watching;
|
|
609
|
+
}
|
|
572
610
|
} else {
|
|
573
611
|
e.flags = Watching;
|
|
574
612
|
}
|
|
@@ -664,7 +702,7 @@ function signalOper(value) {
|
|
|
664
702
|
return;
|
|
665
703
|
}
|
|
666
704
|
const flags = this.flags;
|
|
667
|
-
if (flags & Dirty) {
|
|
705
|
+
if (flags & Dirty && !inCleanup) {
|
|
668
706
|
if (updateSignal(this)) {
|
|
669
707
|
const subs = this.subs;
|
|
670
708
|
if (subs !== void 0) shallowPropagate(subs);
|
|
@@ -746,6 +784,30 @@ function effect(fn) {
|
|
|
746
784
|
}
|
|
747
785
|
return effectOper.bind(e);
|
|
748
786
|
}
|
|
787
|
+
function effectWithCleanup(fn, cleanupRunner) {
|
|
788
|
+
const e = {
|
|
789
|
+
fn,
|
|
790
|
+
subs: void 0,
|
|
791
|
+
subsTail: void 0,
|
|
792
|
+
deps: void 0,
|
|
793
|
+
depsTail: void 0,
|
|
794
|
+
flags: WatchingRunning,
|
|
795
|
+
runCleanup: cleanupRunner,
|
|
796
|
+
__id: void 0
|
|
797
|
+
};
|
|
798
|
+
registerEffectDevtools(e);
|
|
799
|
+
const prevSub = activeSub;
|
|
800
|
+
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
801
|
+
activeSub = e;
|
|
802
|
+
try {
|
|
803
|
+
effectRunDevtools(e);
|
|
804
|
+
fn();
|
|
805
|
+
} finally {
|
|
806
|
+
activeSub = prevSub;
|
|
807
|
+
e.flags &= ~Running;
|
|
808
|
+
}
|
|
809
|
+
return effectOper.bind(e);
|
|
810
|
+
}
|
|
749
811
|
function effectOper() {
|
|
750
812
|
disposeNode(this);
|
|
751
813
|
}
|
|
@@ -766,10 +828,17 @@ function effectScopeOper() {
|
|
|
766
828
|
}
|
|
767
829
|
function batch(fn) {
|
|
768
830
|
++batchDepth;
|
|
831
|
+
let hasError = false;
|
|
769
832
|
try {
|
|
770
833
|
return fn();
|
|
834
|
+
} catch (e) {
|
|
835
|
+
hasError = true;
|
|
836
|
+
throw e;
|
|
771
837
|
} finally {
|
|
772
|
-
|
|
838
|
+
--batchDepth;
|
|
839
|
+
if (!hasError && batchDepth === 0) {
|
|
840
|
+
flush();
|
|
841
|
+
}
|
|
773
842
|
}
|
|
774
843
|
}
|
|
775
844
|
function setActiveSub(sub) {
|
|
@@ -820,7 +889,7 @@ function effectRunDevtools(node) {
|
|
|
820
889
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
821
890
|
let current = source();
|
|
822
891
|
const observers = /* @__PURE__ */ new Map();
|
|
823
|
-
effect(() => {
|
|
892
|
+
const dispose = effect(() => {
|
|
824
893
|
const next = source();
|
|
825
894
|
if (equalityFn(current, next)) return;
|
|
826
895
|
const prevSig = observers.get(current);
|
|
@@ -829,6 +898,10 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
829
898
|
if (nextSig) nextSig(true);
|
|
830
899
|
current = next;
|
|
831
900
|
});
|
|
901
|
+
registerRootCleanup(() => {
|
|
902
|
+
dispose();
|
|
903
|
+
observers.clear();
|
|
904
|
+
});
|
|
832
905
|
return (key) => {
|
|
833
906
|
let sig = observers.get(key);
|
|
834
907
|
if (!sig) {
|
|
@@ -849,8 +922,11 @@ function createMemo(fn) {
|
|
|
849
922
|
function createEffect(fn) {
|
|
850
923
|
let cleanups = [];
|
|
851
924
|
const rootForError = getCurrentRoot();
|
|
852
|
-
const
|
|
925
|
+
const doCleanup = () => {
|
|
853
926
|
runCleanupList(cleanups);
|
|
927
|
+
cleanups = [];
|
|
928
|
+
};
|
|
929
|
+
const run = () => {
|
|
854
930
|
const bucket = [];
|
|
855
931
|
withEffectCleanups(bucket, () => {
|
|
856
932
|
try {
|
|
@@ -867,7 +943,7 @@ function createEffect(fn) {
|
|
|
867
943
|
});
|
|
868
944
|
cleanups = bucket;
|
|
869
945
|
};
|
|
870
|
-
const disposeEffect =
|
|
946
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
871
947
|
const teardown = () => {
|
|
872
948
|
runCleanupList(cleanups);
|
|
873
949
|
disposeEffect();
|
|
@@ -878,24 +954,27 @@ function createEffect(fn) {
|
|
|
878
954
|
function createRenderEffect(fn) {
|
|
879
955
|
let cleanup;
|
|
880
956
|
const rootForError = getCurrentRoot();
|
|
881
|
-
const
|
|
957
|
+
const doCleanup = () => {
|
|
882
958
|
if (cleanup) {
|
|
883
959
|
cleanup();
|
|
884
960
|
cleanup = void 0;
|
|
885
961
|
}
|
|
962
|
+
};
|
|
963
|
+
const run = () => {
|
|
886
964
|
try {
|
|
887
965
|
const maybeCleanup = fn();
|
|
888
966
|
if (typeof maybeCleanup === "function") {
|
|
889
967
|
cleanup = maybeCleanup;
|
|
890
968
|
}
|
|
891
969
|
} catch (err) {
|
|
892
|
-
|
|
970
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
971
|
+
if (handled) {
|
|
893
972
|
return;
|
|
894
973
|
}
|
|
895
974
|
throw err;
|
|
896
975
|
}
|
|
897
976
|
};
|
|
898
|
-
const disposeEffect =
|
|
977
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
899
978
|
const teardown = () => {
|
|
900
979
|
if (cleanup) {
|
|
901
980
|
cleanup();
|
|
@@ -1281,159 +1360,22 @@ var UnitlessStyles = /* @__PURE__ */ new Set([
|
|
|
1281
1360
|
// src/jsx.ts
|
|
1282
1361
|
var Fragment = Symbol("Fragment");
|
|
1283
1362
|
|
|
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
1363
|
// src/hooks.ts
|
|
1428
1364
|
var ctxStack = [];
|
|
1365
|
+
function assertRenderContext(ctx, hookName) {
|
|
1366
|
+
if (!ctx.rendering) {
|
|
1367
|
+
throw new Error(`${hookName} can only be used during render execution`);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1429
1370
|
function __fictUseContext() {
|
|
1430
1371
|
if (ctxStack.length === 0) {
|
|
1431
|
-
const ctx2 = { slots: [], cursor: 0 };
|
|
1372
|
+
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
1432
1373
|
ctxStack.push(ctx2);
|
|
1433
1374
|
return ctx2;
|
|
1434
1375
|
}
|
|
1435
1376
|
const ctx = ctxStack[ctxStack.length - 1];
|
|
1436
1377
|
ctx.cursor = 0;
|
|
1378
|
+
ctx.rendering = true;
|
|
1437
1379
|
return ctx;
|
|
1438
1380
|
}
|
|
1439
1381
|
function __fictPushContext() {
|
|
@@ -1448,6 +1390,7 @@ function __fictResetContext() {
|
|
|
1448
1390
|
ctxStack.length = 0;
|
|
1449
1391
|
}
|
|
1450
1392
|
function __fictUseSignal(ctx, initial, slot) {
|
|
1393
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
1451
1394
|
const index = slot ?? ctx.cursor++;
|
|
1452
1395
|
if (!ctx.slots[index]) {
|
|
1453
1396
|
ctx.slots[index] = signal(initial);
|
|
@@ -1455,6 +1398,7 @@ function __fictUseSignal(ctx, initial, slot) {
|
|
|
1455
1398
|
return ctx.slots[index];
|
|
1456
1399
|
}
|
|
1457
1400
|
function __fictUseMemo(ctx, fn, slot) {
|
|
1401
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
1458
1402
|
const index = slot ?? ctx.cursor++;
|
|
1459
1403
|
if (!ctx.slots[index]) {
|
|
1460
1404
|
ctx.slots[index] = createMemo(fn);
|
|
@@ -1462,6 +1406,7 @@ function __fictUseMemo(ctx, fn, slot) {
|
|
|
1462
1406
|
return ctx.slots[index];
|
|
1463
1407
|
}
|
|
1464
1408
|
function __fictUseEffect(ctx, fn, slot) {
|
|
1409
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
1465
1410
|
const index = slot ?? ctx.cursor++;
|
|
1466
1411
|
if (!ctx.slots[index]) {
|
|
1467
1412
|
ctx.slots[index] = createEffect(fn);
|
|
@@ -1470,9 +1415,11 @@ function __fictUseEffect(ctx, fn, slot) {
|
|
|
1470
1415
|
function __fictRender(ctx, fn) {
|
|
1471
1416
|
ctxStack.push(ctx);
|
|
1472
1417
|
ctx.cursor = 0;
|
|
1418
|
+
ctx.rendering = true;
|
|
1473
1419
|
try {
|
|
1474
1420
|
return fn();
|
|
1475
1421
|
} finally {
|
|
1422
|
+
ctx.rendering = false;
|
|
1476
1423
|
ctxStack.pop();
|
|
1477
1424
|
}
|
|
1478
1425
|
}
|
|
@@ -1675,6 +1622,14 @@ function createElementWithContext(node, namespace) {
|
|
|
1675
1622
|
if (typeof handle.dispose === "function") {
|
|
1676
1623
|
registerRootCleanup(handle.dispose);
|
|
1677
1624
|
}
|
|
1625
|
+
if (typeof handle.flush === "function") {
|
|
1626
|
+
const runFlush = () => handle.flush && handle.flush();
|
|
1627
|
+
if (typeof queueMicrotask === "function") {
|
|
1628
|
+
queueMicrotask(runFlush);
|
|
1629
|
+
} else {
|
|
1630
|
+
Promise.resolve().then(runFlush).catch(() => void 0);
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1678
1633
|
return createElement(handle.marker);
|
|
1679
1634
|
}
|
|
1680
1635
|
const nodeRecord = node;
|
|
@@ -1722,18 +1677,18 @@ function createElementWithContext(node, namespace) {
|
|
|
1722
1677
|
}
|
|
1723
1678
|
});
|
|
1724
1679
|
const props = createPropsProxy(baseProps);
|
|
1680
|
+
__fictPushContext();
|
|
1725
1681
|
try {
|
|
1726
|
-
__fictPushContext();
|
|
1727
1682
|
const rendered = vnode.type(props);
|
|
1728
|
-
__fictPopContext();
|
|
1729
1683
|
return createElementWithContext(rendered, namespace);
|
|
1730
1684
|
} catch (err) {
|
|
1731
|
-
__fictPopContext();
|
|
1732
1685
|
if (handleSuspend(err)) {
|
|
1733
1686
|
return document.createComment("fict:suspend");
|
|
1734
1687
|
}
|
|
1735
1688
|
handleError(err, { source: "render", componentName: vnode.type.name });
|
|
1736
1689
|
throw err;
|
|
1690
|
+
} finally {
|
|
1691
|
+
__fictPopContext();
|
|
1737
1692
|
}
|
|
1738
1693
|
}
|
|
1739
1694
|
if (vnode.type === Fragment) {
|
|
@@ -2025,6 +1980,149 @@ function eventNameFromProp(key) {
|
|
|
2025
1980
|
return key.slice(2).toLowerCase();
|
|
2026
1981
|
}
|
|
2027
1982
|
|
|
1983
|
+
// src/node-ops.ts
|
|
1984
|
+
function toNodeArray(node) {
|
|
1985
|
+
try {
|
|
1986
|
+
if (Array.isArray(node)) {
|
|
1987
|
+
let allNodes = true;
|
|
1988
|
+
for (const item of node) {
|
|
1989
|
+
let isItemNode = false;
|
|
1990
|
+
try {
|
|
1991
|
+
isItemNode = item instanceof Node;
|
|
1992
|
+
} catch {
|
|
1993
|
+
isItemNode = false;
|
|
1994
|
+
}
|
|
1995
|
+
if (!isItemNode) {
|
|
1996
|
+
allNodes = false;
|
|
1997
|
+
break;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
if (allNodes) {
|
|
2001
|
+
return node;
|
|
2002
|
+
}
|
|
2003
|
+
const result = [];
|
|
2004
|
+
for (const item of node) {
|
|
2005
|
+
result.push(...toNodeArray(item));
|
|
2006
|
+
}
|
|
2007
|
+
return result;
|
|
2008
|
+
}
|
|
2009
|
+
if (node === null || node === void 0 || node === false) {
|
|
2010
|
+
return [];
|
|
2011
|
+
}
|
|
2012
|
+
} catch {
|
|
2013
|
+
return [];
|
|
2014
|
+
}
|
|
2015
|
+
let isNode = false;
|
|
2016
|
+
try {
|
|
2017
|
+
isNode = node instanceof Node;
|
|
2018
|
+
} catch {
|
|
2019
|
+
isNode = false;
|
|
2020
|
+
}
|
|
2021
|
+
if (isNode) {
|
|
2022
|
+
try {
|
|
2023
|
+
if (node instanceof DocumentFragment) {
|
|
2024
|
+
return Array.from(node.childNodes);
|
|
2025
|
+
}
|
|
2026
|
+
} catch {
|
|
2027
|
+
}
|
|
2028
|
+
return [node];
|
|
2029
|
+
}
|
|
2030
|
+
try {
|
|
2031
|
+
if (typeof node === "object" && node !== null && "marker" in node) {
|
|
2032
|
+
return toNodeArray(node.marker);
|
|
2033
|
+
}
|
|
2034
|
+
} catch {
|
|
2035
|
+
}
|
|
2036
|
+
try {
|
|
2037
|
+
return [document.createTextNode(String(node))];
|
|
2038
|
+
} catch {
|
|
2039
|
+
return [document.createTextNode("")];
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
function insertNodesBefore(parent, nodes, anchor) {
|
|
2043
|
+
if (nodes.length === 0) return;
|
|
2044
|
+
if (nodes.length === 1) {
|
|
2045
|
+
const node = nodes[0];
|
|
2046
|
+
if (node === void 0 || node === null) return;
|
|
2047
|
+
if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2048
|
+
parent.ownerDocument.adoptNode(node);
|
|
2049
|
+
}
|
|
2050
|
+
try {
|
|
2051
|
+
parent.insertBefore(node, anchor);
|
|
2052
|
+
} catch (e) {
|
|
2053
|
+
if (parent.ownerDocument) {
|
|
2054
|
+
try {
|
|
2055
|
+
const clone = parent.ownerDocument.importNode(node, true);
|
|
2056
|
+
parent.insertBefore(clone, anchor);
|
|
2057
|
+
return;
|
|
2058
|
+
} catch {
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
throw e;
|
|
2062
|
+
}
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
const doc = parent.ownerDocument;
|
|
2066
|
+
if (doc) {
|
|
2067
|
+
const frag = doc.createDocumentFragment();
|
|
2068
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
2069
|
+
const node = nodes[i];
|
|
2070
|
+
if (node === void 0 || node === null) continue;
|
|
2071
|
+
if (node.nodeType === 11) {
|
|
2072
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2073
|
+
for (let j = 0; j < childrenArr.length; j++) {
|
|
2074
|
+
frag.appendChild(childrenArr[j]);
|
|
2075
|
+
}
|
|
2076
|
+
} else {
|
|
2077
|
+
if (node.ownerDocument !== doc) {
|
|
2078
|
+
doc.adoptNode(node);
|
|
2079
|
+
}
|
|
2080
|
+
frag.appendChild(node);
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
parent.insertBefore(frag, anchor);
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
const insertSingle = (nodeToInsert, anchorNode) => {
|
|
2087
|
+
if (nodeToInsert.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
|
|
2088
|
+
parent.ownerDocument.adoptNode(nodeToInsert);
|
|
2089
|
+
}
|
|
2090
|
+
try {
|
|
2091
|
+
parent.insertBefore(nodeToInsert, anchorNode);
|
|
2092
|
+
return nodeToInsert;
|
|
2093
|
+
} catch (e) {
|
|
2094
|
+
if (parent.ownerDocument) {
|
|
2095
|
+
try {
|
|
2096
|
+
const clone = parent.ownerDocument.importNode(nodeToInsert, true);
|
|
2097
|
+
parent.insertBefore(clone, anchorNode);
|
|
2098
|
+
return clone;
|
|
2099
|
+
} catch {
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
throw e;
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2106
|
+
const node = nodes[i];
|
|
2107
|
+
if (node === void 0 || node === null) continue;
|
|
2108
|
+
const isFrag = node.nodeType === 11;
|
|
2109
|
+
if (isFrag) {
|
|
2110
|
+
const childrenArr = Array.from(node.childNodes);
|
|
2111
|
+
for (let j = childrenArr.length - 1; j >= 0; j--) {
|
|
2112
|
+
const child = childrenArr[j];
|
|
2113
|
+
anchor = insertSingle(child, anchor);
|
|
2114
|
+
}
|
|
2115
|
+
} else {
|
|
2116
|
+
anchor = insertSingle(node, anchor);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
function removeNodes(nodes) {
|
|
2121
|
+
for (const node of nodes) {
|
|
2122
|
+
node.parentNode?.removeChild(node);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2028
2126
|
// src/reconcile.ts
|
|
2029
2127
|
function reconcileArrays(parentNode, a, b) {
|
|
2030
2128
|
const bLength = b.length;
|
|
@@ -2252,7 +2350,6 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2252
2350
|
} finally {
|
|
2253
2351
|
setActiveSub(prevSub);
|
|
2254
2352
|
popRoot(prevRoot);
|
|
2255
|
-
flushOnMount(root);
|
|
2256
2353
|
}
|
|
2257
2354
|
return {
|
|
2258
2355
|
key,
|
|
@@ -2276,13 +2373,24 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2276
2373
|
const hostRoot = getCurrentRoot();
|
|
2277
2374
|
const fragment = document.createDocumentFragment();
|
|
2278
2375
|
fragment.append(container.startMarker, container.endMarker);
|
|
2279
|
-
let pendingItems = null;
|
|
2280
2376
|
let disposed = false;
|
|
2377
|
+
let effectDispose;
|
|
2378
|
+
let connectObserver = null;
|
|
2379
|
+
let effectStarted = false;
|
|
2380
|
+
let startScheduled = false;
|
|
2381
|
+
const getConnectedParent = () => {
|
|
2382
|
+
const endParent = container.endMarker.parentNode;
|
|
2383
|
+
const startParent = container.startMarker.parentNode;
|
|
2384
|
+
if (endParent && startParent && endParent === startParent && endParent.nodeType !== 11) {
|
|
2385
|
+
return endParent;
|
|
2386
|
+
}
|
|
2387
|
+
return null;
|
|
2388
|
+
};
|
|
2281
2389
|
const performDiff = () => {
|
|
2282
2390
|
if (disposed) return;
|
|
2391
|
+
const parent = getConnectedParent();
|
|
2392
|
+
if (!parent) return;
|
|
2283
2393
|
batch2(() => {
|
|
2284
|
-
const newItems = pendingItems || getItems();
|
|
2285
|
-
pendingItems = null;
|
|
2286
2394
|
const oldBlocks = container.blocks;
|
|
2287
2395
|
const newBlocks = container.nextBlocks;
|
|
2288
2396
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
@@ -2291,20 +2399,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2291
2399
|
newBlocks.clear();
|
|
2292
2400
|
nextOrderedBlocks.length = 0;
|
|
2293
2401
|
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
|
-
}
|
|
2402
|
+
const createdBlocks = [];
|
|
2403
|
+
const newItems = getItems();
|
|
2302
2404
|
if (newItems.length === 0) {
|
|
2303
2405
|
if (oldBlocks.size > 0) {
|
|
2304
2406
|
for (const block of oldBlocks.values()) {
|
|
2305
2407
|
destroyRoot(block.root);
|
|
2306
|
-
removeNodes(block.nodes);
|
|
2307
2408
|
}
|
|
2409
|
+
const range = document.createRange();
|
|
2410
|
+
range.setStartAfter(container.startMarker);
|
|
2411
|
+
range.setEndBefore(container.endMarker);
|
|
2412
|
+
range.deleteContents();
|
|
2308
2413
|
}
|
|
2309
2414
|
oldBlocks.clear();
|
|
2310
2415
|
newBlocks.clear();
|
|
@@ -2321,8 +2426,8 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2321
2426
|
const appendedBlocks = [];
|
|
2322
2427
|
newItems.forEach((item, index) => {
|
|
2323
2428
|
const key = keyFn(item, index);
|
|
2324
|
-
const existed = oldBlocks.has(key);
|
|
2325
2429
|
let block = oldBlocks.get(key);
|
|
2430
|
+
const existed = block !== void 0;
|
|
2326
2431
|
if (block) {
|
|
2327
2432
|
if (block.rawItem !== item) {
|
|
2328
2433
|
block.rawItem = item;
|
|
@@ -2333,38 +2438,23 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2333
2438
|
block.index(index);
|
|
2334
2439
|
}
|
|
2335
2440
|
}
|
|
2336
|
-
const existingBlock = newBlocks.get(key);
|
|
2337
|
-
if (existingBlock && existingBlock !== block) {
|
|
2338
|
-
destroyRoot(existingBlock.root);
|
|
2339
|
-
removeNodes(existingBlock.nodes);
|
|
2340
|
-
}
|
|
2341
2441
|
if (block) {
|
|
2342
2442
|
newBlocks.set(key, block);
|
|
2343
2443
|
oldBlocks.delete(key);
|
|
2344
2444
|
} else {
|
|
2345
|
-
const
|
|
2346
|
-
if (
|
|
2347
|
-
destroyRoot(
|
|
2348
|
-
removeNodes(
|
|
2445
|
+
const existingBlock = newBlocks.get(key);
|
|
2446
|
+
if (existingBlock) {
|
|
2447
|
+
destroyRoot(existingBlock.root);
|
|
2448
|
+
removeNodes(existingBlock.nodes);
|
|
2349
2449
|
}
|
|
2350
2450
|
block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
|
|
2451
|
+
createdBlocks.push(block);
|
|
2351
2452
|
}
|
|
2352
2453
|
const resolvedBlock = block;
|
|
2353
2454
|
newBlocks.set(key, resolvedBlock);
|
|
2354
2455
|
const position = orderedIndexByKey.get(key);
|
|
2355
2456
|
if (position !== void 0) {
|
|
2356
2457
|
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
2458
|
const prior = nextOrderedBlocks[position];
|
|
2369
2459
|
if (prior && prior !== resolvedBlock) {
|
|
2370
2460
|
destroyRoot(prior.root);
|
|
@@ -2372,6 +2462,15 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2372
2462
|
}
|
|
2373
2463
|
nextOrderedBlocks[position] = resolvedBlock;
|
|
2374
2464
|
} else {
|
|
2465
|
+
if (appendCandidate) {
|
|
2466
|
+
if (index < prevCount) {
|
|
2467
|
+
if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
|
|
2468
|
+
appendCandidate = false;
|
|
2469
|
+
}
|
|
2470
|
+
} else if (existed) {
|
|
2471
|
+
appendCandidate = false;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2375
2474
|
orderedIndexByKey.set(key, nextOrderedBlocks.length);
|
|
2376
2475
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2377
2476
|
}
|
|
@@ -2400,6 +2499,11 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2400
2499
|
container.nextBlocks = oldBlocks;
|
|
2401
2500
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2402
2501
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2502
|
+
for (const block of createdBlocks) {
|
|
2503
|
+
if (newBlocks.get(block.key) === block) {
|
|
2504
|
+
flushOnMount(block.root);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2403
2507
|
return;
|
|
2404
2508
|
}
|
|
2405
2509
|
if (oldBlocks.size > 0) {
|
|
@@ -2429,22 +2533,87 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2429
2533
|
container.nextBlocks = oldBlocks;
|
|
2430
2534
|
container.orderedBlocks = nextOrderedBlocks;
|
|
2431
2535
|
container.nextOrderedBlocks = prevOrderedBlocks;
|
|
2536
|
+
for (const block of createdBlocks) {
|
|
2537
|
+
if (newBlocks.get(block.key) === block) {
|
|
2538
|
+
flushOnMount(block.root);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
});
|
|
2542
|
+
};
|
|
2543
|
+
const disconnectObserver = () => {
|
|
2544
|
+
connectObserver?.disconnect();
|
|
2545
|
+
connectObserver = null;
|
|
2546
|
+
};
|
|
2547
|
+
const ensureEffectStarted = () => {
|
|
2548
|
+
if (disposed || effectStarted) return effectStarted;
|
|
2549
|
+
const parent = getConnectedParent();
|
|
2550
|
+
if (!parent) return false;
|
|
2551
|
+
const start = () => {
|
|
2552
|
+
effectDispose = createRenderEffect(performDiff);
|
|
2553
|
+
effectStarted = true;
|
|
2554
|
+
};
|
|
2555
|
+
if (hostRoot) {
|
|
2556
|
+
const prev = pushRoot(hostRoot);
|
|
2557
|
+
try {
|
|
2558
|
+
start();
|
|
2559
|
+
} finally {
|
|
2560
|
+
popRoot(prev);
|
|
2561
|
+
}
|
|
2562
|
+
} else {
|
|
2563
|
+
start();
|
|
2564
|
+
}
|
|
2565
|
+
return true;
|
|
2566
|
+
};
|
|
2567
|
+
const waitForConnection = () => {
|
|
2568
|
+
if (connectObserver || typeof MutationObserver === "undefined") return;
|
|
2569
|
+
connectObserver = new MutationObserver(() => {
|
|
2570
|
+
if (disposed) return;
|
|
2571
|
+
if (getConnectedParent()) {
|
|
2572
|
+
disconnectObserver();
|
|
2573
|
+
if (ensureEffectStarted()) {
|
|
2574
|
+
flush();
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2432
2577
|
});
|
|
2578
|
+
connectObserver.observe(document, { childList: true, subtree: true });
|
|
2579
|
+
};
|
|
2580
|
+
const scheduleStart = () => {
|
|
2581
|
+
if (startScheduled || disposed || effectStarted) return;
|
|
2582
|
+
startScheduled = true;
|
|
2583
|
+
const run = () => {
|
|
2584
|
+
startScheduled = false;
|
|
2585
|
+
if (!ensureEffectStarted()) {
|
|
2586
|
+
waitForConnection();
|
|
2587
|
+
}
|
|
2588
|
+
};
|
|
2589
|
+
if (typeof queueMicrotask === "function") {
|
|
2590
|
+
queueMicrotask(run);
|
|
2591
|
+
} else {
|
|
2592
|
+
Promise.resolve().then(run).catch(() => void 0);
|
|
2593
|
+
}
|
|
2433
2594
|
};
|
|
2434
|
-
|
|
2595
|
+
scheduleStart();
|
|
2435
2596
|
return {
|
|
2436
|
-
marker
|
|
2597
|
+
get marker() {
|
|
2598
|
+
scheduleStart();
|
|
2599
|
+
return fragment;
|
|
2600
|
+
},
|
|
2437
2601
|
startMarker: container.startMarker,
|
|
2438
2602
|
endMarker: container.endMarker,
|
|
2439
2603
|
// Flush pending items - call after markers are inserted into DOM
|
|
2440
2604
|
flush: () => {
|
|
2441
|
-
if (
|
|
2442
|
-
|
|
2605
|
+
if (disposed) return;
|
|
2606
|
+
scheduleStart();
|
|
2607
|
+
if (ensureEffectStarted()) {
|
|
2608
|
+
flush();
|
|
2609
|
+
} else {
|
|
2610
|
+
waitForConnection();
|
|
2443
2611
|
}
|
|
2444
2612
|
},
|
|
2445
2613
|
dispose: () => {
|
|
2446
2614
|
disposed = true;
|
|
2447
2615
|
effectDispose?.();
|
|
2616
|
+
disconnectObserver();
|
|
2448
2617
|
container.dispose();
|
|
2449
2618
|
}
|
|
2450
2619
|
};
|
|
@@ -2616,8 +2785,17 @@ function createClassBinding(el, value) {
|
|
|
2616
2785
|
}
|
|
2617
2786
|
function bindClass(el, getValue) {
|
|
2618
2787
|
let prev = {};
|
|
2788
|
+
let prevString;
|
|
2619
2789
|
return createRenderEffect(() => {
|
|
2620
2790
|
const next = getValue();
|
|
2791
|
+
if (typeof next === "string") {
|
|
2792
|
+
if (next === prevString) return;
|
|
2793
|
+
prevString = next;
|
|
2794
|
+
el.className = next;
|
|
2795
|
+
prev = {};
|
|
2796
|
+
return;
|
|
2797
|
+
}
|
|
2798
|
+
prevString = void 0;
|
|
2621
2799
|
prev = applyClass(el, next, prev);
|
|
2622
2800
|
});
|
|
2623
2801
|
}
|
|
@@ -2843,11 +3021,19 @@ function clearDelegatedEvents(doc = window.document) {
|
|
|
2843
3021
|
}
|
|
2844
3022
|
}
|
|
2845
3023
|
function globalEventHandler(e) {
|
|
2846
|
-
|
|
3024
|
+
const asNode = (value) => value && typeof value.nodeType === "number" ? value : null;
|
|
3025
|
+
const asElement = (value) => {
|
|
3026
|
+
const n = asNode(value);
|
|
3027
|
+
if (!n) return null;
|
|
3028
|
+
if (n.nodeType === 1) return n;
|
|
3029
|
+
return n.parentElement;
|
|
3030
|
+
};
|
|
3031
|
+
let node = asElement(e.target);
|
|
2847
3032
|
const key = `$$${e.type}`;
|
|
2848
3033
|
const dataKey = `${key}Data`;
|
|
2849
3034
|
const oriTarget = e.target;
|
|
2850
3035
|
const oriCurrentTarget = e.currentTarget;
|
|
3036
|
+
let lastHandled = null;
|
|
2851
3037
|
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
2852
3038
|
configurable: true,
|
|
2853
3039
|
value
|
|
@@ -2870,23 +3056,28 @@ function globalEventHandler(e) {
|
|
|
2870
3056
|
const rawData = node[dataKey];
|
|
2871
3057
|
const hasData = rawData !== void 0;
|
|
2872
3058
|
const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3059
|
+
batch2(() => {
|
|
3060
|
+
if (typeof handler === "function") {
|
|
3061
|
+
callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
|
|
3062
|
+
} else if (Array.isArray(handler)) {
|
|
3063
|
+
const tupleData = resolveData(handler[1]);
|
|
3064
|
+
callEventHandler(handler[0], e, node, tupleData);
|
|
3065
|
+
}
|
|
3066
|
+
});
|
|
2879
3067
|
if (e.cancelBubble) return false;
|
|
2880
3068
|
}
|
|
2881
3069
|
const shadowHost = node.host;
|
|
2882
|
-
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host &&
|
|
3070
|
+
if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && (() => {
|
|
3071
|
+
const targetNode = asNode(e.target);
|
|
3072
|
+
return targetNode ? node.contains(targetNode) : false;
|
|
3073
|
+
})()) {
|
|
2883
3074
|
retarget(shadowHost);
|
|
2884
3075
|
}
|
|
2885
3076
|
return true;
|
|
2886
3077
|
};
|
|
2887
3078
|
const walkUpTree = () => {
|
|
2888
3079
|
while (handleNode() && node) {
|
|
2889
|
-
node = node._$host || node.parentNode || node.host;
|
|
3080
|
+
node = asElement(node._$host || node.parentNode || node.host);
|
|
2890
3081
|
}
|
|
2891
3082
|
};
|
|
2892
3083
|
Object.defineProperty(e, "currentTarget", {
|
|
@@ -2899,8 +3090,11 @@ function globalEventHandler(e) {
|
|
|
2899
3090
|
const path = e.composedPath();
|
|
2900
3091
|
retarget(path[0]);
|
|
2901
3092
|
for (let i = 0; i < path.length - 2; i++) {
|
|
2902
|
-
|
|
3093
|
+
const nextNode = asElement(path[i]);
|
|
3094
|
+
if (!nextNode || nextNode === lastHandled) continue;
|
|
3095
|
+
node = nextNode;
|
|
2903
3096
|
if (!handleNode()) break;
|
|
3097
|
+
lastHandled = node;
|
|
2904
3098
|
if (node._$host) {
|
|
2905
3099
|
node = node._$host;
|
|
2906
3100
|
walkUpTree();
|