@but212/atom-effect 0.1.2 → 0.1.4

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,14 +1,14 @@
1
- const S = {
1
+ const b = {
2
2
  IDLE: "idle",
3
3
  PENDING: "pending",
4
4
  RESOLVED: "resolved",
5
5
  REJECTED: "rejected"
6
- }, y = {
6
+ }, D = {
7
7
  DISPOSED: 1,
8
8
  // 0001 - Effect has been disposed
9
9
  EXECUTING: 2
10
10
  // 0010 - Effect is currently executing
11
- }, u = {
11
+ }, r = {
12
12
  DIRTY: 1,
13
13
  // 0001 - Needs recomputation
14
14
  IDLE: 2,
@@ -23,17 +23,17 @@ const S = {
23
23
  // 100000 - Currently recomputing
24
24
  HAS_ERROR: 64
25
25
  // 1000000 - Has error state
26
- }, j = {
26
+ }, L = {
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
- }, U = {
31
+ }, A = {
32
32
  /** Maximum effect executions per second to detect infinite loops */
33
33
  MAX_EXECUTIONS_PER_SECOND: 100,
34
34
  /** Threshold for cleaning up old execution timestamps */
35
35
  CLEANUP_THRESHOLD: 100
36
- }, m = {
36
+ }, R = {
37
37
  /** Maximum dependencies before warning about large dependency graphs */
38
38
  MAX_DEPENDENCIES: 1e3,
39
39
  /** Enable infinite loop detection warnings */
@@ -50,7 +50,7 @@ class a extends Error {
50
50
  super(e), this.name = "AtomError", this.cause = t, this.recoverable = s, this.timestamp = /* @__PURE__ */ new Date();
51
51
  }
52
52
  }
53
- class d extends a {
53
+ class _ extends a {
54
54
  /**
55
55
  * Creates a new ComputedError
56
56
  * @param message - Error message
@@ -60,7 +60,7 @@ class d extends a {
60
60
  super(e, t, !0), this.name = "ComputedError";
61
61
  }
62
62
  }
63
- class b extends a {
63
+ class d extends a {
64
64
  /**
65
65
  * Creates a new EffectError
66
66
  * @param message - Error message
@@ -70,7 +70,7 @@ class b extends a {
70
70
  super(e, t, !1), this.name = "EffectError";
71
71
  }
72
72
  }
73
- class g extends a {
73
+ class p extends a {
74
74
  /**
75
75
  * Creates a new SchedulerError
76
76
  * @param message - Error message
@@ -80,20 +80,20 @@ class g extends a {
80
80
  super(e, t, !1), this.name = "SchedulerError";
81
81
  }
82
82
  }
83
- function E(i, e, t) {
83
+ function l(i, e, t) {
84
84
  if (i instanceof TypeError)
85
85
  return new e(`Type error (${t}): ${i.message}`, i);
86
86
  if (i instanceof ReferenceError)
87
87
  return new e(`Reference error (${t}): ${i.message}`, i);
88
88
  if (i instanceof a)
89
89
  return i;
90
- const s = i instanceof Error ? i.message : String(i), r = i instanceof Error ? i : null;
91
- return new e(`Unexpected error (${t}): ${s}`, r);
90
+ const s = i instanceof Error ? i.message : String(i), n = i instanceof Error ? i : null;
91
+ return new e(`Unexpected error (${t}): ${s}`, n);
92
92
  }
93
- function A(i) {
93
+ function m(i) {
94
94
  return i != null && typeof i.then == "function";
95
95
  }
96
- const o = {
96
+ const h = {
97
97
  // ─────────────────────────────────────────────────────────────────
98
98
  // Computed errors
99
99
  // ─────────────────────────────────────────────────────────────────
@@ -178,9 +178,9 @@ const o = {
178
178
  */
179
179
  CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
180
180
  };
181
- class x {
181
+ class M {
182
182
  constructor() {
183
- this.queue = /* @__PURE__ */ new Set(), this.isProcessing = !1, this.isBatching = !1, this.batchDepth = 0, this.batchQueue = [], this.batchQueueSize = 0, this.isFlushingSync = !1, this.maxFlushIterations = 1e3;
183
+ this.queueA = /* @__PURE__ */ new Set(), this.queueB = /* @__PURE__ */ new Set(), this.queue = this.queueA, this.isProcessing = !1, this.isBatching = !1, this.batchDepth = 0, this.batchQueue = [], this.batchQueueSize = 0, this.isFlushingSync = !1, this.maxFlushIterations = 1e3;
184
184
  }
185
185
  /**
186
186
  * Schedules a callback for execution.
@@ -202,7 +202,7 @@ class x {
202
202
  */
203
203
  schedule(e) {
204
204
  if (typeof e != "function")
205
- throw new g("Scheduler callback must be a function");
205
+ throw new p("Scheduler callback must be a function");
206
206
  this.isBatching || this.isFlushingSync ? this.batchQueue[this.batchQueueSize++] = e : (this.queue.add(e), this.isProcessing || this.flush());
207
207
  }
208
208
  /**
@@ -220,17 +220,17 @@ class x {
220
220
  flush() {
221
221
  if (this.isProcessing || this.queue.size === 0) return;
222
222
  this.isProcessing = !0;
223
- const e = Array.from(this.queue);
224
- this.queue.clear(), queueMicrotask(() => {
225
- for (let t = 0; t < e.length; t++)
223
+ const e = this.queue;
224
+ this.queue = this.queue === this.queueA ? this.queueB : this.queueA, queueMicrotask(() => {
225
+ for (const t of e)
226
226
  try {
227
- e[t]?.();
227
+ t?.();
228
228
  } catch (s) {
229
229
  console.error(
230
- new g("Error occurred during scheduler execution", s)
230
+ new p("Error occurred during scheduler execution", s)
231
231
  );
232
232
  }
233
- this.isProcessing = !1, this.queue.size > 0 && !this.isBatching && this.flush();
233
+ e.clear(), this.isProcessing = !1, this.queue.size > 0 && !this.isBatching && this.flush();
234
234
  });
235
235
  }
236
236
  /**
@@ -258,23 +258,23 @@ class x {
258
258
  for (; this.queue.size > 0; ) {
259
259
  if (++e > this.maxFlushIterations) {
260
260
  console.error(
261
- new g(
261
+ new p(
262
262
  `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`
263
263
  )
264
264
  ), this.queue.clear(), this.batchQueueSize = 0;
265
265
  break;
266
266
  }
267
- const t = Array.from(this.queue);
268
- this.queue.clear();
269
- for (let s = 0; s < t.length; s++)
267
+ const t = this.queue;
268
+ this.queue = this.queue === this.queueA ? this.queueB : this.queueA;
269
+ for (const s of t)
270
270
  try {
271
- t[s]?.();
272
- } catch (r) {
271
+ s?.();
272
+ } catch (n) {
273
273
  console.error(
274
- new g("Error occurred during batch execution", r)
274
+ new p("Error occurred during batch execution", n)
275
275
  );
276
276
  }
277
- if (this.batchQueueSize > 0) {
277
+ if (t.clear(), this.batchQueueSize > 0) {
278
278
  for (let s = 0; s < this.batchQueueSize; s++)
279
279
  this.queue.add(this.batchQueue[s]);
280
280
  this.batchQueueSize = 0;
@@ -345,24 +345,24 @@ class x {
345
345
  */
346
346
  setMaxFlushIterations(e) {
347
347
  if (e < 10)
348
- throw new g("Max flush iterations must be at least 10");
348
+ throw new p("Max flush iterations must be at least 10");
349
349
  this.maxFlushIterations = e;
350
350
  }
351
351
  }
352
- const D = new x();
353
- function G(i) {
352
+ const E = new M();
353
+ function B(i) {
354
354
  if (typeof i != "function")
355
355
  throw new a("Batch callback must be a function");
356
- D.startBatch();
356
+ E.startBatch();
357
357
  try {
358
358
  return i();
359
359
  } catch (e) {
360
360
  throw new a("Error occurred during batch execution", e);
361
361
  } finally {
362
- D.endBatch();
362
+ E.endBatch();
363
363
  }
364
364
  }
365
- const p = {
365
+ const f = {
366
366
  /** @inheritdoc */
367
367
  current: null,
368
368
  /**
@@ -383,9 +383,9 @@ const p = {
383
383
  return this.current;
384
384
  }
385
385
  };
386
- class F {
386
+ class N {
387
387
  constructor() {
388
- this.depMap = /* @__PURE__ */ new WeakMap(), this.depRefs = [], this.cleanupThreshold = 100, this.addCount = 0;
388
+ this.cleanupThreshold = 100, this.addCount = 0, this.depRefs = [], this.depMap = /* @__PURE__ */ new WeakMap(), this.count = 0;
389
389
  }
390
390
  /**
391
391
  * Adds a dependency with its associated unsubscribe callback.
@@ -394,7 +394,7 @@ class F {
394
394
  * immediately called to prevent duplicate subscriptions.
395
395
  *
396
396
  * @param dep - The dependency to track (atom, computed, etc.)
397
- * @param unsubscribe - Callback to invoke when removing the dependency
397
+ * @param cleanup - Callback to invoke when removing the dependency
398
398
  *
399
399
  * @remarks
400
400
  * - Duplicate dependencies are rejected with immediate unsubscribe
@@ -412,7 +412,8 @@ class F {
412
412
  t();
413
413
  return;
414
414
  }
415
- this.depMap.set(e, t), this.depRefs.push(new WeakRef(e)), ++this.addCount >= this.cleanupThreshold && (this.cleanup(), this.addCount = 0);
415
+ const s = this.count++;
416
+ this.depRefs[s] = e, this.depMap.set(e, t), ++this.addCount >= this.cleanupThreshold && (this.cleanup(), this.addCount = 0);
416
417
  }
417
418
  /**
418
419
  * Removes a dependency and calls its unsubscribe callback.
@@ -438,8 +439,19 @@ class F {
438
439
  if (t) {
439
440
  try {
440
441
  t();
441
- } catch (s) {
442
- console.warn("[DependencyManager] Error during unsubscribe:", s);
442
+ } catch (u) {
443
+ console.warn("[DependencyManager] Error during unsubscribe:", u);
444
+ }
445
+ const s = this.depRefs, n = this.count;
446
+ let c = -1;
447
+ for (let u = 0; u < n; u++)
448
+ if (s[u] === e) {
449
+ c = u;
450
+ break;
451
+ }
452
+ if (c !== -1) {
453
+ const u = n - 1;
454
+ s[c] = s[u], s[u] = void 0, this.count = u;
443
455
  }
444
456
  return this.depMap.delete(e), !0;
445
457
  }
@@ -482,32 +494,33 @@ class F {
482
494
  * ```
483
495
  */
484
496
  unsubscribeAll() {
485
- for (let e = 0; e < this.depRefs.length; e++) {
486
- const t = this.depRefs[e].deref();
497
+ for (let e = 0; e < this.count; e++) {
498
+ const t = this.depRefs[e];
487
499
  if (t) {
488
500
  const s = this.depMap.get(t);
489
501
  if (s) {
490
502
  try {
491
503
  s();
492
- } catch (r) {
493
- console.warn("[DependencyManager] Error during unsubscribe:", r);
504
+ } catch (n) {
505
+ console.warn("[DependencyManager] Error during unsubscribe:", n);
494
506
  }
495
507
  this.depMap.delete(t);
496
508
  }
497
509
  }
498
510
  }
499
- this.depRefs.length = 0, this.addCount = 0;
511
+ this.depRefs.length = 0, this.count = 0, this.addCount = 0;
500
512
  }
501
513
  /**
502
- * Removes stale WeakRefs from the internal array.
514
+ * Removes stale references from the internal array.
503
515
  *
504
- * WeakRefs whose targets have been garbage collected are filtered out
505
- * to prevent unbounded growth of the depRefs array.
516
+ * This method iterates through the `depRefs` array and removes any dependencies
517
+ * that are no longer present in the `depMap` (meaning their unsubscribe
518
+ * callback has been garbage collected or explicitly deleted).
506
519
  *
507
520
  * @remarks
508
521
  * - Called automatically every `cleanupThreshold` additions
509
522
  * - Can be called manually for immediate cleanup
510
- * - Time complexity: O(n) where n is the number of WeakRefs
523
+ * - Time complexity: O(n) where n is the number of dependencies
511
524
  *
512
525
  * @example
513
526
  * ```typescript
@@ -516,7 +529,15 @@ class F {
516
529
  * ```
517
530
  */
518
531
  cleanup() {
519
- this.depRefs = this.depRefs.filter((e) => e.deref() !== void 0);
532
+ let e = 0;
533
+ const t = this.depRefs, s = this.count;
534
+ for (let n = 0; n < s; n++) {
535
+ const c = t[n];
536
+ c && this.depMap.has(c) && (e !== n && (t[e] = c), e++);
537
+ }
538
+ for (let n = e; n < s; n++)
539
+ t[n] = void 0;
540
+ this.count = e, t.length = e;
520
541
  }
521
542
  /**
522
543
  * Gets the current number of live dependencies.
@@ -532,8 +553,8 @@ class F {
532
553
  * console.log(`Tracking ${manager.count} dependencies`);
533
554
  * ```
534
555
  */
535
- get count() {
536
- return this.cleanup(), this.depRefs.length;
556
+ get liveCount() {
557
+ return this.count;
537
558
  }
538
559
  /**
539
560
  * Gets an array of all live dependencies.
@@ -553,8 +574,8 @@ class F {
553
574
  */
554
575
  getDependencies() {
555
576
  const e = [];
556
- for (let t = 0; t < this.depRefs.length; t++) {
557
- const s = this.depRefs[t].deref();
577
+ for (let t = 0; t < this.count; t++) {
578
+ const s = this.depRefs[t];
558
579
  s !== void 0 && e.push(s);
559
580
  }
560
581
  return e;
@@ -601,24 +622,24 @@ class F {
601
622
  this.cleanupThreshold = Math.max(1, e);
602
623
  }
603
624
  }
604
- function V(i) {
625
+ function k(i) {
605
626
  if (typeof i != "function")
606
627
  throw new a("Untracked callback must be a function");
607
- const e = p.current;
608
- p.current = null;
628
+ const e = f.current;
629
+ f.current = null;
609
630
  try {
610
631
  return i();
611
632
  } catch (t) {
612
633
  throw new a("Error occurred during untracked execution", t);
613
634
  } finally {
614
- p.current = e;
635
+ f.current = e;
615
636
  }
616
637
  }
617
- const C = /* @__PURE__ */ Symbol("debugName"), P = /* @__PURE__ */ Symbol("id"), R = /* @__PURE__ */ Symbol("type"), T = /* @__PURE__ */ Symbol("noDefaultValue");
618
- function w(i) {
638
+ const S = /* @__PURE__ */ Symbol("debugName"), O = /* @__PURE__ */ Symbol("id"), I = /* @__PURE__ */ Symbol("type"), C = /* @__PURE__ */ Symbol("noDefaultValue");
639
+ function F(i) {
619
640
  return i !== null && typeof i == "object" && "dependencies" in i && i.dependencies instanceof Set;
620
641
  }
621
- const h = {
642
+ const o = {
622
643
  /**
623
644
  * Whether debug mode is enabled.
624
645
  *
@@ -632,13 +653,13 @@ const h = {
632
653
  *
633
654
  * @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}
634
655
  */
635
- maxDependencies: m.MAX_DEPENDENCIES,
656
+ maxDependencies: R.MAX_DEPENDENCIES,
636
657
  /**
637
658
  * Whether to warn about potential infinite loops.
638
659
  *
639
660
  * @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}
640
661
  */
641
- warnInfiniteLoop: m.WARN_INFINITE_LOOP,
662
+ warnInfiniteLoop: R.WARN_INFINITE_LOOP,
642
663
  /**
643
664
  * Logs a warning message when condition is true and debug is enabled.
644
665
  *
@@ -683,11 +704,11 @@ const h = {
683
704
  */
684
705
  checkCircular(i, e, t = /* @__PURE__ */ new Set()) {
685
706
  if (i === e)
686
- throw new d("Direct circular dependency detected");
707
+ throw new _("Direct circular dependency detected");
687
708
  if (this.enabled) {
688
709
  if (t.has(i))
689
- throw new d("Indirect circular dependency detected");
690
- if (t.add(i), w(i))
710
+ throw new _("Indirect circular dependency detected");
711
+ if (t.add(i), F(i))
691
712
  for (const s of i.dependencies)
692
713
  this.checkCircular(s, e, t);
693
714
  }
@@ -716,7 +737,7 @@ const h = {
716
737
  if (!this.enabled)
717
738
  return;
718
739
  const s = i;
719
- s[C] = `${e}_${t}`, s[P] = t, s[R] = e;
740
+ s[S] = `${e}_${t}`, s[O] = t, s[I] = e;
720
741
  },
721
742
  /**
722
743
  * Retrieves the debug display name from a reactive object.
@@ -731,8 +752,8 @@ const h = {
731
752
  * ```
732
753
  */
733
754
  getDebugName(i) {
734
- if (i !== null && typeof i == "object" && C in i)
735
- return i[C];
755
+ if (i !== null && typeof i == "object" && S in i)
756
+ return i[S];
736
757
  },
737
758
  /**
738
759
  * Retrieves the debug type from a reactive object.
@@ -749,230 +770,13 @@ const h = {
749
770
  * ```
750
771
  */
751
772
  getDebugType(i) {
752
- if (i !== null && typeof i == "object" && R in i)
753
- return i[R];
773
+ if (i !== null && typeof i == "object" && I in i)
774
+ return i[I];
754
775
  }
755
776
  };
756
- let v = 1;
757
- const I = () => v++;
758
- class L {
759
- /**
760
- * Creates a new AtomImpl instance.
761
- *
762
- * @param initialValue - The initial value of the atom
763
- * @param sync - Whether to notify subscribers synchronously
764
- */
765
- constructor(e, t) {
766
- this._value = e, this._version = 0, this._fnSubs = [], this._fnSubCount = 0, this._objSubs = [], this._objSubCount = 0, this._sync = t, this._id = I().toString(), h.attachDebugInfo(this, "atom", I());
767
- }
768
- /**
769
- * Gets the current value and registers the atom as a dependency
770
- * in the current tracking context.
771
- *
772
- * @returns The current value
773
- *
774
- * @remarks
775
- * This getter automatically tracks dependencies when accessed within
776
- * a computed or effect context.
777
- */
778
- get value() {
779
- const e = p.getCurrent();
780
- return e != null && this._track(e), this._value;
781
- }
782
- /**
783
- * Sets a new value and notifies all subscribers if the value changed.
784
- *
785
- * @param newValue - The new value to set
786
- *
787
- * @remarks
788
- * Uses Object.is for equality comparison. If the value is unchanged,
789
- * no notifications are sent. Notifications may be batched unless
790
- * sync mode is enabled.
791
- */
792
- set value(e) {
793
- if (Object.is(this._value, e)) return;
794
- const t = this._value, s = ++this._version;
795
- this._value = e, (this._fnSubCount | this._objSubCount) !== 0 && this._notify(e, t, s);
796
- }
797
- /**
798
- * Tracks the current context as a dependency of this atom.
799
- *
800
- * @param current - The current tracking context (function or object)
801
- *
802
- * @remarks
803
- * Handles both function-based trackers (with optional addDependency method)
804
- * and object-based trackers (with execute or addDependency methods).
805
- */
806
- _track(e) {
807
- if (typeof e == "function") {
808
- const t = e;
809
- t.addDependency !== void 0 ? t.addDependency(this) : this._addFnSub(e);
810
- } else {
811
- const t = e;
812
- t.addDependency !== void 0 ? t.addDependency(this) : t.execute !== void 0 && this._addObjSub(t);
813
- }
814
- }
815
- /**
816
- * Adds a function-based subscriber.
817
- *
818
- * @param sub - The subscriber function to add
819
- * @returns An unsubscribe function
820
- *
821
- * @remarks
822
- * Prevents duplicate subscriptions by checking existing subscribers.
823
- */
824
- _addFnSub(e) {
825
- const t = this._fnSubs, s = this._fnSubCount;
826
- for (let r = 0; r < s; r++)
827
- if (t[r] === e) return this._createUnsub(r, !0);
828
- return t[s] = e, this._fnSubCount = s + 1, this._createUnsub(s, !0);
829
- }
830
- /**
831
- * Adds an object-based subscriber.
832
- *
833
- * @param sub - The subscriber object with an execute method
834
- *
835
- * @remarks
836
- * Prevents duplicate subscriptions by checking existing subscribers.
837
- */
838
- _addObjSub(e) {
839
- const t = this._objSubs, s = this._objSubCount;
840
- for (let r = 0; r < s; r++)
841
- if (t[r] === e) return;
842
- t[s] = e, this._objSubCount = s + 1;
843
- }
844
- /**
845
- * Creates an unsubscribe function for a subscriber at the given index.
846
- *
847
- * @param idx - The index of the subscriber
848
- * @param isFn - Whether this is a function subscriber (true) or object subscriber (false)
849
- * @returns An unsubscribe function
850
- */
851
- _createUnsub(e, t) {
852
- return () => {
853
- t ? this._removeFnSub(e) : this._removeObjSub(e);
854
- };
855
- }
856
- /**
857
- * Removes a function subscriber at the given index.
858
- *
859
- * @param idx - The index of the subscriber to remove
860
- *
861
- * @remarks
862
- * Uses swap-and-pop removal for O(1) performance.
863
- */
864
- _removeFnSub(e) {
865
- const t = this._fnSubCount;
866
- if (e >= t) return;
867
- const s = t - 1, r = this._fnSubs;
868
- r[e] = r[s], r[s] = void 0, this._fnSubCount = s;
869
- }
870
- /**
871
- * Removes an object subscriber at the given index.
872
- *
873
- * @param idx - The index of the subscriber to remove
874
- *
875
- * @remarks
876
- * Uses swap-and-pop removal for O(1) performance.
877
- */
878
- _removeObjSub(e) {
879
- const t = this._objSubCount;
880
- if (e >= t) return;
881
- const s = t - 1, r = this._objSubs;
882
- r[e] = r[s], r[s] = void 0, this._objSubCount = s;
883
- }
884
- /**
885
- * Notifies all subscribers of a value change.
886
- *
887
- * @param newValue - The new value
888
- * @param oldValue - The previous value
889
- * @param currentVersion - The version at the time of change
890
- *
891
- * @remarks
892
- * Notifications are skipped if the version has changed (stale update).
893
- * Errors from individual subscribers are caught and logged without
894
- * interrupting other subscribers.
895
- */
896
- _notify(e, t, s) {
897
- const r = () => {
898
- if (this._version !== s) return;
899
- const c = this._fnSubs, n = this._fnSubCount, _ = this._objSubs, M = this._objSubCount;
900
- for (let f = 0; f < n; f++)
901
- try {
902
- const l = c[f];
903
- l && l(e, t);
904
- } catch (l) {
905
- console.error(
906
- new a(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, l)
907
- );
908
- }
909
- for (let f = 0; f < M; f++)
910
- try {
911
- const l = _[f];
912
- l && l.execute();
913
- } catch (l) {
914
- console.error(
915
- new a(o.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, l)
916
- );
917
- }
918
- };
919
- this._sync && !D.isBatching ? r() : D.schedule(r);
920
- }
921
- /**
922
- * Subscribes a listener function to value changes.
923
- *
924
- * @param listener - Function to call when the value changes
925
- * @returns An unsubscribe function
926
- * @throws {AtomError} If listener is not a function
927
- *
928
- * @example
929
- * ```ts
930
- * const unsub = myAtom.subscribe((newVal, oldVal) => {
931
- * console.log(`Changed from ${oldVal} to ${newVal}`);
932
- * });
933
- * // Later: unsub();
934
- * ```
935
- */
936
- subscribe(e) {
937
- if (typeof e != "function")
938
- throw new a(o.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
939
- return this._addFnSub(e);
940
- }
941
- /**
942
- * Gets the current value without registering as a dependency.
943
- *
944
- * @returns The current value
945
- *
946
- * @remarks
947
- * Use this method when you need to read the value without
948
- * creating a reactive dependency (e.g., in event handlers).
949
- */
950
- peek() {
951
- return this._value;
952
- }
953
- /**
954
- * Disposes the atom, clearing all subscribers and releasing resources.
955
- *
956
- * @remarks
957
- * After disposal, the atom should not be used. The value is set to
958
- * undefined to help with garbage collection.
959
- */
960
- dispose() {
961
- this._fnSubs.length = 0, this._objSubs.length = 0, this._fnSubCount = 0, this._objSubCount = 0, this._value = void 0;
962
- }
963
- /**
964
- * Gets the total number of active subscribers.
965
- *
966
- * @returns The count of function and object subscribers combined
967
- */
968
- subscriberCount() {
969
- return this._fnSubCount + this._objSubCount;
970
- }
971
- }
972
- function X(i, e = {}) {
973
- return new L(i, e.sync ?? !1);
974
- }
975
- class N {
777
+ let x = 1;
778
+ const g = () => x++;
779
+ class y {
976
780
  constructor() {
977
781
  this.subscribers = null, this.subscriberIndex = null;
978
782
  }
@@ -1022,8 +826,8 @@ class N {
1022
826
  return !1;
1023
827
  const s = this.subscribers.length - 1;
1024
828
  if (t !== s) {
1025
- const r = this.subscribers[s];
1026
- this.subscribers[t] = r, this.subscriberIndex.set(r, t);
829
+ const n = this.subscribers[s];
830
+ this.subscribers[t] = n, this.subscriberIndex.set(n, t);
1027
831
  }
1028
832
  return this.subscribers.pop(), this.subscriberIndex.delete(e), !0;
1029
833
  }
@@ -1070,8 +874,8 @@ class N {
1070
874
  for (let s = 0; s < this.subscribers.length; s++)
1071
875
  try {
1072
876
  e(this.subscribers[s], s);
1073
- } catch (r) {
1074
- t ? t(r) : console.error("[SubscriberManager] Error in subscriber callback:", r);
877
+ } catch (n) {
878
+ t ? t(n) : console.error("[SubscriberManager] Error in subscriber callback:", n);
1075
879
  }
1076
880
  }
1077
881
  /**
@@ -1111,22 +915,163 @@ class N {
1111
915
  return this.subscribers ? [...this.subscribers] : [];
1112
916
  }
1113
917
  }
1114
- class k {
918
+ class U {
919
+ /**
920
+ * Creates a new AtomImpl instance.
921
+ *
922
+ * @param initialValue - The initial value of the atom
923
+ * @param sync - Whether to notify subscribers synchronously
924
+ */
925
+ constructor(e, t) {
926
+ this._isNotificationScheduled = !1, this._value = e, this._version = 0, this._functionSubscribers = new y(), this._objectSubscribers = new y(), this._sync = t, this._id = g().toString(), this._notifyTask = this._flushNotifications.bind(this), o.attachDebugInfo(this, "atom", g());
927
+ }
928
+ /**
929
+ * Gets the current value and registers the atom as a dependency
930
+ * in the current tracking context.
931
+ *
932
+ * @returns The current value
933
+ *
934
+ * @remarks
935
+ * This getter automatically tracks dependencies when accessed within
936
+ * a computed or effect context.
937
+ */
938
+ get value() {
939
+ const e = f.getCurrent();
940
+ return e != null && this._track(e), this._value;
941
+ }
942
+ /**
943
+ * Sets a new value and notifies all subscribers if the value changed.
944
+ *
945
+ * @param newValue - The new value to set
946
+ *
947
+ * @remarks
948
+ * Uses Object.is for equality comparison. If the value is unchanged,
949
+ * no notifications are sent. Notifications may be batched unless
950
+ * sync mode is enabled.
951
+ */
952
+ set value(e) {
953
+ if (Object.is(this._value, e)) return;
954
+ const t = this._value, s = ++this._version;
955
+ this._value = e, !(!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers) && this._notify(e, t, s);
956
+ }
957
+ /**
958
+ * Tracks the current context as a dependency of this atom.
959
+ *
960
+ * @param current - The current tracking context (function or object)
961
+ *
962
+ * @remarks
963
+ * Handles both function-based trackers (with optional addDependency method)
964
+ * and object-based trackers (with execute or addDependency methods).
965
+ */
966
+ _track(e) {
967
+ if (typeof e == "function") {
968
+ const t = e;
969
+ t.addDependency !== void 0 ? t.addDependency(this) : this._functionSubscribers.add(e);
970
+ } else {
971
+ const t = e;
972
+ t.addDependency !== void 0 ? t.addDependency(this) : t.execute !== void 0 && this._objectSubscribers.add(t);
973
+ }
974
+ }
975
+ /**
976
+ * Notifies all subscribers of a value change.
977
+ *
978
+ * @param newValue - The new value
979
+ * @param oldValue - The previous value
980
+ * @param currentVersion - The version at the time of change
981
+ *
982
+ * @remarks
983
+ * Notifications are skipped if the version has changed (stale update).
984
+ * Errors from individual subscribers are caught and logged without
985
+ * interrupting other subscribers.
986
+ */
987
+ /**
988
+ * Schedules a notification.
989
+ * Uses coalescing: if a notification is already scheduled, we update the state
990
+ * but don't schedule a new task. The pending task will see the latest value.
991
+ */
992
+ _notify(e, t, s) {
993
+ this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !E.isBatching ? this._flushNotifications() : E.schedule(this._notifyTask);
994
+ }
995
+ /**
996
+ * Executes the pending notifications.
997
+ * Bound to 'this' in constructor to avoid closure allocation.
998
+ */
999
+ _flushNotifications() {
1000
+ if (!this._isNotificationScheduled) return;
1001
+ const e = this._pendingOldValue, t = this._value;
1002
+ this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._functionSubscribers.forEachSafe(
1003
+ (s) => s(t, e),
1004
+ (s) => console.error(new a(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
1005
+ ), this._objectSubscribers.forEachSafe(
1006
+ (s) => s.execute(),
1007
+ (s) => console.error(new a(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
1008
+ );
1009
+ }
1010
+ /**
1011
+ * Subscribes a listener function to value changes.
1012
+ *
1013
+ * @param listener - Function to call when the value changes
1014
+ * @returns An unsubscribe function
1015
+ * @throws {AtomError} If listener is not a function
1016
+ *
1017
+ * @example
1018
+ * ```ts
1019
+ * const unsub = myAtom.subscribe((newVal, oldVal) => {
1020
+ * console.log(`Changed from ${oldVal} to ${newVal}`);
1021
+ * });
1022
+ * // Later: unsub();
1023
+ * ```
1024
+ */
1025
+ subscribe(e) {
1026
+ if (typeof e != "function")
1027
+ throw new a(h.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
1028
+ return this._functionSubscribers.add(e);
1029
+ }
1030
+ /**
1031
+ * Gets the current value without registering as a dependency.
1032
+ *
1033
+ * @returns The current value
1034
+ *
1035
+ * @remarks
1036
+ * Use this method when you need to read the value without
1037
+ * creating a reactive dependency (e.g., in event handlers).
1038
+ */
1039
+ peek() {
1040
+ return this._value;
1041
+ }
1042
+ /**
1043
+ * Disposes the atom, clearing all subscribers and releasing resources.
1044
+ *
1045
+ * @remarks
1046
+ * After disposal, the atom should not be used. The value is set to
1047
+ * undefined to help with garbage collection.
1048
+ */
1049
+ dispose() {
1050
+ this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._value = void 0;
1051
+ }
1052
+ /**
1053
+ * Gets the total number of active subscribers.
1054
+ *
1055
+ * @returns The count of function and object subscribers combined
1056
+ */
1057
+ subscriberCount() {
1058
+ return this._functionSubscribers.size + this._objectSubscribers.size;
1059
+ }
1060
+ }
1061
+ function G(i, e = {}) {
1062
+ return new U(i, e.sync ?? !1);
1063
+ }
1064
+ class T {
1115
1065
  constructor(e, t = {}) {
1116
- if (this._error = null, this._promiseId = 0, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, typeof e != "function")
1117
- throw new d(o.COMPUTED_MUST_BE_FUNCTION);
1118
- this._fn = e, this._stateFlags = u.DIRTY | u.IDLE, this._value = void 0;
1119
- const {
1120
- equal: s = Object.is,
1121
- defaultValue: r = T,
1122
- lazy: c = !0,
1123
- onError: n = null
1124
- } = t;
1125
- if (this._equal = s, this._defaultValue = r, this._hasDefaultValue = r !== T, this._onError = n, this._functionSubscribers = new N(), this._objectSubscribers = new N(), this._dependencyManager = new F(), this._id = I(), h.attachDebugInfo(this, "computed", this._id), h.enabled) {
1126
- const _ = this;
1127
- _.subscriberCount = () => this._functionSubscribers.size + this._objectSubscribers.size, _.isDirty = () => this._isDirty(), _.dependencies = this._dependencyManager.getDependencies(), _.stateFlags = this._getFlagsAsString();
1066
+ if (typeof e != "function")
1067
+ throw new _(h.COMPUTED_MUST_BE_FUNCTION);
1068
+ if (this._value = void 0, this._stateFlags = r.DIRTY | r.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : C, this._hasDefaultValue = this._defaultValue !== C, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new y(), this._objectSubscribers = new y(), this._dependencyManager = new N(), this._dependencyBuffer = /* @__PURE__ */ new Set(), this._trackable = Object.assign(() => this._markDirty(), {
1069
+ addDependency: (s) => this._dependencyBuffer.add(s)
1070
+ }), this._id = g(), o.attachDebugInfo(this, "computed", this._id), o.enabled) {
1071
+ const s = this;
1072
+ s.subscriberCount = () => this._functionSubscribers.size + this._objectSubscribers.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencyManager.getDependencies(), s.stateFlags = this._getFlagsAsString();
1128
1073
  }
1129
- if (!c)
1074
+ if (t.lazy === !1)
1130
1075
  try {
1131
1076
  this._recompute();
1132
1077
  } catch {
@@ -1134,14 +1079,14 @@ class k {
1134
1079
  }
1135
1080
  // === PUBLIC API ===
1136
1081
  get value() {
1137
- if ((this._stateFlags & (u.RESOLVED | u.DIRTY)) === u.RESOLVED)
1082
+ if ((this._stateFlags & (r.RESOLVED | r.DIRTY)) === r.RESOLVED)
1138
1083
  return this._registerTracking(), this._value;
1139
1084
  const t = this._computeValue();
1140
1085
  return this._registerTracking(), t;
1141
1086
  }
1142
1087
  subscribe(e) {
1143
1088
  if (typeof e != "function")
1144
- throw new d(o.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
1089
+ throw new _(h.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
1145
1090
  return this._functionSubscribers.add(e);
1146
1091
  }
1147
1092
  peek() {
@@ -1166,50 +1111,50 @@ class k {
1166
1111
  this._markDirty();
1167
1112
  }
1168
1113
  dispose() {
1169
- this._dependencyManager.unsubscribeAll(), this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._stateFlags = u.DIRTY | u.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
1114
+ this._dependencyManager.unsubscribeAll(), this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._stateFlags = r.DIRTY | r.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
1170
1115
  }
1171
1116
  // === PRIVATE: State Flag Operations (inlined for performance) ===
1172
1117
  _isDirty() {
1173
- return (this._stateFlags & u.DIRTY) !== 0;
1118
+ return (this._stateFlags & r.DIRTY) !== 0;
1174
1119
  }
1175
1120
  _setDirty() {
1176
- this._stateFlags |= u.DIRTY;
1121
+ this._stateFlags |= r.DIRTY;
1177
1122
  }
1178
1123
  _clearDirty() {
1179
1124
  this._stateFlags &= -2;
1180
1125
  }
1181
1126
  _isIdle() {
1182
- return (this._stateFlags & u.IDLE) !== 0;
1127
+ return (this._stateFlags & r.IDLE) !== 0;
1183
1128
  }
1184
1129
  _setIdle() {
1185
- this._stateFlags |= u.IDLE, this._stateFlags &= -29;
1130
+ this._stateFlags |= r.IDLE, this._stateFlags &= -29;
1186
1131
  }
1187
1132
  _isPending() {
1188
- return (this._stateFlags & u.PENDING) !== 0;
1133
+ return (this._stateFlags & r.PENDING) !== 0;
1189
1134
  }
1190
1135
  _setPending() {
1191
- this._stateFlags |= u.PENDING, this._stateFlags &= -27;
1136
+ this._stateFlags |= r.PENDING, this._stateFlags &= -27;
1192
1137
  }
1193
1138
  _isResolved() {
1194
- return (this._stateFlags & u.RESOLVED) !== 0;
1139
+ return (this._stateFlags & r.RESOLVED) !== 0;
1195
1140
  }
1196
1141
  _setResolved() {
1197
- this._stateFlags |= u.RESOLVED, this._stateFlags &= -87;
1142
+ this._stateFlags |= r.RESOLVED, this._stateFlags &= -87;
1198
1143
  }
1199
1144
  _isRejected() {
1200
- return (this._stateFlags & u.REJECTED) !== 0;
1145
+ return (this._stateFlags & r.REJECTED) !== 0;
1201
1146
  }
1202
1147
  _setRejected() {
1203
- this._stateFlags |= u.REJECTED | u.HAS_ERROR, this._stateFlags &= -15;
1148
+ this._stateFlags |= r.REJECTED | r.HAS_ERROR, this._stateFlags &= -15;
1204
1149
  }
1205
1150
  _isRecomputing() {
1206
- return (this._stateFlags & u.RECOMPUTING) !== 0;
1151
+ return (this._stateFlags & r.RECOMPUTING) !== 0;
1207
1152
  }
1208
1153
  _setRecomputing(e) {
1209
- e ? this._stateFlags |= u.RECOMPUTING : this._stateFlags &= -33;
1154
+ e ? this._stateFlags |= r.RECOMPUTING : this._stateFlags &= -33;
1210
1155
  }
1211
1156
  _getAsyncState() {
1212
- return this._isPending() ? S.PENDING : this._isResolved() ? S.RESOLVED : this._isRejected() ? S.REJECTED : S.IDLE;
1157
+ return this._isPending() ? b.PENDING : this._isResolved() ? b.RESOLVED : this._isRejected() ? b.REJECTED : b.IDLE;
1213
1158
  }
1214
1159
  _getFlagsAsString() {
1215
1160
  const e = [];
@@ -1222,19 +1167,17 @@ class k {
1222
1167
  _recompute() {
1223
1168
  if (!this._isDirty() && this._isResolved())
1224
1169
  return;
1225
- this._setRecomputing(!0);
1226
- const e = /* @__PURE__ */ new Set(), t = Object.assign(() => this._markDirty(), {
1227
- addDependency: (s) => e.add(s)
1228
- });
1170
+ this._setRecomputing(!0), this._dependencyBuffer.clear();
1171
+ const e = this._dependencyBuffer;
1229
1172
  try {
1230
- const s = p.run(t, this._fn);
1231
- if (A(s)) {
1232
- this._updateDependencies(e), this._handleAsyncComputation(s), this._setRecomputing(!1);
1173
+ const t = f.run(this._trackable, this._fn);
1174
+ if (m(t)) {
1175
+ this._updateDependencies(e), this._handleAsyncComputation(t), this._setRecomputing(!1);
1233
1176
  return;
1234
1177
  }
1235
- this._updateDependencies(e), this._handleSyncResult(s);
1236
- } catch (s) {
1237
- this._updateDependencies(e), this._handleComputationError(s);
1178
+ this._updateDependencies(e), this._handleSyncResult(t);
1179
+ } catch (t) {
1180
+ this._updateDependencies(e), this._handleComputationError(t);
1238
1181
  }
1239
1182
  }
1240
1183
  _handleSyncResult(e) {
@@ -1255,29 +1198,29 @@ class k {
1255
1198
  this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
1256
1199
  }
1257
1200
  _handleAsyncRejection(e) {
1258
- const t = E(e, d, o.COMPUTED_ASYNC_COMPUTATION_FAILED);
1201
+ const t = l(e, _, h.COMPUTED_ASYNC_COMPUTATION_FAILED);
1259
1202
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1260
1203
  try {
1261
1204
  this._onError(t);
1262
1205
  } catch (s) {
1263
- console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1206
+ console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1264
1207
  }
1265
1208
  this._notifySubscribers();
1266
1209
  }
1267
1210
  _handleComputationError(e) {
1268
- const t = E(e, d, o.COMPUTED_COMPUTATION_FAILED);
1211
+ const t = l(e, _, h.COMPUTED_COMPUTATION_FAILED);
1269
1212
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1270
1213
  try {
1271
1214
  this._onError(t);
1272
1215
  } catch (s) {
1273
- console.error(o.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1216
+ console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1274
1217
  }
1275
1218
  throw t;
1276
1219
  }
1277
1220
  _handlePending() {
1278
1221
  if (this._hasDefaultValue)
1279
1222
  return this._defaultValue;
1280
- throw new d(o.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1223
+ throw new _(h.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1281
1224
  }
1282
1225
  _handleRejected() {
1283
1226
  if (this._error?.recoverable && this._hasDefaultValue)
@@ -1298,36 +1241,29 @@ class k {
1298
1241
  return !0;
1299
1242
  }
1300
1243
  _performDeltaSync(e, t) {
1301
- const s = new Set(e), r = [], c = [];
1302
- for (let n = 0; n < e.length; n++) {
1303
- const _ = e[n];
1304
- t.has(_) || r.push(_);
1244
+ for (let s = 0; s < e.length; s++) {
1245
+ const n = e[s];
1246
+ t.has(n) || this._dependencyManager.removeDependency(n);
1305
1247
  }
1306
- t.forEach((n) => {
1307
- s.has(n) || c.push(n);
1308
- });
1309
- for (let n = 0; n < r.length; n++)
1310
- this._dependencyManager.removeDependency(r[n]);
1311
- for (let n = 0; n < c.length; n++)
1312
- this._addDependency(c[n]);
1313
- e.length = 0, t.forEach((n) => {
1314
- e.push(n);
1248
+ t.forEach((s) => {
1249
+ const n = s;
1250
+ this._dependencyManager.hasDependency(n) || this._addDependency(n);
1315
1251
  });
1316
1252
  }
1317
1253
  _addDependency(e) {
1318
- h.checkCircular(e, this);
1319
- const t = this._dependencyManager.count;
1320
- h.warn(t > h.maxDependencies, o.LARGE_DEPENDENCY_GRAPH(t));
1254
+ o.checkCircular(e, this);
1255
+ const t = this._dependencyManager.liveCount;
1256
+ o.warn(t > o.maxDependencies, h.LARGE_DEPENDENCY_GRAPH(t));
1321
1257
  try {
1322
1258
  const s = e.subscribe(() => this._markDirty());
1323
1259
  this._dependencyManager.addDependency(e, s);
1324
1260
  } catch (s) {
1325
- throw E(s, d, "dependency subscription");
1261
+ throw l(s, _, "dependency subscription");
1326
1262
  }
1327
1263
  }
1328
1264
  // === PRIVATE: Subscriber Management ===
1329
1265
  _markDirty() {
1330
- this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && D.schedule(() => {
1266
+ this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && E.schedule(() => {
1331
1267
  if (this._isDirty())
1332
1268
  try {
1333
1269
  this._recompute();
@@ -1336,7 +1272,7 @@ class k {
1336
1272
  }));
1337
1273
  }
1338
1274
  _notifySubscribers() {
1339
- !this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || D.schedule(() => {
1275
+ !this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || E.schedule(() => {
1340
1276
  this._functionSubscribers.forEachSafe(
1341
1277
  (e) => e(),
1342
1278
  (e) => console.error(e)
@@ -1347,28 +1283,21 @@ class k {
1347
1283
  });
1348
1284
  }
1349
1285
  _registerTracking() {
1350
- const e = p.getCurrent();
1351
- e && (typeof e == "function" ? this._functionSubscribers.add(e) : e.addDependency ? e.addDependency(this) : e.execute && this._objectSubscribers.add(e));
1352
- }
1353
- }
1354
- function z(i, e = {}) {
1355
- return new k(i, e);
1356
- }
1357
- function O(i) {
1358
- return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
1359
- }
1360
- function q(i) {
1361
- if (h.enabled) {
1362
- const e = h.getDebugType(i);
1286
+ const e = f.getCurrent();
1363
1287
  if (e)
1364
- return e === "computed";
1288
+ if (typeof e == "object" && e !== null && e.addDependency)
1289
+ e.addDependency(this);
1290
+ else if (typeof e == "function") {
1291
+ const t = e;
1292
+ t.addDependency ? t.addDependency(this) : this._functionSubscribers.add(e);
1293
+ } else e.execute && this._objectSubscribers.add(e);
1365
1294
  }
1366
- return O(i) && "invalidate" in i && typeof i.invalidate == "function";
1367
1295
  }
1368
- function Y(i) {
1369
- return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
1296
+ Object.freeze(T.prototype);
1297
+ function V(i, e = {}) {
1298
+ return new T(i, e);
1370
1299
  }
1371
- class B {
1300
+ class w {
1372
1301
  /**
1373
1302
  * Creates a new EffectImpl instance.
1374
1303
  *
@@ -1397,44 +1326,48 @@ class B {
1397
1326
  constructor(e, t = {}) {
1398
1327
  this.run = () => {
1399
1328
  if (this.isDisposed)
1400
- throw new b(o.EFFECT_MUST_BE_FUNCTION);
1329
+ throw new d(h.EFFECT_MUST_BE_FUNCTION);
1401
1330
  this.execute();
1402
1331
  }, this.dispose = () => {
1403
- this.isDisposed || (this._setDisposed(), this._safeCleanup(), this._depManager.unsubscribeAll(), this._trackedDeps.size > 0 && (this._trackedDeps.forEach((s) => {
1404
- const r = this._originalDescriptors.get(s);
1405
- if (r)
1406
- try {
1407
- Object.defineProperty(s, "value", r);
1408
- } catch {
1409
- h.warn(!0, "Failed to restore original descriptor");
1410
- }
1411
- }), this._trackedDeps.clear()));
1332
+ this.isDisposed || (this._setDisposed(), this._safeCleanup(), this._depManager.unsubscribeAll());
1412
1333
  }, this.addDependency = (s) => {
1413
- try {
1414
- const r = s.subscribe(() => {
1415
- this._sync ? this.execute() : D.schedule(this.execute);
1416
- });
1417
- this._depManager.addDependency(s, r), this._trackModifications && O(s) && this._trackModificationsForDep(s);
1418
- } catch (r) {
1419
- throw E(r, b, o.EFFECT_EXECUTION_FAILED);
1420
- }
1334
+ this.isExecuting && (this._dependencyBuffer.add(s), this._depManager.hasDependency(s) || this._subscribeTo(s));
1421
1335
  }, this.execute = () => {
1422
1336
  if (this.isDisposed || this.isExecuting) return;
1423
1337
  const s = Date.now();
1424
- this._recordExecution(s), this._setExecuting(!0), this._safeCleanup(), this._depManager.unsubscribeAll(), this._modifiedDeps.clear();
1338
+ this._recordExecution(s), this._setExecuting(!0), this._safeCleanup(), this._dependencyBuffer.clear(), this._modifiedDeps.clear();
1425
1339
  try {
1426
- const r = p.run(this, this._fn);
1427
- this._checkLoopWarnings(), A(r) ? r.then((c) => {
1340
+ const n = f.run(this, this._fn);
1341
+ this._syncDependencies(), this._checkLoopWarnings(), m(n) ? n.then((c) => {
1428
1342
  !this.isDisposed && typeof c == "function" && (this._cleanup = c);
1429
1343
  }).catch((c) => {
1430
- console.error(E(c, b, o.EFFECT_EXECUTION_FAILED));
1431
- }) : this._cleanup = typeof r == "function" ? r : null;
1432
- } catch (r) {
1433
- console.error(E(r, b, o.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1344
+ console.error(l(c, d, h.EFFECT_EXECUTION_FAILED));
1345
+ }) : this._cleanup = typeof n == "function" ? n : null;
1346
+ } catch (n) {
1347
+ console.error(l(n, d, h.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1434
1348
  } finally {
1435
1349
  this._setExecuting(!1);
1436
1350
  }
1437
- }, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? U.MAX_EXECUTIONS_PER_SECOND, this._trackModifications = t.trackModifications ?? !1, this._id = I(), this._flags = 0, this._cleanup = null, this._depManager = new F(), this._modifiedDeps = /* @__PURE__ */ new Set(), this._originalDescriptors = /* @__PURE__ */ new WeakMap(), this._trackedDeps = /* @__PURE__ */ new Set(), this._historyCapacity = this._maxExecutions + 5, this._history = new Float64Array(this._historyCapacity), this._historyIdx = 0, this._historyCount = 0, this._executionCount = 0, h.attachDebugInfo(this, "effect", this._id);
1351
+ }, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? A.MAX_EXECUTIONS_PER_SECOND, this._trackModifications = t.trackModifications ?? !1, this._id = g(), this._flags = 0, this._cleanup = null, this._depManager = new N(), this._modifiedDeps = /* @__PURE__ */ new Set(), this._dependencyBuffer = /* @__PURE__ */ new Set(), this._historyCapacity = this._maxExecutions + 5, this._history = new Float64Array(this._historyCapacity), this._historyIdx = 0, this._historyCount = 0, this._executionCount = 0, o.attachDebugInfo(this, "effect", this._id);
1352
+ }
1353
+ _syncDependencies() {
1354
+ const e = this._dependencyBuffer, t = this._depManager.getDependencies();
1355
+ for (let s = 0; s < t.length; s++) {
1356
+ const n = t[s];
1357
+ e.has(n) || this._depManager.removeDependency(n);
1358
+ }
1359
+ for (const s of e)
1360
+ this._depManager.hasDependency(s) || this._subscribeTo(s);
1361
+ }
1362
+ _subscribeTo(e) {
1363
+ try {
1364
+ const t = e.subscribe(() => {
1365
+ this._trackModifications && this.isExecuting && this._modifiedDeps.add(e), this._sync ? this.execute() : E.schedule(this.execute);
1366
+ });
1367
+ this._depManager.addDependency(e, t);
1368
+ } catch (t) {
1369
+ console.error(l(t, d, h.EFFECT_EXECUTION_FAILED));
1370
+ }
1438
1371
  }
1439
1372
  /**
1440
1373
  * Indicates whether this effect has been disposed.
@@ -1455,7 +1388,7 @@ class B {
1455
1388
  * ```
1456
1389
  */
1457
1390
  get isDisposed() {
1458
- return (this._flags & y.DISPOSED) !== 0;
1391
+ return (this._flags & D.DISPOSED) !== 0;
1459
1392
  }
1460
1393
  /**
1461
1394
  * Returns the total number of times this effect has been executed.
@@ -1497,7 +1430,7 @@ class B {
1497
1430
  * ```
1498
1431
  */
1499
1432
  get isExecuting() {
1500
- return (this._flags & y.EXECUTING) !== 0;
1433
+ return (this._flags & D.EXECUTING) !== 0;
1501
1434
  }
1502
1435
  /**
1503
1436
  * Sets the disposed flag on this effect.
@@ -1509,7 +1442,7 @@ class B {
1509
1442
  * @internal
1510
1443
  */
1511
1444
  _setDisposed() {
1512
- this._flags |= y.DISPOSED;
1445
+ this._flags |= D.DISPOSED;
1513
1446
  }
1514
1447
  /**
1515
1448
  * Sets or clears the executing flag on this effect.
@@ -1523,7 +1456,7 @@ class B {
1523
1456
  * @internal
1524
1457
  */
1525
1458
  _setExecuting(e) {
1526
- e ? this._flags |= y.EXECUTING : this._flags &= -3;
1459
+ e ? this._flags |= D.EXECUTING : this._flags &= -3;
1527
1460
  }
1528
1461
  /**
1529
1462
  * Safely executes the cleanup function if one exists.
@@ -1543,7 +1476,7 @@ class B {
1543
1476
  try {
1544
1477
  this._cleanup();
1545
1478
  } catch (e) {
1546
- console.error(E(e, b, o.EFFECT_CLEANUP_FAILED));
1479
+ console.error(l(e, d, h.EFFECT_CLEANUP_FAILED));
1547
1480
  }
1548
1481
  this._cleanup = null;
1549
1482
  }
@@ -1570,45 +1503,13 @@ class B {
1570
1503
  if (this._maxExecutions <= 0) return;
1571
1504
  const t = e - 1e3;
1572
1505
  this._history[this._historyIdx] = e, this._historyIdx = (this._historyIdx + 1) % this._historyCapacity, this._historyCount < this._historyCapacity && this._historyCount++, this._executionCount++;
1573
- let s = 0, r = (this._historyIdx - 1 + this._historyCapacity) % this._historyCapacity;
1574
- for (let c = 0; c < this._historyCount && !(this._history[r] < t); c++)
1575
- s++, r = (r - 1 + this._historyCapacity) % this._historyCapacity;
1506
+ let s = 0, n = (this._historyIdx - 1 + this._historyCapacity) % this._historyCapacity;
1507
+ for (let c = 0; c < this._historyCount && !(this._history[n] < t); c++)
1508
+ s++, n = (n - 1 + this._historyCapacity) % this._historyCapacity;
1576
1509
  if (s > this._maxExecutions) {
1577
- const c = `Effect executed ${s} times within 1 second. Infinite loop suspected`, n = new b(c);
1578
- if (this.dispose(), console.error(n), h.enabled)
1579
- throw n;
1580
- }
1581
- }
1582
- /**
1583
- * Sets up modification tracking for a dependency.
1584
- *
1585
- * @param dep - The dependency (atom) to track modifications on
1586
- *
1587
- * @remarks
1588
- * This method intercepts the `value` setter on the dependency to detect
1589
- * when the effect modifies a dependency it also reads. This pattern
1590
- * (read-after-write within the same effect) often indicates an infinite loop.
1591
- *
1592
- * The original property descriptor is preserved and can be restored
1593
- * when the effect is disposed.
1594
- *
1595
- * @internal
1596
- */
1597
- _trackModificationsForDep(e) {
1598
- const t = Object.getPrototypeOf(e), s = Object.getOwnPropertyDescriptor(t, "value");
1599
- if (s?.set && !this._originalDescriptors.has(e)) {
1600
- this._originalDescriptors.set(e, s), this._trackedDeps.add(e);
1601
- const r = this;
1602
- Object.defineProperty(e, "value", {
1603
- set(c) {
1604
- r._modifiedDeps.add(e), s.set?.call(e, c);
1605
- },
1606
- get() {
1607
- return e.peek();
1608
- },
1609
- configurable: !0,
1610
- enumerable: !0
1611
- });
1510
+ const c = `Effect executed ${s} times within 1 second. Infinite loop suspected`, u = new d(c);
1511
+ if (this.dispose(), console.error(u), o.enabled)
1512
+ throw u;
1612
1513
  }
1613
1514
  }
1614
1515
  /**
@@ -1625,42 +1526,56 @@ class B {
1625
1526
  * @internal
1626
1527
  */
1627
1528
  _checkLoopWarnings() {
1628
- if (this._trackModifications && h.enabled) {
1529
+ if (this._trackModifications && o.enabled) {
1629
1530
  const e = this._depManager.getDependencies();
1630
1531
  for (let t = 0; t < e.length; t++) {
1631
1532
  const s = e[t];
1632
- this._modifiedDeps.has(s) && h.warn(
1533
+ this._modifiedDeps.has(s) && o.warn(
1633
1534
  !0,
1634
- `Effect is reading a dependency (${h.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1535
+ `Effect is reading a dependency (${o.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1635
1536
  );
1636
1537
  }
1637
1538
  }
1638
1539
  }
1639
1540
  }
1640
- function Q(i, e = {}) {
1541
+ function q(i, e = {}) {
1641
1542
  if (typeof i != "function")
1642
- throw new b(o.EFFECT_MUST_BE_FUNCTION);
1643
- const t = new B(i, e);
1543
+ throw new d(h.EFFECT_MUST_BE_FUNCTION);
1544
+ const t = new w(i, e);
1644
1545
  return t.execute(), t;
1645
1546
  }
1547
+ function P(i) {
1548
+ return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
1549
+ }
1550
+ function z(i) {
1551
+ if (o.enabled) {
1552
+ const e = o.getDebugType(i);
1553
+ if (e)
1554
+ return e === "computed";
1555
+ }
1556
+ return P(i) && "invalidate" in i && typeof i.invalidate == "function";
1557
+ }
1558
+ function j(i) {
1559
+ return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
1560
+ }
1646
1561
  export {
1647
- S as AsyncState,
1562
+ b as AsyncState,
1648
1563
  a as AtomError,
1649
- d as ComputedError,
1650
- m as DEBUG_CONFIG,
1651
- h as DEBUG_RUNTIME,
1652
- b as EffectError,
1653
- j as POOL_CONFIG,
1654
- U as SCHEDULER_CONFIG,
1655
- g as SchedulerError,
1656
- X as atom,
1657
- G as batch,
1658
- z as computed,
1659
- Q as effect,
1660
- O as isAtom,
1661
- q as isComputed,
1662
- Y as isEffect,
1663
- D as scheduler,
1664
- V as untracked
1564
+ _ as ComputedError,
1565
+ R as DEBUG_CONFIG,
1566
+ o as DEBUG_RUNTIME,
1567
+ d as EffectError,
1568
+ L as POOL_CONFIG,
1569
+ A as SCHEDULER_CONFIG,
1570
+ p as SchedulerError,
1571
+ G as atom,
1572
+ B as batch,
1573
+ V as computed,
1574
+ q as effect,
1575
+ P as isAtom,
1576
+ z as isComputed,
1577
+ j as isEffect,
1578
+ E as scheduler,
1579
+ k as untracked
1665
1580
  };
1666
1581
  //# sourceMappingURL=index.mjs.map