@but212/atom-effect 0.3.2 → 0.3.3

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 T = {
1
+ const O = {
2
2
  IDLE: "idle",
3
3
  PENDING: "pending",
4
4
  RESOLVED: "resolved",
@@ -8,7 +8,7 @@ const T = {
8
8
  // 0001 - Effect has been disposed
9
9
  EXECUTING: 2
10
10
  // 0010 - Effect is currently executing
11
- }, h = {
11
+ }, o = {
12
12
  DIRTY: 1,
13
13
  // 0001 - Needs recomputation
14
14
  IDLE: 2,
@@ -23,12 +23,12 @@ const T = {
23
23
  // 100000 - Currently recomputing
24
24
  HAS_ERROR: 64
25
25
  // 1000000 - Has error state
26
- }, ie = {
26
+ }, le = {
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
- }, A = {
31
+ }, P = {
32
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 */
@@ -43,13 +43,13 @@ const T = {
43
43
  * Increased from 1000 to 5000 based on evaluation report
44
44
  */
45
45
  MAX_EXECUTIONS_PER_FLUSH: 5e3
46
- }, k = {
46
+ }, j = {
47
47
  /** Maximum dependencies before warning about large dependency graphs */
48
48
  MAX_DEPENDENCIES: 1e3,
49
49
  /** Enable infinite loop detection warnings */
50
50
  WARN_INFINITE_LOOP: !0
51
- }, D = 1073741823, M = typeof process < "u" && process.env && process.env.NODE_ENV !== "production";
52
- class d extends Error {
51
+ }, T = 1073741823, d = typeof process < "u" && process.env && process.env.NODE_ENV !== "production";
52
+ class E extends Error {
53
53
  /**
54
54
  * Creates a new AtomError
55
55
  * @param message - Error message describing what went wrong
@@ -60,7 +60,7 @@ class d extends Error {
60
60
  super(e), this.name = "AtomError", this.cause = t, this.recoverable = s, this.timestamp = /* @__PURE__ */ new Date();
61
61
  }
62
62
  }
63
- class I extends d {
63
+ class C extends E {
64
64
  /**
65
65
  * Creates a new ComputedError
66
66
  * @param message - Error message
@@ -70,7 +70,7 @@ class I extends d {
70
70
  super(e, t, !0), this.name = "ComputedError";
71
71
  }
72
72
  }
73
- class g extends d {
73
+ class g extends E {
74
74
  /**
75
75
  * Creates a new EffectError
76
76
  * @param message - Error message
@@ -80,7 +80,7 @@ class g extends d {
80
80
  super(e, t, !1), this.name = "EffectError";
81
81
  }
82
82
  }
83
- class C extends d {
83
+ class A extends E {
84
84
  /**
85
85
  * Creates a new SchedulerError
86
86
  * @param message - Error message
@@ -90,20 +90,20 @@ class C extends d {
90
90
  super(e, t, !1), this.name = "SchedulerError";
91
91
  }
92
92
  }
93
- function R(i, e, t) {
93
+ function N(i, e, t) {
94
94
  if (i instanceof TypeError)
95
95
  return new e(`Type error (${t}): ${i.message}`, i);
96
96
  if (i instanceof ReferenceError)
97
97
  return new e(`Reference error (${t}): ${i.message}`, i);
98
- if (i instanceof d)
98
+ if (i instanceof E)
99
99
  return i;
100
100
  const s = i instanceof Error ? i.message : String(i), n = i instanceof Error ? i : null;
101
101
  return new e(`Unexpected error (${t}): ${s}`, n);
102
102
  }
103
- function X(i) {
103
+ function Q(i) {
104
104
  return i != null && typeof i.then == "function";
105
105
  }
106
- const a = {
106
+ const l = {
107
107
  // ─────────────────────────────────────────────────────────────────
108
108
  // Computed errors
109
109
  // ─────────────────────────────────────────────────────────────────
@@ -187,101 +187,150 @@ const a = {
187
187
  * @remarks This prevents cascading failures from masking the original error.
188
188
  */
189
189
  CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
190
+ }, w = /* @__PURE__ */ Symbol("debugName"), ee = /* @__PURE__ */ Symbol("id"), V = /* @__PURE__ */ Symbol("type"), X = /* @__PURE__ */ Symbol("noDefaultValue");
191
+ function te(i) {
192
+ return i !== null && typeof i == "object" && "dependencies" in i && Array.isArray(i.dependencies);
193
+ }
194
+ let G = 0;
195
+ function H(i, e, t) {
196
+ const s = i;
197
+ if (s._visitedEpoch !== t) {
198
+ if (s._visitedEpoch = t, i === e)
199
+ throw new C("Indirect circular dependency detected");
200
+ if (te(i)) {
201
+ const n = i.dependencies;
202
+ for (let r = 0; r < n.length; r++)
203
+ H(n[r], e, t);
204
+ }
205
+ }
206
+ }
207
+ const S = {
208
+ enabled: typeof process < "u" && process.env?.NODE_ENV === "development",
209
+ maxDependencies: j.MAX_DEPENDENCIES,
210
+ warnInfiniteLoop: j.WARN_INFINITE_LOOP,
211
+ warn(i, e) {
212
+ this.enabled && i && console.warn(`[Atom Effect] ${e}`);
213
+ },
214
+ /**
215
+ * Checks for circular dependencies.
216
+ * Direct check runs always; indirect check only in dev mode.
217
+ * @throws {ComputedError} When circular dependency detected
218
+ */
219
+ checkCircular(i, e, t) {
220
+ if (i === e)
221
+ throw new C("Direct circular dependency detected");
222
+ this.enabled && (G++, H(i, e, G));
223
+ },
224
+ attachDebugInfo(i, e, t) {
225
+ if (!this.enabled)
226
+ return;
227
+ const s = i;
228
+ s[w] = `${e}_${t}`, s[ee] = t, s[V] = e;
229
+ },
230
+ getDebugName(i) {
231
+ if (i !== null && typeof i == "object" && w in i)
232
+ return i[w];
233
+ },
234
+ getDebugType(i) {
235
+ if (i !== null && typeof i == "object" && V in i)
236
+ return i[V];
237
+ }
190
238
  };
191
- let P = 0;
192
- function G() {
193
- return P = (P + 1 | 0) & D, P;
239
+ let se = 1;
240
+ const ie = () => se++;
241
+ class J {
242
+ constructor() {
243
+ this.id = ie() & T, this.flags = 0;
244
+ }
194
245
  }
195
- let U = 0, w = 0, O = !1;
196
- function q() {
197
- return O ? (M && console.warn(
246
+ class W extends J {
247
+ constructor() {
248
+ super(), this.version = 0, this._lastSeenEpoch = -1;
249
+ }
250
+ /**
251
+ * Subscribes a listener function or Subscriber object to value changes.
252
+ *
253
+ * @param listener - Function or Subscriber object to call when the value changes
254
+ * @returns An unsubscribe function
255
+ * @throws {AtomError} If listener is not a function or Subscriber
256
+ */
257
+ subscribe(e) {
258
+ if (typeof e == "object" && e !== null && "execute" in e)
259
+ return this._objectSubscribers.add(e);
260
+ if (typeof e != "function")
261
+ throw new E(l.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
262
+ return this._functionSubscribers.add(e);
263
+ }
264
+ /**
265
+ * Gets the total number of active subscribers.
266
+ */
267
+ subscriberCount() {
268
+ return this._functionSubscribers.size + this._objectSubscribers.size;
269
+ }
270
+ /**
271
+ * Notifies all subscribers of a change.
272
+ *
273
+ * @param newValue - The new value
274
+ * @param oldValue - The old value
275
+ */
276
+ _notifySubscribers(e, t) {
277
+ this._functionSubscribers.forEachSafe(
278
+ (s) => s(e, t),
279
+ (s) => console.error(new E(l.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
280
+ ), this._objectSubscribers.forEachSafe(
281
+ (s) => s.execute(),
282
+ (s) => console.error(new E(l.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
283
+ );
284
+ }
285
+ }
286
+ let B = 0;
287
+ function K() {
288
+ return B = (B + 1 | 0) & T, B;
289
+ }
290
+ let v = 0, k = 0, L = !1;
291
+ function Y() {
292
+ return L ? (d && console.warn(
198
293
  "Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"
199
- ), !1) : (O = !0, U = U + 1 & D, w = 0, !0);
294
+ ), !1) : (L = !0, v = v + 1 & T, k = 0, !0);
200
295
  }
201
- function z() {
202
- O = !1;
296
+ function $() {
297
+ L = !1;
203
298
  }
204
- function H() {
205
- return O ? ++w : 0;
299
+ function ne() {
300
+ return L ? ++k : 0;
206
301
  }
207
- class J {
302
+ class re {
208
303
  constructor() {
209
304
  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;
210
305
  }
211
- /**
212
- * Gets the current phase of the scheduler.
213
- */
214
306
  get phase() {
215
307
  return this.isProcessing || this.isFlushingSync ? 2 : this.isBatching ? 1 : 0;
216
308
  }
217
- /**
218
- * Schedules a callback for execution.
219
- *
220
- * If batching is active or a sync flush is in progress, the callback
221
- * is added to the batch queue. Otherwise, it's added to the main queue
222
- * and a flush is triggered via microtask.
223
- *
224
- * @param callback - The function to schedule for execution
225
- * @throws {SchedulerError} If callback is not a function
226
- *
227
- * @example
228
- * ```typescript
229
- * scheduler.schedule(() => {
230
- * // This runs in the next microtask (or sync if batching)
231
- * updateUI();
232
- * });
233
- * ```
234
- */
235
309
  schedule(e) {
236
310
  if (typeof e != "function")
237
- throw new C("Scheduler callback must be a function");
311
+ throw new A("Scheduler callback must be a function");
238
312
  e._nextEpoch !== this._epoch && (e._nextEpoch = this._epoch, this.isBatching || this.isFlushingSync ? this.batchQueue[this.batchQueueSize++] = e : (this.queue[this.queueSize++] = e, this.isProcessing || this.flush()));
239
313
  }
240
- /**
241
- * Flushes the queue asynchronously via microtask.
242
- *
243
- * Executes all queued callbacks in a microtask, allowing the current
244
- * synchronous execution to complete first. Errors in individual
245
- * callbacks are caught and logged without interrupting others.
246
- *
247
- * @private
248
- * @remarks
249
- * This method is idempotent - calling it multiple times while
250
- * processing is active has no effect.
251
- */
252
314
  flush() {
253
315
  if (this.isProcessing || this.queueSize === 0) return;
254
316
  this.isProcessing = !0;
255
317
  const e = this.queue, t = this.queueSize;
256
318
  this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++, queueMicrotask(() => {
257
- const s = q();
319
+ const s = Y();
258
320
  for (let n = 0; n < t; n++)
259
321
  try {
260
322
  e[n]?.();
261
323
  } catch (r) {
262
324
  console.error(
263
- new C("Error occurred during scheduler execution", r)
325
+ new A("Error occurred during scheduler execution", r)
264
326
  );
265
327
  }
266
- e.length = 0, this.isProcessing = !1, s && z(), this.queueSize > 0 && !this.isBatching && this.flush();
328
+ e.length = 0, this.isProcessing = !1, s && $(), this.queueSize > 0 && !this.isBatching && this.flush();
267
329
  });
268
330
  }
269
- /**
270
- * Flushes all queued callbacks synchronously.
271
- *
272
- * This method is called when a batch ends. It processes all callbacks
273
- * in the batch queue and main queue synchronously, allowing callbacks
274
- * to schedule additional callbacks that are processed in the same flush.
275
- *
276
- * @private
277
- * @remarks
278
- * - Includes infinite loop protection via maxFlushIterations
279
- * - Errors in callbacks are caught and logged individually
280
- * - The isFlushingSync flag prevents re-entrancy issues
281
- */
282
331
  flushSync() {
283
332
  this.isFlushingSync = !0;
284
- const e = q();
333
+ const e = Y();
285
334
  try {
286
335
  if (this._epoch++, this.batchQueueSize > 0) {
287
336
  for (let s = 0; s < this.batchQueueSize; s++) {
@@ -294,8 +343,8 @@ class J {
294
343
  for (; this.queueSize > 0; ) {
295
344
  if (++t > this.maxFlushIterations) {
296
345
  console.error(
297
- new C(
298
- `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`
346
+ new A(
347
+ `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`
299
348
  )
300
349
  ), this.queueSize = 0, this.queue.length = 0, this.batchQueueSize = 0;
301
350
  break;
@@ -307,7 +356,7 @@ class J {
307
356
  s[r]?.();
308
357
  } catch (c) {
309
358
  console.error(
310
- new C("Error occurred during batch execution", c)
359
+ new A("Error occurred during batch execution", c)
311
360
  );
312
361
  }
313
362
  if (s.length = 0, this.batchQueueSize > 0) {
@@ -317,94 +366,36 @@ class J {
317
366
  }
318
367
  }
319
368
  } finally {
320
- this.isFlushingSync = !1, e && z();
369
+ this.isFlushingSync = !1, e && $();
321
370
  }
322
371
  }
323
- /**
324
- * Starts a new batch operation.
325
- *
326
- * While batching is active, all scheduled callbacks are deferred
327
- * until endBatch() is called. Batches can be nested - only the
328
- * outermost endBatch() triggers execution.
329
- *
330
- * @example
331
- * ```typescript
332
- * scheduler.startBatch();
333
- * // All updates here are deferred
334
- * atom1.value = 'a';
335
- * atom2.value = 'b';
336
- * scheduler.endBatch(); // Both updates processed together
337
- * ```
338
- */
339
372
  startBatch() {
340
373
  this.batchDepth++, this.isBatching = !0;
341
374
  }
342
- /**
343
- * Ends a batch operation.
344
- *
345
- * Decrements the batch depth counter. When depth reaches zero,
346
- * all queued callbacks are flushed synchronously and batching
347
- * is disabled.
348
- *
349
- * @remarks
350
- * Safe to call even if startBatch() wasn't called - depth is
351
- * clamped to zero minimum.
352
- *
353
- * @example
354
- * ```typescript
355
- * scheduler.startBatch();
356
- * try {
357
- * // ... batched operations
358
- * } finally {
359
- * scheduler.endBatch(); // Always end batch, even on error
360
- * }
361
- * ```
362
- */
363
375
  endBatch() {
364
376
  this.batchDepth = Math.max(0, this.batchDepth - 1), this.batchDepth === 0 && (this.flushSync(), this.isBatching = !1);
365
377
  }
366
- /**
367
- * Sets the maximum number of flush iterations allowed.
368
- *
369
- * This limit prevents infinite loops when reactive dependencies
370
- * form cycles. If exceeded, the queue is cleared and an error
371
- * is logged.
372
- *
373
- * @param max - Maximum iterations (must be at least 10)
374
- * @throws {SchedulerError} If max is less than 10
375
- *
376
- * @example
377
- * ```typescript
378
- * // Increase limit for complex dependency graphs
379
- * scheduler.setMaxFlushIterations(5000);
380
- * ```
381
- */
382
378
  setMaxFlushIterations(e) {
383
379
  if (e < 10)
384
- throw new C("Max flush iterations must be at least 10");
380
+ throw new A("Max flush iterations must be at least 10");
385
381
  this.maxFlushIterations = e;
386
382
  }
387
383
  }
388
- const N = new J();
389
- function ne(i) {
384
+ const U = new re();
385
+ function ae(i) {
390
386
  if (typeof i != "function")
391
- throw new d("Batch callback must be a function");
392
- N.startBatch();
387
+ throw new E("Batch callback must be a function");
388
+ U.startBatch();
393
389
  try {
394
390
  return i();
395
391
  } catch (e) {
396
- throw new d("Error occurred during batch execution", e);
392
+ throw new E("Error occurred during batch execution", e);
397
393
  } finally {
398
- N.endBatch();
394
+ U.endBatch();
399
395
  }
400
396
  }
401
397
  const m = {
402
- /** @inheritdoc */
403
398
  current: null,
404
- /**
405
- * @inheritdoc
406
- * @throws Re-throws any error from the executed function after restoring context
407
- */
408
399
  run(i, e) {
409
400
  const t = this.current;
410
401
  this.current = i;
@@ -414,192 +405,28 @@ const m = {
414
405
  this.current = t;
415
406
  }
416
407
  },
417
- /** @inheritdoc */
418
408
  getCurrent() {
419
409
  return this.current;
420
410
  }
421
411
  };
422
- function re(i) {
412
+ function ce(i) {
423
413
  if (typeof i != "function")
424
- throw new d("Untracked callback must be a function");
414
+ throw new E("Untracked callback must be a function");
425
415
  const e = m.current;
426
416
  m.current = null;
427
417
  try {
428
418
  return i();
429
419
  } catch (t) {
430
- throw new d("Error occurred during untracked execution", t);
420
+ throw new E("Error occurred during untracked execution", t);
431
421
  } finally {
432
422
  m.current = e;
433
423
  }
434
424
  }
435
- const v = /* @__PURE__ */ Symbol("debugName"), W = /* @__PURE__ */ Symbol("id"), L = /* @__PURE__ */ Symbol("type"), V = /* @__PURE__ */ Symbol("noDefaultValue");
436
- function K(i) {
437
- return i !== null && typeof i == "object" && "dependencies" in i && Array.isArray(i.dependencies);
438
- }
439
- let j = 0;
440
- function Y(i, e, t) {
441
- const s = i;
442
- if (s._visitedEpoch !== t) {
443
- if (s._visitedEpoch = t, i === e)
444
- throw new I("Indirect circular dependency detected");
445
- if (K(i)) {
446
- const n = i.dependencies;
447
- for (let r = 0; r < n.length; r++)
448
- Y(n[r], e, t);
449
- }
450
- }
451
- }
452
- const b = {
453
- /**
454
- * Whether debug mode is enabled.
455
- *
456
- * @remarks
457
- * Automatically set based on `NODE_ENV` environment variable.
458
- * Only `'development'` enables debug features.
459
- */
460
- enabled: typeof process < "u" && process.env?.NODE_ENV === "development",
461
- /**
462
- * Maximum number of dependencies before warning.
463
- *
464
- * @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}
465
- */
466
- maxDependencies: k.MAX_DEPENDENCIES,
467
- /**
468
- * Whether to warn about potential infinite loops.
469
- *
470
- * @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}
471
- */
472
- warnInfiniteLoop: k.WARN_INFINITE_LOOP,
473
- /**
474
- * Logs a warning message when condition is true and debug is enabled.
475
- *
476
- * @param condition - When true, the warning is logged
477
- * @param message - The warning message to display
478
- *
479
- * @example
480
- * ```typescript
481
- * debug.warn(deps.length > 100, 'Large dependency graph detected');
482
- * ```
483
- */
484
- warn(i, e) {
485
- this.enabled && i && console.warn(`[Atom Effect] ${e}`);
486
- },
487
- /**
488
- * Checks for circular dependencies in the dependency graph.
489
- *
490
- * Detects two types of circular references:
491
- * 1. **Direct**: A depends on itself (A → A)
492
- * 2. **Indirect**: A depends on B which depends on A (A → B → A)
493
- *
494
- * @param dep - The dependency being added
495
- * @param current - The current reactive object adding the dependency
496
- * @param visited - Set of already visited nodes (for recursion)
497
- *
498
- * @throws {ComputedError} When a circular dependency is detected
499
- *
500
- * @remarks
501
- * - Direct circular detection runs in all environments
502
- * - Indirect circular detection only runs in development mode
503
- * - Uses depth-first traversal with O(n) time complexity
504
- *
505
- * @example
506
- * ```typescript
507
- * // This will throw for direct circular reference
508
- * debug.checkCircular(computedA, computedA);
509
- *
510
- * // This will throw for indirect circular reference (dev only)
511
- * // Given: A → B → C → A
512
- * debug.checkCircular(computedC, computedA);
513
- * ```
514
- */
515
- checkCircular(i, e, t) {
516
- if (i === e)
517
- throw new I("Direct circular dependency detected");
518
- this.enabled && (j++, Y(i, e, j));
519
- },
520
- /**
521
- * Attaches debug metadata to a reactive object.
522
- *
523
- * @param obj - The object to attach metadata to
524
- * @param type - The type of reactive object ('atom' | 'computed' | 'effect')
525
- * @param id - The unique identifier for this object
526
- *
527
- * @remarks
528
- * Only attaches metadata when debug mode is enabled.
529
- * Uses symbol keys to avoid property name collisions.
530
- *
531
- * @example
532
- * ```typescript
533
- * const atom = createAtomInternal(0);
534
- * debug.attachDebugInfo(atom, 'atom', 1);
535
- * // atom[DEBUG_NAME] === 'atom_1'
536
- * // atom[DEBUG_ID] === 1
537
- * // atom[DEBUG_TYPE] === 'atom'
538
- * ```
539
- */
540
- attachDebugInfo(i, e, t) {
541
- if (!this.enabled)
542
- return;
543
- const s = i;
544
- s[v] = `${e}_${t}`, s[W] = t, s[L] = e;
545
- },
546
- /**
547
- * Retrieves the debug display name from a reactive object.
548
- *
549
- * @param obj - The object to get the name from
550
- * @returns The debug name (e.g., 'atom_1') or undefined if not set
551
- *
552
- * @example
553
- * ```typescript
554
- * const name = debug.getDebugName(myAtom);
555
- * console.log(`Updating ${name ?? 'unknown'}`);
556
- * ```
557
- */
558
- getDebugName(i) {
559
- if (i !== null && typeof i == "object" && v in i)
560
- return i[v];
561
- },
562
- /**
563
- * Retrieves the debug type from a reactive object.
564
- *
565
- * @param obj - The object to get the type from
566
- * @returns The type ('atom' | 'computed' | 'effect') or undefined if not set
567
- *
568
- * @example
569
- * ```typescript
570
- * const type = debug.getDebugType(reactiveObj);
571
- * if (type === 'computed') {
572
- * // Handle computed-specific logic
573
- * }
574
- * ```
575
- */
576
- getDebugType(i) {
577
- if (i !== null && typeof i == "object" && L in i)
578
- return i[L];
579
- }
580
- };
581
- let Z = 1;
582
- const B = () => Z++;
583
- class x {
425
+ class M {
584
426
  constructor() {
585
427
  this.subscribers = null;
586
428
  }
587
- /**
588
- * Adds a subscriber and returns an unsubscribe function
589
- *
590
- * Performs lazy initialization on first subscriber.
591
- * Duplicate subscribers are ignored (idempotent).
592
- *
593
- * @param subscriber - Function to add as subscriber
594
- * @returns Unsubscribe function
595
- *
596
- * @example
597
- * ```ts
598
- * const unsub = manager.add((value) => console.log(value));
599
- * // Later...
600
- * unsub(); // Remove this subscriber
601
- * ```
602
- */
429
+ /** Adds subscriber and returns unsubscribe function (idempotent) */
603
430
  add(e) {
604
431
  if (this.subscribers || (this.subscribers = []), this.subscribers.indexOf(e) !== -1)
605
432
  return () => {
@@ -610,16 +437,7 @@ class x {
610
437
  t || (t = !0, this.remove(e));
611
438
  };
612
439
  }
613
- /**
614
- * Removes a subscriber using swap-and-pop optimization
615
- *
616
- * Linear search + O(1) swap-and-pop removal.
617
- * For small arrays, this is faster than hash-based approaches
618
- * due to cache locality.
619
- *
620
- * @param subscriber - Subscriber to remove
621
- * @returns True if removed, false if not found
622
- */
440
+ /** Removes subscriber using swap-and-pop */
623
441
  remove(e) {
624
442
  if (!this.subscribers)
625
443
  return !1;
@@ -629,44 +447,15 @@ class x {
629
447
  const s = this.subscribers.length - 1;
630
448
  return t !== s && (this.subscribers[t] = this.subscribers[s]), this.subscribers.pop(), !0;
631
449
  }
632
- /**
633
- * Checks if a subscriber is registered
634
- *
635
- * @param subscriber - Subscriber to check
636
- * @returns True if registered
637
- */
638
450
  has(e) {
639
451
  return this.subscribers ? this.subscribers.indexOf(e) !== -1 : !1;
640
452
  }
641
- /**
642
- * Iterates over all subscribers with a callback
643
- *
644
- * Optimized for cache-friendly sequential access.
645
- * Errors in callbacks are propagated to the caller.
646
- *
647
- * @param fn - Callback to execute for each subscriber
648
- *
649
- * @example
650
- * ```ts
651
- * manager.forEach((subscriber) => {
652
- * subscriber(newValue, oldValue);
653
- * });
654
- * ```
655
- */
656
453
  forEach(e) {
657
454
  if (this.subscribers)
658
455
  for (let t = 0; t < this.subscribers.length; t++)
659
456
  e(this.subscribers[t], t);
660
457
  }
661
- /**
662
- * Safely iterates over subscribers with error handling
663
- *
664
- * Catches and logs errors from individual callbacks to prevent
665
- * one failing subscriber from breaking the entire notification chain.
666
- *
667
- * @param fn - Callback to execute for each subscriber
668
- * @param onError - Optional error handler for each callback error
669
- */
458
+ /** Iterates with error handling to prevent one failure from breaking the chain */
670
459
  forEachSafe(e, t) {
671
460
  if (this.subscribers)
672
461
  for (let s = 0; s < this.subscribers.length; s++)
@@ -676,224 +465,101 @@ class x {
676
465
  t ? t(n) : console.error("[SubscriberManager] Error in subscriber callback:", n);
677
466
  }
678
467
  }
679
- /**
680
- * Gets the current number of subscribers
681
- *
682
- * @returns Number of active subscribers
683
- */
684
468
  get size() {
685
469
  return this.subscribers?.length ?? 0;
686
470
  }
687
- /**
688
- * Checks if there are any subscribers
689
- *
690
- * @returns True if at least one subscriber exists
691
- */
692
471
  get hasSubscribers() {
693
472
  return this.size > 0;
694
473
  }
695
- /**
696
- * Clears all subscribers
697
- *
698
- * Removes all subscribers and releases memory.
699
- * Subsequent operations will re-initialize lazily.
700
- */
701
474
  clear() {
702
475
  this.subscribers = null;
703
476
  }
704
- /**
705
- * Gets a copy of all subscribers as an array
706
- *
707
- * Useful for debugging or manual iteration.
708
- * Returns empty array if no subscribers.
709
- *
710
- * @returns Array of all subscribers
711
- */
712
477
  toArray() {
713
478
  return this.subscribers ? [...this.subscribers] : [];
714
479
  }
715
480
  }
716
- class ee {
717
- /**
718
- * Creates a new AtomImpl instance.
719
- *
720
- * @param initialValue - The initial value of the atom
721
- * @param sync - Whether to notify subscribers synchronously
722
- */
481
+ class ue extends W {
723
482
  constructor(e, t) {
724
- this._isNotificationScheduled = !1, this.id = B() & D, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = e, this._functionSubscribers = new x(), this._objectSubscribers = new x(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), b.attachDebugInfo(this, "atom", this.id);
483
+ super(), this._isNotificationScheduled = !1, this._value = e, this._functionSubscribersStore = new M(), this._objectSubscribersStore = new M(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), S.attachDebugInfo(this, "atom", this.id);
725
484
  }
726
- /**
727
- * Gets the current value and registers the atom as a dependency
728
- * in the current tracking context.
729
- *
730
- * @returns The current value
731
- *
732
- * @remarks
733
- * This getter automatically tracks dependencies when accessed within
734
- * a computed or effect context.
735
- */
485
+ get _functionSubscribers() {
486
+ return this._functionSubscribersStore;
487
+ }
488
+ get _objectSubscribers() {
489
+ return this._objectSubscribersStore;
490
+ }
491
+ /** Gets value and registers as dependency in current tracking context */
736
492
  get value() {
737
493
  const e = m.getCurrent();
738
494
  return e != null && this._track(e), this._value;
739
495
  }
740
- /**
741
- * Sets a new value and notifies all subscribers if the value changed.
742
- *
743
- * @param newValue - The new value to set
744
- *
745
- * @remarks
746
- * Uses Object.is for equality comparison. If the value is unchanged,
747
- * no notifications are sent. Notifications may be batched unless
748
- * sync mode is enabled.
749
- */
496
+ /** Sets value and notifies subscribers if changed (uses Object.is) */
750
497
  set value(e) {
751
498
  if (Object.is(this._value, e)) return;
752
499
  const t = this._value;
753
- this.version = this.version + 1 & D;
500
+ this.version = this.version + 1 & T;
754
501
  const s = this.version;
755
- this._value = e, !(!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers) && this._notify(e, t, s);
502
+ this._value = e, !(!this._functionSubscribersStore.hasSubscribers && !this._objectSubscribersStore.hasSubscribers) && this._notify(e, t, s);
756
503
  }
757
- /**
758
- * Tracks the current context as a dependency of this atom.
759
- *
760
- * @param current - The current tracking context (function or object)
761
- *
762
- * @remarks
763
- * Handles both function-based trackers (with optional addDependency method)
764
- * and object-based trackers (with execute or addDependency methods).
765
- */
766
504
  _track(e) {
767
505
  if (typeof e == "function") {
768
506
  const t = e;
769
- t.addDependency !== void 0 ? t.addDependency(this) : this._functionSubscribers.add(e);
507
+ t.addDependency !== void 0 ? t.addDependency(this) : this._functionSubscribersStore.add(e);
770
508
  } else {
771
509
  const t = e;
772
- t.addDependency !== void 0 ? t.addDependency(this) : t.execute !== void 0 && this._objectSubscribers.add(t);
510
+ t.addDependency !== void 0 ? t.addDependency(this) : t.execute !== void 0 && this._objectSubscribersStore.add(t);
773
511
  }
774
512
  }
775
- /**
776
- * Notifies all subscribers of a value change.
777
- *
778
- * @param newValue - The new value
779
- * @param oldValue - The previous value
780
- * @param currentVersion - The version at the time of change
781
- *
782
- * @remarks
783
- * Notifications are skipped if the version has changed (stale update).
784
- * Errors from individual subscribers are caught and logged without
785
- * interrupting other subscribers.
786
- */
787
- /**
788
- * Schedules a notification.
789
- * Uses coalescing: if a notification is already scheduled, we update the state
790
- * but don't schedule a new task. The pending task will see the latest value.
791
- */
792
513
  _notify(e, t, s) {
793
- this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !N.isBatching ? this._flushNotifications() : N.schedule(this._notifyTask);
514
+ this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !U.isBatching ? this._flushNotifications() : U.schedule(this._notifyTask);
794
515
  }
795
- /**
796
- * Executes the pending notifications.
797
- * Bound to 'this' in constructor to avoid closure allocation.
798
- */
799
516
  _flushNotifications() {
800
517
  if (!this._isNotificationScheduled) return;
801
518
  const e = this._pendingOldValue, t = this._value;
802
- this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._functionSubscribers.forEachSafe(
803
- (s) => s(t, e),
804
- (s) => console.error(new d(a.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
805
- ), this._objectSubscribers.forEachSafe(
806
- (s) => s.execute(),
807
- (s) => console.error(new d(a.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
808
- );
809
- }
810
- /**
811
- * Subscribes a listener function or Subscriber object to value changes.
812
- *
813
- * @param listener - Function or Subscriber object to call when the value changes
814
- * @returns An unsubscribe function
815
- * @throws {AtomError} If listener is not a function or Subscriber
816
- *
817
- * @example
818
- * ```ts
819
- * const unsub = myAtom.subscribe((newVal, oldVal) => {
820
- * console.log(`Changed from ${oldVal} to ${newVal}`);
821
- * });
822
- * // Later: unsub();
823
- * ```
824
- */
825
- subscribe(e) {
826
- if (typeof e == "object" && e !== null && "execute" in e)
827
- return this._objectSubscribers.add(e);
828
- if (typeof e != "function")
829
- throw new d(a.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
830
- return this._functionSubscribers.add(e);
519
+ this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._notifySubscribers(t, e);
831
520
  }
832
- /**
833
- * Gets the current value without registering as a dependency.
834
- *
835
- * @returns The current value
836
- *
837
- * @remarks
838
- * Use this method when you need to read the value without
839
- * creating a reactive dependency (e.g., in event handlers).
840
- */
521
+ /** Gets value without registering as dependency */
841
522
  peek() {
842
523
  return this._value;
843
524
  }
844
- /**
845
- * Disposes the atom, clearing all subscribers and releasing resources.
846
- *
847
- * @remarks
848
- * After disposal, the atom should not be used. The value is set to
849
- * undefined to help with garbage collection.
850
- */
851
525
  dispose() {
852
- this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._value = void 0;
853
- }
854
- /**
855
- * Gets the total number of active subscribers.
856
- *
857
- * @returns The count of function and object subscribers combined
858
- */
859
- subscriberCount() {
860
- return this._functionSubscribers.size + this._objectSubscribers.size;
526
+ this._functionSubscribersStore.clear(), this._objectSubscribersStore.clear(), this._value = void 0;
861
527
  }
862
528
  }
863
- function ce(i, e = {}) {
864
- return new ee(i, e.sync ?? !1);
529
+ function _e(i, e = {}) {
530
+ return new ue(i, e.sync ?? !1);
865
531
  }
866
- const p = process.env.NODE_ENV !== "production", f = Object.freeze([]), E = Object.freeze([]);
867
- class $ {
532
+ const _ = Object.freeze([]), b = Object.freeze([]), f = Object.freeze([]);
533
+ class z {
868
534
  constructor() {
869
- this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = p ? {
535
+ this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = d ? {
870
536
  acquired: 0,
871
537
  released: 0,
872
538
  rejected: { frozen: 0, tooLarge: 0, poolFull: 0 }
873
539
  } : null;
874
540
  }
875
541
  acquire() {
876
- return p && this.stats && this.stats.acquired++, this.pool.pop() ?? [];
542
+ return d && this.stats && this.stats.acquired++, this.pool.pop() ?? [];
877
543
  }
878
544
  release(e, t) {
879
545
  if (!(t && e === t)) {
880
546
  if (Object.isFrozen(e)) {
881
- p && this.stats && this.stats.rejected.frozen++;
547
+ d && this.stats && this.stats.rejected.frozen++;
882
548
  return;
883
549
  }
884
550
  if (e.length > this.maxReusableCapacity) {
885
- p && this.stats && this.stats.rejected.tooLarge++;
551
+ d && this.stats && this.stats.rejected.tooLarge++;
886
552
  return;
887
553
  }
888
554
  if (this.pool.length >= this.maxPoolSize) {
889
- p && this.stats && this.stats.rejected.poolFull++;
555
+ d && this.stats && this.stats.rejected.poolFull++;
890
556
  return;
891
557
  }
892
- e.length = 0, this.pool.push(e), p && this.stats && this.stats.released++;
558
+ e.length = 0, this.pool.push(e), d && this.stats && this.stats.released++;
893
559
  }
894
560
  }
895
561
  getStats() {
896
- if (!p || !this.stats) return null;
562
+ if (!d || !this.stats) return null;
897
563
  const { acquired: e, released: t, rejected: s } = this.stats, n = s.frozen + s.tooLarge + s.poolFull;
898
564
  return {
899
565
  acquired: e,
@@ -904,28 +570,47 @@ class $ {
904
570
  };
905
571
  }
906
572
  reset() {
907
- this.pool.length = 0, p && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
573
+ this.pool.length = 0, d && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
908
574
  }
909
575
  }
910
- const S = new $(), y = new $();
911
- class Q {
576
+ const y = new z(), I = new z(), p = new z();
577
+ function q(i, e, t, s) {
578
+ if (e !== _ && t !== b)
579
+ for (let r = 0; r < e.length; r++) {
580
+ const c = e[r];
581
+ c && (c._tempUnsub = t[r]);
582
+ }
583
+ const n = I.acquire();
584
+ n.length = i.length;
585
+ for (let r = 0; r < i.length; r++) {
586
+ const c = i[r];
587
+ c && (c._tempUnsub ? (n[r] = c._tempUnsub, c._tempUnsub = void 0) : (S.checkCircular(c, s), n[r] = c.subscribe(s)));
588
+ }
589
+ if (e !== _)
590
+ for (let r = 0; r < e.length; r++) {
591
+ const c = e[r];
592
+ c?._tempUnsub && (c._tempUnsub(), c._tempUnsub = void 0);
593
+ }
594
+ return t !== b && I.release(t), n;
595
+ }
596
+ class Z extends W {
912
597
  constructor(e, t = {}) {
913
598
  if (typeof e != "function")
914
- throw new I(a.COMPUTED_MUST_BE_FUNCTION);
915
- if (this.id = B() & D, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = void 0, this._stateFlags = h.DIRTY | h.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : V, this._hasDefaultValue = this._defaultValue !== V, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new x(), this._objectSubscribers = new x(), this._dependencies = f, this._unsubscribes = E, this._notifyJob = () => {
916
- this._functionSubscribers.forEachSafe(
599
+ throw new C(l.COMPUTED_MUST_BE_FUNCTION);
600
+ if (super(), this._value = void 0, this.flags = o.DIRTY | o.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : X, this._hasDefaultValue = this._defaultValue !== X, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribersStore = new M(), this._objectSubscribersStore = new M(), this._dependencies = _, this._dependencyVersions = f, this._unsubscribes = b, this._notifyJob = () => {
601
+ this._functionSubscribersStore.forEachSafe(
917
602
  (s) => s(),
918
603
  (s) => console.error(s)
919
- ), this._objectSubscribers.forEachSafe(
604
+ ), this._objectSubscribersStore.forEachSafe(
920
605
  (s) => s.execute(),
921
606
  (s) => console.error(s)
922
607
  );
923
608
  }, this._trackable = Object.assign(() => this._markDirty(), {
924
609
  addDependency: (s) => {
925
610
  }
926
- }), b.attachDebugInfo(this, "computed", this.id), b.enabled) {
611
+ }), S.attachDebugInfo(this, "computed", this.id), S.enabled) {
927
612
  const s = this;
928
- s.subscriberCount = () => this._functionSubscribers.size + this._objectSubscribers.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencies, s.stateFlags = this._getFlagsAsString();
613
+ s.subscriberCount = () => this._functionSubscribersStore.size + this._objectSubscribersStore.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencies, s.stateFlags = this._getFlagsAsString();
929
614
  }
930
615
  if (t.lazy === !1)
931
616
  try {
@@ -933,19 +618,15 @@ class Q {
933
618
  } catch {
934
619
  }
935
620
  }
936
- // === PUBLIC API ===
937
- get value() {
938
- if ((this._stateFlags & (h.RESOLVED | h.DIRTY)) === h.RESOLVED)
939
- return this._registerTracking(), this._value;
940
- const t = this._computeValue();
941
- return this._registerTracking(), t;
621
+ get _functionSubscribers() {
622
+ return this._functionSubscribersStore;
942
623
  }
943
- subscribe(e) {
944
- if (typeof e == "object" && e !== null && "execute" in e)
945
- return this._objectSubscribers.add(e);
946
- if (typeof e != "function")
947
- throw new I(a.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
948
- return this._functionSubscribers.add(e);
624
+ get _objectSubscribers() {
625
+ return this._objectSubscribersStore;
626
+ }
627
+ get value() {
628
+ const e = this._computeValue();
629
+ return this._registerTracking(), e;
949
630
  }
950
631
  peek() {
951
632
  return this._value;
@@ -966,126 +647,97 @@ class Q {
966
647
  return this._isResolved();
967
648
  }
968
649
  invalidate() {
969
- this._markDirty();
650
+ this._markDirty(), this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f);
970
651
  }
971
652
  dispose() {
972
- if (this._unsubscribes !== E) {
653
+ if (this._unsubscribes !== b) {
973
654
  for (let e = 0; e < this._unsubscribes.length; e++) {
974
655
  const t = this._unsubscribes[e];
975
656
  t && t();
976
657
  }
977
- y.release(this._unsubscribes), this._unsubscribes = E;
658
+ I.release(this._unsubscribes), this._unsubscribes = b;
978
659
  }
979
- this._dependencies !== f && (S.release(this._dependencies), this._dependencies = f), this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._stateFlags = h.DIRTY | h.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
660
+ this._dependencies !== _ && (y.release(this._dependencies), this._dependencies = _), this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f), this._functionSubscribersStore.clear(), this._objectSubscribersStore.clear(), this.flags = o.DIRTY | o.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
980
661
  }
981
- // === PRIVATE: State Flag Operations (inlined for performance) ===
662
+ // State flag operations
982
663
  _isDirty() {
983
- return (this._stateFlags & h.DIRTY) !== 0;
664
+ return (this.flags & o.DIRTY) !== 0;
984
665
  }
985
666
  _setDirty() {
986
- this._stateFlags |= h.DIRTY;
667
+ this.flags |= o.DIRTY;
987
668
  }
988
669
  _clearDirty() {
989
- this._stateFlags &= -2;
670
+ this.flags &= -2;
990
671
  }
991
672
  _isIdle() {
992
- return (this._stateFlags & h.IDLE) !== 0;
673
+ return (this.flags & o.IDLE) !== 0;
993
674
  }
994
675
  _setIdle() {
995
- this._stateFlags |= h.IDLE, this._stateFlags &= -29;
676
+ this.flags |= o.IDLE, this.flags &= -29;
996
677
  }
997
678
  _isPending() {
998
- return (this._stateFlags & h.PENDING) !== 0;
679
+ return (this.flags & o.PENDING) !== 0;
999
680
  }
1000
681
  _setPending() {
1001
- this._stateFlags |= h.PENDING, this._stateFlags &= -27;
682
+ this.flags |= o.PENDING, this.flags &= -27;
1002
683
  }
1003
684
  _isResolved() {
1004
- return (this._stateFlags & h.RESOLVED) !== 0;
685
+ return (this.flags & o.RESOLVED) !== 0;
1005
686
  }
1006
687
  _setResolved() {
1007
- this._stateFlags |= h.RESOLVED, this._stateFlags &= -87;
688
+ this.flags |= o.RESOLVED, this.flags &= -87;
1008
689
  }
1009
690
  _isRejected() {
1010
- return (this._stateFlags & h.REJECTED) !== 0;
691
+ return (this.flags & o.REJECTED) !== 0;
1011
692
  }
1012
693
  _setRejected() {
1013
- this._stateFlags |= h.REJECTED | h.HAS_ERROR, this._stateFlags &= -15;
694
+ this.flags |= o.REJECTED | o.HAS_ERROR, this.flags &= -15;
1014
695
  }
1015
696
  _isRecomputing() {
1016
- return (this._stateFlags & h.RECOMPUTING) !== 0;
697
+ return (this.flags & o.RECOMPUTING) !== 0;
1017
698
  }
1018
699
  _setRecomputing(e) {
1019
- const t = h.RECOMPUTING;
1020
- this._stateFlags = this._stateFlags & ~t | -Number(e) & t;
700
+ const t = o.RECOMPUTING;
701
+ this.flags = this.flags & ~t | -Number(e) & t;
1021
702
  }
1022
703
  _getAsyncState() {
1023
- return this._isPending() ? T.PENDING : this._isResolved() ? T.RESOLVED : this._isRejected() ? T.REJECTED : T.IDLE;
704
+ return this._isPending() ? O.PENDING : this._isResolved() ? O.RESOLVED : this._isRejected() ? O.REJECTED : O.IDLE;
1024
705
  }
1025
706
  _getFlagsAsString() {
1026
707
  const e = [];
1027
708
  return this._isDirty() && e.push("DIRTY"), this._isIdle() && e.push("IDLE"), this._isPending() && e.push("PENDING"), this._isResolved() && e.push("RESOLVED"), this._isRejected() && e.push("REJECTED"), this._isRecomputing() && e.push("RECOMPUTING"), e.join(" | ");
1028
709
  }
1029
- // === PRIVATE: Core Computation Logic ===
1030
710
  _computeValue() {
1031
- return this._isRecomputing() ? this._value : this._isPending() ? this._handlePending() : this._isRejected() ? this._handleRejected() : (this._isDirty() || this._isIdle()) && (this._recompute(), this._isPending()) ? this._handlePending() : this._value;
711
+ return this._isRecomputing() ? this._value : ((this._isDirty() || this._isIdle()) && this._recompute(), this._isPending() ? this._handlePending() : this._isRejected() ? this._handleRejected() : this._value);
1032
712
  }
1033
713
  _recompute() {
1034
- if (!this._isDirty() && this._isResolved())
1035
- return;
714
+ if (this._isRecomputing()) return;
1036
715
  this._setRecomputing(!0);
1037
- const e = this._dependencies, t = S.acquire(), s = G();
1038
- let n = 0;
1039
- const r = (_) => {
1040
- _._lastSeenEpoch !== s && (_._lastSeenEpoch = s, n < t.length ? t[n] = _ : t.push(_), n++);
1041
- }, c = this._trackable.addDependency;
1042
- this._trackable.addDependency = r;
1043
- let o = !1;
716
+ const e = this._dependencies, t = this._dependencyVersions, s = y.acquire(), n = p.acquire(), r = K();
717
+ let c = 0;
718
+ const x = (h) => {
719
+ h._lastSeenEpoch !== r && (h._lastSeenEpoch = r, c < s.length ? (s[c] = h, n[c] = h.version) : (s.push(h), n.push(h.version)), c++);
720
+ }, D = this._trackable.addDependency;
721
+ this._trackable.addDependency = x;
722
+ let R = !1;
1044
723
  try {
1045
- const _ = m.run(this._trackable, this._fn);
1046
- if (t.length = n, X(_)) {
1047
- this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, o = !0, this._handleAsyncComputation(_), this._setRecomputing(!1);
724
+ const h = m.run(this._trackable, this._fn);
725
+ if (s.length = c, n.length = c, Q(h)) {
726
+ this._unsubscribes = q(s, e, this._unsubscribes, this), this._dependencies = s, this._dependencyVersions = n, R = !0, this._handleAsyncComputation(h), this._setRecomputing(!1);
1048
727
  return;
1049
728
  }
1050
- this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, o = !0, this._handleSyncResult(_);
1051
- } catch (_) {
1052
- t.length = n, this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, this._handleComputationError(_);
729
+ this._unsubscribes = q(s, e, this._unsubscribes, this), this._dependencies = s, this._dependencyVersions = n, R = !0, this._handleSyncResult(h);
730
+ } catch (h) {
731
+ s.length = c, n.length = c, this._unsubscribes = q(s, e, this._unsubscribes, this), this._dependencies = s, this._dependencyVersions = n, R = !0, this._handleComputationError(h);
1053
732
  } finally {
1054
- this._trackable.addDependency = c, o ? e !== f && S.release(e) : S.release(t);
1055
- }
1056
- }
1057
- /**
1058
- * Synchronizes subscriptions based on dependency changes.
1059
- * O(N) Diff using Epoch.
1060
- */
1061
- /**
1062
- * Synchronizes subscriptions based on dependency changes using O(N) strategy.
1063
- * Maps unsubs 1:1 with dependencies array.
1064
- */
1065
- _syncDependencies(e, t, s, n) {
1066
- if (e !== f && s !== E)
1067
- for (let c = 0; c < e.length; c++) {
1068
- const o = e[c];
1069
- o && (o._tempUnsub = s[c]);
1070
- }
1071
- const r = y.acquire();
1072
- r.length = t.length;
1073
- for (let c = 0; c < t.length; c++) {
1074
- const o = t[c];
1075
- o && (o._tempUnsub ? (r[c] = o._tempUnsub, o._tempUnsub = void 0) : (b.checkCircular(o, this), r[c] = o.subscribe(this)));
733
+ this._trackable.addDependency = D, R ? (e !== _ && y.release(e), t !== f && p.release(t)) : (y.release(s), p.release(n));
1076
734
  }
1077
- if (e !== f)
1078
- for (let c = 0; c < e.length; c++) {
1079
- const o = e[c];
1080
- o?._tempUnsub && (o._tempUnsub(), o._tempUnsub = void 0);
1081
- }
1082
- s !== E && y.release(s), this._unsubscribes = r;
1083
735
  }
1084
736
  _handleSyncResult(e) {
1085
- (!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & D), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
737
+ (!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & T), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
1086
738
  }
1087
739
  _handleAsyncComputation(e) {
1088
- this._setPending(), this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
740
+ this._setPending(), this._clearDirty(), this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
1089
741
  const t = this._promiseId;
1090
742
  e.then((s) => {
1091
743
  t === this._promiseId && this._handleAsyncResolution(s);
@@ -1094,68 +746,44 @@ class Q {
1094
746
  });
1095
747
  }
1096
748
  _handleAsyncResolution(e) {
1097
- (!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & D), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
749
+ (!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & T), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
1098
750
  }
1099
751
  _handleAsyncRejection(e) {
1100
- const t = R(e, I, a.COMPUTED_ASYNC_COMPUTATION_FAILED);
752
+ const t = N(e, C, l.COMPUTED_ASYNC_COMPUTATION_FAILED);
1101
753
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1102
754
  try {
1103
755
  this._onError(t);
1104
756
  } catch (s) {
1105
- console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
757
+ console.error(l.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1106
758
  }
1107
- this._notifySubscribers();
759
+ this._notifySubscribers(void 0, void 0);
1108
760
  }
1109
761
  _handleComputationError(e) {
1110
- const t = R(e, I, a.COMPUTED_COMPUTATION_FAILED);
762
+ const t = N(e, C, l.COMPUTED_COMPUTATION_FAILED);
1111
763
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1112
764
  try {
1113
765
  this._onError(t);
1114
766
  } catch (s) {
1115
- console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
767
+ console.error(l.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1116
768
  }
1117
769
  throw t;
1118
770
  }
1119
771
  _handlePending() {
1120
772
  if (this._hasDefaultValue)
1121
773
  return this._defaultValue;
1122
- throw new I(a.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
774
+ throw new C(l.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1123
775
  }
1124
776
  _handleRejected() {
1125
777
  if (this._error?.recoverable && this._hasDefaultValue)
1126
778
  return this._defaultValue;
1127
779
  throw this._error;
1128
780
  }
1129
- // === PRIVATE: Dependency Management ===
1130
- // (Replaced by _syncDependencies and inline pool logic)
1131
- // === PRIVATE: Subscriber Management ===
1132
- /**
1133
- * Subscriber interface implementation (Zero-Allocation pattern)
1134
- * Called by dependencies when they change - delegates to _markDirty
1135
- */
781
+ /** Subscriber interface - marks dirty on dependency change */
1136
782
  execute() {
1137
783
  this._markDirty();
1138
784
  }
1139
- /**
1140
- * Push-State, Pull-Value pattern:
1141
- * Marks this computed as dirty and propagates to all subscribers.
1142
- * - Object subscribers (Computed atoms): will mark themselves dirty
1143
- * - Function subscribers (Effects): will schedule their execution
1144
- * Actual recomputation happens lazily when .value is accessed (Pull).
1145
- */
1146
785
  _markDirty() {
1147
- this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), this._notifyJob());
1148
- }
1149
- /**
1150
- * Notifies function subscribers (Effects) of state changes.
1151
- * Currently only called from _handleAsyncRejection to notify Effects of errors.
1152
- * In normal operation, Effects are notified via _markDirty during dirty propagation.
1153
- */
1154
- _notifySubscribers() {
1155
- this._functionSubscribers.hasSubscribers && this._functionSubscribers.forEachSafe(
1156
- (e) => e(),
1157
- (e) => console.error(e)
1158
- );
786
+ this._isRecomputing() || this._isDirty() || (this._setDirty(), this._notifyJob());
1159
787
  }
1160
788
  _registerTracking() {
1161
789
  const e = m.getCurrent();
@@ -1164,223 +792,121 @@ class Q {
1164
792
  e.addDependency(this);
1165
793
  else if (typeof e == "function") {
1166
794
  const t = e;
1167
- t.addDependency ? t.addDependency(this) : this._functionSubscribers.add(e);
1168
- } else e.execute && this._objectSubscribers.add(e);
795
+ t.addDependency ? t.addDependency(this) : this._functionSubscribersStore.add(e);
796
+ } else e.execute && this._objectSubscribersStore.add(e);
1169
797
  }
1170
798
  }
1171
- Object.freeze(Q.prototype);
1172
- function ue(i, e = {}) {
1173
- return new Q(i, e);
799
+ Object.freeze(Z.prototype);
800
+ function fe(i, e = {}) {
801
+ return new Z(i, e);
1174
802
  }
1175
- class te {
803
+ class oe extends J {
1176
804
  constructor(e, t = {}) {
1177
- this.run = () => {
805
+ super(), this.run = () => {
1178
806
  if (this.isDisposed)
1179
- throw new g(a.EFFECT_MUST_BE_FUNCTION);
1180
- this.execute();
807
+ throw new g(l.EFFECT_MUST_BE_FUNCTION);
808
+ this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f), this.execute();
1181
809
  }, this.dispose = () => {
1182
810
  if (!this.isDisposed) {
1183
- if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== E) {
811
+ if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== b) {
1184
812
  for (let s = 0; s < this._unsubscribes.length; s++) {
1185
813
  const n = this._unsubscribes[s];
1186
814
  n && n();
1187
815
  }
1188
- y.release(this._unsubscribes), this._unsubscribes = E;
816
+ I.release(this._unsubscribes), this._unsubscribes = b;
1189
817
  }
1190
- this._dependencies !== f && (S.release(this._dependencies), this._dependencies = f);
818
+ this._dependencies !== _ && (y.release(this._dependencies), this._dependencies = _), this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f);
1191
819
  }
1192
820
  }, this.addDependency = (s) => {
1193
- if (this.isExecuting && this._nextDeps && this._nextUnsubs) {
821
+ if (this.isExecuting && this._nextDeps && this._nextUnsubs && this._nextVersions) {
1194
822
  const n = s, r = this._currentEpoch;
1195
823
  if (n._lastSeenEpoch === r) return;
1196
- n._lastSeenEpoch = r, this._nextDeps.push(n), n._tempUnsub ? (this._nextUnsubs.push(n._tempUnsub), n._tempUnsub = void 0) : this._subscribeTo(n);
824
+ n._lastSeenEpoch = r, this._nextDeps.push(n), this._nextVersions.push(n.version), n._tempUnsub ? (this._nextUnsubs.push(n._tempUnsub), n._tempUnsub = void 0) : this._subscribeTo(n);
1197
825
  }
1198
826
  }, this.execute = () => {
1199
- if (this.isDisposed || this.isExecuting) return;
827
+ if (this.isDisposed || this.isExecuting || !this._shouldExecute()) return;
1200
828
  this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup();
1201
- const s = this._dependencies, n = this._unsubscribes, r = S.acquire(), c = y.acquire(), o = G();
1202
- if (s !== f && n !== E)
829
+ const s = this._dependencies, n = this._dependencyVersions, r = this._unsubscribes, c = y.acquire(), x = p.acquire(), D = I.acquire(), R = K();
830
+ if (s !== _ && r !== b)
1203
831
  for (let u = 0; u < s.length; u++) {
1204
- const l = s[u];
1205
- l && (l._tempUnsub = n[u]);
832
+ const a = s[u];
833
+ a && (a._tempUnsub = r[u]);
1206
834
  }
1207
- this._nextDeps = r, this._nextUnsubs = c, this._currentEpoch = o;
1208
- let _ = !1;
835
+ this._nextDeps = c, this._nextVersions = x, this._nextUnsubs = D, this._currentEpoch = R;
836
+ let h = !1;
1209
837
  try {
1210
838
  const u = m.run(this, this._fn);
1211
- this._dependencies = r, this._unsubscribes = c, _ = !0, this._checkLoopWarnings(), X(u) ? u.then((l) => {
1212
- !this.isDisposed && typeof l == "function" && (this._cleanup = l);
1213
- }).catch((l) => {
1214
- console.error(R(l, g, a.EFFECT_EXECUTION_FAILED));
839
+ this._dependencies = c, this._dependencyVersions = x, this._unsubscribes = D, h = !0, this._checkLoopWarnings(), Q(u) ? u.then((a) => {
840
+ !this.isDisposed && typeof a == "function" && (this._cleanup = a);
841
+ }).catch((a) => {
842
+ console.error(N(a, g, l.EFFECT_EXECUTION_FAILED));
1215
843
  }) : this._cleanup = typeof u == "function" ? u : null;
1216
844
  } catch (u) {
1217
- _ = !0, console.error(R(u, g, a.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
845
+ h = !0, console.error(N(u, g, l.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1218
846
  } finally {
1219
- if (this._setExecuting(!1), this._nextDeps = null, this._nextUnsubs = null, _) {
1220
- if (s !== f) {
847
+ if (this._setExecuting(!1), this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, h) {
848
+ if (s !== _) {
1221
849
  for (let u = 0; u < s.length; u++) {
1222
- const l = s[u];
1223
- l?._tempUnsub && (l._tempUnsub(), l._tempUnsub = void 0);
850
+ const a = s[u];
851
+ a?._tempUnsub && (a._tempUnsub(), a._tempUnsub = void 0);
1224
852
  }
1225
- S.release(s);
853
+ y.release(s);
1226
854
  }
1227
- n !== E && y.release(n);
855
+ r !== b && I.release(r), n !== f && p.release(n);
1228
856
  } else {
1229
- S.release(r);
1230
- for (let u = 0; u < c.length; u++)
1231
- c[u]?.();
1232
- if (y.release(c), s !== f)
857
+ y.release(c), p.release(x);
858
+ for (let u = 0; u < D.length; u++)
859
+ D[u]?.();
860
+ if (I.release(D), s !== _)
1233
861
  for (let u = 0; u < s.length; u++) {
1234
- const l = s[u];
1235
- l && (l._tempUnsub = void 0);
862
+ const a = s[u];
863
+ a && (a._tempUnsub = void 0);
1236
864
  }
1237
865
  }
1238
866
  }
1239
- }, this._id = B() & D, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? A.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? A.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = f, this._unsubscribes = E, this._nextDeps = null, this._nextUnsubs = null, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._history = M ? [] : null, this._executionCount = 0, b.attachDebugInfo(this, "effect", this._id);
867
+ }, this._currentEpoch = -1, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? P.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? P.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = _, this._dependencyVersions = f, this._unsubscribes = b, this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, this._history = d ? [] : null, this._executionCount = 0, S.attachDebugInfo(this, "effect", this.id);
1240
868
  }
1241
- /**
1242
- * Synchronizes subscriptions by unsubscribing from removed dependencies.
1243
- * Uses epoch-based O(N) diff to identify stale dependencies.
1244
- *
1245
- * @param prevDeps - Previous dependency array
1246
- * @param epoch - Current execution epoch for staleness detection
1247
- */
1248
- // _syncDependencies removed (inline logic in execute)
1249
869
  _subscribeTo(e) {
1250
870
  try {
1251
871
  const t = e.subscribe(() => {
1252
- this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : N.schedule(this.execute);
872
+ this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : U.schedule(this.execute);
1253
873
  });
1254
874
  this._nextUnsubs && this._nextUnsubs.push(t);
1255
875
  } catch (t) {
1256
- console.error(R(t, g, a.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
876
+ console.error(N(t, g, l.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
1257
877
  });
1258
878
  }
1259
879
  }
1260
- /**
1261
- * Indicates whether this effect has been disposed.
1262
- *
1263
- * @returns `true` if the effect has been disposed, `false` otherwise
1264
- *
1265
- * @remarks
1266
- * A disposed effect will not execute and cannot be reactivated.
1267
- * Use this property to check if the effect is still active before
1268
- * performing operations that depend on it.
1269
- *
1270
- * @example
1271
- * ```typescript
1272
- * const fx = effect(() => console.log(counter.value));
1273
- * console.log(fx.isDisposed); // false
1274
- * fx.dispose();
1275
- * console.log(fx.isDisposed); // true
1276
- * ```
1277
- */
1278
880
  get isDisposed() {
1279
- return (this._flags & F.DISPOSED) !== 0;
881
+ return (this.flags & F.DISPOSED) !== 0;
1280
882
  }
1281
- /**
1282
- * Returns the total number of times this effect has been executed.
1283
- *
1284
- * @returns The cumulative execution count since the effect was created
1285
- *
1286
- * @remarks
1287
- * This counter is useful for debugging, testing, and monitoring
1288
- * effect behavior. It increments on every execution, regardless
1289
- * of whether the execution succeeds or fails.
1290
- *
1291
- * @example
1292
- * ```typescript
1293
- * const fx = effect(() => console.log(counter.value));
1294
- * console.log(fx.executionCount); // 1 (initial execution)
1295
- * counter.value = 10;
1296
- * console.log(fx.executionCount); // 2
1297
- * ```
1298
- */
1299
883
  get executionCount() {
1300
884
  return this._executionCount;
1301
885
  }
1302
- /**
1303
- * Indicates whether this effect is currently executing.
1304
- *
1305
- * @returns `true` if the effect is mid-execution, `false` otherwise
1306
- *
1307
- * @remarks
1308
- * This property is used internally to prevent re-entrant execution
1309
- * (an effect triggering itself during its own execution). It can
1310
- * also be useful for debugging to understand the effect's state.
1311
- *
1312
- * @example
1313
- * ```typescript
1314
- * const fx = effect(() => {
1315
- * console.log('executing:', fx.isExecuting); // true
1316
- * });
1317
- * console.log(fx.isExecuting); // false (after execution completes)
1318
- * ```
1319
- */
1320
886
  get isExecuting() {
1321
- return (this._flags & F.EXECUTING) !== 0;
887
+ return (this.flags & F.EXECUTING) !== 0;
1322
888
  }
1323
- /**
1324
- * Sets the disposed flag on this effect.
1325
- *
1326
- * @remarks
1327
- * This is a low-level method that only sets the bit flag.
1328
- * Use the public `dispose()` method for proper cleanup.
1329
- *
1330
- * @internal
1331
- */
1332
889
  _setDisposed() {
1333
- this._flags |= F.DISPOSED;
890
+ this.flags |= F.DISPOSED;
1334
891
  }
1335
- /**
1336
- * Sets or clears the executing flag on this effect.
1337
- *
1338
- * @param value - `true` to mark as executing, `false` to clear
1339
- *
1340
- * @remarks
1341
- * Uses bitwise operations for efficient flag manipulation.
1342
- * This flag prevents re-entrant execution of the effect.
1343
- *
1344
- * @internal
1345
- */
1346
892
  _setExecuting(e) {
1347
893
  const t = F.EXECUTING;
1348
- this._flags = this._flags & ~t | -Number(e) & t;
894
+ this.flags = this.flags & ~t | -Number(e) & t;
1349
895
  }
1350
- /**
1351
- * Safely executes the cleanup function if one exists.
1352
- *
1353
- * @remarks
1354
- * This method:
1355
- * - Checks if a cleanup function exists and is callable
1356
- * - Wraps the cleanup call in a try-catch to prevent cleanup errors
1357
- * from breaking the effect lifecycle
1358
- * - Logs any cleanup errors to the console
1359
- * - Clears the cleanup reference after execution
1360
- *
1361
- * @internal
1362
- */
1363
896
  _safeCleanup() {
1364
897
  if (this._cleanup && typeof this._cleanup == "function") {
1365
898
  try {
1366
899
  this._cleanup();
1367
900
  } catch (e) {
1368
- console.error(R(e, g, a.EFFECT_CLEANUP_FAILED));
901
+ console.error(N(e, g, l.EFFECT_CLEANUP_FAILED));
1369
902
  }
1370
903
  this._cleanup = null;
1371
904
  }
1372
905
  }
1373
- /**
1374
- * Checks for infinite loop conditions using epoch-based detection.
1375
- * Falls back to timestamp-based detection in development mode.
1376
- *
1377
- * @throws {EffectError} When infinite loop is detected
1378
- * @internal
1379
- */
1380
906
  _checkInfiniteLoop() {
1381
- if (this._lastFlushEpoch !== U && (this._lastFlushEpoch = U, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), H() > A.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history) {
907
+ if (this._lastFlushEpoch !== v && (this._lastFlushEpoch = v, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), ne() > P.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history) {
1382
908
  const e = Date.now();
1383
- this._history.push(e), this._history.length > A.MAX_EXECUTIONS_PER_SECOND + 10 && this._history.shift(), this._checkTimestampLoop(e);
909
+ this._history.push(e), this._history.length > P.MAX_EXECUTIONS_PER_SECOND + 10 && this._history.shift(), this._checkTimestampLoop(e);
1384
910
  }
1385
911
  }
1386
912
  _checkTimestampLoop(e) {
@@ -1394,80 +920,84 @@ class te {
1394
920
  const r = new g(
1395
921
  `Effect executed ${n} times within 1 second. Infinite loop suspected`
1396
922
  );
1397
- if (this.dispose(), console.error(r), M)
923
+ if (this.dispose(), console.error(r), d)
1398
924
  throw r;
1399
925
  }
1400
926
  }
1401
927
  _throwInfiniteLoopError(e) {
1402
928
  const t = new g(
1403
- `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${w}`
929
+ `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${k}`
1404
930
  );
1405
931
  throw this.dispose(), console.error(t), t;
1406
932
  }
1407
- /**
1408
- * Checks for and warns about potential infinite loop patterns.
1409
- *
1410
- * @remarks
1411
- * When modification tracking is enabled and debug mode is active,
1412
- * this method checks if any dependencies were both read and modified
1413
- * during the effect execution. Such patterns often lead to infinite loops.
1414
- *
1415
- * Warnings are only emitted in debug mode to avoid performance overhead
1416
- * in production.
1417
- *
1418
- * @internal
1419
- */
933
+ _shouldExecute() {
934
+ if (this._dependencies === _ || this._dependencyVersions === f) return !0;
935
+ for (let e = 0; e < this._dependencies.length; e++) {
936
+ const t = this._dependencies[e];
937
+ if (t) {
938
+ if ("value" in t)
939
+ try {
940
+ ce(() => t.value);
941
+ } catch {
942
+ return !0;
943
+ }
944
+ if (t.version !== this._dependencyVersions[e])
945
+ return !0;
946
+ }
947
+ }
948
+ return !1;
949
+ }
1420
950
  _checkLoopWarnings() {
1421
- if (this._trackModifications && b.enabled) {
951
+ if (this._trackModifications && S.enabled) {
1422
952
  const e = this._dependencies;
1423
953
  for (let t = 0; t < e.length; t++) {
1424
954
  const s = e[t];
1425
- s && s._modifiedAtEpoch === this._currentEpoch && b.warn(
955
+ s && s._modifiedAtEpoch === this._currentEpoch && S.warn(
1426
956
  !0,
1427
- `Effect is reading a dependency (${b.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
957
+ `Effect is reading a dependency (${S.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1428
958
  );
1429
959
  }
1430
960
  }
1431
961
  }
1432
962
  }
1433
- function he(i, e = {}) {
963
+ function de(i, e = {}) {
1434
964
  if (typeof i != "function")
1435
- throw new g(a.EFFECT_MUST_BE_FUNCTION);
1436
- const t = new te(i, e);
965
+ throw new g(l.EFFECT_MUST_BE_FUNCTION);
966
+ const t = new oe(i, e);
1437
967
  return t.execute(), t;
1438
968
  }
1439
- function se(i) {
969
+ function he(i) {
1440
970
  return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
1441
971
  }
1442
- function oe(i) {
1443
- if (b.enabled) {
1444
- const e = b.getDebugType(i);
972
+ function Ee(i) {
973
+ if (S.enabled) {
974
+ const e = S.getDebugType(i);
1445
975
  if (e)
1446
976
  return e === "computed";
1447
977
  }
1448
- return se(i) && "invalidate" in i && typeof i.invalidate == "function";
978
+ return he(i) && "invalidate" in i && typeof i.invalidate == "function";
1449
979
  }
1450
- function ae(i) {
980
+ function be(i) {
1451
981
  return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
1452
982
  }
1453
983
  export {
1454
- T as AsyncState,
1455
- d as AtomError,
1456
- I as ComputedError,
1457
- k as DEBUG_CONFIG,
1458
- b as DEBUG_RUNTIME,
984
+ O as AsyncState,
985
+ E as AtomError,
986
+ C as ComputedError,
987
+ j as DEBUG_CONFIG,
988
+ S as DEBUG_RUNTIME,
1459
989
  g as EffectError,
1460
- ie as POOL_CONFIG,
1461
- A as SCHEDULER_CONFIG,
1462
- C as SchedulerError,
1463
- ce as atom,
1464
- ne as batch,
1465
- ue as computed,
1466
- he as effect,
1467
- se as isAtom,
1468
- oe as isComputed,
1469
- ae as isEffect,
1470
- N as scheduler,
1471
- re as untracked
990
+ le as POOL_CONFIG,
991
+ P as SCHEDULER_CONFIG,
992
+ A as SchedulerError,
993
+ _e as atom,
994
+ ae as batch,
995
+ fe as computed,
996
+ de as effect,
997
+ he as isAtom,
998
+ Ee as isComputed,
999
+ be as isEffect,
1000
+ U as scheduler,
1001
+ ce as untracked
1472
1002
  };
1473
1003
  //# sourceMappingURL=index.mjs.map