sibujs 2.1.0 → 3.0.0

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.
Files changed (62) hide show
  1. package/dist/browser.cjs +324 -273
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +363 -330
  4. package/dist/build.js +10 -10
  5. package/dist/cdn.global.js +8 -8
  6. package/dist/{chunk-ZAQSMOED.js → chunk-2JQUV4Y3.js} +4 -4
  7. package/dist/{chunk-GWWURC5M.js → chunk-2KM2724A.js} +2 -2
  8. package/dist/{chunk-NASX6ST2.js → chunk-4YTVESDX.js} +1 -1
  9. package/dist/chunk-5WD7BYTZ.js +152 -0
  10. package/dist/{chunk-RDTDJCAB.js → chunk-6QZO7MMG.js} +48 -16
  11. package/dist/{chunk-DRUZZAK4.js → chunk-DF3GTP4Q.js} +7 -2
  12. package/dist/{chunk-AMK2TYNW.js → chunk-INBOWHQ3.js} +14 -11
  13. package/dist/{chunk-O6EFQ3KT.js → chunk-KH4OE6WY.js} +5 -5
  14. package/dist/{chunk-V6C4FADE.js → chunk-KZA7ANXP.js} +3 -3
  15. package/dist/chunk-L4DAT4WU.js +400 -0
  16. package/dist/{chunk-WANSMF2L.js → chunk-L52H775O.js} +4 -4
  17. package/dist/{chunk-45YP72ZQ.js → chunk-NEWH4O5U.js} +1 -1
  18. package/dist/{chunk-ON5MMR2J.js → chunk-RJIRT46U.js} +4 -4
  19. package/dist/{chunk-P2HSJDDN.js → chunk-STFTTMO2.js} +2 -2
  20. package/dist/{chunk-WIPZPFBQ.js → chunk-UKMXT5T6.js} +1 -1
  21. package/dist/{chunk-KGYT6UO6.js → chunk-V65KTDZW.js} +3 -3
  22. package/dist/{chunk-CWBVQML6.js → chunk-VSNLICTS.js} +1 -1
  23. package/dist/{chunk-3DZP6OIT.js → chunk-XDKP4T7G.js} +2 -2
  24. package/dist/{chunk-TH2ILCYW.js → chunk-XVYB3J6C.js} +27 -33
  25. package/dist/{chunk-OJ3P4ECI.js → chunk-YMOIAHWA.js} +1 -1
  26. package/dist/data.cjs +332 -298
  27. package/dist/data.js +6 -6
  28. package/dist/devtools.cjs +353 -296
  29. package/dist/devtools.d.cts +1 -1
  30. package/dist/devtools.d.ts +1 -1
  31. package/dist/devtools.js +4 -4
  32. package/dist/ecosystem.cjs +332 -298
  33. package/dist/ecosystem.js +7 -7
  34. package/dist/extras.cjs +372 -328
  35. package/dist/extras.d.cts +1 -1
  36. package/dist/extras.d.ts +1 -1
  37. package/dist/extras.js +19 -19
  38. package/dist/index.cjs +363 -330
  39. package/dist/index.d.cts +26 -36
  40. package/dist/index.d.ts +26 -36
  41. package/dist/index.js +10 -10
  42. package/dist/{introspect-DnIpHQQz.d.ts → introspect-BZWKvQUZ.d.ts} +2 -3
  43. package/dist/{introspect-2TOlQ7oa.d.cts → introspect-DsJlDD2T.d.cts} +2 -3
  44. package/dist/motion.cjs +147 -123
  45. package/dist/motion.js +3 -3
  46. package/dist/patterns.cjs +332 -298
  47. package/dist/patterns.js +5 -5
  48. package/dist/performance.cjs +315 -268
  49. package/dist/performance.js +4 -4
  50. package/dist/plugins.cjs +332 -266
  51. package/dist/plugins.js +6 -6
  52. package/dist/ssr.cjs +340 -270
  53. package/dist/ssr.js +7 -7
  54. package/dist/testing.cjs +167 -146
  55. package/dist/testing.js +2 -2
  56. package/dist/ui.cjs +324 -294
  57. package/dist/ui.js +6 -6
  58. package/dist/widgets.cjs +332 -298
  59. package/dist/widgets.js +6 -6
  60. package/package.json +1 -1
  61. package/dist/chunk-QO3WC6FS.js +0 -384
  62. package/dist/chunk-WZA53FXU.js +0 -149
package/dist/build.cjs CHANGED
@@ -1352,24 +1352,89 @@ function isUrlAttribute(attr) {
1352
1352
 
1353
1353
  // src/reactivity/track.ts
1354
1354
  var _isDev2 = isDev();
1355
- var STACK_INITIAL = 32;
1356
- var STACK_SHRINK_THRESHOLD = 128;
1357
- var subscriberStack = new Array(STACK_INITIAL);
1358
- var stackCapacity = STACK_INITIAL;
1359
- var stackTop = -1;
1360
- var currentSubscriber = null;
1361
- var SUBS = "__s";
1362
- function syncFastPath(signal2, subs) {
1363
- const size = subs.size;
1364
- if (size === 0) {
1365
- signal2.__f = void 0;
1366
- delete signal2[SUBS];
1367
- } else if (size === 1) {
1368
- signal2.__f = subs.values().next().value;
1369
- } else {
1370
- signal2.__f = void 0;
1371
- }
1355
+ var POOL_MAX = 4096;
1356
+ var nodePool = [];
1357
+ function createNode() {
1358
+ return {
1359
+ sig: null,
1360
+ sub: null,
1361
+ epoch: 0,
1362
+ sigPrev: null,
1363
+ sigNext: null,
1364
+ subPrev: null,
1365
+ subNext: null,
1366
+ prevActive: null
1367
+ };
1368
+ }
1369
+ function allocNode(sig, sub2, epoch) {
1370
+ const n = nodePool.pop();
1371
+ if (n) {
1372
+ n.sig = sig;
1373
+ n.sub = sub2;
1374
+ n.epoch = epoch;
1375
+ return n;
1376
+ }
1377
+ const fresh = createNode();
1378
+ fresh.sig = sig;
1379
+ fresh.sub = sub2;
1380
+ fresh.epoch = epoch;
1381
+ return fresh;
1382
+ }
1383
+ function freeNode(node) {
1384
+ node.sig = null;
1385
+ node.sub = null;
1386
+ node.sigPrev = null;
1387
+ node.sigNext = null;
1388
+ node.subPrev = null;
1389
+ node.subNext = null;
1390
+ node.prevActive = null;
1391
+ if (nodePool.length < POOL_MAX) nodePool.push(node);
1392
+ }
1393
+ function linkSignal(sig, node) {
1394
+ const oldHead = sig.subsHead ?? null;
1395
+ node.sigPrev = null;
1396
+ node.sigNext = oldHead;
1397
+ if (oldHead) oldHead.sigPrev = node;
1398
+ else sig.subsTail = node;
1399
+ sig.subsHead = node;
1400
+ sig.__sc = (sig.__sc ?? 0) + 1;
1401
+ }
1402
+ function unlinkSignal(node) {
1403
+ const sig = node.sig;
1404
+ if (!sig) return;
1405
+ const prev = node.sigPrev;
1406
+ const next = node.sigNext;
1407
+ if (prev) prev.sigNext = next;
1408
+ else sig.subsHead = next;
1409
+ if (next) next.sigPrev = prev;
1410
+ else sig.subsTail = prev;
1411
+ sig.__sc = (sig.__sc ?? 1) - 1;
1412
+ if (sig.__activeNode === node) sig.__activeNode = node.prevActive;
1413
+ if (sig.__sc === 0) {
1414
+ sig.subsHead = null;
1415
+ sig.subsTail = null;
1416
+ }
1417
+ }
1418
+ function linkSub(sub2, node) {
1419
+ const oldTail = sub2.depsTail ?? null;
1420
+ node.subPrev = oldTail;
1421
+ node.subNext = null;
1422
+ if (oldTail) oldTail.subNext = node;
1423
+ else sub2.depsHead = node;
1424
+ sub2.depsTail = node;
1425
+ }
1426
+ function unlinkSub(node) {
1427
+ const sub2 = node.sub;
1428
+ if (!sub2) return;
1429
+ const prev = node.subPrev;
1430
+ const next = node.subNext;
1431
+ if (prev) prev.subNext = next;
1432
+ else sub2.depsHead = next;
1433
+ if (next) next.subPrev = prev;
1434
+ else sub2.depsTail = prev;
1372
1435
  }
1436
+ var currentSubscriber = null;
1437
+ var suspendSavedSub = null;
1373
1438
  var notifyDepth = 0;
1374
1439
  var pendingQueue = [];
1375
1440
  var pendingSet = /* @__PURE__ */ new Set();
@@ -1383,6 +1448,30 @@ function safeInvoke(sub2) {
1383
1448
  }
1384
1449
  var suspendDepth = 0;
1385
1450
  var trackingSuspended = false;
1451
+ function suspendTracking() {
1452
+ if (suspendDepth === 0) {
1453
+ suspendSavedSub = currentSubscriber;
1454
+ currentSubscriber = null;
1455
+ trackingSuspended = true;
1456
+ }
1457
+ suspendDepth++;
1458
+ }
1459
+ function resumeTracking() {
1460
+ suspendDepth--;
1461
+ if (suspendDepth === 0) {
1462
+ currentSubscriber = suspendSavedSub;
1463
+ suspendSavedSub = null;
1464
+ trackingSuspended = false;
1465
+ }
1466
+ }
1467
+ function untracked(fn) {
1468
+ suspendTracking();
1469
+ try {
1470
+ return fn();
1471
+ } finally {
1472
+ resumeTracking();
1473
+ }
1474
+ }
1386
1475
  var subscriberEpochCounter = 0;
1387
1476
  function retrack(effectFn, subscriber) {
1388
1477
  const prev = currentSubscriber;
@@ -1390,139 +1479,77 @@ function retrack(effectFn, subscriber) {
1390
1479
  const sub2 = subscriber;
1391
1480
  const epoch = ++subscriberEpochCounter;
1392
1481
  sub2._epoch = epoch;
1482
+ sub2._structDirty = false;
1483
+ for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
1484
+ const sig = n.sig;
1485
+ n.prevActive = sig.__activeNode ?? null;
1486
+ sig.__activeNode = n;
1487
+ }
1393
1488
  try {
1394
1489
  effectFn();
1395
1490
  } finally {
1396
1491
  currentSubscriber = prev;
1397
- pruneStaleDeps(sub2, epoch);
1398
- }
1399
- }
1400
- function pruneStaleDeps(sub2, currentEpoch) {
1401
- if (sub2._dep !== void 0) {
1402
- if (sub2._depEpoch !== currentEpoch) {
1403
- const sig = sub2._dep;
1404
- const subs = sig[SUBS];
1405
- if (subs?.delete(sub2)) syncFastPath(sig, subs);
1406
- sub2._dep = void 0;
1407
- sub2._depEpoch = void 0;
1408
- }
1409
- return;
1410
- }
1411
- const deps = sub2._deps;
1412
- if (!deps || deps.size === 0) return;
1413
- let stales;
1414
- for (const [signal2, epoch] of deps) {
1415
- if (epoch !== currentEpoch) {
1416
- (stales ?? (stales = [])).push(signal2);
1492
+ let node = sub2.depsHead ?? null;
1493
+ while (node !== null) {
1494
+ const next = node.subNext;
1495
+ const sig = node.sig;
1496
+ sig.__activeNode = node.prevActive;
1497
+ node.prevActive = null;
1498
+ if (node.epoch !== epoch) {
1499
+ unlinkSub(node);
1500
+ unlinkSignal(node);
1501
+ freeNode(node);
1502
+ }
1503
+ node = next;
1417
1504
  }
1418
1505
  }
1419
- if (!stales) return;
1420
- for (const signal2 of stales) {
1421
- deps.delete(signal2);
1422
- const sig = signal2;
1423
- const subs = sig[SUBS];
1424
- if (subs?.delete(sub2)) syncFastPath(sig, subs);
1425
- }
1426
1506
  }
1427
1507
  function track(effectFn, subscriber) {
1428
1508
  if (!subscriber) subscriber = effectFn;
1429
1509
  cleanup(subscriber);
1430
- ++stackTop;
1431
- if (stackTop >= stackCapacity) {
1432
- stackCapacity *= 2;
1433
- subscriberStack.length = stackCapacity;
1434
- }
1435
- subscriberStack[stackTop] = subscriber;
1510
+ const prev = currentSubscriber;
1436
1511
  currentSubscriber = subscriber;
1437
1512
  try {
1438
1513
  effectFn();
1439
1514
  } finally {
1440
- stackTop--;
1441
- currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
1442
- if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
1443
- stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
1444
- subscriberStack.length = stackCapacity;
1515
+ currentSubscriber = prev;
1516
+ const sub3 = subscriber;
1517
+ for (let n = sub3.depsHead ?? null; n !== null; n = n.subNext) {
1518
+ const sig = n.sig;
1519
+ sig.__activeNode = n.prevActive;
1520
+ n.prevActive = null;
1445
1521
  }
1446
1522
  }
1447
- return () => cleanup(subscriber);
1448
- }
1449
- function suspendTracking() {
1450
- if (suspendDepth === 0) {
1451
- ++stackTop;
1452
- if (stackTop >= stackCapacity) {
1453
- stackCapacity *= 2;
1454
- subscriberStack.length = stackCapacity;
1455
- }
1456
- subscriberStack[stackTop] = null;
1457
- currentSubscriber = null;
1458
- trackingSuspended = true;
1459
- }
1460
- suspendDepth++;
1461
- }
1462
- function resumeTracking() {
1463
- suspendDepth--;
1464
- if (suspendDepth === 0) {
1465
- stackTop--;
1466
- currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
1467
- trackingSuspended = false;
1468
- }
1469
- }
1470
- function untracked(fn) {
1471
- suspendTracking();
1472
- try {
1473
- return fn();
1474
- } finally {
1475
- resumeTracking();
1476
- }
1523
+ const sub2 = subscriber;
1524
+ return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
1477
1525
  }
1478
1526
  function recordDependency(signal2) {
1479
1527
  if (!currentSubscriber) return;
1480
1528
  const sub2 = currentSubscriber;
1481
- const epoch = sub2._epoch;
1482
- if (sub2._dep === signal2) {
1483
- sub2._depEpoch = epoch;
1484
- return;
1485
- }
1486
- const deps = sub2._deps;
1487
- if (deps) {
1488
- deps.set(signal2, epoch);
1489
- } else if (sub2._dep !== void 0) {
1490
- const map2 = /* @__PURE__ */ new Map();
1491
- map2.set(sub2._dep, sub2._depEpoch);
1492
- map2.set(signal2, epoch);
1493
- sub2._deps = map2;
1494
- sub2._dep = void 0;
1495
- sub2._depEpoch = void 0;
1496
- } else {
1497
- sub2._dep = signal2;
1498
- sub2._depEpoch = epoch;
1499
- }
1500
1529
  const sig = signal2;
1501
- let subs = sig[SUBS];
1502
- if (!subs) {
1503
- subs = /* @__PURE__ */ new Set();
1504
- sig[SUBS] = subs;
1505
- }
1506
- const prevSize = subs.size;
1507
- subs.add(currentSubscriber);
1508
- if (subs.size !== prevSize) {
1509
- if (subs.size === 1) {
1510
- sig.__f = currentSubscriber;
1511
- } else if (sig.__f !== void 0) {
1512
- sig.__f = void 0;
1513
- }
1530
+ const epoch = sub2._epoch ?? 0;
1531
+ const active = sig.__activeNode ?? null;
1532
+ if (active !== null && active.sub === sub2) {
1533
+ active.epoch = epoch;
1534
+ return;
1514
1535
  }
1536
+ const node = allocNode(signal2, sub2, epoch);
1537
+ node.prevActive = active;
1538
+ sig.__activeNode = node;
1539
+ linkSub(sub2, node);
1540
+ linkSignal(sig, node);
1541
+ sub2._structDirty = true;
1515
1542
  }
1516
- function queueSignalNotification(signal2) {
1517
- const subs = signal2[SUBS];
1518
- if (!subs) return;
1519
- for (const sub2 of subs) {
1520
- if (sub2._c) {
1521
- propagateDirty(sub2);
1522
- } else if (!pendingSet.has(sub2)) {
1523
- pendingSet.add(sub2);
1524
- pendingQueue.push(sub2);
1525
- }
1543
+ function cleanup(subscriber) {
1544
+ const sub2 = subscriber;
1545
+ let node = sub2.depsHead ?? null;
1546
+ sub2.depsHead = null;
1547
+ sub2.depsTail = null;
1548
+ while (node) {
1549
+ const next = node.subNext;
1550
+ unlinkSignal(node);
1551
+ freeNode(node);
1552
+ node = next;
1526
1553
  }
1527
1554
  }
1528
1555
  var maxSubscriberRepeats = 50;
@@ -1540,7 +1567,8 @@ function tickRepeat(sub2) {
1540
1567
  s2._runs = 1;
1541
1568
  return false;
1542
1569
  }
1543
- return ++s2._runs > maxSubscriberRepeats;
1570
+ s2._runs = (s2._runs ?? 0) + 1;
1571
+ return s2._runs > maxSubscriberRepeats;
1544
1572
  }
1545
1573
  function cycleError(sub2) {
1546
1574
  if (typeof console !== "undefined") {
@@ -1596,93 +1624,80 @@ function propagateDirty(sub2) {
1596
1624
  stack.push(rootSig);
1597
1625
  while (stack.length > baseLen) {
1598
1626
  const sig = stack.pop();
1599
- const first = sig.__f;
1600
- if (first) {
1601
- if (first._c) {
1602
- const nSig = first._sig;
1603
- if (!nSig._d) {
1604
- nSig._d = true;
1605
- stack.push(nSig);
1627
+ let node = sig.subsHead ?? null;
1628
+ while (node) {
1629
+ const s2 = node.sub;
1630
+ if (s2) {
1631
+ if (s2._c) {
1632
+ const nSig = s2._sig;
1633
+ if (nSig) {
1634
+ if (!nSig._d) {
1635
+ nSig._d = true;
1636
+ stack.push(nSig);
1637
+ }
1638
+ } else {
1639
+ s2();
1640
+ }
1641
+ } else if (!pendingSet.has(s2)) {
1642
+ pendingSet.add(s2);
1643
+ pendingQueue.push(s2);
1606
1644
  }
1607
- } else if (!pendingSet.has(first)) {
1608
- pendingSet.add(first);
1609
- pendingQueue.push(first);
1610
1645
  }
1611
- continue;
1646
+ node = node.sigNext;
1612
1647
  }
1613
- const subs = sig[SUBS];
1614
- if (!subs) continue;
1615
- for (const s2 of subs) {
1648
+ }
1649
+ }
1650
+ function queueSignalNotification(signal2) {
1651
+ const sig = signal2;
1652
+ let node = sig.subsHead ?? null;
1653
+ while (node) {
1654
+ const s2 = node.sub;
1655
+ if (s2) {
1616
1656
  if (s2._c) {
1617
- const nSig = s2._sig;
1618
- if (nSig && !nSig._d) {
1619
- nSig._d = true;
1620
- stack.push(nSig);
1621
- } else if (!nSig) {
1622
- s2();
1623
- }
1657
+ propagateDirty(s2);
1624
1658
  } else if (!pendingSet.has(s2)) {
1625
1659
  pendingSet.add(s2);
1626
1660
  pendingQueue.push(s2);
1627
1661
  }
1628
1662
  }
1663
+ node = node.sigNext;
1629
1664
  }
1630
1665
  }
1631
1666
  function notifySubscribers(signal2) {
1632
- const first = signal2.__f;
1633
- if (first) {
1634
- if (notifyDepth > 0) {
1635
- if (first._c) {
1636
- propagateDirty(first);
1637
- } else if (!pendingSet.has(first)) {
1638
- pendingSet.add(first);
1639
- pendingQueue.push(first);
1640
- }
1641
- return;
1642
- }
1643
- notifyDepth++;
1644
- drainEpoch++;
1645
- try {
1646
- if (first._c) {
1647
- propagateDirty(first);
1648
- } else if (tickRepeat(first)) {
1649
- cycleError(first);
1650
- } else {
1651
- safeInvoke(first);
1652
- }
1653
- drainQueue();
1654
- } finally {
1655
- notifyDepth--;
1656
- if (notifyDepth === 0) {
1657
- pendingQueue.length = 0;
1658
- pendingSet.clear();
1659
- }
1660
- }
1661
- return;
1662
- }
1663
- const subs = signal2[SUBS];
1664
- if (!subs || subs.size === 0) return;
1667
+ const sig = signal2;
1668
+ const head2 = sig.subsHead;
1669
+ if (!head2) return;
1665
1670
  if (notifyDepth > 0) {
1666
- for (const sub2 of subs) {
1667
- if (sub2._c) {
1668
- propagateDirty(sub2);
1669
- } else if (!pendingSet.has(sub2)) {
1670
- pendingSet.add(sub2);
1671
- pendingQueue.push(sub2);
1671
+ let node = head2;
1672
+ while (node) {
1673
+ const s2 = node.sub;
1674
+ if (s2) {
1675
+ if (s2._c) {
1676
+ propagateDirty(s2);
1677
+ } else if (!pendingSet.has(s2)) {
1678
+ pendingSet.add(s2);
1679
+ pendingQueue.push(s2);
1680
+ }
1672
1681
  }
1682
+ node = node.sigNext;
1673
1683
  }
1674
1684
  return;
1675
1685
  }
1676
1686
  notifyDepth++;
1677
1687
  drainEpoch++;
1678
1688
  try {
1679
- for (const sub2 of subs) {
1680
- if (sub2._c) {
1681
- propagateDirty(sub2);
1682
- } else if (!pendingSet.has(sub2)) {
1683
- pendingSet.add(sub2);
1684
- pendingQueue.push(sub2);
1689
+ let node = head2;
1690
+ while (node) {
1691
+ const s2 = node.sub;
1692
+ if (s2) {
1693
+ if (s2._c) {
1694
+ propagateDirty(s2);
1695
+ } else if (!pendingSet.has(s2)) {
1696
+ pendingSet.add(s2);
1697
+ pendingQueue.push(s2);
1698
+ }
1685
1699
  }
1700
+ node = node.sigNext;
1686
1701
  }
1687
1702
  drainQueue();
1688
1703
  } finally {
@@ -1693,30 +1708,6 @@ function notifySubscribers(signal2) {
1693
1708
  }
1694
1709
  }
1695
1710
  }
1696
- function cleanup(subscriber) {
1697
- const sub2 = subscriber;
1698
- const singleDep = sub2._dep;
1699
- if (singleDep !== void 0) {
1700
- const sig = singleDep;
1701
- const subs = sig[SUBS];
1702
- if (subs?.delete(subscriber)) {
1703
- syncFastPath(sig, subs);
1704
- }
1705
- sub2._dep = void 0;
1706
- sub2._depEpoch = void 0;
1707
- return;
1708
- }
1709
- const deps = sub2._deps;
1710
- if (!deps || deps.size === 0) return;
1711
- for (const signal2 of deps.keys()) {
1712
- const sig = signal2;
1713
- const subs = sig[SUBS];
1714
- if (subs?.delete(subscriber)) {
1715
- syncFastPath(sig, subs);
1716
- }
1717
- }
1718
- deps.clear();
1719
- }
1720
1711
 
1721
1712
  // src/reactivity/bindAttribute.ts
1722
1713
  var _isDev3 = isDev();
@@ -3356,32 +3347,64 @@ function flushBatch() {
3356
3347
  var _g = globalThis;
3357
3348
  var _isDev9 = isDev();
3358
3349
  function signal(initial, options) {
3359
- const state = { value: initial };
3350
+ const state = {
3351
+ value: initial,
3352
+ __v: 0,
3353
+ __sc: 0,
3354
+ subsHead: null,
3355
+ subsTail: null,
3356
+ __activeNode: null,
3357
+ __name: void 0
3358
+ };
3360
3359
  const debugName = _isDev9 ? options?.name : void 0;
3361
3360
  const equalsFn = options?.equals;
3362
- if (debugName) {
3363
- state.__name = debugName;
3364
- }
3361
+ if (debugName) state.__name = debugName;
3365
3362
  function get() {
3366
3363
  recordDependency(state);
3367
3364
  return state.value;
3368
3365
  }
3369
3366
  get.__signal = state;
3370
3367
  if (debugName) get.__name = debugName;
3371
- function set(next) {
3372
- const newValue = typeof next === "function" ? next(state.value) : next;
3373
- if (equalsFn ? equalsFn(state.value, newValue) : Object.is(newValue, state.value)) return;
3374
- if (_isDev9) {
3375
- const oldValue = state.value;
3368
+ let set;
3369
+ if (equalsFn) {
3370
+ set = (next) => {
3371
+ const prev = state.value;
3372
+ const newValue = typeof next === "function" ? next(prev) : next;
3373
+ if (equalsFn(prev, newValue)) return;
3374
+ state.value = newValue;
3375
+ state.__v++;
3376
+ if (_isDev9) {
3377
+ const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3378
+ if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
3379
+ }
3380
+ if (!enqueueBatchedSignal(state)) {
3381
+ notifySubscribers(state);
3382
+ }
3383
+ };
3384
+ } else if (_isDev9) {
3385
+ set = (next) => {
3386
+ const prev = state.value;
3387
+ const newValue = typeof next === "function" ? next(prev) : next;
3388
+ if (Object.is(newValue, prev)) return;
3376
3389
  state.value = newValue;
3390
+ state.__v++;
3377
3391
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3378
- if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
3379
- } else {
3392
+ if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
3393
+ if (!enqueueBatchedSignal(state)) {
3394
+ notifySubscribers(state);
3395
+ }
3396
+ };
3397
+ } else {
3398
+ set = (next) => {
3399
+ const prev = state.value;
3400
+ const newValue = typeof next === "function" ? next(prev) : next;
3401
+ if (Object.is(newValue, prev)) return;
3380
3402
  state.value = newValue;
3381
- }
3382
- if (!enqueueBatchedSignal(state)) {
3383
- notifySubscribers(state);
3384
- }
3403
+ state.__v++;
3404
+ if (!enqueueBatchedSignal(state)) {
3405
+ notifySubscribers(state);
3406
+ }
3407
+ };
3385
3408
  }
3386
3409
  if (_isDev9) {
3387
3410
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
@@ -3465,120 +3488,122 @@ function on(deps, handler) {
3465
3488
  }
3466
3489
  };
3467
3490
  }
3491
+ var MAX_RERUNS = 100;
3492
+ function flushUserCleanups(ctx) {
3493
+ const list = ctx.userCleanups;
3494
+ if (list.length === 0) return;
3495
+ ctx.userCleanups = [];
3496
+ for (let i2 = list.length - 1; i2 >= 0; i2--) {
3497
+ try {
3498
+ list[i2]();
3499
+ } catch (err) {
3500
+ if (typeof console !== "undefined") console.warn("[SibuJS effect] onCleanup threw:", err);
3501
+ }
3502
+ }
3503
+ }
3504
+ function drainReruns(ctx) {
3505
+ let reruns = 1;
3506
+ do {
3507
+ ctx.rerunPending = false;
3508
+ if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
3509
+ retrack(ctx.bodyFn, ctx.subscriber);
3510
+ } while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
3511
+ if (ctx.rerunPending) {
3512
+ ctx.rerunPending = false;
3513
+ if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
3514
+ console.error(
3515
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
3516
+ );
3517
+ }
3518
+ }
3519
+ }
3520
+ function disposeEffect(ctx) {
3521
+ if (ctx.disposed) return;
3522
+ ctx.disposed = true;
3523
+ const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3524
+ if (h) {
3525
+ try {
3526
+ h.emit("effect:destroy", { effectFn: ctx.fn });
3527
+ } catch {
3528
+ }
3529
+ }
3530
+ try {
3531
+ if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
3532
+ } catch (err) {
3533
+ if (typeof console !== "undefined") {
3534
+ console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
3535
+ }
3536
+ }
3537
+ try {
3538
+ cleanup(ctx.subscriber);
3539
+ } catch (err) {
3540
+ if (typeof console !== "undefined") {
3541
+ console.warn("[SibuJS effect] dispose threw:", err);
3542
+ }
3543
+ }
3544
+ }
3468
3545
  function effect(effectFn, options) {
3469
3546
  devAssert(typeof effectFn === "function", "effect: argument must be a function.");
3470
3547
  if (isSSR()) return () => {
3471
3548
  };
3472
- const onError = options?.onError;
3473
- let userCleanups = [];
3474
- const onCleanup2 = (fn) => {
3475
- userCleanups.push(fn);
3549
+ const ctx = {
3550
+ fn: effectFn,
3551
+ onError: options?.onError,
3552
+ userCleanups: [],
3553
+ running: false,
3554
+ rerunPending: false,
3555
+ disposed: false,
3556
+ onCleanup: null,
3557
+ subscriber: null,
3558
+ bodyFn: null
3476
3559
  };
3477
- const runUserCleanups = () => {
3478
- if (userCleanups.length === 0) return;
3479
- const list = userCleanups;
3480
- userCleanups = [];
3481
- for (let i2 = list.length - 1; i2 >= 0; i2--) {
3482
- try {
3483
- list[i2]();
3484
- } catch (err) {
3485
- if (typeof console !== "undefined") {
3486
- console.warn("[SibuJS effect] onCleanup threw:", err);
3487
- }
3488
- }
3489
- }
3560
+ ctx.onCleanup = (fn) => {
3561
+ ctx.userCleanups.push(fn);
3490
3562
  };
3491
- const invokeBody = () => effectFn(onCleanup2);
3492
- const wrappedFn = onError ? () => {
3563
+ const onErrorCaptured = ctx.onError;
3564
+ ctx.bodyFn = onErrorCaptured ? () => {
3493
3565
  try {
3494
- invokeBody();
3566
+ ctx.fn(ctx.onCleanup);
3495
3567
  } catch (err) {
3496
- onError(err);
3568
+ onErrorCaptured(err);
3497
3569
  }
3498
- } : invokeBody;
3499
- let cleanupHandle = () => {
3570
+ } : () => {
3571
+ ctx.fn(ctx.onCleanup);
3500
3572
  };
3501
- let running = false;
3502
- let rerunPending = false;
3503
- const MAX_RERUNS = 100;
3504
- const subscriber = () => {
3505
- if (running) {
3506
- rerunPending = true;
3573
+ const sub2 = (() => {
3574
+ if (ctx.running) {
3575
+ ctx.rerunPending = true;
3507
3576
  return;
3508
3577
  }
3509
- running = true;
3578
+ ctx.running = true;
3510
3579
  try {
3511
- let reruns = 0;
3512
- do {
3513
- rerunPending = false;
3514
- runUserCleanups();
3515
- cleanupHandle();
3516
- cleanupHandle = track(wrappedFn, subscriber);
3517
- if (++reruns > MAX_RERUNS) {
3518
- if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
3519
- console.error(
3520
- `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
3521
- );
3522
- }
3523
- rerunPending = false;
3524
- break;
3525
- }
3526
- } while (rerunPending);
3580
+ ctx.rerunPending = false;
3581
+ if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
3582
+ retrack(ctx.bodyFn, sub2);
3583
+ if (ctx.rerunPending) drainReruns(ctx);
3527
3584
  } finally {
3528
- running = false;
3529
- rerunPending = false;
3585
+ ctx.running = false;
3586
+ ctx.rerunPending = false;
3530
3587
  }
3531
- };
3532
- running = true;
3588
+ });
3589
+ sub2.depsHead = null;
3590
+ sub2.depsTail = null;
3591
+ sub2._epoch = 0;
3592
+ sub2._structDirty = false;
3593
+ sub2._runEpoch = 0;
3594
+ sub2._runs = 0;
3595
+ ctx.subscriber = sub2;
3596
+ ctx.running = true;
3533
3597
  try {
3534
- let reruns = 0;
3535
- do {
3536
- rerunPending = false;
3537
- runUserCleanups();
3538
- cleanupHandle();
3539
- cleanupHandle = track(wrappedFn, subscriber);
3540
- if (++reruns > MAX_RERUNS) {
3541
- if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
3542
- console.error(
3543
- `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
3544
- );
3545
- }
3546
- rerunPending = false;
3547
- break;
3548
- }
3549
- } while (rerunPending);
3598
+ retrack(ctx.bodyFn, ctx.subscriber);
3599
+ if (ctx.rerunPending) drainReruns(ctx);
3550
3600
  } finally {
3551
- running = false;
3552
- rerunPending = false;
3601
+ ctx.running = false;
3602
+ ctx.rerunPending = false;
3553
3603
  }
3554
3604
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3555
3605
  if (hook) hook.emit("effect:create", { effectFn });
3556
- let disposed = false;
3557
- return () => {
3558
- if (disposed) return;
3559
- disposed = true;
3560
- const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
3561
- if (h) {
3562
- try {
3563
- h.emit("effect:destroy", { effectFn });
3564
- } catch {
3565
- }
3566
- }
3567
- try {
3568
- runUserCleanups();
3569
- } catch (err) {
3570
- if (typeof console !== "undefined") {
3571
- console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
3572
- }
3573
- }
3574
- try {
3575
- cleanupHandle();
3576
- } catch (err) {
3577
- if (typeof console !== "undefined") {
3578
- console.warn("[SibuJS effect] dispose threw:", err);
3579
- }
3580
- }
3581
- };
3606
+ return () => disposeEffect(ctx);
3582
3607
  }
3583
3608
 
3584
3609
  // src/core/signals/derived.ts
@@ -3589,6 +3614,7 @@ function derived(getter, options) {
3589
3614
  const cs = {};
3590
3615
  cs._d = false;
3591
3616
  cs._g = getter;
3617
+ cs.__v = 0;
3592
3618
  const markDirty = () => {
3593
3619
  if (cs._d) return;
3594
3620
  cs._d = true;
@@ -3618,11 +3644,14 @@ function derived(getter, options) {
3618
3644
  evaluating = true;
3619
3645
  let threw = true;
3620
3646
  try {
3647
+ const prev = cs._v;
3621
3648
  retrack(() => {
3622
- cs._v = getter();
3649
+ const next = getter();
3650
+ cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
3623
3651
  cs._d = false;
3624
3652
  threw = false;
3625
3653
  }, markDirty);
3654
+ if (!Object.is(prev, cs._v)) cs.__v++;
3626
3655
  } finally {
3627
3656
  evaluating = false;
3628
3657
  if (threw) cs._d = true;
@@ -3642,6 +3671,7 @@ function derived(getter, options) {
3642
3671
  cs._d = false;
3643
3672
  threw = false;
3644
3673
  }, markDirty);
3674
+ if (!Object.is(oldValue, cs._v)) cs.__v++;
3645
3675
  } finally {
3646
3676
  evaluating = false;
3647
3677
  if (threw) cs._d = true;
@@ -5178,7 +5208,10 @@ function getMemoizedFallback(fallbackFn, error, retry) {
5178
5208
  }
5179
5209
  return factory();
5180
5210
  }
5181
- function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
5211
+ function ErrorBoundary(optionsOrChildren, maybeChildren) {
5212
+ const children = typeof optionsOrChildren === "function" ? optionsOrChildren : maybeChildren;
5213
+ const options = typeof optionsOrChildren === "function" ? {} : optionsOrChildren;
5214
+ const { fallback, onError, resetKeys } = options;
5182
5215
  injectStyles2();
5183
5216
  const [error, setError] = signal(null);
5184
5217
  const retry = () => {
@@ -5253,7 +5286,7 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
5253
5286
  return tryRenderFallback(currentError);
5254
5287
  }
5255
5288
  try {
5256
- const result = nodes();
5289
+ const result = children();
5257
5290
  if (result && typeof result.then === "function") {
5258
5291
  const asyncContainer = div({ class: "sibu-error-async" });
5259
5292
  asyncContainer.appendChild(span({ class: "sibu-lazy-loading", nodes: "Loading..." }));