@fictjs/runtime 0.0.7 → 0.0.9

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/slim.cjs CHANGED
@@ -1117,6 +1117,85 @@ var DelegatedEvents = /* @__PURE__ */ new Set([
1117
1117
  "touchmove",
1118
1118
  "touchstart"
1119
1119
  ]);
1120
+ var SVGElements = /* @__PURE__ */ new Set([
1121
+ "altGlyph",
1122
+ "altGlyphDef",
1123
+ "altGlyphItem",
1124
+ "animate",
1125
+ "animateColor",
1126
+ "animateMotion",
1127
+ "animateTransform",
1128
+ "circle",
1129
+ "clipPath",
1130
+ "color-profile",
1131
+ "cursor",
1132
+ "defs",
1133
+ "desc",
1134
+ "ellipse",
1135
+ "feBlend",
1136
+ "feColorMatrix",
1137
+ "feComponentTransfer",
1138
+ "feComposite",
1139
+ "feConvolveMatrix",
1140
+ "feDiffuseLighting",
1141
+ "feDisplacementMap",
1142
+ "feDistantLight",
1143
+ "feDropShadow",
1144
+ "feFlood",
1145
+ "feFuncA",
1146
+ "feFuncB",
1147
+ "feFuncG",
1148
+ "feFuncR",
1149
+ "feGaussianBlur",
1150
+ "feImage",
1151
+ "feMerge",
1152
+ "feMergeNode",
1153
+ "feMorphology",
1154
+ "feOffset",
1155
+ "fePointLight",
1156
+ "feSpecularLighting",
1157
+ "feSpotLight",
1158
+ "feTile",
1159
+ "feTurbulence",
1160
+ "filter",
1161
+ "font",
1162
+ "font-face",
1163
+ "font-face-format",
1164
+ "font-face-name",
1165
+ "font-face-src",
1166
+ "font-face-uri",
1167
+ "foreignObject",
1168
+ "g",
1169
+ "glyph",
1170
+ "glyphRef",
1171
+ "hkern",
1172
+ "image",
1173
+ "line",
1174
+ "linearGradient",
1175
+ "marker",
1176
+ "mask",
1177
+ "metadata",
1178
+ "missing-glyph",
1179
+ "mpath",
1180
+ "path",
1181
+ "pattern",
1182
+ "polygon",
1183
+ "polyline",
1184
+ "radialGradient",
1185
+ "rect",
1186
+ "set",
1187
+ "stop",
1188
+ "svg",
1189
+ "switch",
1190
+ "symbol",
1191
+ "text",
1192
+ "textPath",
1193
+ "tref",
1194
+ "tspan",
1195
+ "use",
1196
+ "view",
1197
+ "vkern"
1198
+ ]);
1120
1199
  var SVGNamespace = {
1121
1200
  xlink: "http://www.w3.org/1999/xlink",
1122
1201
  xml: "http://www.w3.org/XML/1998/namespace"
@@ -1345,2070 +1424,1999 @@ function removeNodes(nodes) {
1345
1424
  }
1346
1425
  }
1347
1426
 
1348
- // src/binding.ts
1349
- function isReactive(value) {
1350
- return typeof value === "function" && value.length === 0;
1427
+ // src/hooks.ts
1428
+ var ctxStack = [];
1429
+ function __fictUseContext() {
1430
+ if (ctxStack.length === 0) {
1431
+ const ctx2 = { slots: [], cursor: 0 };
1432
+ ctxStack.push(ctx2);
1433
+ return ctx2;
1434
+ }
1435
+ const ctx = ctxStack[ctxStack.length - 1];
1436
+ ctx.cursor = 0;
1437
+ return ctx;
1351
1438
  }
1352
- function callEventHandler(handler, event, node, data) {
1353
- if (!handler) return;
1354
- const context = node ?? event.currentTarget ?? void 0;
1355
- const invoke = (fn) => {
1356
- if (typeof fn === "function") {
1357
- const result = data === void 0 ? fn.call(context, event) : fn.call(context, data, event);
1358
- if (typeof result === "function" && result !== fn) {
1359
- if (data === void 0) {
1360
- result.call(context, event);
1361
- } else {
1362
- result.call(context, data, event);
1363
- }
1364
- } else if (result && typeof result.handleEvent === "function") {
1365
- result.handleEvent.call(result, event);
1439
+ function __fictPushContext() {
1440
+ const ctx = { slots: [], cursor: 0 };
1441
+ ctxStack.push(ctx);
1442
+ return ctx;
1443
+ }
1444
+ function __fictPopContext() {
1445
+ ctxStack.pop();
1446
+ }
1447
+ function __fictResetContext() {
1448
+ ctxStack.length = 0;
1449
+ }
1450
+ function __fictUseSignal(ctx, initial, slot) {
1451
+ const index = slot ?? ctx.cursor++;
1452
+ if (!ctx.slots[index]) {
1453
+ ctx.slots[index] = signal(initial);
1454
+ }
1455
+ return ctx.slots[index];
1456
+ }
1457
+ function __fictUseMemo(ctx, fn, slot) {
1458
+ const index = slot ?? ctx.cursor++;
1459
+ if (!ctx.slots[index]) {
1460
+ ctx.slots[index] = createMemo(fn);
1461
+ }
1462
+ return ctx.slots[index];
1463
+ }
1464
+ function __fictUseEffect(ctx, fn, slot) {
1465
+ const index = slot ?? ctx.cursor++;
1466
+ if (!ctx.slots[index]) {
1467
+ ctx.slots[index] = createEffect(fn);
1468
+ }
1469
+ }
1470
+ function __fictRender(ctx, fn) {
1471
+ ctxStack.push(ctx);
1472
+ ctx.cursor = 0;
1473
+ try {
1474
+ return fn();
1475
+ } finally {
1476
+ ctxStack.pop();
1477
+ }
1478
+ }
1479
+
1480
+ // src/props.ts
1481
+ var propGetters = /* @__PURE__ */ new WeakSet();
1482
+ var rawToProxy = /* @__PURE__ */ new WeakMap();
1483
+ var proxyToRaw = /* @__PURE__ */ new WeakMap();
1484
+ function __fictProp(getter) {
1485
+ if (typeof getter === "function" && getter.length === 0) {
1486
+ propGetters.add(getter);
1487
+ }
1488
+ return getter;
1489
+ }
1490
+ function isPropGetter(value) {
1491
+ return typeof value === "function" && propGetters.has(value);
1492
+ }
1493
+ function createPropsProxy(props) {
1494
+ if (!props || typeof props !== "object") {
1495
+ return props;
1496
+ }
1497
+ if (proxyToRaw.has(props)) {
1498
+ return props;
1499
+ }
1500
+ const cached = rawToProxy.get(props);
1501
+ if (cached) {
1502
+ return cached;
1503
+ }
1504
+ const proxy = new Proxy(props, {
1505
+ get(target, prop, receiver) {
1506
+ const value = Reflect.get(target, prop, receiver);
1507
+ if (isPropGetter(value)) {
1508
+ return value();
1366
1509
  }
1367
- } else if (fn && typeof fn.handleEvent === "function") {
1368
- fn.handleEvent.call(fn, event);
1510
+ return value;
1511
+ },
1512
+ set(target, prop, value, receiver) {
1513
+ return Reflect.set(target, prop, value, receiver);
1514
+ },
1515
+ has(target, prop) {
1516
+ return prop in target;
1517
+ },
1518
+ ownKeys(target) {
1519
+ return Reflect.ownKeys(target);
1520
+ },
1521
+ getOwnPropertyDescriptor(target, prop) {
1522
+ return Object.getOwnPropertyDescriptor(target, prop);
1369
1523
  }
1370
- };
1371
- invoke(handler);
1524
+ });
1525
+ rawToProxy.set(props, proxy);
1526
+ proxyToRaw.set(proxy, props);
1527
+ return proxy;
1372
1528
  }
1373
- var PRIMITIVE_PROXY = Symbol("fict:primitive-proxy");
1374
- var PRIMITIVE_PROXY_RAW_VALUE = Symbol("fict:primitive-proxy:raw-value");
1375
- function createValueProxy(read) {
1376
- const getPrimitivePrototype = (value) => {
1377
- switch (typeof value) {
1378
- case "string":
1379
- return String.prototype;
1380
- case "number":
1381
- return Number.prototype;
1382
- case "boolean":
1383
- return Boolean.prototype;
1384
- case "bigint":
1385
- return BigInt.prototype;
1386
- case "symbol":
1387
- return Symbol.prototype;
1388
- default:
1389
- return void 0;
1390
- }
1529
+ function unwrapProps(props) {
1530
+ if (!props || typeof props !== "object") {
1531
+ return props;
1532
+ }
1533
+ return proxyToRaw.get(props) ?? props;
1534
+ }
1535
+ function __fictPropsRest(props, exclude) {
1536
+ const raw = unwrapProps(props);
1537
+ const out = {};
1538
+ const excludeSet = new Set(exclude);
1539
+ for (const key of Reflect.ownKeys(raw)) {
1540
+ if (excludeSet.has(key)) continue;
1541
+ out[key] = raw[key];
1542
+ }
1543
+ return createPropsProxy(out);
1544
+ }
1545
+ function mergeProps(...sources) {
1546
+ const validSources = sources.filter(
1547
+ (s) => s != null && (typeof s === "object" || typeof s === "function")
1548
+ );
1549
+ if (validSources.length === 0) {
1550
+ return {};
1551
+ }
1552
+ if (validSources.length === 1 && typeof validSources[0] === "object") {
1553
+ return validSources[0];
1554
+ }
1555
+ const resolveSource = (src) => {
1556
+ const value = typeof src === "function" ? src() : src;
1557
+ if (!value || typeof value !== "object") return void 0;
1558
+ return unwrapProps(value);
1391
1559
  };
1392
- const target = {};
1393
- const handler = {
1394
- get(_target, prop, receiver) {
1395
- if (prop === PRIMITIVE_PROXY) {
1396
- return true;
1397
- }
1398
- if (prop === PRIMITIVE_PROXY_RAW_VALUE) {
1399
- return () => read();
1400
- }
1401
- if (prop === Symbol.toPrimitive) {
1402
- return (hint) => {
1403
- const value2 = read();
1404
- if (value2 != null && (typeof value2 === "object" || typeof value2 === "function")) {
1405
- const toPrimitive = value2[Symbol.toPrimitive];
1406
- if (typeof toPrimitive === "function") {
1407
- return toPrimitive.call(value2, hint);
1408
- }
1409
- if (hint === "string") return value2.toString?.() ?? "[object Object]";
1410
- if (hint === "number") return value2.valueOf?.() ?? value2;
1411
- return value2.valueOf?.() ?? value2;
1412
- }
1413
- return value2;
1414
- };
1415
- }
1416
- if (prop === "valueOf") {
1417
- return () => {
1418
- const value2 = read();
1419
- if (value2 != null && (typeof value2 === "object" || typeof value2 === "function")) {
1420
- return typeof value2.valueOf === "function" ? value2.valueOf() : value2;
1421
- }
1422
- return value2;
1423
- };
1424
- }
1425
- if (prop === "toString") {
1426
- return () => String(read());
1427
- }
1428
- const value = read();
1429
- if (value != null && (typeof value === "object" || typeof value === "function")) {
1430
- return Reflect.get(value, prop, receiver === _target ? value : receiver);
1560
+ return new Proxy({}, {
1561
+ get(_, prop) {
1562
+ if (typeof prop === "symbol") {
1563
+ return void 0;
1431
1564
  }
1432
- const proto = getPrimitivePrototype(value);
1433
- if (proto && prop in proto) {
1434
- const descriptor = Reflect.get(proto, prop, value);
1435
- return typeof descriptor === "function" ? descriptor.bind(value) : descriptor;
1565
+ for (let i = validSources.length - 1; i >= 0; i--) {
1566
+ const src = validSources[i];
1567
+ const raw = resolveSource(src);
1568
+ if (!raw || !(prop in raw)) continue;
1569
+ const value = raw[prop];
1570
+ if (typeof src === "function" && !isPropGetter(value)) {
1571
+ return __fictProp(() => {
1572
+ const latest = resolveSource(src);
1573
+ if (!latest || !(prop in latest)) return void 0;
1574
+ return latest[prop];
1575
+ });
1576
+ }
1577
+ return value;
1436
1578
  }
1437
1579
  return void 0;
1438
1580
  },
1439
- set(_target, prop, newValue, receiver) {
1440
- const value = read();
1441
- if (value != null && (typeof value === "object" || typeof value === "function")) {
1442
- return Reflect.set(value, prop, newValue, receiver === _target ? value : receiver);
1581
+ has(_, prop) {
1582
+ for (const src of validSources) {
1583
+ const raw = resolveSource(src);
1584
+ if (raw && prop in raw) {
1585
+ return true;
1586
+ }
1443
1587
  }
1444
1588
  return false;
1445
1589
  },
1446
- has(_target, prop) {
1447
- if (prop === PRIMITIVE_PROXY || prop === PRIMITIVE_PROXY_RAW_VALUE) {
1448
- return true;
1449
- }
1450
- const value = read();
1451
- if (value != null && (typeof value === "object" || typeof value === "function")) {
1452
- return prop in value;
1453
- }
1454
- const proto = getPrimitivePrototype(value);
1455
- return proto ? prop in proto : false;
1456
- },
1457
1590
  ownKeys() {
1458
- const value = read();
1459
- if (value != null && (typeof value === "object" || typeof value === "function")) {
1460
- return Reflect.ownKeys(value);
1591
+ const keys = /* @__PURE__ */ new Set();
1592
+ for (const src of validSources) {
1593
+ const raw = resolveSource(src);
1594
+ if (raw) {
1595
+ for (const key of Reflect.ownKeys(raw)) {
1596
+ keys.add(key);
1597
+ }
1598
+ }
1461
1599
  }
1462
- const proto = getPrimitivePrototype(value);
1463
- return proto ? Reflect.ownKeys(proto) : [];
1600
+ return Array.from(keys);
1464
1601
  },
1465
- getOwnPropertyDescriptor(_target, prop) {
1466
- const value = read();
1467
- if (value != null && (typeof value === "object" || typeof value === "function")) {
1468
- return Object.getOwnPropertyDescriptor(value, prop);
1602
+ getOwnPropertyDescriptor(_, prop) {
1603
+ for (let i = validSources.length - 1; i >= 0; i--) {
1604
+ const raw = resolveSource(validSources[i]);
1605
+ if (raw && prop in raw) {
1606
+ return {
1607
+ enumerable: true,
1608
+ configurable: true,
1609
+ get: () => {
1610
+ const value = raw[prop];
1611
+ return value;
1612
+ }
1613
+ };
1614
+ }
1469
1615
  }
1470
- const proto = getPrimitivePrototype(value);
1471
- return proto ? Object.getOwnPropertyDescriptor(proto, prop) || void 0 : void 0;
1472
- }
1473
- };
1474
- return new Proxy(target, handler);
1475
- }
1476
- function bindText(textNode, getValue) {
1477
- return createRenderEffect(() => {
1478
- const value = formatTextValue(getValue());
1479
- if (textNode.data !== value) {
1480
- textNode.data = value;
1616
+ return void 0;
1481
1617
  }
1482
1618
  });
1483
1619
  }
1484
- function formatTextValue(value) {
1485
- if (value == null || value === false) {
1486
- return "";
1487
- }
1488
- return String(value);
1620
+ function useProp(getter) {
1621
+ return __fictProp(createMemo(getter));
1489
1622
  }
1490
- function createAttributeBinding(el, key, value, setter) {
1491
- if (isReactive(value)) {
1492
- createRenderEffect(() => {
1493
- setter(el, key, value());
1494
- });
1495
- } else {
1496
- setter(el, key, value);
1497
- }
1623
+
1624
+ // src/scheduler.ts
1625
+ function batch2(fn) {
1626
+ return batch(fn);
1498
1627
  }
1499
- function bindAttribute(el, key, getValue) {
1500
- let prevValue = void 0;
1501
- return createRenderEffect(() => {
1502
- const value = getValue();
1503
- if (value === prevValue) return;
1504
- prevValue = value;
1505
- if (value === void 0 || value === null || value === false) {
1506
- el.removeAttribute(key);
1507
- } else if (value === true) {
1508
- el.setAttribute(key, "");
1509
- } else {
1510
- el.setAttribute(key, String(value));
1511
- }
1512
- });
1628
+ function untrack2(fn) {
1629
+ return untrack(fn);
1513
1630
  }
1514
- function bindProperty(el, key, getValue) {
1515
- const PROPERTY_BINDING_KEYS = /* @__PURE__ */ new Set([
1516
- "value",
1517
- "checked",
1518
- "selected",
1519
- "disabled",
1520
- "readOnly",
1521
- "multiple",
1522
- "muted"
1523
- ]);
1524
- let prevValue = void 0;
1525
- return createRenderEffect(() => {
1526
- const next = getValue();
1527
- if (next === prevValue) return;
1528
- prevValue = next;
1529
- if (PROPERTY_BINDING_KEYS.has(key) && (next === void 0 || next === null)) {
1530
- const fallback = key === "checked" || key === "selected" ? false : "";
1531
- el[key] = fallback;
1532
- return;
1533
- }
1534
- ;
1535
- el[key] = next;
1536
- });
1537
- }
1538
- function createStyleBinding(el, value) {
1539
- if (isReactive(value)) {
1540
- let prev;
1541
- createRenderEffect(() => {
1542
- const next = value();
1543
- applyStyle(el, next, prev);
1544
- prev = next;
1545
- });
1546
- } else {
1547
- applyStyle(el, value, void 0);
1631
+
1632
+ // src/dom.ts
1633
+ var SVG_NS = "http://www.w3.org/2000/svg";
1634
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
1635
+ function render(view, container) {
1636
+ const root = createRootContext();
1637
+ const prev = pushRoot(root);
1638
+ let dom;
1639
+ try {
1640
+ const output = view();
1641
+ dom = createElement(output);
1642
+ } finally {
1643
+ popRoot(prev);
1548
1644
  }
1645
+ container.replaceChildren(dom);
1646
+ container.setAttribute("data-fict-fine-grained", "1");
1647
+ flushOnMount(root);
1648
+ const teardown = () => {
1649
+ destroyRoot(root);
1650
+ container.innerHTML = "";
1651
+ };
1652
+ return teardown;
1549
1653
  }
1550
- function bindStyle(el, getValue) {
1551
- let prev;
1552
- return createRenderEffect(() => {
1553
- const next = getValue();
1554
- applyStyle(el, next, prev);
1555
- prev = next;
1556
- });
1654
+ function createElement(node) {
1655
+ return createElementWithContext(node, null);
1557
1656
  }
1558
- function applyStyle(el, value, prev) {
1559
- if (typeof value === "string") {
1560
- el.style.cssText = value;
1561
- } else if (value && typeof value === "object") {
1562
- const styles = value;
1563
- if (typeof prev === "string") {
1564
- el.style.cssText = "";
1565
- }
1566
- if (prev && typeof prev === "object") {
1567
- const prevStyles = prev;
1568
- for (const key of Object.keys(prevStyles)) {
1569
- if (!(key in styles)) {
1570
- const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
1571
- el.style.removeProperty(cssProperty);
1572
- }
1657
+ function resolveNamespace(tagName, namespace) {
1658
+ if (tagName === "svg") return "svg";
1659
+ if (tagName === "math") return "mathml";
1660
+ if (namespace === "mathml") return "mathml";
1661
+ if (namespace === "svg") return "svg";
1662
+ if (SVGElements.has(tagName)) return "svg";
1663
+ return null;
1664
+ }
1665
+ function createElementWithContext(node, namespace) {
1666
+ if (node instanceof Node) {
1667
+ return node;
1668
+ }
1669
+ if (node === null || node === void 0 || node === false) {
1670
+ return document.createTextNode("");
1671
+ }
1672
+ if (typeof node === "object" && node !== null && !(node instanceof Node)) {
1673
+ if ("marker" in node) {
1674
+ const handle = node;
1675
+ if (typeof handle.dispose === "function") {
1676
+ registerRootCleanup(handle.dispose);
1573
1677
  }
1678
+ return createElement(handle.marker);
1574
1679
  }
1575
- for (const [prop, v] of Object.entries(styles)) {
1576
- if (v != null) {
1577
- const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
1578
- const unitless = isUnitlessStyleProperty(prop) || isUnitlessStyleProperty(cssProperty);
1579
- const valueStr = typeof v === "number" && !unitless ? `${v}px` : String(v);
1580
- el.style.setProperty(cssProperty, valueStr);
1581
- } else {
1582
- const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
1583
- el.style.removeProperty(cssProperty);
1584
- }
1680
+ const nodeRecord = node;
1681
+ if (nodeRecord[PRIMITIVE_PROXY]) {
1682
+ const primitiveGetter = nodeRecord[Symbol.toPrimitive];
1683
+ const value = typeof primitiveGetter === "function" ? primitiveGetter.call(node, "default") : node;
1684
+ return document.createTextNode(value == null || value === false ? "" : String(value));
1585
1685
  }
1586
- } else {
1587
- if (prev && typeof prev === "object") {
1588
- const prevStyles = prev;
1589
- for (const key of Object.keys(prevStyles)) {
1590
- const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
1591
- el.style.removeProperty(cssProperty);
1592
- }
1593
- } else if (typeof prev === "string") {
1594
- el.style.cssText = "";
1686
+ }
1687
+ if (Array.isArray(node)) {
1688
+ const frag = document.createDocumentFragment();
1689
+ for (const child of node) {
1690
+ appendChildNode(frag, child, namespace);
1595
1691
  }
1692
+ return frag;
1596
1693
  }
1597
- }
1598
- function isUnitlessStyleProperty(prop) {
1599
- return UnitlessStyles.has(prop);
1600
- }
1601
- function createClassBinding(el, value) {
1602
- if (isReactive(value)) {
1603
- let prev = {};
1604
- createRenderEffect(() => {
1605
- const next = value();
1606
- prev = applyClass(el, next, prev);
1694
+ if (typeof node === "string" || typeof node === "number") {
1695
+ return document.createTextNode(String(node));
1696
+ }
1697
+ if (typeof node === "boolean") {
1698
+ return document.createTextNode("");
1699
+ }
1700
+ const vnode = node;
1701
+ if (typeof vnode.type === "function") {
1702
+ const rawProps = unwrapProps(vnode.props ?? {});
1703
+ const baseProps = vnode.key === void 0 ? rawProps : new Proxy(rawProps, {
1704
+ get(target, prop, receiver) {
1705
+ if (prop === "key") return vnode.key;
1706
+ return Reflect.get(target, prop, receiver);
1707
+ },
1708
+ has(target, prop) {
1709
+ if (prop === "key") return true;
1710
+ return prop in target;
1711
+ },
1712
+ ownKeys(target) {
1713
+ const keys = new Set(Reflect.ownKeys(target));
1714
+ keys.add("key");
1715
+ return Array.from(keys);
1716
+ },
1717
+ getOwnPropertyDescriptor(target, prop) {
1718
+ if (prop === "key") {
1719
+ return { enumerable: true, configurable: true, value: vnode.key };
1720
+ }
1721
+ return Object.getOwnPropertyDescriptor(target, prop);
1722
+ }
1607
1723
  });
1608
- } else {
1609
- applyClass(el, value, {});
1724
+ const props = createPropsProxy(baseProps);
1725
+ try {
1726
+ __fictPushContext();
1727
+ const rendered = vnode.type(props);
1728
+ __fictPopContext();
1729
+ return createElementWithContext(rendered, namespace);
1730
+ } catch (err) {
1731
+ __fictPopContext();
1732
+ if (handleSuspend(err)) {
1733
+ return document.createComment("fict:suspend");
1734
+ }
1735
+ handleError(err, { source: "render", componentName: vnode.type.name });
1736
+ throw err;
1737
+ }
1610
1738
  }
1611
- }
1612
- function bindClass(el, getValue) {
1613
- let prev = {};
1614
- return createRenderEffect(() => {
1615
- const next = getValue();
1616
- prev = applyClass(el, next, prev);
1617
- });
1618
- }
1619
- function toggleClassKey(node, key, value) {
1620
- const classNames = key.trim().split(/\s+/);
1621
- for (let i = 0, len = classNames.length; i < len; i++) {
1622
- node.classList.toggle(classNames[i], value);
1739
+ if (vnode.type === Fragment) {
1740
+ const frag = document.createDocumentFragment();
1741
+ const children = vnode.props?.children;
1742
+ appendChildren(frag, children, namespace);
1743
+ return frag;
1623
1744
  }
1745
+ const tagName = typeof vnode.type === "string" ? vnode.type : "div";
1746
+ const resolvedNamespace = resolveNamespace(tagName, namespace);
1747
+ const el = resolvedNamespace === "svg" ? document.createElementNS(SVG_NS, tagName) : resolvedNamespace === "mathml" ? document.createElementNS(MATHML_NS, tagName) : document.createElement(tagName);
1748
+ applyProps(el, vnode.props ?? {}, resolvedNamespace === "svg");
1749
+ appendChildren(
1750
+ el,
1751
+ vnode.props?.children,
1752
+ tagName === "foreignObject" ? null : resolvedNamespace
1753
+ );
1754
+ return el;
1624
1755
  }
1625
- function applyClass(el, value, prev) {
1626
- const prevState = prev && typeof prev === "object" ? prev : {};
1627
- if (typeof value === "string") {
1628
- el.className = value;
1629
- return {};
1630
- }
1631
- if (value && typeof value === "object") {
1632
- const classes = value;
1633
- const classKeys = Object.keys(classes);
1634
- const prevKeys = Object.keys(prevState);
1635
- for (let i = 0, len = prevKeys.length; i < len; i++) {
1636
- const key = prevKeys[i];
1637
- if (!key || key === "undefined" || classes[key]) continue;
1638
- toggleClassKey(el, key, false);
1639
- delete prevState[key];
1756
+ function template(html, isImportNode, isSVG, isMathML) {
1757
+ let node = null;
1758
+ const create = () => {
1759
+ const t = isMathML ? document.createElementNS(MATHML_NS, "template") : document.createElement("template");
1760
+ t.innerHTML = html;
1761
+ if (isSVG) {
1762
+ return t.content.firstChild.firstChild;
1640
1763
  }
1641
- for (let i = 0, len = classKeys.length; i < len; i++) {
1642
- const key = classKeys[i];
1643
- const classValue = !!classes[key];
1644
- if (!key || key === "undefined" || prevState[key] === classValue || !classValue) continue;
1645
- toggleClassKey(el, key, true);
1646
- prevState[key] = classValue;
1764
+ if (isMathML) {
1765
+ return t.firstChild;
1647
1766
  }
1648
- return prevState;
1767
+ return t.content.firstChild;
1768
+ };
1769
+ const fn = isImportNode ? () => untrack2(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true);
1770
+ fn.cloneNode = fn;
1771
+ return fn;
1772
+ }
1773
+ function isBindingHandle(node) {
1774
+ return node !== null && typeof node === "object" && "marker" in node && "dispose" in node && typeof node.dispose === "function";
1775
+ }
1776
+ function appendChildNode(parent, child, namespace) {
1777
+ if (child === null || child === void 0 || child === false) {
1778
+ return;
1649
1779
  }
1650
- if (!value) {
1651
- for (const key of Object.keys(prevState)) {
1652
- if (key && key !== "undefined") {
1653
- toggleClassKey(el, key, false);
1654
- }
1780
+ if (isBindingHandle(child)) {
1781
+ appendChildNode(parent, child.marker, namespace);
1782
+ child.flush?.();
1783
+ return;
1784
+ }
1785
+ if (typeof child === "function" && child.length === 0) {
1786
+ const childGetter = child;
1787
+ createChildBinding(parent, childGetter, (node) => createElementWithContext(node, namespace));
1788
+ return;
1789
+ }
1790
+ if (Array.isArray(child)) {
1791
+ for (const item of child) {
1792
+ appendChildNode(parent, item, namespace);
1655
1793
  }
1656
- return {};
1794
+ return;
1657
1795
  }
1658
- return prevState;
1659
- }
1660
- function insert(parent, getValue, markerOrCreateElement, createElementFn) {
1661
- let marker;
1662
- let ownsMarker = false;
1663
- let createFn = createElementFn;
1664
- if (markerOrCreateElement instanceof Node) {
1665
- marker = markerOrCreateElement;
1666
- createFn = createElementFn;
1796
+ let domNode;
1797
+ if (typeof child !== "object" || child === null) {
1798
+ domNode = document.createTextNode(String(child ?? ""));
1667
1799
  } else {
1668
- marker = document.createComment("fict:insert");
1669
- parent.appendChild(marker);
1670
- createFn = markerOrCreateElement;
1671
- ownsMarker = true;
1800
+ domNode = createElementWithContext(child, namespace);
1672
1801
  }
1673
- let currentNodes = [];
1674
- let currentText = null;
1675
- let currentRoot2 = null;
1676
- const clearCurrentNodes = () => {
1677
- if (currentNodes.length > 0) {
1678
- removeNodes(currentNodes);
1679
- currentNodes = [];
1680
- }
1681
- };
1682
- const setTextNode = (textValue, shouldInsert, parentNode) => {
1683
- if (!currentText) {
1684
- currentText = document.createTextNode(textValue);
1685
- } else if (currentText.data !== textValue) {
1686
- currentText.data = textValue;
1802
+ if (domNode.nodeType === 11) {
1803
+ const children = Array.from(domNode.childNodes);
1804
+ for (const node of children) {
1805
+ appendChildNode(parent, node, namespace);
1687
1806
  }
1688
- if (!shouldInsert) {
1689
- clearCurrentNodes();
1807
+ return;
1808
+ }
1809
+ if (domNode.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
1810
+ parent.ownerDocument.adoptNode(domNode);
1811
+ }
1812
+ try {
1813
+ parent.appendChild(domNode);
1814
+ } catch (e) {
1815
+ if (parent.ownerDocument) {
1816
+ const clone = parent.ownerDocument.importNode(domNode, true);
1817
+ parent.appendChild(clone);
1690
1818
  return;
1691
1819
  }
1692
- if (currentNodes.length === 1 && currentNodes[0] === currentText) {
1693
- return;
1820
+ throw e;
1821
+ }
1822
+ }
1823
+ function appendChildren(parent, children, namespace) {
1824
+ if (children === void 0) return;
1825
+ if (Array.isArray(children)) {
1826
+ for (const child of children) {
1827
+ appendChildren(parent, child, namespace);
1694
1828
  }
1695
- clearCurrentNodes();
1696
- insertNodesBefore(parentNode, [currentText], marker);
1697
- currentNodes = [currentText];
1698
- };
1699
- const dispose = createRenderEffect(() => {
1700
- const value = getValue();
1701
- const parentNode = marker.parentNode;
1702
- const isPrimitive = value == null || value === false || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1703
- if (isPrimitive) {
1704
- if (currentRoot2) {
1705
- destroyRoot(currentRoot2);
1706
- currentRoot2 = null;
1707
- }
1708
- if (!parentNode) {
1709
- clearCurrentNodes();
1710
- return;
1711
- }
1712
- const textValue = value == null || value === false ? "" : String(value);
1713
- const shouldInsert = value != null && value !== false;
1714
- setTextNode(textValue, shouldInsert, parentNode);
1715
- return;
1829
+ return;
1830
+ }
1831
+ appendChildNode(parent, children, namespace);
1832
+ }
1833
+ function applyRef(el, value) {
1834
+ if (typeof value === "function") {
1835
+ const refFn = value;
1836
+ refFn(el);
1837
+ if (getCurrentRoot()) {
1838
+ registerRootCleanup(() => {
1839
+ refFn(null);
1840
+ });
1716
1841
  }
1717
- if (currentRoot2) {
1718
- destroyRoot(currentRoot2);
1719
- currentRoot2 = null;
1842
+ } else if (value && typeof value === "object" && "current" in value) {
1843
+ const refObj = value;
1844
+ refObj.current = el;
1845
+ if (getCurrentRoot()) {
1846
+ registerRootCleanup(() => {
1847
+ refObj.current = null;
1848
+ });
1720
1849
  }
1721
- clearCurrentNodes();
1722
- const root = createRootContext();
1723
- const prev = pushRoot(root);
1724
- let nodes = [];
1725
- try {
1726
- let newNode;
1727
- if (value instanceof Node) {
1728
- newNode = value;
1729
- } else if (Array.isArray(value)) {
1730
- if (value.every((v) => v instanceof Node)) {
1731
- newNode = value;
1850
+ }
1851
+ }
1852
+ function applyProps(el, props, isSVG = false) {
1853
+ props = unwrapProps(props);
1854
+ const tagName = el.tagName;
1855
+ const isCE = tagName.includes("-") || "is" in props;
1856
+ for (const [key, value] of Object.entries(props)) {
1857
+ if (key === "children") continue;
1858
+ if (key === "ref") {
1859
+ applyRef(el, value);
1860
+ continue;
1861
+ }
1862
+ if (isEventKey(key)) {
1863
+ bindEvent(
1864
+ el,
1865
+ eventNameFromProp(key),
1866
+ value
1867
+ );
1868
+ continue;
1869
+ }
1870
+ if (key.slice(0, 3) === "on:") {
1871
+ bindEvent(
1872
+ el,
1873
+ key.slice(3),
1874
+ value,
1875
+ false
1876
+ // Non-delegated
1877
+ );
1878
+ continue;
1879
+ }
1880
+ if (key.slice(0, 10) === "oncapture:") {
1881
+ bindEvent(
1882
+ el,
1883
+ key.slice(10),
1884
+ value,
1885
+ true
1886
+ // Capture
1887
+ );
1888
+ continue;
1889
+ }
1890
+ if (key === "class" || key === "className") {
1891
+ createClassBinding(el, value);
1892
+ continue;
1893
+ }
1894
+ if (key === "classList") {
1895
+ createClassBinding(el, value);
1896
+ continue;
1897
+ }
1898
+ if (key === "style") {
1899
+ createStyleBinding(
1900
+ el,
1901
+ value
1902
+ );
1903
+ continue;
1904
+ }
1905
+ if (key === "dangerouslySetInnerHTML" && value && typeof value === "object") {
1906
+ const htmlValue = value.__html;
1907
+ if (htmlValue !== void 0) {
1908
+ if (isReactive(htmlValue)) {
1909
+ createAttributeBinding(el, "innerHTML", htmlValue, setInnerHTML);
1732
1910
  } else {
1733
- newNode = createFn ? createFn(value) : document.createTextNode(String(value));
1911
+ el.innerHTML = htmlValue;
1734
1912
  }
1735
- } else {
1736
- newNode = createFn ? createFn(value) : document.createTextNode(String(value));
1737
- }
1738
- nodes = toNodeArray(newNode);
1739
- if (parentNode) {
1740
- insertNodesBefore(parentNode, nodes, marker);
1741
1913
  }
1742
- } finally {
1743
- popRoot(prev);
1744
- flushOnMount(root);
1914
+ continue;
1745
1915
  }
1746
- currentRoot2 = root;
1747
- currentNodes = nodes;
1748
- });
1749
- return () => {
1750
- dispose();
1751
- if (currentRoot2) {
1752
- destroyRoot(currentRoot2);
1753
- currentRoot2 = null;
1916
+ if (ChildProperties.has(key)) {
1917
+ createAttributeBinding(el, key, value, setProperty);
1918
+ continue;
1754
1919
  }
1755
- clearCurrentNodes();
1756
- if (ownsMarker) {
1757
- marker.parentNode?.removeChild(marker);
1920
+ if (key.slice(0, 5) === "attr:") {
1921
+ createAttributeBinding(el, key.slice(5), value, setAttribute);
1922
+ continue;
1758
1923
  }
1759
- };
1760
- }
1761
- function createChildBinding(parent, getValue, createElementFn) {
1762
- const marker = document.createComment("fict:child");
1763
- parent.appendChild(marker);
1764
- const dispose = createRenderEffect(() => {
1765
- const root = createRootContext();
1766
- const prev = pushRoot(root);
1767
- let nodes = [];
1768
- let handledError = false;
1769
- try {
1770
- const value = getValue();
1771
- if (value == null || value === false) {
1772
- return;
1773
- }
1774
- const output = createElementFn(value);
1775
- nodes = toNodeArray(output);
1776
- const parentNode = marker.parentNode;
1777
- if (parentNode) {
1778
- insertNodesBefore(parentNode, nodes, marker);
1779
- }
1780
- return () => {
1781
- destroyRoot(root);
1782
- removeNodes(nodes);
1783
- };
1784
- } catch (err) {
1785
- if (handleSuspend(err, root)) {
1786
- handledError = true;
1787
- destroyRoot(root);
1788
- return;
1789
- }
1790
- if (handleError(err, { source: "renderChild" }, root)) {
1791
- handledError = true;
1792
- destroyRoot(root);
1793
- return;
1794
- }
1795
- throw err;
1796
- } finally {
1797
- popRoot(prev);
1798
- if (!handledError) {
1799
- flushOnMount(root);
1800
- }
1924
+ if (key.slice(0, 5) === "bool:") {
1925
+ createAttributeBinding(el, key.slice(5), value, setBoolAttribute);
1926
+ continue;
1801
1927
  }
1802
- });
1803
- return {
1804
- marker,
1805
- dispose: () => {
1806
- dispose();
1807
- marker.parentNode?.removeChild(marker);
1928
+ if (key.slice(0, 5) === "prop:") {
1929
+ createAttributeBinding(el, key.slice(5), value, setProperty);
1930
+ continue;
1808
1931
  }
1809
- };
1810
- }
1811
- function delegateEvents(eventNames, doc = window.document) {
1812
- const e = doc[$$EVENTS] || (doc[$$EVENTS] = /* @__PURE__ */ new Set());
1813
- for (let i = 0, l = eventNames.length; i < l; i++) {
1814
- const name = eventNames[i];
1815
- if (!e.has(name)) {
1816
- e.add(name);
1817
- doc.addEventListener(name, globalEventHandler);
1932
+ const propAlias = !isSVG ? getPropAlias(key, tagName) : void 0;
1933
+ if (propAlias || !isSVG && Properties.has(key) || isCE && !isSVG) {
1934
+ const propName = propAlias || key;
1935
+ if (isCE && !Properties.has(key)) {
1936
+ createAttributeBinding(
1937
+ el,
1938
+ toPropertyName(propName),
1939
+ value,
1940
+ setProperty
1941
+ );
1942
+ } else {
1943
+ createAttributeBinding(el, propName, value, setProperty);
1944
+ }
1945
+ continue;
1818
1946
  }
1819
- }
1820
- }
1821
- function clearDelegatedEvents(doc = window.document) {
1822
- const e = doc[$$EVENTS];
1823
- if (e) {
1824
- for (const name of e.keys()) {
1825
- doc.removeEventListener(name, globalEventHandler);
1947
+ if (isSVG && key.indexOf(":") > -1) {
1948
+ const [prefix, name] = key.split(":");
1949
+ const ns = SVGNamespace[prefix];
1950
+ if (ns) {
1951
+ createAttributeBinding(
1952
+ el,
1953
+ key,
1954
+ value,
1955
+ (el2, _key, val) => setAttributeNS(el2, ns, name, val)
1956
+ );
1957
+ continue;
1958
+ }
1826
1959
  }
1827
- delete doc[$$EVENTS];
1960
+ const attrName = Aliases[key] || key;
1961
+ createAttributeBinding(el, attrName, value, setAttribute);
1828
1962
  }
1829
1963
  }
1830
- function globalEventHandler(e) {
1831
- let node = e.target;
1832
- const key = `$$${e.type}`;
1833
- const dataKey = `${key}Data`;
1834
- const oriTarget = e.target;
1835
- const oriCurrentTarget = e.currentTarget;
1836
- const retarget = (value) => Object.defineProperty(e, "target", {
1837
- configurable: true,
1838
- value
1839
- });
1840
- const handleNode = () => {
1841
- if (!node) return false;
1842
- const handler = node[key];
1843
- if (handler && !node.disabled) {
1844
- const resolveData = (value) => {
1845
- if (typeof value === "function") {
1846
- try {
1847
- const fn = value;
1848
- return fn.length > 0 ? fn(e) : fn();
1849
- } catch {
1850
- return value();
1851
- }
1852
- }
1853
- return value;
1854
- };
1855
- const rawData = node[dataKey];
1856
- const hasData = rawData !== void 0;
1857
- const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
1858
- if (typeof handler === "function") {
1859
- callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
1860
- } else if (Array.isArray(handler)) {
1861
- const tupleData = resolveData(handler[1]);
1862
- callEventHandler(handler[0], e, node, tupleData);
1964
+ function toPropertyName(name) {
1965
+ return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
1966
+ }
1967
+ var setAttribute = (el, key, value) => {
1968
+ if (value === void 0 || value === null || value === false) {
1969
+ el.removeAttribute(key);
1970
+ return;
1971
+ }
1972
+ if (value === true) {
1973
+ el.setAttribute(key, "");
1974
+ return;
1975
+ }
1976
+ const valueType = typeof value;
1977
+ if (valueType === "string" || valueType === "number") {
1978
+ el.setAttribute(key, String(value));
1979
+ return;
1980
+ }
1981
+ if (key in el) {
1982
+ el[key] = value;
1983
+ return;
1984
+ }
1985
+ el.setAttribute(key, String(value));
1986
+ };
1987
+ var setProperty = (el, key, value) => {
1988
+ if (value === void 0 || value === null) {
1989
+ const fallback = key === "checked" || key === "selected" ? false : "";
1990
+ el[key] = fallback;
1991
+ return;
1992
+ }
1993
+ if (key === "style" && typeof value === "object" && value !== null) {
1994
+ for (const k in value) {
1995
+ const v = value[k];
1996
+ if (v !== void 0) {
1997
+ el.style[k] = String(v);
1863
1998
  }
1864
- if (e.cancelBubble) return false;
1865
1999
  }
1866
- const shadowHost = node.host;
1867
- if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && node.contains(e.target)) {
1868
- retarget(shadowHost);
1869
- }
1870
- return true;
1871
- };
1872
- const walkUpTree = () => {
1873
- while (handleNode() && node) {
1874
- node = node._$host || node.parentNode || node.host;
2000
+ return;
2001
+ }
2002
+ el[key] = value;
2003
+ };
2004
+ var setInnerHTML = (el, _key, value) => {
2005
+ el.innerHTML = value == null ? "" : String(value);
2006
+ };
2007
+ var setBoolAttribute = (el, key, value) => {
2008
+ if (value) {
2009
+ el.setAttribute(key, "");
2010
+ } else {
2011
+ el.removeAttribute(key);
2012
+ }
2013
+ };
2014
+ function setAttributeNS(el, namespace, name, value) {
2015
+ if (value == null) {
2016
+ el.removeAttributeNS(namespace, name);
2017
+ } else {
2018
+ el.setAttributeNS(namespace, name, String(value));
2019
+ }
2020
+ }
2021
+ function isEventKey(key) {
2022
+ return key.startsWith("on") && key.length > 2 && key[2].toUpperCase() === key[2];
2023
+ }
2024
+ function eventNameFromProp(key) {
2025
+ return key.slice(2).toLowerCase();
2026
+ }
2027
+
2028
+ // src/reconcile.ts
2029
+ function reconcileArrays(parentNode, a, b) {
2030
+ const bLength = b.length;
2031
+ let aEnd = a.length;
2032
+ let bEnd = bLength;
2033
+ let aStart = 0;
2034
+ let bStart = 0;
2035
+ const after = aEnd > 0 ? a[aEnd - 1].nextSibling : null;
2036
+ let map = null;
2037
+ while (aStart < aEnd || bStart < bEnd) {
2038
+ if (a[aStart] === b[bStart]) {
2039
+ aStart++;
2040
+ bStart++;
2041
+ continue;
1875
2042
  }
1876
- };
1877
- Object.defineProperty(e, "currentTarget", {
1878
- configurable: true,
1879
- get() {
1880
- return node || document;
2043
+ while (a[aEnd - 1] === b[bEnd - 1]) {
2044
+ aEnd--;
2045
+ bEnd--;
1881
2046
  }
1882
- });
1883
- if (e.composedPath) {
1884
- const path = e.composedPath();
1885
- retarget(path[0]);
1886
- for (let i = 0; i < path.length - 2; i++) {
1887
- node = path[i];
1888
- if (!handleNode()) break;
1889
- if (node._$host) {
1890
- node = node._$host;
1891
- walkUpTree();
1892
- break;
2047
+ if (aEnd === aStart) {
2048
+ const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] ?? null : after;
2049
+ const count = bEnd - bStart;
2050
+ const doc = parentNode.ownerDocument;
2051
+ if (count > 1 && doc) {
2052
+ const frag = doc.createDocumentFragment();
2053
+ for (let i = bStart; i < bEnd; i++) {
2054
+ frag.appendChild(b[i]);
2055
+ }
2056
+ parentNode.insertBefore(frag, node);
2057
+ bStart = bEnd;
2058
+ } else {
2059
+ while (bStart < bEnd) {
2060
+ parentNode.insertBefore(b[bStart++], node);
2061
+ }
1893
2062
  }
1894
- if (node.parentNode === oriCurrentTarget) {
1895
- break;
2063
+ } else if (bEnd === bStart) {
2064
+ while (aStart < aEnd) {
2065
+ const nodeToRemove = a[aStart];
2066
+ if (!map || !map.has(nodeToRemove)) {
2067
+ nodeToRemove.parentNode?.removeChild(nodeToRemove);
2068
+ }
2069
+ aStart++;
2070
+ }
2071
+ } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
2072
+ const node = a[--aEnd].nextSibling;
2073
+ parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling);
2074
+ parentNode.insertBefore(b[--bEnd], node);
2075
+ a[aEnd] = b[bEnd];
2076
+ } else {
2077
+ if (!map) {
2078
+ map = /* @__PURE__ */ new Map();
2079
+ let i = bStart;
2080
+ while (i < bEnd) {
2081
+ map.set(b[i], i++);
2082
+ }
2083
+ }
2084
+ const index = map.get(a[aStart]);
2085
+ if (index != null) {
2086
+ if (bStart < index && index < bEnd) {
2087
+ let i = aStart;
2088
+ let sequence = 1;
2089
+ let t;
2090
+ while (++i < aEnd && i < bEnd) {
2091
+ t = map.get(a[i]);
2092
+ if (t == null || t !== index + sequence) break;
2093
+ sequence++;
2094
+ }
2095
+ if (sequence > index - bStart) {
2096
+ const node = a[aStart];
2097
+ while (bStart < index) {
2098
+ parentNode.insertBefore(b[bStart++], node);
2099
+ }
2100
+ } else {
2101
+ parentNode.replaceChild(b[bStart++], a[aStart++]);
2102
+ }
2103
+ } else {
2104
+ aStart++;
2105
+ }
2106
+ } else {
2107
+ const nodeToRemove = a[aStart++];
2108
+ nodeToRemove.parentNode?.removeChild(nodeToRemove);
1896
2109
  }
1897
2110
  }
1898
- } else {
1899
- walkUpTree();
1900
2111
  }
1901
- retarget(oriTarget);
1902
2112
  }
1903
- function bindEvent(el, eventName, handler, options2) {
1904
- if (handler == null) return () => {
1905
- };
1906
- const rootRef = getCurrentRoot();
1907
- if (DelegatedEvents.has(eventName) && !options2) {
1908
- const key = `$$${eventName}`;
1909
- delegateEvents([eventName]);
1910
- const resolveHandler = isReactive(handler) ? handler : () => handler;
1911
- el[key] = function(...args) {
1912
- try {
1913
- const fn = resolveHandler();
1914
- callEventHandler(fn, args[0], el);
1915
- } catch (err) {
1916
- handleError(err, { source: "event", eventName }, rootRef);
2113
+
2114
+ // src/list-helpers.ts
2115
+ function moveNodesBefore(parent, nodes, anchor) {
2116
+ for (let i = nodes.length - 1; i >= 0; i--) {
2117
+ const node = nodes[i];
2118
+ if (!node || !(node instanceof Node)) {
2119
+ throw new Error("Invalid node in moveNodesBefore");
2120
+ }
2121
+ if (node.nextSibling !== anchor) {
2122
+ if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
2123
+ parent.ownerDocument.adoptNode(node);
1917
2124
  }
1918
- };
1919
- return () => {
1920
- el[key] = void 0;
1921
- };
1922
- }
1923
- const getHandler = isReactive(handler) ? handler : () => handler;
1924
- const wrapped = (event) => {
1925
- try {
1926
- const resolved = getHandler();
1927
- callEventHandler(resolved, event, el);
1928
- } catch (err) {
1929
- if (handleError(err, { source: "event", eventName }, rootRef)) {
1930
- return;
2125
+ try {
2126
+ parent.insertBefore(node, anchor);
2127
+ } catch (e) {
2128
+ if (parent.ownerDocument) {
2129
+ try {
2130
+ const clone = parent.ownerDocument.importNode(node, true);
2131
+ parent.insertBefore(clone, anchor);
2132
+ continue;
2133
+ } catch {
2134
+ }
2135
+ }
2136
+ throw e;
1931
2137
  }
1932
- throw err;
1933
2138
  }
1934
- };
1935
- el.addEventListener(eventName, wrapped, options2);
1936
- const cleanup = () => el.removeEventListener(eventName, wrapped, options2);
1937
- registerRootCleanup(cleanup);
1938
- return cleanup;
2139
+ anchor = node;
2140
+ }
1939
2141
  }
1940
- function bindRef(el, ref) {
1941
- if (ref == null) return () => {
1942
- };
1943
- const getRef = isReactive(ref) ? ref : () => ref;
1944
- const applyRef2 = (refValue) => {
1945
- if (refValue == null) return;
1946
- if (typeof refValue === "function") {
1947
- refValue(el);
1948
- } else if (typeof refValue === "object" && "current" in refValue) {
1949
- refValue.current = el;
1950
- }
1951
- };
1952
- const initialRef = getRef();
1953
- applyRef2(initialRef);
1954
- if (isReactive(ref)) {
1955
- const cleanup2 = createRenderEffect(() => {
1956
- const currentRef = getRef();
1957
- applyRef2(currentRef);
1958
- });
1959
- registerRootCleanup(cleanup2);
1960
- const nullifyCleanup = () => {
1961
- const currentRef = getRef();
1962
- if (currentRef && typeof currentRef === "object" && "current" in currentRef) {
1963
- currentRef.current = null;
1964
- }
1965
- };
1966
- registerRootCleanup(nullifyCleanup);
1967
- return () => {
1968
- cleanup2();
1969
- nullifyCleanup();
1970
- };
2142
+ function moveMarkerBlock(parent, block, anchor) {
2143
+ const nodes = collectBlockNodes(block);
2144
+ if (nodes.length === 0) return;
2145
+ moveNodesBefore(parent, nodes, anchor);
2146
+ }
2147
+ function destroyMarkerBlock(block) {
2148
+ if (block.root) {
2149
+ destroyRoot(block.root);
1971
2150
  }
1972
- const cleanup = () => {
1973
- const refValue = getRef();
1974
- if (refValue && typeof refValue === "object" && "current" in refValue) {
1975
- refValue.current = null;
1976
- }
1977
- };
1978
- registerRootCleanup(cleanup);
1979
- return cleanup;
2151
+ removeBlockRange(block);
1980
2152
  }
1981
- function createConditional(condition, renderTrue, createElementFn, renderFalse) {
1982
- const startMarker = document.createComment("fict:cond:start");
1983
- const endMarker = document.createComment("fict:cond:end");
1984
- const fragment = document.createDocumentFragment();
1985
- fragment.append(startMarker, endMarker);
1986
- let currentNodes = [];
1987
- let currentRoot2 = null;
1988
- let lastCondition = void 0;
1989
- let pendingRender = false;
1990
- const conditionMemo = computed(condition);
1991
- const runConditional = () => {
1992
- const cond = conditionMemo();
1993
- const parent = startMarker.parentNode;
1994
- if (!parent) {
1995
- pendingRender = true;
1996
- return;
2153
+ function collectBlockNodes(block) {
2154
+ const nodes = [];
2155
+ let cursor = block.start;
2156
+ while (cursor) {
2157
+ nodes.push(cursor);
2158
+ if (cursor === block.end) {
2159
+ break;
1997
2160
  }
1998
- pendingRender = false;
1999
- if (lastCondition === cond && currentNodes.length > 0) {
2000
- return;
2161
+ cursor = cursor.nextSibling;
2162
+ }
2163
+ return nodes;
2164
+ }
2165
+ function removeBlockRange(block) {
2166
+ let cursor = block.start;
2167
+ while (cursor) {
2168
+ const next = cursor.nextSibling;
2169
+ cursor.parentNode?.removeChild(cursor);
2170
+ if (cursor === block.end) {
2171
+ break;
2001
2172
  }
2002
- if (lastCondition === cond && lastCondition === false && renderFalse === void 0) {
2003
- return;
2173
+ cursor = next;
2174
+ }
2175
+ }
2176
+ function createVersionedSignalAccessor(initialValue) {
2177
+ let current = initialValue;
2178
+ let version = 0;
2179
+ const track = signal(version);
2180
+ function accessor(value) {
2181
+ if (arguments.length === 0) {
2182
+ track();
2183
+ return current;
2004
2184
  }
2005
- lastCondition = cond;
2006
- if (currentRoot2) {
2007
- destroyRoot(currentRoot2);
2008
- currentRoot2 = null;
2185
+ current = value;
2186
+ version++;
2187
+ track(version);
2188
+ }
2189
+ return accessor;
2190
+ }
2191
+ function createKeyedListContainer() {
2192
+ const startMarker = document.createComment("fict:list:start");
2193
+ const endMarker = document.createComment("fict:list:end");
2194
+ const dispose = () => {
2195
+ for (const block of container.blocks.values()) {
2196
+ destroyRoot(block.root);
2009
2197
  }
2010
- removeNodes(currentNodes);
2011
- currentNodes = [];
2012
- const render2 = cond ? renderTrue : renderFalse;
2013
- if (!render2) {
2198
+ container.blocks.clear();
2199
+ container.nextBlocks.clear();
2200
+ if (!startMarker.parentNode || !endMarker.parentNode) {
2201
+ container.currentNodes = [];
2202
+ container.nextNodes = [];
2203
+ container.orderedBlocks.length = 0;
2204
+ container.nextOrderedBlocks.length = 0;
2205
+ container.orderedIndexByKey.clear();
2014
2206
  return;
2015
2207
  }
2016
- const root = createRootContext();
2017
- const prev = pushRoot(root);
2018
- let handledError = false;
2019
- try {
2020
- const output = untrack(render2);
2021
- if (output == null || output === false) {
2022
- return;
2023
- }
2024
- const el = createElementFn(output);
2025
- const nodes = toNodeArray(el);
2026
- insertNodesBefore(parent, nodes, endMarker);
2027
- currentNodes = nodes;
2028
- } catch (err) {
2029
- if (handleSuspend(err, root)) {
2030
- handledError = true;
2031
- destroyRoot(root);
2032
- return;
2033
- }
2034
- if (handleError(err, { source: "renderChild" }, root)) {
2035
- handledError = true;
2036
- destroyRoot(root);
2037
- return;
2038
- }
2039
- throw err;
2040
- } finally {
2041
- popRoot(prev);
2042
- if (!handledError) {
2043
- flushOnMount(root);
2044
- currentRoot2 = root;
2045
- } else {
2046
- currentRoot2 = null;
2047
- }
2048
- }
2208
+ const range = document.createRange();
2209
+ range.setStartBefore(startMarker);
2210
+ range.setEndAfter(endMarker);
2211
+ range.deleteContents();
2212
+ container.currentNodes = [];
2213
+ container.nextNodes = [];
2214
+ container.nextBlocks.clear();
2215
+ container.orderedBlocks.length = 0;
2216
+ container.nextOrderedBlocks.length = 0;
2217
+ container.orderedIndexByKey.clear();
2049
2218
  };
2050
- const dispose = createRenderEffect(runConditional);
2051
- return {
2052
- marker: fragment,
2053
- flush: () => {
2054
- if (pendingRender) {
2055
- runConditional();
2056
- }
2057
- },
2058
- dispose: () => {
2059
- dispose();
2060
- if (currentRoot2) {
2061
- destroyRoot(currentRoot2);
2062
- }
2063
- removeNodes(currentNodes);
2064
- currentNodes = [];
2065
- startMarker.parentNode?.removeChild(startMarker);
2066
- endMarker.parentNode?.removeChild(endMarker);
2067
- }
2219
+ const container = {
2220
+ startMarker,
2221
+ endMarker,
2222
+ blocks: /* @__PURE__ */ new Map(),
2223
+ nextBlocks: /* @__PURE__ */ new Map(),
2224
+ currentNodes: [startMarker, endMarker],
2225
+ nextNodes: [],
2226
+ orderedBlocks: [],
2227
+ nextOrderedBlocks: [],
2228
+ orderedIndexByKey: /* @__PURE__ */ new Map(),
2229
+ dispose
2068
2230
  };
2231
+ return container;
2069
2232
  }
2070
- function createList(items, renderItem, createElementFn, getKey) {
2071
- const startMarker = document.createComment("fict:list:start");
2072
- const endMarker = document.createComment("fict:list:end");
2073
- const fragment = document.createDocumentFragment();
2074
- fragment.append(startMarker, endMarker);
2075
- const nodeMap = /* @__PURE__ */ new Map();
2076
- let pendingItems = null;
2077
- const runListUpdate = () => {
2078
- const arr = items();
2079
- const parent = startMarker.parentNode;
2080
- if (!parent) {
2081
- pendingItems = arr;
2082
- return;
2233
+ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot) {
2234
+ const itemSig = createVersionedSignalAccessor(item);
2235
+ const indexSig = needsIndex ? signal(index) : ((next) => {
2236
+ if (arguments.length === 0) return index;
2237
+ index = next;
2238
+ return index;
2239
+ });
2240
+ const root = createRootContext(hostRoot);
2241
+ const prevRoot = pushRoot(root);
2242
+ const prevSub = setActiveSub(void 0);
2243
+ let nodes = [];
2244
+ try {
2245
+ const rendered = render2(itemSig, indexSig, key);
2246
+ if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
2247
+ nodes = toNodeArray(rendered);
2248
+ } else {
2249
+ const element = createElement(rendered);
2250
+ nodes = toNodeArray(element);
2083
2251
  }
2084
- pendingItems = null;
2085
- const newNodeMap = /* @__PURE__ */ new Map();
2086
- const blocks = [];
2087
- for (let i = 0; i < arr.length; i++) {
2088
- const item = arr[i];
2089
- const key = getKey ? getKey(item, i) : i;
2090
- const existing = nodeMap.get(key);
2091
- let block;
2092
- if (existing) {
2093
- const previousValue = existing.value();
2094
- if (!getKey && previousValue !== item) {
2095
- destroyRoot(existing.root);
2096
- removeBlockNodes(existing);
2097
- block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn);
2252
+ } finally {
2253
+ setActiveSub(prevSub);
2254
+ popRoot(prevRoot);
2255
+ flushOnMount(root);
2256
+ }
2257
+ return {
2258
+ key,
2259
+ nodes,
2260
+ root,
2261
+ item: itemSig,
2262
+ index: indexSig,
2263
+ rawItem: item,
2264
+ rawIndex: index
2265
+ };
2266
+ }
2267
+ function getFirstNodeAfter(marker) {
2268
+ return marker.nextSibling;
2269
+ }
2270
+ function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
2271
+ const resolvedNeedsIndex = arguments.length >= 4 ? !!needsIndex : renderItem.length > 1;
2272
+ return createFineGrainedKeyedList(getItems, keyFn, renderItem, resolvedNeedsIndex);
2273
+ }
2274
+ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
2275
+ const container = createKeyedListContainer();
2276
+ const hostRoot = getCurrentRoot();
2277
+ const fragment = document.createDocumentFragment();
2278
+ fragment.append(container.startMarker, container.endMarker);
2279
+ let pendingItems = null;
2280
+ let disposed = false;
2281
+ const performDiff = () => {
2282
+ if (disposed) return;
2283
+ batch2(() => {
2284
+ const newItems = pendingItems || getItems();
2285
+ pendingItems = null;
2286
+ const oldBlocks = container.blocks;
2287
+ const newBlocks = container.nextBlocks;
2288
+ const prevOrderedBlocks = container.orderedBlocks;
2289
+ const nextOrderedBlocks = container.nextOrderedBlocks;
2290
+ const orderedIndexByKey = container.orderedIndexByKey;
2291
+ newBlocks.clear();
2292
+ nextOrderedBlocks.length = 0;
2293
+ orderedIndexByKey.clear();
2294
+ const endParent = container.endMarker.parentNode;
2295
+ const startParent = container.startMarker.parentNode;
2296
+ const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
2297
+ if (!parent) {
2298
+ pendingItems = newItems;
2299
+ queueMicrotask(performDiff);
2300
+ return;
2301
+ }
2302
+ if (newItems.length === 0) {
2303
+ if (oldBlocks.size > 0) {
2304
+ for (const block of oldBlocks.values()) {
2305
+ destroyRoot(block.root);
2306
+ removeNodes(block.nodes);
2307
+ }
2308
+ }
2309
+ oldBlocks.clear();
2310
+ newBlocks.clear();
2311
+ prevOrderedBlocks.length = 0;
2312
+ nextOrderedBlocks.length = 0;
2313
+ orderedIndexByKey.clear();
2314
+ container.currentNodes.length = 0;
2315
+ container.currentNodes.push(container.startMarker, container.endMarker);
2316
+ container.nextNodes.length = 0;
2317
+ return;
2318
+ }
2319
+ const prevCount = prevOrderedBlocks.length;
2320
+ let appendCandidate = prevCount > 0 && newItems.length >= prevCount;
2321
+ const appendedBlocks = [];
2322
+ newItems.forEach((item, index) => {
2323
+ const key = keyFn(item, index);
2324
+ const existed = oldBlocks.has(key);
2325
+ let block = oldBlocks.get(key);
2326
+ if (block) {
2327
+ if (block.rawItem !== item) {
2328
+ block.rawItem = item;
2329
+ block.item(item);
2330
+ }
2331
+ if (needsIndex && block.rawIndex !== index) {
2332
+ block.rawIndex = index;
2333
+ block.index(index);
2334
+ }
2335
+ }
2336
+ const existingBlock = newBlocks.get(key);
2337
+ if (existingBlock && existingBlock !== block) {
2338
+ destroyRoot(existingBlock.root);
2339
+ removeNodes(existingBlock.nodes);
2340
+ }
2341
+ if (block) {
2342
+ newBlocks.set(key, block);
2343
+ oldBlocks.delete(key);
2098
2344
  } else {
2099
- const previousIndex = existing.index();
2100
- existing.value(item);
2101
- existing.index(i);
2102
- if (previousValue === item) {
2103
- bumpBlockVersion(existing);
2345
+ const existingBlock2 = newBlocks.get(key);
2346
+ if (existingBlock2) {
2347
+ destroyRoot(existingBlock2.root);
2348
+ removeNodes(existingBlock2.nodes);
2104
2349
  }
2105
- const needsRerender = getKey ? true : previousValue !== item || previousIndex !== i;
2106
- block = needsRerender ? rerenderBlock(existing, createElementFn) : existing;
2350
+ block = createKeyedBlock(key, item, index, renderItem, needsIndex, hostRoot);
2107
2351
  }
2108
- } else {
2109
- block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn);
2352
+ const resolvedBlock = block;
2353
+ newBlocks.set(key, resolvedBlock);
2354
+ const position = orderedIndexByKey.get(key);
2355
+ if (position !== void 0) {
2356
+ 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
+ const prior = nextOrderedBlocks[position];
2369
+ if (prior && prior !== resolvedBlock) {
2370
+ destroyRoot(prior.root);
2371
+ removeNodes(prior.nodes);
2372
+ }
2373
+ nextOrderedBlocks[position] = resolvedBlock;
2374
+ } else {
2375
+ orderedIndexByKey.set(key, nextOrderedBlocks.length);
2376
+ nextOrderedBlocks.push(resolvedBlock);
2377
+ }
2378
+ if (appendCandidate && index >= prevCount) {
2379
+ appendedBlocks.push(resolvedBlock);
2380
+ }
2381
+ });
2382
+ const canAppend = appendCandidate && prevCount > 0 && newItems.length > prevCount && oldBlocks.size === 0 && appendedBlocks.length > 0;
2383
+ if (canAppend) {
2384
+ const appendedNodes = [];
2385
+ for (const block of appendedBlocks) {
2386
+ for (let i = 0; i < block.nodes.length; i++) {
2387
+ appendedNodes.push(block.nodes[i]);
2388
+ }
2389
+ }
2390
+ if (appendedNodes.length > 0) {
2391
+ insertNodesBefore(parent, appendedNodes, container.endMarker);
2392
+ const currentNodes = container.currentNodes;
2393
+ currentNodes.pop();
2394
+ for (let i = 0; i < appendedNodes.length; i++) {
2395
+ currentNodes.push(appendedNodes[i]);
2396
+ }
2397
+ currentNodes.push(container.endMarker);
2398
+ }
2399
+ container.blocks = newBlocks;
2400
+ container.nextBlocks = oldBlocks;
2401
+ container.orderedBlocks = nextOrderedBlocks;
2402
+ container.nextOrderedBlocks = prevOrderedBlocks;
2403
+ return;
2110
2404
  }
2111
- newNodeMap.set(key, block);
2112
- blocks.push(block);
2113
- }
2114
- for (const [key, managed] of nodeMap) {
2115
- if (!newNodeMap.has(key)) {
2116
- destroyRoot(managed.root);
2117
- removeBlockNodes(managed);
2405
+ if (oldBlocks.size > 0) {
2406
+ for (const block of oldBlocks.values()) {
2407
+ destroyRoot(block.root);
2408
+ removeNodes(block.nodes);
2409
+ }
2410
+ oldBlocks.clear();
2118
2411
  }
2119
- }
2120
- let anchor = endMarker;
2121
- for (let i = blocks.length - 1; i >= 0; i--) {
2122
- const block = blocks[i];
2123
- insertNodesBefore(parent, block.nodes, anchor);
2124
- if (block.nodes.length > 0) {
2125
- anchor = block.nodes[0];
2412
+ if (newBlocks.size > 0 || container.currentNodes.length > 0) {
2413
+ const prevNodes = container.currentNodes;
2414
+ const nextNodes = container.nextNodes;
2415
+ nextNodes.length = 0;
2416
+ nextNodes.push(container.startMarker);
2417
+ for (let i = 0; i < nextOrderedBlocks.length; i++) {
2418
+ const nodes = nextOrderedBlocks[i].nodes;
2419
+ for (let j = 0; j < nodes.length; j++) {
2420
+ nextNodes.push(nodes[j]);
2421
+ }
2422
+ }
2423
+ nextNodes.push(container.endMarker);
2424
+ reconcileArrays(parent, prevNodes, nextNodes);
2425
+ container.currentNodes = nextNodes;
2426
+ container.nextNodes = prevNodes;
2126
2427
  }
2127
- }
2128
- nodeMap.clear();
2129
- for (const [k, v] of newNodeMap) {
2130
- nodeMap.set(k, v);
2131
- }
2428
+ container.blocks = newBlocks;
2429
+ container.nextBlocks = oldBlocks;
2430
+ container.orderedBlocks = nextOrderedBlocks;
2431
+ container.nextOrderedBlocks = prevOrderedBlocks;
2432
+ });
2132
2433
  };
2133
- const dispose = createRenderEffect(runListUpdate);
2434
+ const effectDispose = createRenderEffect(performDiff);
2134
2435
  return {
2135
2436
  marker: fragment,
2437
+ startMarker: container.startMarker,
2438
+ endMarker: container.endMarker,
2439
+ // Flush pending items - call after markers are inserted into DOM
2136
2440
  flush: () => {
2137
2441
  if (pendingItems !== null) {
2138
- runListUpdate();
2442
+ performDiff();
2139
2443
  }
2140
2444
  },
2141
2445
  dispose: () => {
2142
- dispose();
2143
- for (const [, managed] of nodeMap) {
2144
- destroyRoot(managed.root);
2145
- removeBlockNodes(managed);
2446
+ disposed = true;
2447
+ effectDispose?.();
2448
+ container.dispose();
2449
+ }
2450
+ };
2451
+ }
2452
+
2453
+ // src/binding.ts
2454
+ function isReactive(value) {
2455
+ return typeof value === "function" && value.length === 0;
2456
+ }
2457
+ function callEventHandler(handler, event, node, data) {
2458
+ if (!handler) return;
2459
+ const context = node ?? event.currentTarget ?? void 0;
2460
+ const invoke = (fn) => {
2461
+ if (typeof fn === "function") {
2462
+ const result = data === void 0 ? fn.call(context, event) : fn.call(context, data, event);
2463
+ if (typeof result === "function" && result !== fn) {
2464
+ if (data === void 0) {
2465
+ result.call(context, event);
2466
+ } else {
2467
+ result.call(context, data, event);
2468
+ }
2469
+ } else if (result && typeof result.handleEvent === "function") {
2470
+ result.handleEvent.call(result, event);
2146
2471
  }
2147
- nodeMap.clear();
2148
- startMarker.parentNode?.removeChild(startMarker);
2149
- endMarker.parentNode?.removeChild(endMarker);
2472
+ } else if (fn && typeof fn.handleEvent === "function") {
2473
+ fn.handleEvent.call(fn, event);
2150
2474
  }
2151
2475
  };
2476
+ invoke(handler);
2152
2477
  }
2153
- function mountBlock(initialValue, initialIndex, renderItem, parent, anchor, createElementFn) {
2154
- const start = document.createComment("fict:block:start");
2155
- const end = document.createComment("fict:block:end");
2156
- const valueSig = signal(initialValue);
2157
- const indexSig = signal(initialIndex);
2158
- const versionSig = signal(0);
2159
- const valueProxy = createValueProxy(() => {
2160
- versionSig();
2161
- return valueSig();
2478
+ var PRIMITIVE_PROXY = Symbol("fict:primitive-proxy");
2479
+ function bindText(textNode, getValue) {
2480
+ return createRenderEffect(() => {
2481
+ const value = formatTextValue(getValue());
2482
+ if (textNode.data !== value) {
2483
+ textNode.data = value;
2484
+ }
2162
2485
  });
2163
- const renderCurrent = () => renderItem(valueProxy, indexSig());
2164
- const root = createRootContext();
2165
- const prev = pushRoot(root);
2166
- const nodes = [start];
2167
- let handledError = false;
2168
- try {
2169
- const output = renderCurrent();
2170
- if (output != null && output !== false) {
2171
- const el = createElementFn(output);
2172
- const rendered = toNodeArray(el);
2173
- nodes.push(...rendered);
2174
- }
2175
- nodes.push(end);
2176
- insertNodesBefore(parent, nodes, anchor);
2177
- } catch (err) {
2178
- if (handleSuspend(err, root)) {
2179
- handledError = true;
2180
- nodes.push(end);
2181
- insertNodesBefore(parent, nodes, anchor);
2182
- } else if (handleError(err, { source: "renderChild" }, root)) {
2183
- handledError = true;
2184
- nodes.push(end);
2185
- insertNodesBefore(parent, nodes, anchor);
2186
- } else {
2187
- throw err;
2188
- }
2189
- } finally {
2190
- popRoot(prev);
2191
- if (!handledError) {
2192
- flushOnMount(root);
2193
- } else {
2194
- destroyRoot(root);
2195
- }
2486
+ }
2487
+ function formatTextValue(value) {
2488
+ if (value == null || value === false) {
2489
+ return "";
2196
2490
  }
2197
- return {
2198
- nodes,
2199
- root,
2200
- value: valueSig,
2201
- index: indexSig,
2202
- version: versionSig,
2203
- start,
2204
- end,
2205
- valueProxy,
2206
- renderCurrent
2207
- };
2491
+ return String(value);
2208
2492
  }
2209
- function rerenderBlock(block, createElementFn) {
2210
- const currentContent = block.nodes.slice(1, Math.max(1, block.nodes.length - 1));
2211
- const currentNode = currentContent.length === 1 ? currentContent[0] : null;
2212
- clearRoot(block.root);
2213
- const prev = pushRoot(block.root);
2214
- let nextOutput;
2215
- let handledError = false;
2216
- try {
2217
- nextOutput = block.renderCurrent();
2218
- } catch (err) {
2219
- if (handleSuspend(err, block.root)) {
2220
- handledError = true;
2221
- popRoot(prev);
2222
- destroyRoot(block.root);
2223
- block.nodes = [block.start, block.end];
2224
- return block;
2225
- }
2226
- if (handleError(err, { source: "renderChild" }, block.root)) {
2227
- handledError = true;
2228
- popRoot(prev);
2229
- destroyRoot(block.root);
2230
- block.nodes = [block.start, block.end];
2231
- return block;
2232
- }
2233
- throw err;
2234
- } finally {
2235
- if (!handledError) {
2236
- popRoot(prev);
2237
- }
2493
+ function createAttributeBinding(el, key, value, setter) {
2494
+ if (isReactive(value)) {
2495
+ createRenderEffect(() => {
2496
+ setter(el, key, value());
2497
+ });
2498
+ } else {
2499
+ setter(el, key, value);
2238
2500
  }
2239
- if (isFragmentVNode(nextOutput) && currentContent.length > 0) {
2240
- const patched = patchFragmentChildren(currentContent, nextOutput.props?.children);
2241
- if (patched) {
2242
- block.nodes = [block.start, ...currentContent, block.end];
2243
- return block;
2501
+ }
2502
+ function bindAttribute(el, key, getValue) {
2503
+ let prevValue = void 0;
2504
+ return createRenderEffect(() => {
2505
+ const value = getValue();
2506
+ if (value === prevValue) return;
2507
+ prevValue = value;
2508
+ if (value === void 0 || value === null || value === false) {
2509
+ el.removeAttribute(key);
2510
+ } else if (value === true) {
2511
+ el.setAttribute(key, "");
2512
+ } else {
2513
+ el.setAttribute(key, String(value));
2244
2514
  }
2245
- }
2246
- if (currentNode && patchNode(currentNode, nextOutput)) {
2247
- block.nodes = [block.start, currentNode, block.end];
2248
- return block;
2249
- }
2250
- clearContent(block);
2251
- if (nextOutput != null && nextOutput !== false) {
2252
- const newNodes = toNodeArray(
2253
- nextOutput instanceof Node ? nextOutput : createElementFn(nextOutput)
2254
- );
2255
- insertNodesBefore(block.start.parentNode, newNodes, block.end);
2256
- block.nodes = [block.start, ...newNodes, block.end];
2515
+ });
2516
+ }
2517
+ function bindProperty(el, key, getValue) {
2518
+ const PROPERTY_BINDING_KEYS = /* @__PURE__ */ new Set([
2519
+ "value",
2520
+ "checked",
2521
+ "selected",
2522
+ "disabled",
2523
+ "readOnly",
2524
+ "multiple",
2525
+ "muted"
2526
+ ]);
2527
+ let prevValue = void 0;
2528
+ return createRenderEffect(() => {
2529
+ const next = getValue();
2530
+ if (next === prevValue) return;
2531
+ prevValue = next;
2532
+ if (PROPERTY_BINDING_KEYS.has(key) && (next === void 0 || next === null)) {
2533
+ const fallback = key === "checked" || key === "selected" ? false : "";
2534
+ el[key] = fallback;
2535
+ return;
2536
+ }
2537
+ ;
2538
+ el[key] = next;
2539
+ });
2540
+ }
2541
+ function createStyleBinding(el, value) {
2542
+ const target = el;
2543
+ if (isReactive(value)) {
2544
+ let prev;
2545
+ createRenderEffect(() => {
2546
+ const next = value();
2547
+ applyStyle(target, next, prev);
2548
+ prev = next;
2549
+ });
2257
2550
  } else {
2258
- block.nodes = [block.start, block.end];
2551
+ applyStyle(target, value, void 0);
2259
2552
  }
2260
- return block;
2261
2553
  }
2262
- function patchElement(el, output) {
2263
- if (output === null || output === void 0 || output === false || typeof output === "string" || typeof output === "number") {
2264
- el.textContent = output === null || output === void 0 || output === false ? "" : String(output);
2265
- return true;
2266
- }
2267
- if (output instanceof Text) {
2268
- el.textContent = output.data;
2269
- return true;
2270
- }
2271
- if (output && typeof output === "object" && !(output instanceof Node)) {
2272
- const vnode = output;
2273
- if (typeof vnode.type === "string" && vnode.type.toLowerCase() === el.tagName.toLowerCase()) {
2274
- const children = vnode.props?.children;
2275
- const props = vnode.props ?? {};
2276
- for (const [key, value] of Object.entries(props)) {
2277
- if (key === "children" || key === "key") continue;
2278
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) {
2279
- if (key === "class" || key === "className") {
2280
- el.setAttribute("class", value === false || value === null ? "" : String(value));
2281
- } else if (key === "style" && typeof value === "string") {
2282
- el.style.cssText = value;
2283
- } else if (value === false || value === null || value === void 0) {
2284
- el.removeAttribute(key);
2285
- } else if (value === true) {
2286
- el.setAttribute(key, "");
2287
- } else {
2288
- el.setAttribute(key, String(value));
2289
- }
2554
+ function bindStyle(el, getValue) {
2555
+ const target = el;
2556
+ let prev;
2557
+ return createRenderEffect(() => {
2558
+ const next = getValue();
2559
+ applyStyle(target, next, prev);
2560
+ prev = next;
2561
+ });
2562
+ }
2563
+ function applyStyle(el, value, prev) {
2564
+ if (typeof value === "string") {
2565
+ el.style.cssText = value;
2566
+ } else if (value && typeof value === "object") {
2567
+ const styles = value;
2568
+ if (typeof prev === "string") {
2569
+ el.style.cssText = "";
2570
+ }
2571
+ if (prev && typeof prev === "object") {
2572
+ const prevStyles = prev;
2573
+ for (const key of Object.keys(prevStyles)) {
2574
+ if (!(key in styles)) {
2575
+ const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
2576
+ el.style.removeProperty(cssProperty);
2290
2577
  }
2291
2578
  }
2292
- if (typeof children === "string" || typeof children === "number" || children === null || children === void 0 || children === false) {
2293
- el.textContent = children === null || children === void 0 || children === false ? "" : String(children);
2294
- return true;
2295
- }
2296
- if (children && typeof children === "object" && !Array.isArray(children) && !(children instanceof Node)) {
2297
- const childVNode = children;
2298
- if (typeof childVNode.type === "string") {
2299
- const childEl = el.querySelector(childVNode.type);
2300
- if (childEl && patchElement(childEl, children)) {
2301
- return true;
2302
- }
2303
- }
2579
+ }
2580
+ for (const [prop, v] of Object.entries(styles)) {
2581
+ if (v != null) {
2582
+ const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
2583
+ const unitless = isUnitlessStyleProperty(prop) || isUnitlessStyleProperty(cssProperty);
2584
+ const valueStr = typeof v === "number" && !unitless ? `${v}px` : String(v);
2585
+ el.style.setProperty(cssProperty, valueStr);
2586
+ } else {
2587
+ const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
2588
+ el.style.removeProperty(cssProperty);
2304
2589
  }
2305
- return false;
2306
2590
  }
2307
- }
2308
- if (output instanceof Node) {
2309
- if (output.nodeType === Node.ELEMENT_NODE) {
2310
- const nextEl = output;
2311
- if (nextEl.tagName.toLowerCase() === el.tagName.toLowerCase()) {
2312
- el.textContent = nextEl.textContent;
2313
- return true;
2591
+ } else {
2592
+ if (prev && typeof prev === "object") {
2593
+ const prevStyles = prev;
2594
+ for (const key of Object.keys(prevStyles)) {
2595
+ const cssProperty = key.replace(/([A-Z])/g, "-$1").toLowerCase();
2596
+ el.style.removeProperty(cssProperty);
2314
2597
  }
2315
- } else if (output.nodeType === Node.TEXT_NODE) {
2316
- el.textContent = output.data;
2317
- return true;
2598
+ } else if (typeof prev === "string") {
2599
+ el.style.cssText = "";
2318
2600
  }
2319
2601
  }
2320
- return false;
2321
- }
2322
- function patchNode(currentNode, nextOutput) {
2323
- if (!currentNode) return false;
2324
- if (currentNode instanceof Text && (nextOutput === null || nextOutput === void 0 || nextOutput === false || typeof nextOutput === "string" || typeof nextOutput === "number" || nextOutput instanceof Text)) {
2325
- const nextText = nextOutput instanceof Text ? nextOutput.data : nextOutput === null || nextOutput === void 0 || nextOutput === false ? "" : String(nextOutput);
2326
- currentNode.data = nextText;
2327
- return true;
2328
- }
2329
- if (currentNode instanceof Element && patchElement(currentNode, nextOutput)) {
2330
- return true;
2331
- }
2332
- if (nextOutput instanceof Node && currentNode === nextOutput) {
2333
- return true;
2334
- }
2335
- return false;
2336
2602
  }
2337
- function isFragmentVNode(value) {
2338
- return value != null && typeof value === "object" && !(value instanceof Node) && value.type === Fragment;
2603
+ function isUnitlessStyleProperty(prop) {
2604
+ return UnitlessStyles.has(prop);
2339
2605
  }
2340
- function normalizeChildren(children, result = []) {
2341
- if (children === void 0) {
2342
- return result;
2343
- }
2344
- if (Array.isArray(children)) {
2345
- for (const child of children) {
2346
- normalizeChildren(child, result);
2347
- }
2348
- return result;
2606
+ function createClassBinding(el, value) {
2607
+ if (isReactive(value)) {
2608
+ let prev = {};
2609
+ createRenderEffect(() => {
2610
+ const next = value();
2611
+ prev = applyClass(el, next, prev);
2612
+ });
2613
+ } else {
2614
+ applyClass(el, value, {});
2349
2615
  }
2350
- if (children === null || children === false) {
2351
- return result;
2616
+ }
2617
+ function bindClass(el, getValue) {
2618
+ let prev = {};
2619
+ return createRenderEffect(() => {
2620
+ const next = getValue();
2621
+ prev = applyClass(el, next, prev);
2622
+ });
2623
+ }
2624
+ function toggleClassKey(node, key, value) {
2625
+ const classNames = key.trim().split(/\s+/);
2626
+ for (let i = 0, len = classNames.length; i < len; i++) {
2627
+ node.classList.toggle(classNames[i], value);
2352
2628
  }
2353
- result.push(children);
2354
- return result;
2355
2629
  }
2356
- function patchFragmentChildren(nodes, children) {
2357
- const normalized = normalizeChildren(children);
2358
- if (normalized.length !== nodes.length) {
2359
- return false;
2630
+ function applyClass(el, value, prev) {
2631
+ const prevState = prev && typeof prev === "object" ? prev : {};
2632
+ if (typeof value === "string") {
2633
+ el.className = value;
2634
+ return {};
2360
2635
  }
2361
- for (let i = 0; i < normalized.length; i++) {
2362
- if (!patchNode(nodes[i], normalized[i])) {
2363
- return false;
2636
+ if (value && typeof value === "object") {
2637
+ const classes = value;
2638
+ const classKeys = Object.keys(classes);
2639
+ const prevKeys = Object.keys(prevState);
2640
+ for (let i = 0, len = prevKeys.length; i < len; i++) {
2641
+ const key = prevKeys[i];
2642
+ if (!key || key === "undefined" || classes[key]) continue;
2643
+ toggleClassKey(el, key, false);
2644
+ delete prevState[key];
2645
+ }
2646
+ for (let i = 0, len = classKeys.length; i < len; i++) {
2647
+ const key = classKeys[i];
2648
+ const classValue = !!classes[key];
2649
+ if (!key || key === "undefined" || prevState[key] === classValue || !classValue) continue;
2650
+ toggleClassKey(el, key, true);
2651
+ prevState[key] = classValue;
2364
2652
  }
2653
+ return prevState;
2365
2654
  }
2366
- return true;
2367
- }
2368
- function clearContent(block) {
2369
- const nodes = block.nodes.slice(1, Math.max(1, block.nodes.length - 1));
2370
- removeNodes(nodes);
2371
- }
2372
- function removeBlockNodes(block) {
2373
- let cursor = block.start;
2374
- const end = block.end;
2375
- while (cursor) {
2376
- const next = cursor.nextSibling;
2377
- cursor.parentNode?.removeChild(cursor);
2378
- if (cursor === end) break;
2379
- cursor = next;
2655
+ if (!value) {
2656
+ for (const key of Object.keys(prevState)) {
2657
+ if (key && key !== "undefined") {
2658
+ toggleClassKey(el, key, false);
2659
+ }
2660
+ }
2661
+ return {};
2380
2662
  }
2663
+ return prevState;
2381
2664
  }
2382
- function bumpBlockVersion(block) {
2383
- block.version(block.version() + 1);
2384
- }
2385
-
2386
- // src/scope.ts
2387
- function createScope() {
2388
- let dispose = null;
2389
- const stop = () => {
2390
- if (dispose) {
2391
- dispose();
2392
- dispose = null;
2665
+ function insert(parent, getValue, markerOrCreateElement, createElementFn) {
2666
+ const hostRoot = getCurrentRoot();
2667
+ let marker;
2668
+ let ownsMarker = false;
2669
+ let createFn = createElementFn;
2670
+ if (markerOrCreateElement instanceof Node) {
2671
+ marker = markerOrCreateElement;
2672
+ createFn = createElementFn;
2673
+ } else {
2674
+ marker = document.createComment("fict:insert");
2675
+ parent.appendChild(marker);
2676
+ createFn = markerOrCreateElement;
2677
+ ownsMarker = true;
2678
+ }
2679
+ let currentNodes = [];
2680
+ let currentText = null;
2681
+ let currentRoot2 = null;
2682
+ const clearCurrentNodes = () => {
2683
+ if (currentNodes.length > 0) {
2684
+ removeNodes(currentNodes);
2685
+ currentNodes = [];
2393
2686
  }
2394
2687
  };
2395
- const run = (fn) => {
2396
- stop();
2397
- const { dispose: rootDispose, value } = createRoot(fn);
2398
- dispose = rootDispose;
2399
- return value;
2688
+ const setTextNode = (textValue, shouldInsert, parentNode) => {
2689
+ if (!currentText) {
2690
+ currentText = document.createTextNode(textValue);
2691
+ } else if (currentText.data !== textValue) {
2692
+ currentText.data = textValue;
2693
+ }
2694
+ if (!shouldInsert) {
2695
+ clearCurrentNodes();
2696
+ return;
2697
+ }
2698
+ if (currentNodes.length === 1 && currentNodes[0] === currentText) {
2699
+ return;
2700
+ }
2701
+ clearCurrentNodes();
2702
+ insertNodesBefore(parentNode, [currentText], marker);
2703
+ currentNodes = [currentText];
2704
+ };
2705
+ const dispose = createRenderEffect(() => {
2706
+ const value = getValue();
2707
+ const parentNode = marker.parentNode;
2708
+ const isPrimitive = value == null || value === false || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
2709
+ if (isPrimitive) {
2710
+ if (currentRoot2) {
2711
+ destroyRoot(currentRoot2);
2712
+ currentRoot2 = null;
2713
+ }
2714
+ if (!parentNode) {
2715
+ clearCurrentNodes();
2716
+ return;
2717
+ }
2718
+ const textValue = value == null || value === false ? "" : String(value);
2719
+ const shouldInsert = value != null && value !== false;
2720
+ setTextNode(textValue, shouldInsert, parentNode);
2721
+ return;
2722
+ }
2723
+ if (currentRoot2) {
2724
+ destroyRoot(currentRoot2);
2725
+ currentRoot2 = null;
2726
+ }
2727
+ clearCurrentNodes();
2728
+ const root = createRootContext(hostRoot);
2729
+ const prev = pushRoot(root);
2730
+ let nodes = [];
2731
+ try {
2732
+ let newNode;
2733
+ if (value instanceof Node) {
2734
+ newNode = value;
2735
+ } else if (Array.isArray(value)) {
2736
+ if (value.every((v) => v instanceof Node)) {
2737
+ newNode = value;
2738
+ } else {
2739
+ if (createFn) {
2740
+ const mapped = [];
2741
+ for (const item of value) {
2742
+ mapped.push(...toNodeArray(createFn(item)));
2743
+ }
2744
+ newNode = mapped;
2745
+ } else {
2746
+ newNode = document.createTextNode(String(value));
2747
+ }
2748
+ }
2749
+ } else {
2750
+ newNode = createFn ? createFn(value) : document.createTextNode(String(value));
2751
+ }
2752
+ nodes = toNodeArray(newNode);
2753
+ if (parentNode) {
2754
+ insertNodesBefore(parentNode, nodes, marker);
2755
+ }
2756
+ } finally {
2757
+ popRoot(prev);
2758
+ flushOnMount(root);
2759
+ }
2760
+ currentRoot2 = root;
2761
+ currentNodes = nodes;
2762
+ });
2763
+ return () => {
2764
+ dispose();
2765
+ if (currentRoot2) {
2766
+ destroyRoot(currentRoot2);
2767
+ currentRoot2 = null;
2768
+ }
2769
+ clearCurrentNodes();
2770
+ if (ownsMarker) {
2771
+ marker.parentNode?.removeChild(marker);
2772
+ }
2400
2773
  };
2401
- registerRootCleanup(stop);
2402
- return { run, stop };
2403
2774
  }
2404
- function runInScope(flag, fn) {
2405
- const scope = createScope();
2406
- const evaluate = () => isReactive(flag) ? flag() : !!flag;
2407
- createEffect(() => {
2408
- const enabled = evaluate();
2409
- if (enabled) {
2410
- scope.run(fn);
2411
- } else {
2412
- scope.stop();
2775
+ function createChildBinding(parent, getValue, createElementFn) {
2776
+ const marker = document.createComment("fict:child");
2777
+ parent.appendChild(marker);
2778
+ const hostRoot = getCurrentRoot();
2779
+ const dispose = createRenderEffect(() => {
2780
+ const root = createRootContext(hostRoot);
2781
+ const prev = pushRoot(root);
2782
+ let nodes = [];
2783
+ let handledError = false;
2784
+ try {
2785
+ const value = getValue();
2786
+ if (value == null || value === false) {
2787
+ return;
2788
+ }
2789
+ const output = createElementFn(value);
2790
+ nodes = toNodeArray(output);
2791
+ const parentNode = marker.parentNode;
2792
+ if (parentNode) {
2793
+ insertNodesBefore(parentNode, nodes, marker);
2794
+ }
2795
+ return () => {
2796
+ destroyRoot(root);
2797
+ removeNodes(nodes);
2798
+ };
2799
+ } catch (err) {
2800
+ if (handleSuspend(err, root)) {
2801
+ handledError = true;
2802
+ destroyRoot(root);
2803
+ return;
2804
+ }
2805
+ if (handleError(err, { source: "renderChild" }, root)) {
2806
+ handledError = true;
2807
+ destroyRoot(root);
2808
+ return;
2809
+ }
2810
+ throw err;
2811
+ } finally {
2812
+ popRoot(prev);
2813
+ if (!handledError) {
2814
+ flushOnMount(root);
2815
+ }
2413
2816
  }
2414
2817
  });
2415
- onCleanup(scope.stop);
2818
+ return {
2819
+ marker,
2820
+ dispose: () => {
2821
+ dispose();
2822
+ marker.parentNode?.removeChild(marker);
2823
+ }
2824
+ };
2416
2825
  }
2417
-
2418
- // src/scheduler.ts
2419
- function batch2(fn) {
2420
- return batch(fn);
2421
- }
2422
- function untrack2(fn) {
2423
- return untrack(fn);
2424
- }
2425
-
2426
- // src/hooks.ts
2427
- var ctxStack = [];
2428
- function __fictUseContext() {
2429
- if (ctxStack.length === 0) {
2430
- const ctx2 = { slots: [], cursor: 0 };
2431
- ctxStack.push(ctx2);
2432
- return ctx2;
2433
- }
2434
- const ctx = ctxStack[ctxStack.length - 1];
2435
- ctx.cursor = 0;
2436
- return ctx;
2437
- }
2438
- function __fictPushContext() {
2439
- const ctx = { slots: [], cursor: 0 };
2440
- ctxStack.push(ctx);
2441
- return ctx;
2442
- }
2443
- function __fictPopContext() {
2444
- ctxStack.pop();
2445
- }
2446
- function __fictResetContext() {
2447
- ctxStack.length = 0;
2448
- }
2449
- function __fictUseSignal(ctx, initial, slot) {
2450
- const index = slot ?? ctx.cursor++;
2451
- if (!ctx.slots[index]) {
2452
- ctx.slots[index] = signal(initial);
2453
- }
2454
- return ctx.slots[index];
2455
- }
2456
- function __fictUseMemo(ctx, fn, slot) {
2457
- const index = slot ?? ctx.cursor++;
2458
- if (!ctx.slots[index]) {
2459
- ctx.slots[index] = createMemo(fn);
2460
- }
2461
- return ctx.slots[index];
2462
- }
2463
- function __fictUseEffect(ctx, fn, slot) {
2464
- const index = slot ?? ctx.cursor++;
2465
- if (!ctx.slots[index]) {
2466
- ctx.slots[index] = createEffect(fn);
2467
- }
2468
- }
2469
- function __fictRender(ctx, fn) {
2470
- ctxStack.push(ctx);
2471
- ctx.cursor = 0;
2472
- try {
2473
- return fn();
2474
- } finally {
2475
- ctxStack.pop();
2826
+ function delegateEvents(eventNames, doc = window.document) {
2827
+ const e = doc[$$EVENTS] || (doc[$$EVENTS] = /* @__PURE__ */ new Set());
2828
+ for (let i = 0, l = eventNames.length; i < l; i++) {
2829
+ const name = eventNames[i];
2830
+ if (!e.has(name)) {
2831
+ e.add(name);
2832
+ doc.addEventListener(name, globalEventHandler);
2833
+ }
2476
2834
  }
2477
2835
  }
2478
-
2479
- // src/props.ts
2480
- var propGetters = /* @__PURE__ */ new WeakSet();
2481
- var rawToProxy = /* @__PURE__ */ new WeakMap();
2482
- var proxyToRaw = /* @__PURE__ */ new WeakMap();
2483
- function __fictProp(getter) {
2484
- if (typeof getter === "function" && getter.length === 0) {
2485
- propGetters.add(getter);
2836
+ function clearDelegatedEvents(doc = window.document) {
2837
+ const e = doc[$$EVENTS];
2838
+ if (e) {
2839
+ for (const name of e.keys()) {
2840
+ doc.removeEventListener(name, globalEventHandler);
2841
+ }
2842
+ delete doc[$$EVENTS];
2486
2843
  }
2487
- return getter;
2488
- }
2489
- function isPropGetter(value) {
2490
- return typeof value === "function" && propGetters.has(value);
2491
2844
  }
2492
- function createPropsProxy(props) {
2493
- if (!props || typeof props !== "object") {
2494
- return props;
2495
- }
2496
- if (proxyToRaw.has(props)) {
2497
- return props;
2498
- }
2499
- const cached = rawToProxy.get(props);
2500
- if (cached) {
2501
- return cached;
2502
- }
2503
- const proxy = new Proxy(props, {
2504
- get(target, prop, receiver) {
2505
- const value = Reflect.get(target, prop, receiver);
2506
- if (isPropGetter(value)) {
2507
- return value();
2845
+ function globalEventHandler(e) {
2846
+ let node = e.target;
2847
+ const key = `$$${e.type}`;
2848
+ const dataKey = `${key}Data`;
2849
+ const oriTarget = e.target;
2850
+ const oriCurrentTarget = e.currentTarget;
2851
+ const retarget = (value) => Object.defineProperty(e, "target", {
2852
+ configurable: true,
2853
+ value
2854
+ });
2855
+ const handleNode = () => {
2856
+ if (!node) return false;
2857
+ const handler = node[key];
2858
+ if (handler && !node.disabled) {
2859
+ const resolveData = (value) => {
2860
+ if (typeof value === "function") {
2861
+ try {
2862
+ const fn = value;
2863
+ return fn.length > 0 ? fn(e) : fn();
2864
+ } catch {
2865
+ return value();
2866
+ }
2867
+ }
2868
+ return value;
2869
+ };
2870
+ const rawData = node[dataKey];
2871
+ const hasData = rawData !== void 0;
2872
+ const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
2873
+ if (typeof handler === "function") {
2874
+ callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
2875
+ } else if (Array.isArray(handler)) {
2876
+ const tupleData = resolveData(handler[1]);
2877
+ callEventHandler(handler[0], e, node, tupleData);
2508
2878
  }
2509
- return value;
2510
- },
2511
- set(target, prop, value, receiver) {
2512
- return Reflect.set(target, prop, value, receiver);
2513
- },
2514
- has(target, prop) {
2515
- return prop in target;
2516
- },
2517
- ownKeys(target) {
2518
- return Reflect.ownKeys(target);
2519
- },
2520
- getOwnPropertyDescriptor(target, prop) {
2521
- return Object.getOwnPropertyDescriptor(target, prop);
2879
+ if (e.cancelBubble) return false;
2880
+ }
2881
+ const shadowHost = node.host;
2882
+ if (shadowHost && typeof shadowHost !== "string" && !shadowHost._$host && node.contains(e.target)) {
2883
+ retarget(shadowHost);
2884
+ }
2885
+ return true;
2886
+ };
2887
+ const walkUpTree = () => {
2888
+ while (handleNode() && node) {
2889
+ node = node._$host || node.parentNode || node.host;
2890
+ }
2891
+ };
2892
+ Object.defineProperty(e, "currentTarget", {
2893
+ configurable: true,
2894
+ get() {
2895
+ return node || document;
2522
2896
  }
2523
2897
  });
2524
- rawToProxy.set(props, proxy);
2525
- proxyToRaw.set(proxy, props);
2526
- return proxy;
2527
- }
2528
- function unwrapProps(props) {
2529
- if (!props || typeof props !== "object") {
2530
- return props;
2531
- }
2532
- return proxyToRaw.get(props) ?? props;
2533
- }
2534
- function __fictPropsRest(props, exclude) {
2535
- const raw = unwrapProps(props);
2536
- const out = {};
2537
- const excludeSet = new Set(exclude);
2538
- for (const key of Reflect.ownKeys(raw)) {
2539
- if (excludeSet.has(key)) continue;
2540
- out[key] = raw[key];
2898
+ if (e.composedPath) {
2899
+ const path = e.composedPath();
2900
+ retarget(path[0]);
2901
+ for (let i = 0; i < path.length - 2; i++) {
2902
+ node = path[i];
2903
+ if (!handleNode()) break;
2904
+ if (node._$host) {
2905
+ node = node._$host;
2906
+ walkUpTree();
2907
+ break;
2908
+ }
2909
+ if (node.parentNode === oriCurrentTarget) {
2910
+ break;
2911
+ }
2912
+ }
2913
+ } else {
2914
+ walkUpTree();
2541
2915
  }
2542
- return createPropsProxy(out);
2916
+ retarget(oriTarget);
2543
2917
  }
2544
- function mergeProps(...sources) {
2545
- const validSources = sources.filter(
2546
- (s) => s != null && (typeof s === "object" || typeof s === "function")
2547
- );
2548
- if (validSources.length === 0) {
2549
- return {};
2550
- }
2551
- if (validSources.length === 1 && typeof validSources[0] === "object") {
2552
- return validSources[0];
2553
- }
2554
- const resolveSource = (src) => {
2555
- const value = typeof src === "function" ? src() : src;
2556
- if (!value || typeof value !== "object") return void 0;
2557
- return unwrapProps(value);
2918
+ function bindEvent(el, eventName, handler, options2) {
2919
+ if (handler == null) return () => {
2558
2920
  };
2559
- return new Proxy({}, {
2560
- get(_, prop) {
2561
- if (typeof prop === "symbol") {
2562
- return void 0;
2921
+ const rootRef = getCurrentRoot();
2922
+ if (DelegatedEvents.has(eventName) && !options2) {
2923
+ const key = `$$${eventName}`;
2924
+ delegateEvents([eventName]);
2925
+ const resolveHandler = isReactive(handler) ? handler : () => handler;
2926
+ el[key] = function(...args) {
2927
+ try {
2928
+ const fn = resolveHandler();
2929
+ callEventHandler(fn, args[0], el);
2930
+ } catch (err) {
2931
+ handleError(err, { source: "event", eventName }, rootRef);
2563
2932
  }
2564
- for (let i = validSources.length - 1; i >= 0; i--) {
2565
- const src = validSources[i];
2566
- const raw = resolveSource(src);
2567
- if (!raw || !(prop in raw)) continue;
2568
- const value = raw[prop];
2569
- if (typeof src === "function" && !isPropGetter(value)) {
2570
- return __fictProp(() => {
2571
- const latest = resolveSource(src);
2572
- if (!latest || !(prop in latest)) return void 0;
2573
- return latest[prop];
2574
- });
2575
- }
2576
- return value;
2933
+ };
2934
+ return () => {
2935
+ el[key] = void 0;
2936
+ };
2937
+ }
2938
+ const getHandler = isReactive(handler) ? handler : () => handler;
2939
+ const wrapped = (event) => {
2940
+ try {
2941
+ const resolved = getHandler();
2942
+ callEventHandler(resolved, event, el);
2943
+ } catch (err) {
2944
+ if (handleError(err, { source: "event", eventName }, rootRef)) {
2945
+ return;
2577
2946
  }
2578
- return void 0;
2579
- },
2580
- has(_, prop) {
2581
- for (const src of validSources) {
2582
- const raw = resolveSource(src);
2583
- if (raw && prop in raw) {
2584
- return true;
2585
- }
2586
- }
2587
- return false;
2588
- },
2589
- ownKeys() {
2590
- const keys = /* @__PURE__ */ new Set();
2591
- for (const src of validSources) {
2592
- const raw = resolveSource(src);
2593
- if (raw) {
2594
- for (const key of Reflect.ownKeys(raw)) {
2595
- keys.add(key);
2596
- }
2597
- }
2598
- }
2599
- return Array.from(keys);
2600
- },
2601
- getOwnPropertyDescriptor(_, prop) {
2602
- for (let i = validSources.length - 1; i >= 0; i--) {
2603
- const raw = resolveSource(validSources[i]);
2604
- if (raw && prop in raw) {
2605
- return {
2606
- enumerable: true,
2607
- configurable: true,
2608
- get: () => {
2609
- const value = raw[prop];
2610
- return value;
2611
- }
2612
- };
2613
- }
2614
- }
2615
- return void 0;
2947
+ throw err;
2616
2948
  }
2617
- });
2618
- }
2619
- function useProp(getter) {
2620
- return __fictProp(createMemo(getter));
2621
- }
2622
-
2623
- // src/dom.ts
2624
- function render(view, container) {
2625
- const root = createRootContext();
2626
- const prev = pushRoot(root);
2627
- let dom;
2628
- try {
2629
- const output = view();
2630
- dom = createElement(output);
2631
- } finally {
2632
- popRoot(prev);
2633
- }
2634
- container.replaceChildren(dom);
2635
- container.setAttribute("data-fict-fine-grained", "1");
2636
- flushOnMount(root);
2637
- const teardown = () => {
2638
- destroyRoot(root);
2639
- container.innerHTML = "";
2640
2949
  };
2641
- return teardown;
2950
+ el.addEventListener(eventName, wrapped, options2);
2951
+ const cleanup = () => el.removeEventListener(eventName, wrapped, options2);
2952
+ registerRootCleanup(cleanup);
2953
+ return cleanup;
2642
2954
  }
2643
- function createElement(node) {
2644
- if (node instanceof Node) {
2645
- return node;
2646
- }
2647
- if (node === null || node === void 0 || node === false) {
2648
- return document.createTextNode("");
2649
- }
2650
- if (typeof node === "object" && node !== null && !(node instanceof Node)) {
2651
- if ("marker" in node) {
2652
- return createElement(node.marker);
2653
- }
2654
- const nodeRecord = node;
2655
- if (nodeRecord[PRIMITIVE_PROXY]) {
2656
- const primitiveGetter = nodeRecord[Symbol.toPrimitive];
2657
- const value = typeof primitiveGetter === "function" ? primitiveGetter.call(node, "default") : node;
2658
- return document.createTextNode(value == null || value === false ? "" : String(value));
2659
- }
2660
- }
2661
- if (Array.isArray(node)) {
2662
- const frag = document.createDocumentFragment();
2663
- for (const child of node) {
2664
- appendChildNode(frag, child);
2955
+ function bindRef(el, ref) {
2956
+ if (ref == null) return () => {
2957
+ };
2958
+ const getRef = isReactive(ref) ? ref : () => ref;
2959
+ const applyRef2 = (refValue) => {
2960
+ if (refValue == null) return;
2961
+ if (typeof refValue === "function") {
2962
+ refValue(el);
2963
+ } else if (typeof refValue === "object" && "current" in refValue) {
2964
+ refValue.current = el;
2665
2965
  }
2666
- return frag;
2667
- }
2668
- if (typeof node === "string" || typeof node === "number") {
2669
- return document.createTextNode(String(node));
2670
- }
2671
- if (typeof node === "boolean") {
2672
- return document.createTextNode("");
2673
- }
2674
- const vnode = node;
2675
- if (typeof vnode.type === "function") {
2676
- const rawProps = unwrapProps(vnode.props ?? {});
2677
- const baseProps = vnode.key === void 0 ? rawProps : new Proxy(rawProps, {
2678
- get(target, prop, receiver) {
2679
- if (prop === "key") return vnode.key;
2680
- return Reflect.get(target, prop, receiver);
2681
- },
2682
- has(target, prop) {
2683
- if (prop === "key") return true;
2684
- return prop in target;
2685
- },
2686
- ownKeys(target) {
2687
- const keys = new Set(Reflect.ownKeys(target));
2688
- keys.add("key");
2689
- return Array.from(keys);
2690
- },
2691
- getOwnPropertyDescriptor(target, prop) {
2692
- if (prop === "key") {
2693
- return { enumerable: true, configurable: true, value: vnode.key };
2694
- }
2695
- return Object.getOwnPropertyDescriptor(target, prop);
2696
- }
2966
+ };
2967
+ const initialRef = getRef();
2968
+ applyRef2(initialRef);
2969
+ if (isReactive(ref)) {
2970
+ const cleanup2 = createRenderEffect(() => {
2971
+ const currentRef = getRef();
2972
+ applyRef2(currentRef);
2697
2973
  });
2698
- const props = createPropsProxy(baseProps);
2699
- try {
2700
- __fictPushContext();
2701
- const rendered = vnode.type(props);
2702
- __fictPopContext();
2703
- return createElement(rendered);
2704
- } catch (err) {
2705
- __fictPopContext();
2706
- if (handleSuspend(err)) {
2707
- return document.createComment("fict:suspend");
2974
+ registerRootCleanup(cleanup2);
2975
+ const nullifyCleanup = () => {
2976
+ const currentRef = getRef();
2977
+ if (currentRef && typeof currentRef === "object" && "current" in currentRef) {
2978
+ currentRef.current = null;
2708
2979
  }
2709
- handleError(err, { source: "render", componentName: vnode.type.name });
2710
- throw err;
2711
- }
2712
- }
2713
- if (vnode.type === Fragment) {
2714
- const frag = document.createDocumentFragment();
2715
- const children = vnode.props?.children;
2716
- appendChildren(frag, children);
2717
- return frag;
2980
+ };
2981
+ registerRootCleanup(nullifyCleanup);
2982
+ return () => {
2983
+ cleanup2();
2984
+ nullifyCleanup();
2985
+ };
2718
2986
  }
2719
- const tagName = typeof vnode.type === "string" ? vnode.type : "div";
2720
- const el = document.createElement(tagName);
2721
- applyProps(el, vnode.props ?? {});
2722
- return el;
2723
- }
2724
- function template(html, isImportNode, isSVG, isMathML) {
2725
- let node = null;
2726
- const create = () => {
2727
- const t = isMathML ? document.createElementNS("http://www.w3.org/1998/Math/MathML", "template") : document.createElement("template");
2728
- t.innerHTML = html;
2729
- if (isSVG) {
2730
- return t.content.firstChild.firstChild;
2731
- }
2732
- if (isMathML) {
2733
- return t.firstChild;
2987
+ const cleanup = () => {
2988
+ const refValue = getRef();
2989
+ if (refValue && typeof refValue === "object" && "current" in refValue) {
2990
+ refValue.current = null;
2734
2991
  }
2735
- return t.content.firstChild;
2736
2992
  };
2737
- const fn = isImportNode ? () => untrack2(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true);
2738
- fn.cloneNode = fn;
2739
- return fn;
2740
- }
2741
- function isBindingHandle(node) {
2742
- return node !== null && typeof node === "object" && "marker" in node && "dispose" in node && typeof node.dispose === "function";
2993
+ registerRootCleanup(cleanup);
2994
+ return cleanup;
2743
2995
  }
2744
- function appendChildNode(parent, child) {
2745
- if (child === null || child === void 0 || child === false) {
2746
- return;
2747
- }
2748
- if (isBindingHandle(child)) {
2749
- appendChildNode(parent, child.marker);
2750
- child.flush?.();
2751
- return;
2752
- }
2753
- if (typeof child === "function" && child.length === 0) {
2754
- const childGetter = child;
2755
- createChildBinding(parent, childGetter, createElement);
2756
- return;
2757
- }
2758
- if (Array.isArray(child)) {
2759
- for (const item of child) {
2760
- appendChildNode(parent, item);
2996
+ function createConditional(condition, renderTrue, createElementFn, renderFalse) {
2997
+ const startMarker = document.createComment("fict:cond:start");
2998
+ const endMarker = document.createComment("fict:cond:end");
2999
+ const fragment = document.createDocumentFragment();
3000
+ fragment.append(startMarker, endMarker);
3001
+ const hostRoot = getCurrentRoot();
3002
+ let currentNodes = [];
3003
+ let currentRoot2 = null;
3004
+ let lastCondition = void 0;
3005
+ let pendingRender = false;
3006
+ const conditionMemo = computed(condition);
3007
+ const runConditional = () => {
3008
+ const cond = conditionMemo();
3009
+ const parent = startMarker.parentNode;
3010
+ if (!parent) {
3011
+ pendingRender = true;
3012
+ return;
2761
3013
  }
2762
- return;
2763
- }
2764
- let domNode;
2765
- if (typeof child !== "object" || child === null) {
2766
- domNode = document.createTextNode(String(child ?? ""));
2767
- } else {
2768
- domNode = createElement(child);
2769
- }
2770
- if (domNode.nodeType === 11) {
2771
- const children = Array.from(domNode.childNodes);
2772
- for (const node of children) {
2773
- appendChildNode(parent, node);
3014
+ pendingRender = false;
3015
+ if (lastCondition === cond && currentNodes.length > 0) {
3016
+ return;
2774
3017
  }
2775
- return;
2776
- }
2777
- if (domNode.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
2778
- parent.ownerDocument.adoptNode(domNode);
2779
- }
2780
- try {
2781
- parent.appendChild(domNode);
2782
- } catch (e) {
2783
- if (parent.ownerDocument) {
2784
- const clone = parent.ownerDocument.importNode(domNode, true);
2785
- parent.appendChild(clone);
3018
+ if (lastCondition === cond && lastCondition === false && renderFalse === void 0) {
2786
3019
  return;
2787
3020
  }
2788
- throw e;
2789
- }
2790
- }
2791
- function appendChildren(parent, children) {
2792
- if (children === void 0) return;
2793
- if (Array.isArray(children)) {
2794
- for (const child of children) {
2795
- appendChildren(parent, child);
3021
+ lastCondition = cond;
3022
+ if (currentRoot2) {
3023
+ destroyRoot(currentRoot2);
3024
+ currentRoot2 = null;
2796
3025
  }
2797
- return;
2798
- }
2799
- appendChildNode(parent, children);
2800
- }
2801
- function applyRef(el, value) {
2802
- if (typeof value === "function") {
2803
- const refFn = value;
2804
- refFn(el);
2805
- if (getCurrentRoot()) {
2806
- registerRootCleanup(() => {
2807
- refFn(null);
2808
- });
2809
- }
2810
- } else if (value && typeof value === "object" && "current" in value) {
2811
- const refObj = value;
2812
- refObj.current = el;
2813
- if (getCurrentRoot()) {
2814
- registerRootCleanup(() => {
2815
- refObj.current = null;
2816
- });
2817
- }
2818
- }
2819
- }
2820
- function applyProps(el, props, isSVG = false) {
2821
- props = unwrapProps(props);
2822
- const tagName = el.tagName;
2823
- const isCE = tagName.includes("-") || "is" in props;
2824
- for (const [key, value] of Object.entries(props)) {
2825
- if (key === "children") continue;
2826
- if (key === "ref") {
2827
- applyRef(el, value);
2828
- continue;
2829
- }
2830
- if (isEventKey(key)) {
2831
- bindEvent(
2832
- el,
2833
- eventNameFromProp(key),
2834
- value
2835
- );
2836
- continue;
2837
- }
2838
- if (key.slice(0, 3) === "on:") {
2839
- bindEvent(
2840
- el,
2841
- key.slice(3),
2842
- value,
2843
- false
2844
- // Non-delegated
2845
- );
2846
- continue;
2847
- }
2848
- if (key.slice(0, 10) === "oncapture:") {
2849
- bindEvent(
2850
- el,
2851
- key.slice(10),
2852
- value,
2853
- true
2854
- // Capture
2855
- );
2856
- continue;
3026
+ removeNodes(currentNodes);
3027
+ currentNodes = [];
3028
+ const render2 = cond ? renderTrue : renderFalse;
3029
+ if (!render2) {
3030
+ return;
2857
3031
  }
2858
- if (key === "class" || key === "className") {
2859
- createClassBinding(el, value);
2860
- continue;
3032
+ const root = createRootContext(hostRoot);
3033
+ const prev = pushRoot(root);
3034
+ let handledError = false;
3035
+ try {
3036
+ const output = untrack(render2);
3037
+ if (output == null || output === false) {
3038
+ return;
3039
+ }
3040
+ const el = createElementFn(output);
3041
+ const nodes = toNodeArray(el);
3042
+ insertNodesBefore(parent, nodes, endMarker);
3043
+ currentNodes = nodes;
3044
+ } catch (err) {
3045
+ if (handleSuspend(err, root)) {
3046
+ handledError = true;
3047
+ destroyRoot(root);
3048
+ return;
3049
+ }
3050
+ if (handleError(err, { source: "renderChild" }, root)) {
3051
+ handledError = true;
3052
+ destroyRoot(root);
3053
+ return;
3054
+ }
3055
+ throw err;
3056
+ } finally {
3057
+ popRoot(prev);
3058
+ if (!handledError) {
3059
+ flushOnMount(root);
3060
+ currentRoot2 = root;
3061
+ } else {
3062
+ currentRoot2 = null;
3063
+ }
2861
3064
  }
2862
- if (key === "classList") {
2863
- createClassBinding(el, value);
2864
- continue;
3065
+ };
3066
+ const dispose = createRenderEffect(runConditional);
3067
+ return {
3068
+ marker: fragment,
3069
+ flush: () => {
3070
+ if (pendingRender) {
3071
+ runConditional();
3072
+ }
3073
+ },
3074
+ dispose: () => {
3075
+ dispose();
3076
+ if (currentRoot2) {
3077
+ destroyRoot(currentRoot2);
3078
+ }
3079
+ removeNodes(currentNodes);
3080
+ currentNodes = [];
3081
+ startMarker.parentNode?.removeChild(startMarker);
3082
+ endMarker.parentNode?.removeChild(endMarker);
2865
3083
  }
2866
- if (key === "style") {
2867
- createStyleBinding(
2868
- el,
2869
- value
2870
- );
2871
- continue;
3084
+ };
3085
+ }
3086
+ function createList(items, renderItem, createElementFn, getKey) {
3087
+ const startMarker = document.createComment("fict:list:start");
3088
+ const endMarker = document.createComment("fict:list:end");
3089
+ const fragment = document.createDocumentFragment();
3090
+ fragment.append(startMarker, endMarker);
3091
+ const hostRoot = getCurrentRoot();
3092
+ const nodeMap = /* @__PURE__ */ new Map();
3093
+ let pendingItems = null;
3094
+ const runListUpdate = () => {
3095
+ const arr = items();
3096
+ const parent = startMarker.parentNode;
3097
+ if (!parent) {
3098
+ pendingItems = arr;
3099
+ return;
2872
3100
  }
2873
- if (key === "dangerouslySetInnerHTML" && value && typeof value === "object") {
2874
- const htmlValue = value.__html;
2875
- if (htmlValue !== void 0) {
2876
- if (isReactive(htmlValue)) {
2877
- createAttributeBinding(el, "innerHTML", htmlValue, setInnerHTML);
3101
+ pendingItems = null;
3102
+ const newNodeMap = /* @__PURE__ */ new Map();
3103
+ const blocks = [];
3104
+ for (let i = 0; i < arr.length; i++) {
3105
+ const item = arr[i];
3106
+ const key = getKey ? getKey(item, i) : i;
3107
+ const existing = nodeMap.get(key);
3108
+ let block;
3109
+ if (existing) {
3110
+ const previousValue = existing.value();
3111
+ if (!getKey && previousValue !== item) {
3112
+ destroyRoot(existing.root);
3113
+ removeBlockNodes(existing);
3114
+ block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn, hostRoot);
2878
3115
  } else {
2879
- el.innerHTML = htmlValue;
3116
+ const previousIndex = existing.index();
3117
+ existing.value(item);
3118
+ existing.index(i);
3119
+ const needsRerender = getKey ? true : previousValue !== item || previousIndex !== i;
3120
+ block = needsRerender ? rerenderBlock(existing, createElementFn) : existing;
2880
3121
  }
3122
+ } else {
3123
+ block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn, hostRoot);
2881
3124
  }
2882
- continue;
2883
- }
2884
- if (ChildProperties.has(key)) {
2885
- createAttributeBinding(el, key, value, setProperty);
2886
- continue;
3125
+ newNodeMap.set(key, block);
3126
+ blocks.push(block);
2887
3127
  }
2888
- if (key.slice(0, 5) === "attr:") {
2889
- createAttributeBinding(el, key.slice(5), value, setAttribute);
2890
- continue;
3128
+ for (const [key, managed] of nodeMap) {
3129
+ if (!newNodeMap.has(key)) {
3130
+ destroyRoot(managed.root);
3131
+ removeBlockNodes(managed);
3132
+ }
2891
3133
  }
2892
- if (key.slice(0, 5) === "bool:") {
2893
- createAttributeBinding(el, key.slice(5), value, setBoolAttribute);
2894
- continue;
3134
+ let anchor = endMarker;
3135
+ for (let i = blocks.length - 1; i >= 0; i--) {
3136
+ const block = blocks[i];
3137
+ insertNodesBefore(parent, block.nodes, anchor);
3138
+ if (block.nodes.length > 0) {
3139
+ anchor = block.nodes[0];
3140
+ }
2895
3141
  }
2896
- if (key.slice(0, 5) === "prop:") {
2897
- createAttributeBinding(el, key.slice(5), value, setProperty);
2898
- continue;
3142
+ nodeMap.clear();
3143
+ for (const [k, v] of newNodeMap) {
3144
+ nodeMap.set(k, v);
2899
3145
  }
2900
- const propAlias = !isSVG ? getPropAlias(key, tagName) : void 0;
2901
- if (propAlias || !isSVG && Properties.has(key) || isCE && !isSVG) {
2902
- const propName = propAlias || key;
2903
- if (isCE && !Properties.has(key)) {
2904
- createAttributeBinding(
2905
- el,
2906
- toPropertyName(propName),
2907
- value,
2908
- setProperty
2909
- );
2910
- } else {
2911
- createAttributeBinding(el, propName, value, setProperty);
3146
+ };
3147
+ const dispose = createRenderEffect(runListUpdate);
3148
+ return {
3149
+ marker: fragment,
3150
+ flush: () => {
3151
+ if (pendingItems !== null) {
3152
+ runListUpdate();
2912
3153
  }
2913
- continue;
2914
- }
2915
- if (isSVG && key.indexOf(":") > -1) {
2916
- const [prefix, name] = key.split(":");
2917
- const ns = SVGNamespace[prefix];
2918
- if (ns) {
2919
- createAttributeBinding(
2920
- el,
2921
- key,
2922
- value,
2923
- (el2, _key, val) => setAttributeNS(el2, ns, name, val)
2924
- );
2925
- continue;
3154
+ },
3155
+ dispose: () => {
3156
+ dispose();
3157
+ for (const [, managed] of nodeMap) {
3158
+ destroyRoot(managed.root);
3159
+ removeBlockNodes(managed);
2926
3160
  }
3161
+ nodeMap.clear();
3162
+ startMarker.parentNode?.removeChild(startMarker);
3163
+ endMarker.parentNode?.removeChild(endMarker);
2927
3164
  }
2928
- const attrName = Aliases[key] || key;
2929
- createAttributeBinding(el, attrName, value, setAttribute);
2930
- }
2931
- const children = props.children;
2932
- appendChildren(el, children);
2933
- }
2934
- function toPropertyName(name) {
2935
- return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
3165
+ };
2936
3166
  }
2937
- var setAttribute = (el, key, value) => {
2938
- if (value === void 0 || value === null || value === false) {
2939
- el.removeAttribute(key);
2940
- return;
2941
- }
2942
- if (value === true) {
2943
- el.setAttribute(key, "");
2944
- return;
2945
- }
2946
- const valueType = typeof value;
2947
- if (valueType === "string" || valueType === "number") {
2948
- el.setAttribute(key, String(value));
2949
- return;
2950
- }
2951
- if (key in el) {
2952
- el[key] = value;
2953
- return;
3167
+ function mountBlock(initialValue, initialIndex, renderItem, parent, anchor, createElementFn, hostRoot) {
3168
+ const start = document.createComment("fict:block:start");
3169
+ const end = document.createComment("fict:block:end");
3170
+ const valueSig = createVersionedSignalAccessor(initialValue);
3171
+ const indexSig = signal(initialIndex);
3172
+ const renderCurrent = () => renderItem(valueSig, indexSig);
3173
+ const root = createRootContext(hostRoot);
3174
+ const prev = pushRoot(root);
3175
+ const nodes = [start];
3176
+ let handledError = false;
3177
+ try {
3178
+ const output = renderCurrent();
3179
+ if (output != null && output !== false) {
3180
+ const el = createElementFn(output);
3181
+ const rendered = toNodeArray(el);
3182
+ nodes.push(...rendered);
3183
+ }
3184
+ nodes.push(end);
3185
+ insertNodesBefore(parent, nodes, anchor);
3186
+ } catch (err) {
3187
+ if (handleSuspend(err, root)) {
3188
+ handledError = true;
3189
+ nodes.push(end);
3190
+ insertNodesBefore(parent, nodes, anchor);
3191
+ } else if (handleError(err, { source: "renderChild" }, root)) {
3192
+ handledError = true;
3193
+ nodes.push(end);
3194
+ insertNodesBefore(parent, nodes, anchor);
3195
+ } else {
3196
+ throw err;
3197
+ }
3198
+ } finally {
3199
+ popRoot(prev);
3200
+ if (!handledError) {
3201
+ flushOnMount(root);
3202
+ } else {
3203
+ destroyRoot(root);
3204
+ }
2954
3205
  }
2955
- el.setAttribute(key, String(value));
2956
- };
2957
- var setProperty = (el, key, value) => {
2958
- if (value === void 0 || value === null) {
2959
- const fallback = key === "checked" || key === "selected" ? false : "";
2960
- el[key] = fallback;
2961
- return;
3206
+ return {
3207
+ nodes,
3208
+ root,
3209
+ value: valueSig,
3210
+ index: indexSig,
3211
+ start,
3212
+ end,
3213
+ renderCurrent
3214
+ };
3215
+ }
3216
+ function rerenderBlock(block, createElementFn) {
3217
+ const currentContent = block.nodes.slice(1, Math.max(1, block.nodes.length - 1));
3218
+ const currentNode = currentContent.length === 1 ? currentContent[0] : null;
3219
+ clearRoot(block.root);
3220
+ const prev = pushRoot(block.root);
3221
+ let nextOutput;
3222
+ let handledError = false;
3223
+ try {
3224
+ nextOutput = block.renderCurrent();
3225
+ } catch (err) {
3226
+ if (handleSuspend(err, block.root)) {
3227
+ handledError = true;
3228
+ popRoot(prev);
3229
+ destroyRoot(block.root);
3230
+ block.nodes = [block.start, block.end];
3231
+ return block;
3232
+ }
3233
+ if (handleError(err, { source: "renderChild" }, block.root)) {
3234
+ handledError = true;
3235
+ popRoot(prev);
3236
+ destroyRoot(block.root);
3237
+ block.nodes = [block.start, block.end];
3238
+ return block;
3239
+ }
3240
+ throw err;
3241
+ } finally {
3242
+ if (!handledError) {
3243
+ popRoot(prev);
3244
+ }
2962
3245
  }
2963
- if (key === "style" && typeof value === "object" && value !== null) {
2964
- for (const k in value) {
2965
- const v = value[k];
2966
- if (v !== void 0) {
2967
- el.style[k] = String(v);
2968
- }
3246
+ if (isFragmentVNode(nextOutput) && currentContent.length > 0) {
3247
+ const patched = patchFragmentChildren(currentContent, nextOutput.props?.children);
3248
+ if (patched) {
3249
+ block.nodes = [block.start, ...currentContent, block.end];
3250
+ return block;
2969
3251
  }
2970
- return;
2971
3252
  }
2972
- el[key] = value;
2973
- };
2974
- var setInnerHTML = (el, _key, value) => {
2975
- el.innerHTML = value == null ? "" : String(value);
2976
- };
2977
- var setBoolAttribute = (el, key, value) => {
2978
- if (value) {
2979
- el.setAttribute(key, "");
2980
- } else {
2981
- el.removeAttribute(key);
3253
+ if (currentNode && patchNode(currentNode, nextOutput)) {
3254
+ block.nodes = [block.start, currentNode, block.end];
3255
+ return block;
2982
3256
  }
2983
- };
2984
- function setAttributeNS(el, namespace, name, value) {
2985
- if (value == null) {
2986
- el.removeAttributeNS(namespace, name);
3257
+ clearContent(block);
3258
+ if (nextOutput != null && nextOutput !== false) {
3259
+ const newNodes = toNodeArray(
3260
+ nextOutput instanceof Node ? nextOutput : createElementFn(nextOutput)
3261
+ );
3262
+ insertNodesBefore(block.start.parentNode, newNodes, block.end);
3263
+ block.nodes = [block.start, ...newNodes, block.end];
2987
3264
  } else {
2988
- el.setAttributeNS(namespace, name, String(value));
3265
+ block.nodes = [block.start, block.end];
2989
3266
  }
3267
+ return block;
2990
3268
  }
2991
- function isEventKey(key) {
2992
- return key.startsWith("on") && key.length > 2 && key[2].toUpperCase() === key[2];
2993
- }
2994
- function eventNameFromProp(key) {
2995
- return key.slice(2).toLowerCase();
2996
- }
2997
-
2998
- // src/reconcile.ts
2999
- function reconcileArrays(parentNode, a, b) {
3000
- const bLength = b.length;
3001
- let aEnd = a.length;
3002
- let bEnd = bLength;
3003
- let aStart = 0;
3004
- let bStart = 0;
3005
- const after = aEnd > 0 ? a[aEnd - 1].nextSibling : null;
3006
- let map = null;
3007
- while (aStart < aEnd || bStart < bEnd) {
3008
- if (a[aStart] === b[bStart]) {
3009
- aStart++;
3010
- bStart++;
3011
- continue;
3012
- }
3013
- while (a[aEnd - 1] === b[bEnd - 1]) {
3014
- aEnd--;
3015
- bEnd--;
3016
- }
3017
- if (aEnd === aStart) {
3018
- const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] ?? null : after;
3019
- const count = bEnd - bStart;
3020
- const doc = parentNode.ownerDocument;
3021
- if (count > 1 && doc) {
3022
- const frag = doc.createDocumentFragment();
3023
- for (let i = bStart; i < bEnd; i++) {
3024
- frag.appendChild(b[i]);
3025
- }
3026
- parentNode.insertBefore(frag, node);
3027
- bStart = bEnd;
3028
- } else {
3029
- while (bStart < bEnd) {
3030
- parentNode.insertBefore(b[bStart++], node);
3031
- }
3032
- }
3033
- } else if (bEnd === bStart) {
3034
- while (aStart < aEnd) {
3035
- const nodeToRemove = a[aStart];
3036
- if (!map || !map.has(nodeToRemove)) {
3037
- nodeToRemove.parentNode?.removeChild(nodeToRemove);
3269
+ function patchElement(el, output) {
3270
+ if (output === null || output === void 0 || output === false || typeof output === "string" || typeof output === "number") {
3271
+ el.textContent = output === null || output === void 0 || output === false ? "" : String(output);
3272
+ return true;
3273
+ }
3274
+ if (output instanceof Text) {
3275
+ el.textContent = output.data;
3276
+ return true;
3277
+ }
3278
+ if (output && typeof output === "object" && !(output instanceof Node)) {
3279
+ const vnode = output;
3280
+ if (typeof vnode.type === "string" && vnode.type.toLowerCase() === el.tagName.toLowerCase()) {
3281
+ const children = vnode.props?.children;
3282
+ const props = vnode.props ?? {};
3283
+ for (const [key, value] of Object.entries(props)) {
3284
+ if (key === "children" || key === "key") continue;
3285
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) {
3286
+ if (key === "class" || key === "className") {
3287
+ el.setAttribute("class", value === false || value === null ? "" : String(value));
3288
+ } else if (key === "style" && typeof value === "string") {
3289
+ el.style.cssText = value;
3290
+ } else if (value === false || value === null || value === void 0) {
3291
+ el.removeAttribute(key);
3292
+ } else if (value === true) {
3293
+ el.setAttribute(key, "");
3294
+ } else {
3295
+ el.setAttribute(key, String(value));
3296
+ }
3038
3297
  }
3039
- aStart++;
3040
3298
  }
3041
- } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
3042
- const node = a[--aEnd].nextSibling;
3043
- parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling);
3044
- parentNode.insertBefore(b[--bEnd], node);
3045
- a[aEnd] = b[bEnd];
3046
- } else {
3047
- if (!map) {
3048
- map = /* @__PURE__ */ new Map();
3049
- let i = bStart;
3050
- while (i < bEnd) {
3051
- map.set(b[i], i++);
3052
- }
3299
+ if (typeof children === "string" || typeof children === "number" || children === null || children === void 0 || children === false) {
3300
+ el.textContent = children === null || children === void 0 || children === false ? "" : String(children);
3301
+ return true;
3053
3302
  }
3054
- const index = map.get(a[aStart]);
3055
- if (index != null) {
3056
- if (bStart < index && index < bEnd) {
3057
- let i = aStart;
3058
- let sequence = 1;
3059
- let t;
3060
- while (++i < aEnd && i < bEnd) {
3061
- t = map.get(a[i]);
3062
- if (t == null || t !== index + sequence) break;
3063
- sequence++;
3064
- }
3065
- if (sequence > index - bStart) {
3066
- const node = a[aStart];
3067
- while (bStart < index) {
3068
- parentNode.insertBefore(b[bStart++], node);
3069
- }
3070
- } else {
3071
- parentNode.replaceChild(b[bStart++], a[aStart++]);
3303
+ if (children && typeof children === "object" && !Array.isArray(children) && !(children instanceof Node)) {
3304
+ const childVNode = children;
3305
+ if (typeof childVNode.type === "string") {
3306
+ const childEl = el.querySelector(childVNode.type);
3307
+ if (childEl && patchElement(childEl, children)) {
3308
+ return true;
3072
3309
  }
3073
- } else {
3074
- aStart++;
3075
3310
  }
3076
- } else {
3077
- const nodeToRemove = a[aStart++];
3078
- nodeToRemove.parentNode?.removeChild(nodeToRemove);
3079
3311
  }
3312
+ return false;
3313
+ }
3314
+ }
3315
+ if (output instanceof Node) {
3316
+ if (output.nodeType === Node.ELEMENT_NODE) {
3317
+ const nextEl = output;
3318
+ if (nextEl.tagName.toLowerCase() === el.tagName.toLowerCase()) {
3319
+ el.textContent = nextEl.textContent;
3320
+ return true;
3321
+ }
3322
+ } else if (output.nodeType === Node.TEXT_NODE) {
3323
+ el.textContent = output.data;
3324
+ return true;
3080
3325
  }
3081
3326
  }
3327
+ return false;
3082
3328
  }
3083
-
3084
- // src/list-helpers.ts
3085
- function moveNodesBefore(parent, nodes, anchor) {
3086
- for (let i = nodes.length - 1; i >= 0; i--) {
3087
- const node = nodes[i];
3088
- if (!node || !(node instanceof Node)) {
3089
- throw new Error("Invalid node in moveNodesBefore");
3090
- }
3091
- if (node.nextSibling !== anchor) {
3092
- if (node.ownerDocument !== parent.ownerDocument && parent.ownerDocument) {
3093
- parent.ownerDocument.adoptNode(node);
3094
- }
3095
- try {
3096
- parent.insertBefore(node, anchor);
3097
- } catch (e) {
3098
- if (parent.ownerDocument) {
3099
- try {
3100
- const clone = parent.ownerDocument.importNode(node, true);
3101
- parent.insertBefore(clone, anchor);
3102
- continue;
3103
- } catch {
3104
- }
3105
- }
3106
- throw e;
3107
- }
3108
- }
3109
- anchor = node;
3329
+ function patchNode(currentNode, nextOutput) {
3330
+ if (!currentNode) return false;
3331
+ if (currentNode instanceof Text && (nextOutput === null || nextOutput === void 0 || nextOutput === false || typeof nextOutput === "string" || typeof nextOutput === "number" || nextOutput instanceof Text)) {
3332
+ const nextText = nextOutput instanceof Text ? nextOutput.data : nextOutput === null || nextOutput === void 0 || nextOutput === false ? "" : String(nextOutput);
3333
+ currentNode.data = nextText;
3334
+ return true;
3335
+ }
3336
+ if (currentNode instanceof Element && patchElement(currentNode, nextOutput)) {
3337
+ return true;
3110
3338
  }
3339
+ if (nextOutput instanceof Node && currentNode === nextOutput) {
3340
+ return true;
3341
+ }
3342
+ return false;
3111
3343
  }
3112
- function moveMarkerBlock(parent, block, anchor) {
3113
- const nodes = collectBlockNodes(block);
3114
- if (nodes.length === 0) return;
3115
- moveNodesBefore(parent, nodes, anchor);
3344
+ function isFragmentVNode(value) {
3345
+ return value != null && typeof value === "object" && !(value instanceof Node) && value.type === Fragment;
3116
3346
  }
3117
- function destroyMarkerBlock(block) {
3118
- if (block.root) {
3119
- destroyRoot(block.root);
3347
+ function normalizeChildren(children, result = []) {
3348
+ if (children === void 0) {
3349
+ return result;
3120
3350
  }
3121
- removeBlockRange(block);
3351
+ if (Array.isArray(children)) {
3352
+ for (const child of children) {
3353
+ normalizeChildren(child, result);
3354
+ }
3355
+ return result;
3356
+ }
3357
+ if (children === null || children === false) {
3358
+ return result;
3359
+ }
3360
+ result.push(children);
3361
+ return result;
3122
3362
  }
3123
- function collectBlockNodes(block) {
3124
- const nodes = [];
3125
- let cursor = block.start;
3126
- while (cursor) {
3127
- nodes.push(cursor);
3128
- if (cursor === block.end) {
3129
- break;
3363
+ function patchFragmentChildren(nodes, children) {
3364
+ const normalized = normalizeChildren(children);
3365
+ if (normalized.length !== nodes.length) {
3366
+ return false;
3367
+ }
3368
+ for (let i = 0; i < normalized.length; i++) {
3369
+ if (!patchNode(nodes[i], normalized[i])) {
3370
+ return false;
3130
3371
  }
3131
- cursor = cursor.nextSibling;
3132
3372
  }
3133
- return nodes;
3373
+ return true;
3134
3374
  }
3135
- function removeBlockRange(block) {
3375
+ function clearContent(block) {
3376
+ const nodes = block.nodes.slice(1, Math.max(1, block.nodes.length - 1));
3377
+ removeNodes(nodes);
3378
+ }
3379
+ function removeBlockNodes(block) {
3136
3380
  let cursor = block.start;
3381
+ const end = block.end;
3137
3382
  while (cursor) {
3138
3383
  const next = cursor.nextSibling;
3139
3384
  cursor.parentNode?.removeChild(cursor);
3140
- if (cursor === block.end) {
3141
- break;
3142
- }
3385
+ if (cursor === end) break;
3143
3386
  cursor = next;
3144
3387
  }
3145
3388
  }
3146
- function createVersionedSignalAccessor(initialValue) {
3147
- let current = initialValue;
3148
- let version = 0;
3149
- const track = signal(version);
3150
- function accessor(value) {
3151
- if (arguments.length === 0) {
3152
- track();
3153
- return current;
3154
- }
3155
- current = value;
3156
- version++;
3157
- track(version);
3158
- }
3159
- return accessor;
3160
- }
3161
- function createKeyedListContainer() {
3162
- const startMarker = document.createComment("fict:list:start");
3163
- const endMarker = document.createComment("fict:list:end");
3164
- const dispose = () => {
3165
- for (const block of container.blocks.values()) {
3166
- destroyRoot(block.root);
3389
+
3390
+ // src/scope.ts
3391
+ function createScope() {
3392
+ let dispose = null;
3393
+ const stop = () => {
3394
+ if (dispose) {
3395
+ dispose();
3396
+ dispose = null;
3167
3397
  }
3168
- container.blocks.clear();
3169
- container.nextBlocks.clear();
3170
- const range = document.createRange();
3171
- range.setStartBefore(startMarker);
3172
- range.setEndAfter(endMarker);
3173
- range.deleteContents();
3174
- container.currentNodes = [];
3175
- container.nextNodes = [];
3176
- container.nextBlocks.clear();
3177
- container.orderedBlocks.length = 0;
3178
- container.nextOrderedBlocks.length = 0;
3179
- container.orderedIndexByKey.clear();
3180
3398
  };
3181
- const container = {
3182
- startMarker,
3183
- endMarker,
3184
- blocks: /* @__PURE__ */ new Map(),
3185
- nextBlocks: /* @__PURE__ */ new Map(),
3186
- currentNodes: [startMarker, endMarker],
3187
- nextNodes: [],
3188
- orderedBlocks: [],
3189
- nextOrderedBlocks: [],
3190
- orderedIndexByKey: /* @__PURE__ */ new Map(),
3191
- dispose
3399
+ const run = (fn) => {
3400
+ stop();
3401
+ const { dispose: rootDispose, value } = createRoot(fn);
3402
+ dispose = rootDispose;
3403
+ return value;
3192
3404
  };
3193
- return container;
3405
+ registerRootCleanup(stop);
3406
+ return { run, stop };
3194
3407
  }
3195
- function createKeyedBlock(key, item, index, render2, needsIndex = true) {
3196
- const itemSig = createVersionedSignalAccessor(item);
3197
- const indexSig = needsIndex ? signal(index) : ((next) => {
3198
- if (arguments.length === 0) return index;
3199
- index = next;
3200
- return index;
3201
- });
3202
- const root = createRootContext();
3203
- const prevRoot = pushRoot(root);
3204
- const prevSub = setActiveSub(void 0);
3205
- let nodes = [];
3206
- try {
3207
- const rendered = render2(itemSig, indexSig, key);
3208
- if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
3209
- nodes = toNodeArray(rendered);
3408
+ function runInScope(flag, fn) {
3409
+ const scope = createScope();
3410
+ const evaluate = () => isReactive(flag) ? flag() : !!flag;
3411
+ createEffect(() => {
3412
+ const enabled = evaluate();
3413
+ if (enabled) {
3414
+ scope.run(fn);
3210
3415
  } else {
3211
- const element = createElement(rendered);
3212
- nodes = toNodeArray(element);
3213
- }
3214
- } finally {
3215
- setActiveSub(prevSub);
3216
- popRoot(prevRoot);
3217
- flushOnMount(root);
3218
- }
3219
- return {
3220
- key,
3221
- nodes,
3222
- root,
3223
- item: itemSig,
3224
- index: indexSig,
3225
- rawItem: item,
3226
- rawIndex: index
3227
- };
3228
- }
3229
- function getFirstNodeAfter(marker) {
3230
- return marker.nextSibling;
3231
- }
3232
- function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
3233
- const resolvedNeedsIndex = arguments.length >= 4 ? !!needsIndex : renderItem.length > 1;
3234
- return createFineGrainedKeyedList(getItems, keyFn, renderItem, resolvedNeedsIndex);
3235
- }
3236
- function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
3237
- const container = createKeyedListContainer();
3238
- const fragment = document.createDocumentFragment();
3239
- fragment.append(container.startMarker, container.endMarker);
3240
- let pendingItems = null;
3241
- let disposed = false;
3242
- const performDiff = () => {
3243
- if (disposed) return;
3244
- batch2(() => {
3245
- const newItems = pendingItems || getItems();
3246
- pendingItems = null;
3247
- const oldBlocks = container.blocks;
3248
- const newBlocks = container.nextBlocks;
3249
- const prevOrderedBlocks = container.orderedBlocks;
3250
- const nextOrderedBlocks = container.nextOrderedBlocks;
3251
- const orderedIndexByKey = container.orderedIndexByKey;
3252
- newBlocks.clear();
3253
- nextOrderedBlocks.length = 0;
3254
- orderedIndexByKey.clear();
3255
- const endParent = container.endMarker.parentNode;
3256
- const startParent = container.startMarker.parentNode;
3257
- const parent = endParent && startParent && endParent === startParent && endParent.isConnected ? endParent : null;
3258
- if (!parent) {
3259
- pendingItems = newItems;
3260
- queueMicrotask(performDiff);
3261
- return;
3262
- }
3263
- if (newItems.length === 0) {
3264
- if (oldBlocks.size > 0) {
3265
- for (const block of oldBlocks.values()) {
3266
- destroyRoot(block.root);
3267
- removeNodes(block.nodes);
3268
- }
3269
- }
3270
- oldBlocks.clear();
3271
- newBlocks.clear();
3272
- prevOrderedBlocks.length = 0;
3273
- nextOrderedBlocks.length = 0;
3274
- orderedIndexByKey.clear();
3275
- container.currentNodes.length = 0;
3276
- container.currentNodes.push(container.startMarker, container.endMarker);
3277
- container.nextNodes.length = 0;
3278
- return;
3279
- }
3280
- const prevCount = prevOrderedBlocks.length;
3281
- let appendCandidate = prevCount > 0 && newItems.length >= prevCount;
3282
- const appendedBlocks = [];
3283
- newItems.forEach((item, index) => {
3284
- const key = keyFn(item, index);
3285
- const existed = oldBlocks.has(key);
3286
- let block = oldBlocks.get(key);
3287
- if (block) {
3288
- if (block.rawItem !== item) {
3289
- block.rawItem = item;
3290
- block.item(item);
3291
- }
3292
- if (needsIndex && block.rawIndex !== index) {
3293
- block.rawIndex = index;
3294
- block.index(index);
3295
- }
3296
- }
3297
- const existingBlock = newBlocks.get(key);
3298
- if (existingBlock && existingBlock !== block) {
3299
- destroyRoot(existingBlock.root);
3300
- removeNodes(existingBlock.nodes);
3301
- }
3302
- if (block) {
3303
- newBlocks.set(key, block);
3304
- oldBlocks.delete(key);
3305
- } else {
3306
- const existingBlock2 = newBlocks.get(key);
3307
- if (existingBlock2) {
3308
- destroyRoot(existingBlock2.root);
3309
- removeNodes(existingBlock2.nodes);
3310
- }
3311
- block = createKeyedBlock(key, item, index, renderItem, needsIndex);
3312
- }
3313
- const resolvedBlock = block;
3314
- newBlocks.set(key, resolvedBlock);
3315
- const position = orderedIndexByKey.get(key);
3316
- if (position !== void 0) {
3317
- appendCandidate = false;
3318
- }
3319
- if (appendCandidate) {
3320
- if (index < prevCount) {
3321
- if (!prevOrderedBlocks[index] || prevOrderedBlocks[index].key !== key) {
3322
- appendCandidate = false;
3323
- }
3324
- } else if (existed) {
3325
- appendCandidate = false;
3326
- }
3327
- }
3328
- if (position !== void 0) {
3329
- const prior = nextOrderedBlocks[position];
3330
- if (prior && prior !== resolvedBlock) {
3331
- destroyRoot(prior.root);
3332
- removeNodes(prior.nodes);
3333
- }
3334
- nextOrderedBlocks[position] = resolvedBlock;
3335
- } else {
3336
- orderedIndexByKey.set(key, nextOrderedBlocks.length);
3337
- nextOrderedBlocks.push(resolvedBlock);
3338
- }
3339
- if (appendCandidate && index >= prevCount) {
3340
- appendedBlocks.push(resolvedBlock);
3341
- }
3342
- });
3343
- const canAppend = appendCandidate && prevCount > 0 && newItems.length > prevCount && oldBlocks.size === 0 && appendedBlocks.length > 0;
3344
- if (canAppend) {
3345
- const appendedNodes = [];
3346
- for (const block of appendedBlocks) {
3347
- for (let i = 0; i < block.nodes.length; i++) {
3348
- appendedNodes.push(block.nodes[i]);
3349
- }
3350
- }
3351
- if (appendedNodes.length > 0) {
3352
- insertNodesBefore(parent, appendedNodes, container.endMarker);
3353
- const currentNodes = container.currentNodes;
3354
- currentNodes.pop();
3355
- for (let i = 0; i < appendedNodes.length; i++) {
3356
- currentNodes.push(appendedNodes[i]);
3357
- }
3358
- currentNodes.push(container.endMarker);
3359
- }
3360
- container.blocks = newBlocks;
3361
- container.nextBlocks = oldBlocks;
3362
- container.orderedBlocks = nextOrderedBlocks;
3363
- container.nextOrderedBlocks = prevOrderedBlocks;
3364
- return;
3365
- }
3366
- if (oldBlocks.size > 0) {
3367
- for (const block of oldBlocks.values()) {
3368
- destroyRoot(block.root);
3369
- removeNodes(block.nodes);
3370
- }
3371
- oldBlocks.clear();
3372
- }
3373
- if (newBlocks.size > 0 || container.currentNodes.length > 0) {
3374
- const prevNodes = container.currentNodes;
3375
- const nextNodes = container.nextNodes;
3376
- nextNodes.length = 0;
3377
- nextNodes.push(container.startMarker);
3378
- for (let i = 0; i < nextOrderedBlocks.length; i++) {
3379
- const nodes = nextOrderedBlocks[i].nodes;
3380
- for (let j = 0; j < nodes.length; j++) {
3381
- nextNodes.push(nodes[j]);
3382
- }
3383
- }
3384
- nextNodes.push(container.endMarker);
3385
- reconcileArrays(parent, prevNodes, nextNodes);
3386
- container.currentNodes = nextNodes;
3387
- container.nextNodes = prevNodes;
3388
- }
3389
- container.blocks = newBlocks;
3390
- container.nextBlocks = oldBlocks;
3391
- container.orderedBlocks = nextOrderedBlocks;
3392
- container.nextOrderedBlocks = prevOrderedBlocks;
3393
- });
3394
- };
3395
- const effectDispose = createRenderEffect(performDiff);
3396
- return {
3397
- marker: fragment,
3398
- startMarker: container.startMarker,
3399
- endMarker: container.endMarker,
3400
- // Flush pending items - call after markers are inserted into DOM
3401
- flush: () => {
3402
- if (pendingItems !== null) {
3403
- performDiff();
3404
- }
3405
- },
3406
- dispose: () => {
3407
- disposed = true;
3408
- effectDispose?.();
3409
- container.dispose();
3416
+ scope.stop();
3410
3417
  }
3411
- };
3418
+ });
3419
+ onCleanup(scope.stop);
3412
3420
  }
3413
3421
 
3414
3422
  exports.$state = $state;