@but212/atom-effect 0.2.2 → 0.3.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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const C = {
1
+ const R = {
2
2
  IDLE: "idle",
3
3
  PENDING: "pending",
4
4
  RESOLVED: "resolved",
@@ -23,22 +23,32 @@ const C = {
23
23
  // 100000 - Currently recomputing
24
24
  HAS_ERROR: 64
25
25
  // 1000000 - Has error state
26
- }, X = {
26
+ }, W = {
27
27
  /** Maximum number of pooled objects to prevent memory bloat */
28
28
  MAX_SIZE: 1e3,
29
29
  /** Number of objects to pre-allocate for performance-critical paths */
30
30
  WARMUP_SIZE: 100
31
- }, L = {
32
- /** Maximum effect executions per second to detect infinite loops */
31
+ }, N = {
32
+ /** Maximum effect executions per second to detect infinite loops (Legacy/Fallback) */
33
33
  MAX_EXECUTIONS_PER_SECOND: 100,
34
34
  /** Threshold for cleaning up old execution timestamps */
35
- CLEANUP_THRESHOLD: 100
36
- }, x = {
35
+ CLEANUP_THRESHOLD: 100,
36
+ /**
37
+ * Maximum executions per effect within a single flush cycle
38
+ * Increased from 10 to 50 based on evaluation report
39
+ */
40
+ MAX_EXECUTIONS_PER_EFFECT: 50,
41
+ /**
42
+ * Maximum total executions across all effects in a single flush cycle
43
+ * Increased from 1000 to 5000 based on evaluation report
44
+ */
45
+ MAX_EXECUTIONS_PER_FLUSH: 5e3
46
+ }, M = {
37
47
  /** Maximum dependencies before warning about large dependency graphs */
38
48
  MAX_DEPENDENCIES: 1e3,
39
49
  /** Enable infinite loop detection warnings */
40
50
  WARN_INFINITE_LOOP: !0
41
- }, I = 1073741823;
51
+ }, I = 1073741823, U = typeof process < "u" && process.env && process.env.NODE_ENV !== "production";
42
52
  class _ extends Error {
43
53
  /**
44
54
  * Creates a new AtomError
@@ -60,7 +70,7 @@ class b extends _ {
60
70
  super(e, t, !0), this.name = "ComputedError";
61
71
  }
62
72
  }
63
- class p extends _ {
73
+ class E extends _ {
64
74
  /**
65
75
  * Creates a new EffectError
66
76
  * @param message - Error message
@@ -80,7 +90,7 @@ class y extends _ {
80
90
  super(e, t, !1), this.name = "SchedulerError";
81
91
  }
82
92
  }
83
- function g(i, e, t) {
93
+ function D(i, e, t) {
84
94
  if (i instanceof TypeError)
85
95
  return new e(`Type error (${t}): ${i.message}`, i);
86
96
  if (i instanceof ReferenceError)
@@ -90,10 +100,10 @@ function g(i, e, t) {
90
100
  const s = i instanceof Error ? i.message : String(i), n = i instanceof Error ? i : null;
91
101
  return new e(`Unexpected error (${t}): ${s}`, n);
92
102
  }
93
- function P(i) {
103
+ function k(i) {
94
104
  return i != null && typeof i.then == "function";
95
105
  }
96
- const o = {
106
+ const h = {
97
107
  // ─────────────────────────────────────────────────────────────────
98
108
  // Computed errors
99
109
  // ─────────────────────────────────────────────────────────────────
@@ -178,7 +188,23 @@ const o = {
178
188
  */
179
189
  CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
180
190
  };
181
- class v {
191
+ let A = 0;
192
+ function q() {
193
+ return A = (A + 1 | 0) & I, A;
194
+ }
195
+ let C = 0, P = 0, T = !1;
196
+ function w() {
197
+ return T ? (U && console.warn(
198
+ "Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"
199
+ ), !1) : (T = !0, C = C + 1 & I, P = 0, !0);
200
+ }
201
+ function v() {
202
+ T = !1;
203
+ }
204
+ function V() {
205
+ return T ? ++P : 0;
206
+ }
207
+ class X {
182
208
  constructor() {
183
209
  this.queueA = [], this.queueB = [], this.queue = this.queueA, this.queueSize = 0, this._epoch = 0, this.isProcessing = !1, this.isBatching = !1, this.batchDepth = 0, this.batchQueue = [], this.batchQueueSize = 0, this.isFlushingSync = !1, this.maxFlushIterations = 1e3;
184
210
  }
@@ -228,15 +254,16 @@ class v {
228
254
  this.isProcessing = !0;
229
255
  const e = this.queue, t = this.queueSize;
230
256
  this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++, queueMicrotask(() => {
231
- for (let s = 0; s < t; s++)
257
+ const s = w();
258
+ for (let n = 0; n < t; n++)
232
259
  try {
233
- e[s]?.();
234
- } catch (n) {
260
+ e[n]?.();
261
+ } catch (r) {
235
262
  console.error(
236
- new y("Error occurred during scheduler execution", n)
263
+ new y("Error occurred during scheduler execution", r)
237
264
  );
238
265
  }
239
- e.length = 0, this.isProcessing = !1, this.queueSize > 0 && !this.isBatching && this.flush();
266
+ e.length = 0, this.isProcessing = !1, s && v(), this.queueSize > 0 && !this.isBatching && this.flush();
240
267
  });
241
268
  }
242
269
  /**
@@ -254,17 +281,18 @@ class v {
254
281
  */
255
282
  flushSync() {
256
283
  this.isFlushingSync = !0;
284
+ const e = w();
257
285
  try {
258
286
  if (this._epoch++, this.batchQueueSize > 0) {
259
- for (let t = 0; t < this.batchQueueSize; t++) {
260
- const s = this.batchQueue[t];
261
- s._nextEpoch !== this._epoch && (s._nextEpoch = this._epoch, this.queue[this.queueSize++] = s);
287
+ for (let s = 0; s < this.batchQueueSize; s++) {
288
+ const n = this.batchQueue[s];
289
+ n._nextEpoch !== this._epoch && (n._nextEpoch = this._epoch, this.queue[this.queueSize++] = n);
262
290
  }
263
291
  this.batchQueueSize = 0;
264
292
  }
265
- let e = 0;
293
+ let t = 0;
266
294
  for (; this.queueSize > 0; ) {
267
- if (++e > this.maxFlushIterations) {
295
+ if (++t > this.maxFlushIterations) {
268
296
  console.error(
269
297
  new y(
270
298
  `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`
@@ -272,24 +300,24 @@ class v {
272
300
  ), this.queueSize = 0, this.queue.length = 0, this.batchQueueSize = 0;
273
301
  break;
274
302
  }
275
- const t = this.queue, s = this.queueSize;
303
+ const s = this.queue, n = this.queueSize;
276
304
  this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++;
277
- for (let n = 0; n < s; n++)
305
+ for (let r = 0; r < n; r++)
278
306
  try {
279
- t[n]?.();
280
- } catch (r) {
307
+ s[r]?.();
308
+ } catch (u) {
281
309
  console.error(
282
- new y("Error occurred during batch execution", r)
310
+ new y("Error occurred during batch execution", u)
283
311
  );
284
312
  }
285
- if (t.length = 0, this.batchQueueSize > 0) {
286
- for (let n = 0; n < this.batchQueueSize; n++)
287
- this.queue[this.queueSize++] = this.batchQueue[n];
313
+ if (s.length = 0, this.batchQueueSize > 0) {
314
+ for (let r = 0; r < this.batchQueueSize; r++)
315
+ this.queue[this.queueSize++] = this.batchQueue[r];
288
316
  this.batchQueueSize = 0;
289
317
  }
290
318
  }
291
319
  } finally {
292
- this.isFlushingSync = !1;
320
+ this.isFlushingSync = !1, e && v();
293
321
  }
294
322
  }
295
323
  /**
@@ -357,17 +385,17 @@ class v {
357
385
  this.maxFlushIterations = e;
358
386
  }
359
387
  }
360
- const D = new v();
361
- function Y(i) {
388
+ const g = new X();
389
+ function K(i) {
362
390
  if (typeof i != "function")
363
391
  throw new _("Batch callback must be a function");
364
- D.startBatch();
392
+ g.startBatch();
365
393
  try {
366
394
  return i();
367
395
  } catch (e) {
368
396
  throw new _("Error occurred during batch execution", e);
369
397
  } finally {
370
- D.endBatch();
398
+ g.endBatch();
371
399
  }
372
400
  }
373
401
  const S = {
@@ -391,7 +419,7 @@ const S = {
391
419
  return this.current;
392
420
  }
393
421
  };
394
- function Q(i) {
422
+ function Z(i) {
395
423
  if (typeof i != "function")
396
424
  throw new _("Untracked callback must be a function");
397
425
  const e = S.current;
@@ -404,11 +432,11 @@ function Q(i) {
404
432
  S.current = e;
405
433
  }
406
434
  }
407
- const T = /* @__PURE__ */ Symbol("debugName"), B = /* @__PURE__ */ Symbol("id"), A = /* @__PURE__ */ Symbol("type"), U = /* @__PURE__ */ Symbol("noDefaultValue");
408
- function q(i) {
435
+ const O = /* @__PURE__ */ Symbol("debugName"), j = /* @__PURE__ */ Symbol("id"), x = /* @__PURE__ */ Symbol("type"), B = /* @__PURE__ */ Symbol("noDefaultValue");
436
+ function G(i) {
409
437
  return i !== null && typeof i == "object" && "dependencies" in i && i.dependencies instanceof Set;
410
438
  }
411
- const a = {
439
+ const f = {
412
440
  /**
413
441
  * Whether debug mode is enabled.
414
442
  *
@@ -422,13 +450,13 @@ const a = {
422
450
  *
423
451
  * @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}
424
452
  */
425
- maxDependencies: x.MAX_DEPENDENCIES,
453
+ maxDependencies: M.MAX_DEPENDENCIES,
426
454
  /**
427
455
  * Whether to warn about potential infinite loops.
428
456
  *
429
457
  * @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}
430
458
  */
431
- warnInfiniteLoop: x.WARN_INFINITE_LOOP,
459
+ warnInfiniteLoop: M.WARN_INFINITE_LOOP,
432
460
  /**
433
461
  * Logs a warning message when condition is true and debug is enabled.
434
462
  *
@@ -477,7 +505,7 @@ const a = {
477
505
  if (this.enabled) {
478
506
  if (t.has(i))
479
507
  throw new b("Indirect circular dependency detected");
480
- if (t.add(i), q(i))
508
+ if (t.add(i), G(i))
481
509
  for (const s of i.dependencies)
482
510
  this.checkCircular(s, e, t);
483
511
  }
@@ -506,7 +534,7 @@ const a = {
506
534
  if (!this.enabled)
507
535
  return;
508
536
  const s = i;
509
- s[T] = `${e}_${t}`, s[B] = t, s[A] = e;
537
+ s[O] = `${e}_${t}`, s[j] = t, s[x] = e;
510
538
  },
511
539
  /**
512
540
  * Retrieves the debug display name from a reactive object.
@@ -521,8 +549,8 @@ const a = {
521
549
  * ```
522
550
  */
523
551
  getDebugName(i) {
524
- if (i !== null && typeof i == "object" && T in i)
525
- return i[T];
552
+ if (i !== null && typeof i == "object" && O in i)
553
+ return i[O];
526
554
  },
527
555
  /**
528
556
  * Retrieves the debug type from a reactive object.
@@ -539,13 +567,13 @@ const a = {
539
567
  * ```
540
568
  */
541
569
  getDebugType(i) {
542
- if (i !== null && typeof i == "object" && A in i)
543
- return i[A];
570
+ if (i !== null && typeof i == "object" && x in i)
571
+ return i[x];
544
572
  }
545
573
  };
546
- let k = 1;
547
- const F = () => k++;
548
- class N {
574
+ let $ = 1;
575
+ const L = () => $++;
576
+ class F {
549
577
  constructor() {
550
578
  this.subscribers = null;
551
579
  }
@@ -678,7 +706,7 @@ class N {
678
706
  return this.subscribers ? [...this.subscribers] : [];
679
707
  }
680
708
  }
681
- class z {
709
+ class Y {
682
710
  /**
683
711
  * Creates a new AtomImpl instance.
684
712
  *
@@ -686,7 +714,7 @@ class z {
686
714
  * @param sync - Whether to notify subscribers synchronously
687
715
  */
688
716
  constructor(e, t) {
689
- this._isNotificationScheduled = !1, this.id = F() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = e, this._functionSubscribers = new N(), this._objectSubscribers = new N(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), a.attachDebugInfo(this, "atom", this.id);
717
+ this._isNotificationScheduled = !1, this.id = L() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = e, this._functionSubscribers = new F(), this._objectSubscribers = new F(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), f.attachDebugInfo(this, "atom", this.id);
690
718
  }
691
719
  /**
692
720
  * Gets the current value and registers the atom as a dependency
@@ -755,7 +783,7 @@ class z {
755
783
  * but don't schedule a new task. The pending task will see the latest value.
756
784
  */
757
785
  _notify(e, t, s) {
758
- this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !D.isBatching ? this._flushNotifications() : D.schedule(this._notifyTask);
786
+ this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !g.isBatching ? this._flushNotifications() : g.schedule(this._notifyTask);
759
787
  }
760
788
  /**
761
789
  * Executes the pending notifications.
@@ -766,10 +794,10 @@ class z {
766
794
  const e = this._pendingOldValue, t = this._value;
767
795
  this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._functionSubscribers.forEachSafe(
768
796
  (s) => s(t, e),
769
- (s) => console.error(new _(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
797
+ (s) => console.error(new _(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
770
798
  ), this._objectSubscribers.forEachSafe(
771
799
  (s) => s.execute(),
772
- (s) => console.error(new _(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
800
+ (s) => console.error(new _(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
773
801
  );
774
802
  }
775
803
  /**
@@ -789,7 +817,7 @@ class z {
789
817
  */
790
818
  subscribe(e) {
791
819
  if (typeof e != "function")
792
- throw new _(o.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
820
+ throw new _(h.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
793
821
  return this._functionSubscribers.add(e);
794
822
  }
795
823
  /**
@@ -823,44 +851,40 @@ class z {
823
851
  return this._functionSubscribers.size + this._objectSubscribers.size;
824
852
  }
825
853
  }
826
- function $(i, e = {}) {
827
- return new z(i, e.sync ?? !1);
828
- }
829
- let O = 0;
830
- function M() {
831
- return O = (O + 1 | 0) & I, O;
854
+ function ee(i, e = {}) {
855
+ return new Y(i, e.sync ?? !1);
832
856
  }
833
- const f = process.env.NODE_ENV !== "production", l = Object.freeze([]);
834
- class V {
857
+ const d = process.env.NODE_ENV !== "production", l = Object.freeze([]);
858
+ class Q {
835
859
  constructor() {
836
- this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = f ? {
860
+ this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = d ? {
837
861
  acquired: 0,
838
862
  released: 0,
839
863
  rejected: { frozen: 0, tooLarge: 0, poolFull: 0 }
840
864
  } : null;
841
865
  }
842
866
  acquire() {
843
- return f && this.stats && this.stats.acquired++, this.pool.pop() ?? [];
867
+ return d && this.stats && this.stats.acquired++, this.pool.pop() ?? [];
844
868
  }
845
869
  release(e, t) {
846
870
  if (!(t && e === t)) {
847
871
  if (Object.isFrozen(e)) {
848
- f && this.stats && this.stats.rejected.frozen++;
872
+ d && this.stats && this.stats.rejected.frozen++;
849
873
  return;
850
874
  }
851
875
  if (e.length > this.maxReusableCapacity) {
852
- f && this.stats && this.stats.rejected.tooLarge++;
876
+ d && this.stats && this.stats.rejected.tooLarge++;
853
877
  return;
854
878
  }
855
879
  if (this.pool.length >= this.maxPoolSize) {
856
- f && this.stats && this.stats.rejected.poolFull++;
880
+ d && this.stats && this.stats.rejected.poolFull++;
857
881
  return;
858
882
  }
859
- e.length = 0, this.pool.push(e), f && this.stats && this.stats.released++;
883
+ e.length = 0, this.pool.push(e), d && this.stats && this.stats.released++;
860
884
  }
861
885
  }
862
886
  getStats() {
863
- if (!f || !this.stats) return null;
887
+ if (!d || !this.stats) return null;
864
888
  const { acquired: e, released: t, rejected: s } = this.stats, n = s.frozen + s.tooLarge + s.poolFull;
865
889
  return {
866
890
  acquired: e,
@@ -871,15 +895,15 @@ class V {
871
895
  };
872
896
  }
873
897
  reset() {
874
- this.pool.length = 0, f && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
898
+ this.pool.length = 0, d && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
875
899
  }
876
900
  }
877
- const E = new V();
878
- class w {
901
+ const p = new Q();
902
+ class z {
879
903
  constructor(e, t = {}) {
880
904
  if (typeof e != "function")
881
- throw new b(o.COMPUTED_MUST_BE_FUNCTION);
882
- if (this.id = F() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = void 0, this._stateFlags = c.DIRTY | c.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : U, this._hasDefaultValue = this._defaultValue !== U, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new N(), this._objectSubscribers = new N(), this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._recomputeJob = () => {
905
+ throw new b(h.COMPUTED_MUST_BE_FUNCTION);
906
+ if (this.id = L() & I, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = void 0, this._stateFlags = c.DIRTY | c.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : B, this._hasDefaultValue = this._defaultValue !== B, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new F(), this._objectSubscribers = new F(), this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._recomputeJob = () => {
883
907
  if (this._isDirty())
884
908
  try {
885
909
  this._recompute();
@@ -896,7 +920,7 @@ class w {
896
920
  }, this._trackable = Object.assign(() => this._markDirty(), {
897
921
  addDependency: (s) => {
898
922
  }
899
- }), a.attachDebugInfo(this, "computed", this.id), a.enabled) {
923
+ }), f.attachDebugInfo(this, "computed", this.id), f.enabled) {
900
924
  const s = this;
901
925
  s.subscriberCount = () => this._functionSubscribers.size + this._objectSubscribers.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencies, s.stateFlags = this._getFlagsAsString();
902
926
  }
@@ -915,7 +939,7 @@ class w {
915
939
  }
916
940
  subscribe(e) {
917
941
  if (typeof e != "function")
918
- throw new b(o.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
942
+ throw new b(h.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
919
943
  return this._functionSubscribers.add(e);
920
944
  }
921
945
  peek() {
@@ -945,7 +969,7 @@ class w {
945
969
  const t = this._subscriptions.get(e.id);
946
970
  t && t(), this._subscriptions.delete(e.id);
947
971
  }
948
- E.release(this._dependencies);
972
+ p.release(this._dependencies);
949
973
  }
950
974
  this._dependencies = l, this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._stateFlags = c.DIRTY | c.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
951
975
  }
@@ -987,10 +1011,11 @@ class w {
987
1011
  return (this._stateFlags & c.RECOMPUTING) !== 0;
988
1012
  }
989
1013
  _setRecomputing(e) {
990
- e ? this._stateFlags |= c.RECOMPUTING : this._stateFlags &= -33;
1014
+ const t = c.RECOMPUTING;
1015
+ this._stateFlags = this._stateFlags & ~t | -Number(e) & t;
991
1016
  }
992
1017
  _getAsyncState() {
993
- return this._isPending() ? C.PENDING : this._isResolved() ? C.RESOLVED : this._isRejected() ? C.REJECTED : C.IDLE;
1018
+ return this._isPending() ? R.PENDING : this._isResolved() ? R.RESOLVED : this._isRejected() ? R.REJECTED : R.IDLE;
994
1019
  }
995
1020
  _getFlagsAsString() {
996
1021
  const e = [];
@@ -1004,24 +1029,24 @@ class w {
1004
1029
  if (!this._isDirty() && this._isResolved())
1005
1030
  return;
1006
1031
  this._setRecomputing(!0);
1007
- const e = this._dependencies, t = E.acquire(), s = M();
1032
+ const e = this._dependencies, t = p.acquire(), s = q();
1008
1033
  let n = 0;
1009
- const r = (h) => {
1010
- h._lastSeenEpoch !== s && (h._lastSeenEpoch = s, n < t.length ? t[n] = h : t.push(h), n++);
1034
+ const r = (o) => {
1035
+ o._lastSeenEpoch !== s && (o._lastSeenEpoch = s, n < t.length ? t[n] = o : t.push(o), n++);
1011
1036
  }, u = this._trackable.addDependency;
1012
1037
  this._trackable.addDependency = r;
1013
- let d = !1;
1038
+ let a = !1;
1014
1039
  try {
1015
- const h = S.run(this._trackable, this._fn);
1016
- if (t.length = n, P(h)) {
1017
- this._syncDependencies(e, t, s), this._dependencies = t, d = !0, this._handleAsyncComputation(h), this._setRecomputing(!1);
1040
+ const o = S.run(this._trackable, this._fn);
1041
+ if (t.length = n, k(o)) {
1042
+ this._syncDependencies(e, t, s), this._dependencies = t, a = !0, this._handleAsyncComputation(o), this._setRecomputing(!1);
1018
1043
  return;
1019
1044
  }
1020
- this._syncDependencies(e, t, s), this._dependencies = t, d = !0, this._handleSyncResult(h);
1021
- } catch (h) {
1022
- t.length = n, this._syncDependencies(e, t, s), this._dependencies = t, d = !0, this._handleComputationError(h);
1045
+ this._syncDependencies(e, t, s), this._dependencies = t, a = !0, this._handleSyncResult(o);
1046
+ } catch (o) {
1047
+ t.length = n, this._syncDependencies(e, t, s), this._dependencies = t, a = !0, this._handleComputationError(o);
1023
1048
  } finally {
1024
- this._trackable.addDependency = u, d ? e !== l && E.release(e) : E.release(t);
1049
+ this._trackable.addDependency = u, a ? e !== l && p.release(e) : p.release(t);
1025
1050
  }
1026
1051
  }
1027
1052
  /**
@@ -1040,7 +1065,7 @@ class w {
1040
1065
  for (let n = 0; n < t.length; n++) {
1041
1066
  const r = t[n];
1042
1067
  if (r && !this._subscriptions.has(r.id)) {
1043
- a.checkCircular(r, this);
1068
+ f.checkCircular(r, this);
1044
1069
  const u = r.subscribe(() => this._markDirty());
1045
1070
  this._subscriptions.set(r.id, u);
1046
1071
  }
@@ -1064,29 +1089,29 @@ class w {
1064
1089
  this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
1065
1090
  }
1066
1091
  _handleAsyncRejection(e) {
1067
- const t = g(e, b, o.COMPUTED_ASYNC_COMPUTATION_FAILED);
1092
+ const t = D(e, b, h.COMPUTED_ASYNC_COMPUTATION_FAILED);
1068
1093
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1069
1094
  try {
1070
1095
  this._onError(t);
1071
1096
  } catch (s) {
1072
- console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1097
+ console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1073
1098
  }
1074
1099
  this._notifySubscribers();
1075
1100
  }
1076
1101
  _handleComputationError(e) {
1077
- const t = g(e, b, o.COMPUTED_COMPUTATION_FAILED);
1102
+ const t = D(e, b, h.COMPUTED_COMPUTATION_FAILED);
1078
1103
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1079
1104
  try {
1080
1105
  this._onError(t);
1081
1106
  } catch (s) {
1082
- console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1107
+ console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1083
1108
  }
1084
1109
  throw t;
1085
1110
  }
1086
1111
  _handlePending() {
1087
1112
  if (this._hasDefaultValue)
1088
1113
  return this._defaultValue;
1089
- throw new b(o.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1114
+ throw new b(h.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1090
1115
  }
1091
1116
  _handleRejected() {
1092
1117
  if (this._error?.recoverable && this._hasDefaultValue)
@@ -1097,10 +1122,10 @@ class w {
1097
1122
  // (Replaced by _syncDependencies and inline pool logic)
1098
1123
  // === PRIVATE: Subscriber Management ===
1099
1124
  _markDirty() {
1100
- this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && D.schedule(this._recomputeJob));
1125
+ this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && g.schedule(this._recomputeJob));
1101
1126
  }
1102
1127
  _notifySubscribers() {
1103
- !this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || D.schedule(this._notifyJob);
1128
+ !this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || g.schedule(this._notifyJob);
1104
1129
  }
1105
1130
  _registerTracking() {
1106
1131
  const e = S.getCurrent();
@@ -1113,15 +1138,15 @@ class w {
1113
1138
  } else e.execute && this._objectSubscribers.add(e);
1114
1139
  }
1115
1140
  }
1116
- Object.freeze(w.prototype);
1117
- function J(i, e = {}) {
1118
- return new w(i, e);
1141
+ Object.freeze(z.prototype);
1142
+ function te(i, e = {}) {
1143
+ return new z(i, e);
1119
1144
  }
1120
- class j {
1145
+ class H {
1121
1146
  constructor(e, t = {}) {
1122
1147
  this.run = () => {
1123
1148
  if (this.isDisposed)
1124
- throw new p(o.EFFECT_MUST_BE_FUNCTION);
1149
+ throw new E(h.EFFECT_MUST_BE_FUNCTION);
1125
1150
  this.execute();
1126
1151
  }, this.dispose = () => {
1127
1152
  if (!this.isDisposed && (this._setDisposed(), this._safeCleanup(), this._dependencies !== l)) {
@@ -1129,7 +1154,7 @@ class j {
1129
1154
  const n = this._subscriptions.get(s.id);
1130
1155
  n && n(), this._subscriptions.delete(s.id);
1131
1156
  }
1132
- E.release(this._dependencies), this._dependencies = l;
1157
+ p.release(this._dependencies), this._dependencies = l;
1133
1158
  }
1134
1159
  }, this.addDependency = (s) => {
1135
1160
  if (this.isExecuting && this._nextDeps) {
@@ -1139,24 +1164,23 @@ class j {
1139
1164
  }
1140
1165
  }, this.execute = () => {
1141
1166
  if (this.isDisposed || this.isExecuting) return;
1142
- const s = Date.now();
1143
- this._recordExecution(s), this._setExecuting(!0), this._safeCleanup(), this._modifiedDeps.clear();
1144
- const n = this._dependencies, r = E.acquire(), u = M();
1145
- this._nextDeps = r, this._currentEpoch = u;
1146
- let d = !1;
1167
+ this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup(), this._modifiedDeps.clear();
1168
+ const s = this._dependencies, n = p.acquire(), r = q();
1169
+ this._nextDeps = n, this._currentEpoch = r;
1170
+ let u = !1;
1147
1171
  try {
1148
- const h = S.run(this, this._fn);
1149
- this._syncDependencies(n, u), this._dependencies = r, d = !0, this._checkLoopWarnings(), P(h) ? h.then((R) => {
1150
- !this.isDisposed && typeof R == "function" && (this._cleanup = R);
1151
- }).catch((R) => {
1152
- console.error(g(R, p, o.EFFECT_EXECUTION_FAILED));
1153
- }) : this._cleanup = typeof h == "function" ? h : null;
1154
- } catch (h) {
1155
- this._syncDependencies(n, u), this._dependencies = r, d = !0, console.error(g(h, p, o.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1172
+ const a = S.run(this, this._fn);
1173
+ this._syncDependencies(s, r), this._dependencies = n, u = !0, this._checkLoopWarnings(), k(a) ? a.then((o) => {
1174
+ !this.isDisposed && typeof o == "function" && (this._cleanup = o);
1175
+ }).catch((o) => {
1176
+ console.error(D(o, E, h.EFFECT_EXECUTION_FAILED));
1177
+ }) : this._cleanup = typeof a == "function" ? a : null;
1178
+ } catch (a) {
1179
+ this._syncDependencies(s, r), this._dependencies = n, u = !0, console.error(D(a, E, h.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1156
1180
  } finally {
1157
- this._setExecuting(!1), this._nextDeps = null, d ? n !== l && E.release(n) : E.release(r);
1181
+ this._setExecuting(!1), this._nextDeps = null, u ? s !== l && p.release(s) : p.release(n);
1158
1182
  }
1159
- }, this._id = F() & I, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? L.MAX_EXECUTIONS_PER_SECOND, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._nextDeps = null, this._modifiedDeps = /* @__PURE__ */ new Set(), this._historyCapacity = this._maxExecutions + 5, this._history = new Float64Array(this._historyCapacity), this._historyIdx = 0, this._historyCount = 0, this._executionCount = 0, a.attachDebugInfo(this, "effect", this._id);
1183
+ }, this._id = L() & I, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? N.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? N.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = l, this._subscriptions = /* @__PURE__ */ new Map(), this._nextDeps = null, this._modifiedDeps = /* @__PURE__ */ new Set(), this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._history = U ? [] : null, this._executionCount = 0, f.attachDebugInfo(this, "effect", this._id);
1160
1184
  }
1161
1185
  /**
1162
1186
  * Synchronizes subscriptions by unsubscribing from removed dependencies.
@@ -1178,11 +1202,11 @@ class j {
1178
1202
  _subscribeTo(e) {
1179
1203
  try {
1180
1204
  const t = e.subscribe(() => {
1181
- this._trackModifications && this.isExecuting && this._modifiedDeps.add(e), this._sync ? this.execute() : D.schedule(this.execute);
1205
+ this._trackModifications && this.isExecuting && this._modifiedDeps.add(e), this._sync ? this.execute() : g.schedule(this.execute);
1182
1206
  });
1183
1207
  this._subscriptions.set(e.id, t);
1184
1208
  } catch (t) {
1185
- console.error(g(t, p, o.EFFECT_EXECUTION_FAILED));
1209
+ console.error(D(t, E, h.EFFECT_EXECUTION_FAILED));
1186
1210
  }
1187
1211
  }
1188
1212
  /**
@@ -1272,7 +1296,8 @@ class j {
1272
1296
  * @internal
1273
1297
  */
1274
1298
  _setExecuting(e) {
1275
- e ? this._flags |= m.EXECUTING : this._flags &= -3;
1299
+ const t = m.EXECUTING;
1300
+ this._flags = this._flags & ~t | -Number(e) & t;
1276
1301
  }
1277
1302
  /**
1278
1303
  * Safely executes the cleanup function if one exists.
@@ -1292,42 +1317,45 @@ class j {
1292
1317
  try {
1293
1318
  this._cleanup();
1294
1319
  } catch (e) {
1295
- console.error(g(e, p, o.EFFECT_CLEANUP_FAILED));
1320
+ console.error(D(e, E, h.EFFECT_CLEANUP_FAILED));
1296
1321
  }
1297
1322
  this._cleanup = null;
1298
1323
  }
1299
1324
  }
1300
1325
  /**
1301
- * Records an execution timestamp and checks for infinite loop conditions.
1302
- *
1303
- * @param now - The current timestamp in milliseconds (from `Date.now()`)
1304
- *
1305
- * @remarks
1306
- * This method implements a circular buffer to track recent execution
1307
- * timestamps. If the number of executions within the last second exceeds
1308
- * `_maxExecutions`, the effect is disposed and an error is thrown (in debug mode)
1309
- * or logged (in production mode).
1310
- *
1311
- * The circular buffer approach provides O(1) insertion and efficient
1312
- * memory usage for tracking execution history.
1313
- *
1314
- * @throws {EffectError} In debug mode, throws when infinite loop is detected
1326
+ * Checks for infinite loop conditions using epoch-based detection.
1327
+ * Falls back to timestamp-based detection in development mode.
1315
1328
  *
1329
+ * @throws {EffectError} When infinite loop is detected
1316
1330
  * @internal
1317
1331
  */
1318
- _recordExecution(e) {
1319
- if (this._maxExecutions <= 0) return;
1320
- const t = e - 1e3;
1321
- this._history[this._historyIdx] = e, this._historyIdx = (this._historyIdx + 1) % this._historyCapacity, this._historyCount < this._historyCapacity && this._historyCount++, this._executionCount++;
1322
- let s = 0, n = (this._historyIdx - 1 + this._historyCapacity) % this._historyCapacity;
1323
- for (let r = 0; r < this._historyCount && !(this._history[n] < t); r++)
1324
- s++, n = (n - 1 + this._historyCapacity) % this._historyCapacity;
1325
- if (s > this._maxExecutions) {
1326
- const r = `Effect executed ${s} times within 1 second. Infinite loop suspected`, u = new p(r);
1327
- if (this.dispose(), console.error(u), a.enabled)
1328
- throw u;
1332
+ _checkInfiniteLoop() {
1333
+ if (this._lastFlushEpoch !== C && (this._lastFlushEpoch = C, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), V() > N.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history) {
1334
+ const e = Date.now();
1335
+ this._history.push(e), this._history.length > N.MAX_EXECUTIONS_PER_SECOND + 10 && this._history.shift(), this._checkTimestampLoop(e);
1329
1336
  }
1330
1337
  }
1338
+ _checkTimestampLoop(e) {
1339
+ const t = this._history;
1340
+ if (!t || this._maxExecutions <= 0) return;
1341
+ const s = e - 1e3;
1342
+ let n = 0;
1343
+ for (let r = t.length - 1; r >= 0 && !(t[r] < s); r--)
1344
+ n++;
1345
+ if (n > this._maxExecutions) {
1346
+ const r = new E(
1347
+ `Effect executed ${n} times within 1 second. Infinite loop suspected`
1348
+ );
1349
+ if (this.dispose(), console.error(r), U)
1350
+ throw r;
1351
+ }
1352
+ }
1353
+ _throwInfiniteLoopError(e) {
1354
+ const t = new E(
1355
+ `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${P}`
1356
+ );
1357
+ throw this.dispose(), console.error(t), t;
1358
+ }
1331
1359
  /**
1332
1360
  * Checks for and warns about potential infinite loop patterns.
1333
1361
  *
@@ -1342,56 +1370,56 @@ class j {
1342
1370
  * @internal
1343
1371
  */
1344
1372
  _checkLoopWarnings() {
1345
- if (this._trackModifications && a.enabled) {
1373
+ if (this._trackModifications && f.enabled) {
1346
1374
  const e = this._dependencies;
1347
1375
  for (let t = 0; t < e.length; t++) {
1348
1376
  const s = e[t];
1349
- s && this._modifiedDeps.has(s) && a.warn(
1377
+ s && this._modifiedDeps.has(s) && f.warn(
1350
1378
  !0,
1351
- `Effect is reading a dependency (${a.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1379
+ `Effect is reading a dependency (${f.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1352
1380
  );
1353
1381
  }
1354
1382
  }
1355
1383
  }
1356
1384
  }
1357
- function H(i, e = {}) {
1385
+ function se(i, e = {}) {
1358
1386
  if (typeof i != "function")
1359
- throw new p(o.EFFECT_MUST_BE_FUNCTION);
1360
- const t = new j(i, e);
1387
+ throw new E(h.EFFECT_MUST_BE_FUNCTION);
1388
+ const t = new H(i, e);
1361
1389
  return t.execute(), t;
1362
1390
  }
1363
- function G(i) {
1391
+ function J(i) {
1364
1392
  return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
1365
1393
  }
1366
- function W(i) {
1367
- if (a.enabled) {
1368
- const e = a.getDebugType(i);
1394
+ function ie(i) {
1395
+ if (f.enabled) {
1396
+ const e = f.getDebugType(i);
1369
1397
  if (e)
1370
1398
  return e === "computed";
1371
1399
  }
1372
- return G(i) && "invalidate" in i && typeof i.invalidate == "function";
1400
+ return J(i) && "invalidate" in i && typeof i.invalidate == "function";
1373
1401
  }
1374
- function K(i) {
1402
+ function ne(i) {
1375
1403
  return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
1376
1404
  }
1377
1405
  export {
1378
- C as AsyncState,
1406
+ R as AsyncState,
1379
1407
  _ as AtomError,
1380
1408
  b as ComputedError,
1381
- x as DEBUG_CONFIG,
1382
- a as DEBUG_RUNTIME,
1383
- p as EffectError,
1384
- X as POOL_CONFIG,
1385
- L as SCHEDULER_CONFIG,
1409
+ M as DEBUG_CONFIG,
1410
+ f as DEBUG_RUNTIME,
1411
+ E as EffectError,
1412
+ W as POOL_CONFIG,
1413
+ N as SCHEDULER_CONFIG,
1386
1414
  y as SchedulerError,
1387
- $ as atom,
1388
- Y as batch,
1389
- J as computed,
1390
- H as effect,
1391
- G as isAtom,
1392
- W as isComputed,
1393
- K as isEffect,
1394
- D as scheduler,
1395
- Q as untracked
1415
+ ee as atom,
1416
+ K as batch,
1417
+ te as computed,
1418
+ se as effect,
1419
+ J as isAtom,
1420
+ ie as isComputed,
1421
+ ne as isEffect,
1422
+ g as scheduler,
1423
+ Z as untracked
1396
1424
  };
1397
1425
  //# sourceMappingURL=index.mjs.map