sibujs 2.0.0 → 2.1.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 (60) hide show
  1. package/dist/browser.cjs +144 -102
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +183 -102
  4. package/dist/build.js +10 -10
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-MIUAXB7K.js → chunk-3DZP6OIT.js} +2 -2
  7. package/dist/{chunk-ITX6OO3F.js → chunk-45YP72ZQ.js} +1 -1
  8. package/dist/{chunk-ND2664SF.js → chunk-AMK2TYNW.js} +13 -9
  9. package/dist/{chunk-R73P76YZ.js → chunk-CWBVQML6.js} +1 -1
  10. package/dist/{chunk-54EDRCEF.js → chunk-DRUZZAK4.js} +1 -1
  11. package/dist/{chunk-3NSGB5JN.js → chunk-GWWURC5M.js} +2 -2
  12. package/dist/{chunk-SAHNHTFC.js → chunk-KGYT6UO6.js} +3 -3
  13. package/dist/{chunk-52YJLLRO.js → chunk-NASX6ST2.js} +1 -1
  14. package/dist/{chunk-O2MNQFLP.js → chunk-O6EFQ3KT.js} +5 -5
  15. package/dist/{chunk-GTBNNBJ6.js → chunk-OJ3P4ECI.js} +1 -1
  16. package/dist/{chunk-7JDB7I65.js → chunk-ON5MMR2J.js} +4 -4
  17. package/dist/{chunk-KLRMB5ZS.js → chunk-P2HSJDDN.js} +2 -2
  18. package/dist/{chunk-VLPPXTYG.js → chunk-QO3WC6FS.js} +145 -93
  19. package/dist/{chunk-CC65Y57T.js → chunk-RDTDJCAB.js} +1 -1
  20. package/dist/{chunk-JXMMDLBY.js → chunk-TH2ILCYW.js} +8 -4
  21. package/dist/{chunk-3LR7GLWQ.js → chunk-V6C4FADE.js} +3 -3
  22. package/dist/{chunk-WOMYAHHI.js → chunk-WANSMF2L.js} +4 -4
  23. package/dist/{chunk-DFPFITST.js → chunk-WIPZPFBQ.js} +1 -1
  24. package/dist/{chunk-HB24TBAF.js → chunk-WZA53FXU.js} +38 -10
  25. package/dist/{chunk-JA6667UN.js → chunk-ZAQSMOED.js} +4 -4
  26. package/dist/data.cjs +176 -102
  27. package/dist/data.js +6 -6
  28. package/dist/devtools.cjs +148 -91
  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 +176 -102
  33. package/dist/ecosystem.js +7 -7
  34. package/dist/extras.cjs +182 -104
  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 +185 -102
  39. package/dist/index.d.cts +15 -1
  40. package/dist/index.d.ts +15 -1
  41. package/dist/index.js +14 -10
  42. package/dist/{introspect-BWNjNw64.d.cts → introspect-2TOlQ7oa.d.cts} +3 -1
  43. package/dist/{introspect-cY2pg9pW.d.ts → introspect-DnIpHQQz.d.ts} +3 -1
  44. package/dist/motion.cjs +78 -62
  45. package/dist/motion.js +3 -3
  46. package/dist/patterns.cjs +176 -102
  47. package/dist/patterns.js +5 -5
  48. package/dist/performance.cjs +142 -89
  49. package/dist/performance.js +4 -4
  50. package/dist/plugins.cjs +142 -89
  51. package/dist/plugins.js +6 -6
  52. package/dist/ssr.cjs +144 -102
  53. package/dist/ssr.js +7 -7
  54. package/dist/testing.cjs +66 -28
  55. package/dist/testing.js +2 -2
  56. package/dist/ui.cjs +174 -89
  57. package/dist/ui.js +6 -6
  58. package/dist/widgets.cjs +176 -102
  59. package/dist/widgets.js +6 -6
  60. package/package.json +1 -1
package/dist/ssr.cjs CHANGED
@@ -682,11 +682,24 @@ function escapeAttr(str) {
682
682
 
683
683
  // src/reactivity/track.ts
684
684
  var _isDev3 = isDev();
685
- var subscriberStack = new Array(32);
686
- var stackCapacity = 32;
685
+ var STACK_INITIAL = 32;
686
+ var STACK_SHRINK_THRESHOLD = 128;
687
+ var subscriberStack = new Array(STACK_INITIAL);
688
+ var stackCapacity = STACK_INITIAL;
687
689
  var stackTop = -1;
688
690
  var currentSubscriber = null;
689
691
  var SUBS = "__s";
692
+ function syncFastPath(signal2, subs) {
693
+ const size = subs.size;
694
+ if (size === 0) {
695
+ signal2.__f = void 0;
696
+ delete signal2[SUBS];
697
+ } else if (size === 1) {
698
+ signal2.__f = subs.values().next().value;
699
+ } else {
700
+ signal2.__f = void 0;
701
+ }
702
+ }
690
703
  var notifyDepth = 0;
691
704
  var pendingQueue = [];
692
705
  var pendingSet = /* @__PURE__ */ new Set();
@@ -713,36 +726,49 @@ function track(effectFn, subscriber) {
713
726
  } finally {
714
727
  stackTop--;
715
728
  currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
729
+ if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
730
+ stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
731
+ subscriberStack.length = stackCapacity;
732
+ }
716
733
  }
717
734
  return () => cleanup(subscriber);
718
735
  }
719
736
  function recordDependency(signal2) {
720
737
  if (!currentSubscriber) return;
721
738
  const sub2 = currentSubscriber;
722
- if (sub2._dep === signal2) return;
739
+ const epoch = sub2._epoch;
740
+ if (sub2._dep === signal2) {
741
+ sub2._depEpoch = epoch;
742
+ return;
743
+ }
723
744
  const deps = sub2._deps;
724
745
  if (deps) {
725
- if (deps.has(signal2)) return;
726
- deps.add(signal2);
746
+ deps.set(signal2, epoch);
727
747
  } else if (sub2._dep !== void 0) {
728
- const set = /* @__PURE__ */ new Set();
729
- set.add(sub2._dep);
730
- set.add(signal2);
731
- sub2._deps = set;
748
+ const map2 = /* @__PURE__ */ new Map();
749
+ map2.set(sub2._dep, sub2._depEpoch);
750
+ map2.set(signal2, epoch);
751
+ sub2._deps = map2;
732
752
  sub2._dep = void 0;
753
+ sub2._depEpoch = void 0;
733
754
  } else {
734
755
  sub2._dep = signal2;
756
+ sub2._depEpoch = epoch;
735
757
  }
736
- let subs = signal2[SUBS];
758
+ const sig = signal2;
759
+ let subs = sig[SUBS];
737
760
  if (!subs) {
738
761
  subs = /* @__PURE__ */ new Set();
739
- signal2[SUBS] = subs;
762
+ sig[SUBS] = subs;
740
763
  }
764
+ const prevSize = subs.size;
741
765
  subs.add(currentSubscriber);
742
- if (subs.size === 1) {
743
- signal2.__f = currentSubscriber;
744
- } else if (signal2.__f !== void 0) {
745
- signal2.__f = void 0;
766
+ if (subs.size !== prevSize) {
767
+ if (subs.size === 1) {
768
+ sig.__f = currentSubscriber;
769
+ } else if (sig.__f !== void 0) {
770
+ sig.__f = void 0;
771
+ }
746
772
  }
747
773
  }
748
774
  function queueSignalNotification(signal2) {
@@ -757,24 +783,55 @@ function queueSignalNotification(signal2) {
757
783
  }
758
784
  }
759
785
  }
760
- var maxDrainIterations = 1e5;
786
+ var maxSubscriberRepeats = 50;
787
+ var maxDrainIterations = 1e6;
788
+ var drainEpoch = 0;
789
+ function tickRepeat(sub2) {
790
+ const s2 = sub2;
791
+ if (s2._runEpoch !== drainEpoch) {
792
+ s2._runEpoch = drainEpoch;
793
+ s2._runs = 1;
794
+ return false;
795
+ }
796
+ return ++s2._runs > maxSubscriberRepeats;
797
+ }
798
+ function cycleError(sub2) {
799
+ if (typeof console !== "undefined") {
800
+ const name = sub2.__name ?? "<unnamed>";
801
+ console.error(
802
+ `[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
803
+ );
804
+ }
805
+ }
806
+ function absoluteDrainError() {
807
+ if (typeof console !== "undefined") {
808
+ console.error(
809
+ `[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
810
+ );
811
+ }
812
+ }
813
+ function drainQueue() {
814
+ let i2 = 0;
815
+ while (i2 < pendingQueue.length) {
816
+ if (i2 >= maxDrainIterations) {
817
+ absoluteDrainError();
818
+ break;
819
+ }
820
+ const sub2 = pendingQueue[i2++];
821
+ if (tickRepeat(sub2)) {
822
+ cycleError(sub2);
823
+ break;
824
+ }
825
+ pendingSet.delete(sub2);
826
+ safeInvoke(sub2);
827
+ }
828
+ }
761
829
  function drainNotificationQueue() {
762
830
  if (notifyDepth > 0) return;
763
831
  notifyDepth++;
832
+ drainEpoch++;
764
833
  try {
765
- let i2 = 0;
766
- while (i2 < pendingQueue.length) {
767
- if (i2 >= maxDrainIterations) {
768
- if (typeof console !== "undefined") {
769
- console.error(
770
- `[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
771
- );
772
- }
773
- break;
774
- }
775
- safeInvoke(pendingQueue[i2]);
776
- i2++;
777
- }
834
+ drainQueue();
778
835
  } finally {
779
836
  notifyDepth--;
780
837
  if (notifyDepth === 0) {
@@ -837,25 +894,16 @@ function notifySubscribers(signal2) {
837
894
  return;
838
895
  }
839
896
  notifyDepth++;
897
+ drainEpoch++;
840
898
  try {
841
899
  if (first._c) {
842
900
  propagateDirty(first);
901
+ } else if (tickRepeat(first)) {
902
+ cycleError(first);
843
903
  } else {
844
904
  safeInvoke(first);
845
905
  }
846
- let i2 = 0;
847
- while (i2 < pendingQueue.length) {
848
- if (i2 >= maxDrainIterations) {
849
- if (typeof console !== "undefined") {
850
- console.error(
851
- `[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
852
- );
853
- }
854
- break;
855
- }
856
- safeInvoke(pendingQueue[i2]);
857
- i2++;
858
- }
906
+ drainQueue();
859
907
  } finally {
860
908
  notifyDepth--;
861
909
  if (notifyDepth === 0) {
@@ -879,44 +927,17 @@ function notifySubscribers(signal2) {
879
927
  return;
880
928
  }
881
929
  notifyDepth++;
930
+ drainEpoch++;
882
931
  try {
883
- let directCount = 0;
884
- let hasComputedSub = false;
885
932
  for (const sub2 of subs) {
886
- if (sub2._c) hasComputedSub = true;
887
- pendingQueue[directCount++] = sub2;
888
- }
889
- if (!hasComputedSub) {
890
- for (let i3 = 0; i3 < directCount; i3++) {
891
- safeInvoke(pendingQueue[i3]);
892
- }
893
- } else {
894
- for (let i3 = 0; i3 < directCount; i3++) {
895
- if (pendingQueue[i3]._c) {
896
- propagateDirty(pendingQueue[i3]);
897
- }
898
- }
899
- for (let i3 = 0; i3 < directCount; i3++) {
900
- const sub2 = pendingQueue[i3];
901
- if (!sub2._c && !pendingSet.has(sub2)) {
902
- pendingSet.add(sub2);
903
- safeInvoke(sub2);
904
- }
905
- }
906
- }
907
- let i2 = directCount;
908
- while (i2 < pendingQueue.length) {
909
- if (i2 - directCount >= maxDrainIterations) {
910
- if (typeof console !== "undefined") {
911
- console.error(
912
- `[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
913
- );
914
- }
915
- break;
933
+ if (sub2._c) {
934
+ propagateDirty(sub2);
935
+ } else if (!pendingSet.has(sub2)) {
936
+ pendingSet.add(sub2);
937
+ pendingQueue.push(sub2);
916
938
  }
917
- safeInvoke(pendingQueue[i2]);
918
- i2++;
919
939
  }
940
+ drainQueue();
920
941
  } finally {
921
942
  notifyDepth--;
922
943
  if (notifyDepth === 0) {
@@ -929,29 +950,22 @@ function cleanup(subscriber) {
929
950
  const sub2 = subscriber;
930
951
  const singleDep = sub2._dep;
931
952
  if (singleDep !== void 0) {
932
- const subs = singleDep[SUBS];
933
- if (subs) {
934
- subs.delete(subscriber);
935
- if (singleDep.__f === subscriber) {
936
- singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
937
- } else if (subs.size === 1 && singleDep.__f === void 0) {
938
- singleDep.__f = subs.values().next().value;
939
- }
953
+ const sig = singleDep;
954
+ const subs = sig[SUBS];
955
+ if (subs?.delete(subscriber)) {
956
+ syncFastPath(sig, subs);
940
957
  }
941
958
  sub2._dep = void 0;
959
+ sub2._depEpoch = void 0;
942
960
  return;
943
961
  }
944
962
  const deps = sub2._deps;
945
963
  if (!deps || deps.size === 0) return;
946
- for (const signal2 of deps) {
947
- const subs = signal2[SUBS];
948
- if (subs) {
949
- subs.delete(subscriber);
950
- if (signal2.__f === subscriber) {
951
- signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
952
- } else if (subs.size === 1 && signal2.__f === void 0) {
953
- signal2.__f = subs.values().next().value;
954
- }
964
+ for (const signal2 of deps.keys()) {
965
+ const sig = signal2;
966
+ const subs = sig[SUBS];
967
+ if (subs?.delete(subscriber)) {
968
+ syncFastPath(sig, subs);
955
969
  }
956
970
  }
957
971
  deps.clear();
@@ -993,29 +1007,57 @@ function effect(effectFn, options) {
993
1007
  let cleanupHandle = () => {
994
1008
  };
995
1009
  let running = false;
1010
+ let rerunPending = false;
1011
+ const MAX_RERUNS = 100;
996
1012
  const subscriber = () => {
997
1013
  if (running) {
998
- if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
999
- console.warn(
1000
- "[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
1001
- );
1002
- }
1014
+ rerunPending = true;
1003
1015
  return;
1004
1016
  }
1005
1017
  running = true;
1006
1018
  try {
1007
- runUserCleanups();
1008
- cleanupHandle();
1009
- cleanupHandle = track(wrappedFn, subscriber);
1019
+ let reruns = 0;
1020
+ do {
1021
+ rerunPending = false;
1022
+ runUserCleanups();
1023
+ cleanupHandle();
1024
+ cleanupHandle = track(wrappedFn, subscriber);
1025
+ if (++reruns > MAX_RERUNS) {
1026
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1027
+ console.error(
1028
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1029
+ );
1030
+ }
1031
+ rerunPending = false;
1032
+ break;
1033
+ }
1034
+ } while (rerunPending);
1010
1035
  } finally {
1011
1036
  running = false;
1037
+ rerunPending = false;
1012
1038
  }
1013
1039
  };
1014
1040
  running = true;
1015
1041
  try {
1016
- cleanupHandle = track(wrappedFn, subscriber);
1042
+ let reruns = 0;
1043
+ do {
1044
+ rerunPending = false;
1045
+ runUserCleanups();
1046
+ cleanupHandle();
1047
+ cleanupHandle = track(wrappedFn, subscriber);
1048
+ if (++reruns > MAX_RERUNS) {
1049
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1050
+ console.error(
1051
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1052
+ );
1053
+ }
1054
+ rerunPending = false;
1055
+ break;
1056
+ }
1057
+ } while (rerunPending);
1017
1058
  } finally {
1018
1059
  running = false;
1060
+ rerunPending = false;
1019
1061
  }
1020
1062
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1021
1063
  if (hook) hook.emit("effect:create", { effectFn });
package/dist/ssr.js CHANGED
@@ -22,8 +22,8 @@ import {
22
22
  wasm,
23
23
  worker,
24
24
  workerFn
25
- } from "./chunk-SAHNHTFC.js";
26
- import "./chunk-R73P76YZ.js";
25
+ } from "./chunk-KGYT6UO6.js";
26
+ import "./chunk-CWBVQML6.js";
27
27
  import {
28
28
  collectStream,
29
29
  deserializeState,
@@ -43,14 +43,14 @@ import {
43
43
  suspenseSwapScript,
44
44
  trustHTML
45
45
  } from "./chunk-JYD2PWXH.js";
46
- import "./chunk-KLRMB5ZS.js";
47
- import "./chunk-DFPFITST.js";
46
+ import "./chunk-P2HSJDDN.js";
47
+ import "./chunk-WIPZPFBQ.js";
48
48
  import "./chunk-2UPRY23K.js";
49
49
  import "./chunk-UCS6AMJ7.js";
50
- import "./chunk-HB24TBAF.js";
50
+ import "./chunk-WZA53FXU.js";
51
51
  import "./chunk-2RA7SHDA.js";
52
- import "./chunk-CC65Y57T.js";
53
- import "./chunk-VLPPXTYG.js";
52
+ import "./chunk-RDTDJCAB.js";
53
+ import "./chunk-QO3WC6FS.js";
54
54
  import "./chunk-LMLD24FC.js";
55
55
  export {
56
56
  Head,
package/dist/testing.cjs CHANGED
@@ -1549,11 +1549,24 @@ function testComponent(component, options = {}) {
1549
1549
 
1550
1550
  // src/reactivity/track.ts
1551
1551
  var _isDev3 = isDev();
1552
- var subscriberStack = new Array(32);
1553
- var stackCapacity = 32;
1552
+ var STACK_INITIAL = 32;
1553
+ var STACK_SHRINK_THRESHOLD = 128;
1554
+ var subscriberStack = new Array(STACK_INITIAL);
1555
+ var stackCapacity = STACK_INITIAL;
1554
1556
  var stackTop = -1;
1555
1557
  var currentSubscriber = null;
1556
1558
  var SUBS = "__s";
1559
+ function syncFastPath(signal, subs) {
1560
+ const size = subs.size;
1561
+ if (size === 0) {
1562
+ signal.__f = void 0;
1563
+ delete signal[SUBS];
1564
+ } else if (size === 1) {
1565
+ signal.__f = subs.values().next().value;
1566
+ } else {
1567
+ signal.__f = void 0;
1568
+ }
1569
+ }
1557
1570
  function track(effectFn, subscriber) {
1558
1571
  if (!subscriber) subscriber = effectFn;
1559
1572
  cleanup(subscriber);
@@ -1569,6 +1582,10 @@ function track(effectFn, subscriber) {
1569
1582
  } finally {
1570
1583
  stackTop--;
1571
1584
  currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
1585
+ if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
1586
+ stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
1587
+ subscriberStack.length = stackCapacity;
1588
+ }
1572
1589
  }
1573
1590
  return () => cleanup(subscriber);
1574
1591
  }
@@ -1576,29 +1593,22 @@ function cleanup(subscriber) {
1576
1593
  const sub = subscriber;
1577
1594
  const singleDep = sub._dep;
1578
1595
  if (singleDep !== void 0) {
1579
- const subs = singleDep[SUBS];
1580
- if (subs) {
1581
- subs.delete(subscriber);
1582
- if (singleDep.__f === subscriber) {
1583
- singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
1584
- } else if (subs.size === 1 && singleDep.__f === void 0) {
1585
- singleDep.__f = subs.values().next().value;
1586
- }
1596
+ const sig = singleDep;
1597
+ const subs = sig[SUBS];
1598
+ if (subs?.delete(subscriber)) {
1599
+ syncFastPath(sig, subs);
1587
1600
  }
1588
1601
  sub._dep = void 0;
1602
+ sub._depEpoch = void 0;
1589
1603
  return;
1590
1604
  }
1591
1605
  const deps = sub._deps;
1592
1606
  if (!deps || deps.size === 0) return;
1593
- for (const signal of deps) {
1594
- const subs = signal[SUBS];
1595
- if (subs) {
1596
- subs.delete(subscriber);
1597
- if (signal.__f === subscriber) {
1598
- signal.__f = subs.size === 1 ? subs.values().next().value : void 0;
1599
- } else if (subs.size === 1 && signal.__f === void 0) {
1600
- signal.__f = subs.values().next().value;
1601
- }
1607
+ for (const signal of deps.keys()) {
1608
+ const sig = signal;
1609
+ const subs = sig[SUBS];
1610
+ if (subs?.delete(subscriber)) {
1611
+ syncFastPath(sig, subs);
1602
1612
  }
1603
1613
  }
1604
1614
  deps.clear();
@@ -1665,29 +1675,57 @@ function effect(effectFn, options) {
1665
1675
  let cleanupHandle = () => {
1666
1676
  };
1667
1677
  let running = false;
1678
+ let rerunPending = false;
1679
+ const MAX_RERUNS = 100;
1668
1680
  const subscriber = () => {
1669
1681
  if (running) {
1670
- if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1671
- console.warn(
1672
- "[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
1673
- );
1674
- }
1682
+ rerunPending = true;
1675
1683
  return;
1676
1684
  }
1677
1685
  running = true;
1678
1686
  try {
1679
- runUserCleanups();
1680
- cleanupHandle();
1681
- cleanupHandle = track(wrappedFn, subscriber);
1687
+ let reruns = 0;
1688
+ do {
1689
+ rerunPending = false;
1690
+ runUserCleanups();
1691
+ cleanupHandle();
1692
+ cleanupHandle = track(wrappedFn, subscriber);
1693
+ if (++reruns > MAX_RERUNS) {
1694
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1695
+ console.error(
1696
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1697
+ );
1698
+ }
1699
+ rerunPending = false;
1700
+ break;
1701
+ }
1702
+ } while (rerunPending);
1682
1703
  } finally {
1683
1704
  running = false;
1705
+ rerunPending = false;
1684
1706
  }
1685
1707
  };
1686
1708
  running = true;
1687
1709
  try {
1688
- cleanupHandle = track(wrappedFn, subscriber);
1710
+ let reruns = 0;
1711
+ do {
1712
+ rerunPending = false;
1713
+ runUserCleanups();
1714
+ cleanupHandle();
1715
+ cleanupHandle = track(wrappedFn, subscriber);
1716
+ if (++reruns > MAX_RERUNS) {
1717
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1718
+ console.error(
1719
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1720
+ );
1721
+ }
1722
+ rerunPending = false;
1723
+ break;
1724
+ }
1725
+ } while (rerunPending);
1689
1726
  } finally {
1690
1727
  running = false;
1728
+ rerunPending = false;
1691
1729
  }
1692
1730
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1693
1731
  if (hook) hook.emit("effect:create", { effectFn });
package/dist/testing.js CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  } from "./chunk-2UPRY23K.js";
4
4
  import {
5
5
  effect
6
- } from "./chunk-HB24TBAF.js";
6
+ } from "./chunk-WZA53FXU.js";
7
7
  import "./chunk-2RA7SHDA.js";
8
- import "./chunk-VLPPXTYG.js";
8
+ import "./chunk-QO3WC6FS.js";
9
9
  import "./chunk-LMLD24FC.js";
10
10
 
11
11
  // src/testing/a11y.ts