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