@but212/atom-effect 0.3.1 → 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
- }, U = {
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
- }, N = 1073741823, w = 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 D 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 D extends d {
70
70
  super(e, t, !0), this.name = "ComputedError";
71
71
  }
72
72
  }
73
- class S 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 S 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) & N, P;
239
+ let se = 1;
240
+ const ie = () => se++;
241
+ class J {
242
+ constructor() {
243
+ this.id = ie() & T, this.flags = 0;
244
+ }
245
+ }
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
+ }
194
285
  }
195
- let A = 0, v = 0, O = !1;
196
- function q() {
197
- return O ? (w && console.warn(
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, A = A + 1 & N, v = 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 ? ++v : 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 m = 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
- m.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
- m.endBatch();
394
+ U.endBatch();
399
395
  }
400
396
  }
401
- const y = {
402
- /** @inheritdoc */
397
+ const m = {
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 y = {
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");
425
- const e = y.current;
426
- y.current = null;
414
+ throw new E("Untracked callback must be a function");
415
+ const e = m.current;
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
- y.current = e;
433
- }
434
- }
435
- const L = /* @__PURE__ */ Symbol("debugName"), W = /* @__PURE__ */ Symbol("id"), M = /* @__PURE__ */ Symbol("type"), j = /* @__PURE__ */ Symbol("noDefaultValue");
436
- function K(i) {
437
- return i !== null && typeof i == "object" && "dependencies" in i && Array.isArray(i.dependencies);
438
- }
439
- let V = 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 D("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
- }
422
+ m.current = e;
450
423
  }
451
424
  }
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 D("Direct circular dependency detected");
518
- this.enabled && (V++, Y(i, e, V));
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[L] = `${e}_${t}`, s[W] = t, s[M] = 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" && L in i)
560
- return i[L];
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" && M in i)
578
- return i[M];
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() & N, 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
- const e = y.getCurrent();
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 & N;
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 && !m.isBatching ? this._flushNotifications() : m.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,34 +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 g = new $(), I = 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 D(a.COMPUTED_MUST_BE_FUNCTION);
915
- if (this.id = B() & N, 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 : j, this._hasDefaultValue = this._defaultValue !== j, 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._recomputeJob = () => {
916
- if (this._isDirty())
917
- try {
918
- this._recompute();
919
- } catch {
920
- }
921
- }, this._notifyJob = () => {
922
- 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(
923
602
  (s) => s(),
924
603
  (s) => console.error(s)
925
- ), this._objectSubscribers.forEachSafe(
604
+ ), this._objectSubscribersStore.forEachSafe(
926
605
  (s) => s.execute(),
927
606
  (s) => console.error(s)
928
607
  );
929
608
  }, this._trackable = Object.assign(() => this._markDirty(), {
930
609
  addDependency: (s) => {
931
610
  }
932
- }), b.attachDebugInfo(this, "computed", this.id), b.enabled) {
611
+ }), S.attachDebugInfo(this, "computed", this.id), S.enabled) {
933
612
  const s = this;
934
- 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();
935
614
  }
936
615
  if (t.lazy === !1)
937
616
  try {
@@ -939,19 +618,15 @@ class Q {
939
618
  } catch {
940
619
  }
941
620
  }
942
- // === PUBLIC API ===
943
- get value() {
944
- if ((this._stateFlags & (h.RESOLVED | h.DIRTY)) === h.RESOLVED)
945
- return this._registerTracking(), this._value;
946
- const t = this._computeValue();
947
- return this._registerTracking(), t;
621
+ get _functionSubscribers() {
622
+ return this._functionSubscribersStore;
948
623
  }
949
- subscribe(e) {
950
- if (typeof e == "object" && e !== null && "execute" in e)
951
- return this._objectSubscribers.add(e);
952
- if (typeof e != "function")
953
- throw new D(a.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
954
- 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;
955
630
  }
956
631
  peek() {
957
632
  return this._value;
@@ -972,127 +647,97 @@ class Q {
972
647
  return this._isResolved();
973
648
  }
974
649
  invalidate() {
975
- this._markDirty();
650
+ this._markDirty(), this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f);
976
651
  }
977
652
  dispose() {
978
- if (this._unsubscribes !== E) {
653
+ if (this._unsubscribes !== b) {
979
654
  for (let e = 0; e < this._unsubscribes.length; e++) {
980
655
  const t = this._unsubscribes[e];
981
656
  t && t();
982
657
  }
983
- I.release(this._unsubscribes), this._unsubscribes = E;
658
+ I.release(this._unsubscribes), this._unsubscribes = b;
984
659
  }
985
- this._dependencies !== f && (g.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;
986
661
  }
987
- // === PRIVATE: State Flag Operations (inlined for performance) ===
662
+ // State flag operations
988
663
  _isDirty() {
989
- return (this._stateFlags & h.DIRTY) !== 0;
664
+ return (this.flags & o.DIRTY) !== 0;
990
665
  }
991
666
  _setDirty() {
992
- this._stateFlags |= h.DIRTY;
667
+ this.flags |= o.DIRTY;
993
668
  }
994
669
  _clearDirty() {
995
- this._stateFlags &= -2;
670
+ this.flags &= -2;
996
671
  }
997
672
  _isIdle() {
998
- return (this._stateFlags & h.IDLE) !== 0;
673
+ return (this.flags & o.IDLE) !== 0;
999
674
  }
1000
675
  _setIdle() {
1001
- this._stateFlags |= h.IDLE, this._stateFlags &= -29;
676
+ this.flags |= o.IDLE, this.flags &= -29;
1002
677
  }
1003
678
  _isPending() {
1004
- return (this._stateFlags & h.PENDING) !== 0;
679
+ return (this.flags & o.PENDING) !== 0;
1005
680
  }
1006
681
  _setPending() {
1007
- this._stateFlags |= h.PENDING, this._stateFlags &= -27;
682
+ this.flags |= o.PENDING, this.flags &= -27;
1008
683
  }
1009
684
  _isResolved() {
1010
- return (this._stateFlags & h.RESOLVED) !== 0;
685
+ return (this.flags & o.RESOLVED) !== 0;
1011
686
  }
1012
687
  _setResolved() {
1013
- this._stateFlags |= h.RESOLVED, this._stateFlags &= -87;
688
+ this.flags |= o.RESOLVED, this.flags &= -87;
1014
689
  }
1015
690
  _isRejected() {
1016
- return (this._stateFlags & h.REJECTED) !== 0;
691
+ return (this.flags & o.REJECTED) !== 0;
1017
692
  }
1018
693
  _setRejected() {
1019
- this._stateFlags |= h.REJECTED | h.HAS_ERROR, this._stateFlags &= -15;
694
+ this.flags |= o.REJECTED | o.HAS_ERROR, this.flags &= -15;
1020
695
  }
1021
696
  _isRecomputing() {
1022
- return (this._stateFlags & h.RECOMPUTING) !== 0;
697
+ return (this.flags & o.RECOMPUTING) !== 0;
1023
698
  }
1024
699
  _setRecomputing(e) {
1025
- const t = h.RECOMPUTING;
1026
- this._stateFlags = this._stateFlags & ~t | -Number(e) & t;
700
+ const t = o.RECOMPUTING;
701
+ this.flags = this.flags & ~t | -Number(e) & t;
1027
702
  }
1028
703
  _getAsyncState() {
1029
- 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;
1030
705
  }
1031
706
  _getFlagsAsString() {
1032
707
  const e = [];
1033
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(" | ");
1034
709
  }
1035
- // === PRIVATE: Core Computation Logic ===
1036
710
  _computeValue() {
1037
- 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);
1038
712
  }
1039
713
  _recompute() {
1040
- if (!this._isDirty() && this._isResolved())
1041
- return;
714
+ if (this._isRecomputing()) return;
1042
715
  this._setRecomputing(!0);
1043
- const e = this._dependencies, t = g.acquire(), s = G();
1044
- let n = 0;
1045
- const r = (_) => {
1046
- _._lastSeenEpoch !== s && (_._lastSeenEpoch = s, n < t.length ? t[n] = _ : t.push(_), n++);
1047
- }, c = this._trackable.addDependency;
1048
- this._trackable.addDependency = r;
1049
- 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;
1050
723
  try {
1051
- const _ = y.run(this._trackable, this._fn);
1052
- if (t.length = n, X(_)) {
1053
- 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);
1054
727
  return;
1055
728
  }
1056
- this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, o = !0, this._handleSyncResult(_);
1057
- } catch (_) {
1058
- 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);
1059
732
  } finally {
1060
- this._trackable.addDependency = c, o ? e !== f && g.release(e) : g.release(t);
1061
- }
1062
- }
1063
- /**
1064
- * Synchronizes subscriptions based on dependency changes.
1065
- * O(N) Diff using Epoch.
1066
- */
1067
- /**
1068
- * Synchronizes subscriptions based on dependency changes using O(N) strategy.
1069
- * Maps unsubs 1:1 with dependencies array.
1070
- */
1071
- _syncDependencies(e, t, s, n) {
1072
- if (e !== f && s !== E)
1073
- for (let c = 0; c < e.length; c++) {
1074
- const o = e[c];
1075
- o && (o._tempUnsub = s[c]);
1076
- }
1077
- const r = I.acquire();
1078
- r.length = t.length;
1079
- for (let c = 0; c < t.length; c++) {
1080
- const o = t[c];
1081
- 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));
1082
734
  }
1083
- if (e !== f)
1084
- for (let c = 0; c < e.length; c++) {
1085
- const o = e[c];
1086
- o?._tempUnsub && (o._tempUnsub(), o._tempUnsub = void 0);
1087
- }
1088
- s !== E && I.release(s), this._unsubscribes = r;
1089
735
  }
1090
736
  _handleSyncResult(e) {
1091
- const t = !this._isResolved() || !this._equal(this._value, e);
1092
- this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
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);
1093
738
  }
1094
739
  _handleAsyncComputation(e) {
1095
- 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;
1096
741
  const t = this._promiseId;
1097
742
  e.then((s) => {
1098
743
  t === this._promiseId && this._handleAsyncResolution(s);
@@ -1101,279 +746,167 @@ class Q {
1101
746
  });
1102
747
  }
1103
748
  _handleAsyncResolution(e) {
1104
- const t = !this._isResolved() || !this._equal(this._value, e);
1105
- this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
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);
1106
750
  }
1107
751
  _handleAsyncRejection(e) {
1108
- const t = R(e, D, a.COMPUTED_ASYNC_COMPUTATION_FAILED);
752
+ const t = N(e, C, l.COMPUTED_ASYNC_COMPUTATION_FAILED);
1109
753
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1110
754
  try {
1111
755
  this._onError(t);
1112
756
  } catch (s) {
1113
- console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
757
+ console.error(l.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1114
758
  }
1115
- this._notifySubscribers();
759
+ this._notifySubscribers(void 0, void 0);
1116
760
  }
1117
761
  _handleComputationError(e) {
1118
- const t = R(e, D, a.COMPUTED_COMPUTATION_FAILED);
762
+ const t = N(e, C, l.COMPUTED_COMPUTATION_FAILED);
1119
763
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
1120
764
  try {
1121
765
  this._onError(t);
1122
766
  } catch (s) {
1123
- console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
767
+ console.error(l.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1124
768
  }
1125
769
  throw t;
1126
770
  }
1127
771
  _handlePending() {
1128
772
  if (this._hasDefaultValue)
1129
773
  return this._defaultValue;
1130
- throw new D(a.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
774
+ throw new C(l.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1131
775
  }
1132
776
  _handleRejected() {
1133
777
  if (this._error?.recoverable && this._hasDefaultValue)
1134
778
  return this._defaultValue;
1135
779
  throw this._error;
1136
780
  }
1137
- // === PRIVATE: Dependency Management ===
1138
- // (Replaced by _syncDependencies and inline pool logic)
1139
- // === PRIVATE: Subscriber Management ===
1140
- /**
1141
- * Subscriber interface implementation (Zero-Allocation pattern)
1142
- * Called by dependencies when they change - delegates to _markDirty
1143
- */
781
+ /** Subscriber interface - marks dirty on dependency change */
1144
782
  execute() {
1145
783
  this._markDirty();
1146
784
  }
1147
785
  _markDirty() {
1148
- this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), (this._functionSubscribers.hasSubscribers || this._objectSubscribers.hasSubscribers) && m.schedule(this._recomputeJob));
1149
- }
1150
- _notifySubscribers() {
1151
- !this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers || m.schedule(this._notifyJob);
786
+ this._isRecomputing() || this._isDirty() || (this._setDirty(), this._notifyJob());
1152
787
  }
1153
788
  _registerTracking() {
1154
- const e = y.getCurrent();
789
+ const e = m.getCurrent();
1155
790
  if (e)
1156
791
  if (typeof e == "object" && e !== null && e.addDependency)
1157
792
  e.addDependency(this);
1158
793
  else if (typeof e == "function") {
1159
794
  const t = e;
1160
- t.addDependency ? t.addDependency(this) : this._functionSubscribers.add(e);
1161
- } 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);
1162
797
  }
1163
798
  }
1164
- Object.freeze(Q.prototype);
1165
- function ue(i, e = {}) {
1166
- return new Q(i, e);
799
+ Object.freeze(Z.prototype);
800
+ function fe(i, e = {}) {
801
+ return new Z(i, e);
1167
802
  }
1168
- class te {
803
+ class oe extends J {
1169
804
  constructor(e, t = {}) {
1170
- this.run = () => {
805
+ super(), this.run = () => {
1171
806
  if (this.isDisposed)
1172
- throw new S(a.EFFECT_MUST_BE_FUNCTION);
1173
- this.execute();
807
+ throw new g(l.EFFECT_MUST_BE_FUNCTION);
808
+ this._dependencyVersions !== f && (p.release(this._dependencyVersions), this._dependencyVersions = f), this.execute();
1174
809
  }, this.dispose = () => {
1175
810
  if (!this.isDisposed) {
1176
- if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== E) {
811
+ if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== b) {
1177
812
  for (let s = 0; s < this._unsubscribes.length; s++) {
1178
813
  const n = this._unsubscribes[s];
1179
814
  n && n();
1180
815
  }
1181
- I.release(this._unsubscribes), this._unsubscribes = E;
816
+ I.release(this._unsubscribes), this._unsubscribes = b;
1182
817
  }
1183
- this._dependencies !== f && (g.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);
1184
819
  }
1185
820
  }, this.addDependency = (s) => {
1186
- if (this.isExecuting && this._nextDeps && this._nextUnsubs) {
821
+ if (this.isExecuting && this._nextDeps && this._nextUnsubs && this._nextVersions) {
1187
822
  const n = s, r = this._currentEpoch;
1188
823
  if (n._lastSeenEpoch === r) return;
1189
- 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);
1190
825
  }
1191
826
  }, this.execute = () => {
1192
- if (this.isDisposed || this.isExecuting) return;
827
+ if (this.isDisposed || this.isExecuting || !this._shouldExecute()) return;
1193
828
  this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup();
1194
- const s = this._dependencies, n = this._unsubscribes, r = g.acquire(), c = I.acquire(), o = G();
1195
- 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)
1196
831
  for (let u = 0; u < s.length; u++) {
1197
- const l = s[u];
1198
- l && (l._tempUnsub = n[u]);
832
+ const a = s[u];
833
+ a && (a._tempUnsub = r[u]);
1199
834
  }
1200
- this._nextDeps = r, this._nextUnsubs = c, this._currentEpoch = o;
1201
- let _ = !1;
835
+ this._nextDeps = c, this._nextVersions = x, this._nextUnsubs = D, this._currentEpoch = R;
836
+ let h = !1;
1202
837
  try {
1203
- const u = y.run(this, this._fn);
1204
- this._dependencies = r, this._unsubscribes = c, _ = !0, this._checkLoopWarnings(), X(u) ? u.then((l) => {
1205
- !this.isDisposed && typeof l == "function" && (this._cleanup = l);
1206
- }).catch((l) => {
1207
- console.error(R(l, S, a.EFFECT_EXECUTION_FAILED));
838
+ const u = m.run(this, this._fn);
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));
1208
843
  }) : this._cleanup = typeof u == "function" ? u : null;
1209
844
  } catch (u) {
1210
- _ = !0, console.error(R(u, S, a.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
845
+ h = !0, console.error(N(u, g, l.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
1211
846
  } finally {
1212
- if (this._setExecuting(!1), this._nextDeps = null, this._nextUnsubs = null, _) {
1213
- if (s !== f) {
847
+ if (this._setExecuting(!1), this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, h) {
848
+ if (s !== _) {
1214
849
  for (let u = 0; u < s.length; u++) {
1215
- const l = s[u];
1216
- l?._tempUnsub && (l._tempUnsub(), l._tempUnsub = void 0);
850
+ const a = s[u];
851
+ a?._tempUnsub && (a._tempUnsub(), a._tempUnsub = void 0);
1217
852
  }
1218
- g.release(s);
853
+ y.release(s);
1219
854
  }
1220
- n !== E && I.release(n);
855
+ r !== b && I.release(r), n !== f && p.release(n);
1221
856
  } else {
1222
- g.release(r);
1223
- for (let u = 0; u < c.length; u++)
1224
- c[u]?.();
1225
- if (I.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 !== _)
1226
861
  for (let u = 0; u < s.length; u++) {
1227
- const l = s[u];
1228
- l && (l._tempUnsub = void 0);
862
+ const a = s[u];
863
+ a && (a._tempUnsub = void 0);
1229
864
  }
1230
865
  }
1231
866
  }
1232
- }, this._id = B() & N, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? U.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? U.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 = w ? [] : 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);
1233
868
  }
1234
- /**
1235
- * Synchronizes subscriptions by unsubscribing from removed dependencies.
1236
- * Uses epoch-based O(N) diff to identify stale dependencies.
1237
- *
1238
- * @param prevDeps - Previous dependency array
1239
- * @param epoch - Current execution epoch for staleness detection
1240
- */
1241
- // _syncDependencies removed (inline logic in execute)
1242
869
  _subscribeTo(e) {
1243
870
  try {
1244
871
  const t = e.subscribe(() => {
1245
- this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : m.schedule(this.execute);
872
+ this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : U.schedule(this.execute);
1246
873
  });
1247
874
  this._nextUnsubs && this._nextUnsubs.push(t);
1248
875
  } catch (t) {
1249
- console.error(R(t, S, a.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
876
+ console.error(N(t, g, l.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
1250
877
  });
1251
878
  }
1252
879
  }
1253
- /**
1254
- * Indicates whether this effect has been disposed.
1255
- *
1256
- * @returns `true` if the effect has been disposed, `false` otherwise
1257
- *
1258
- * @remarks
1259
- * A disposed effect will not execute and cannot be reactivated.
1260
- * Use this property to check if the effect is still active before
1261
- * performing operations that depend on it.
1262
- *
1263
- * @example
1264
- * ```typescript
1265
- * const fx = effect(() => console.log(counter.value));
1266
- * console.log(fx.isDisposed); // false
1267
- * fx.dispose();
1268
- * console.log(fx.isDisposed); // true
1269
- * ```
1270
- */
1271
880
  get isDisposed() {
1272
- return (this._flags & F.DISPOSED) !== 0;
881
+ return (this.flags & F.DISPOSED) !== 0;
1273
882
  }
1274
- /**
1275
- * Returns the total number of times this effect has been executed.
1276
- *
1277
- * @returns The cumulative execution count since the effect was created
1278
- *
1279
- * @remarks
1280
- * This counter is useful for debugging, testing, and monitoring
1281
- * effect behavior. It increments on every execution, regardless
1282
- * of whether the execution succeeds or fails.
1283
- *
1284
- * @example
1285
- * ```typescript
1286
- * const fx = effect(() => console.log(counter.value));
1287
- * console.log(fx.executionCount); // 1 (initial execution)
1288
- * counter.value = 10;
1289
- * console.log(fx.executionCount); // 2
1290
- * ```
1291
- */
1292
883
  get executionCount() {
1293
884
  return this._executionCount;
1294
885
  }
1295
- /**
1296
- * Indicates whether this effect is currently executing.
1297
- *
1298
- * @returns `true` if the effect is mid-execution, `false` otherwise
1299
- *
1300
- * @remarks
1301
- * This property is used internally to prevent re-entrant execution
1302
- * (an effect triggering itself during its own execution). It can
1303
- * also be useful for debugging to understand the effect's state.
1304
- *
1305
- * @example
1306
- * ```typescript
1307
- * const fx = effect(() => {
1308
- * console.log('executing:', fx.isExecuting); // true
1309
- * });
1310
- * console.log(fx.isExecuting); // false (after execution completes)
1311
- * ```
1312
- */
1313
886
  get isExecuting() {
1314
- return (this._flags & F.EXECUTING) !== 0;
887
+ return (this.flags & F.EXECUTING) !== 0;
1315
888
  }
1316
- /**
1317
- * Sets the disposed flag on this effect.
1318
- *
1319
- * @remarks
1320
- * This is a low-level method that only sets the bit flag.
1321
- * Use the public `dispose()` method for proper cleanup.
1322
- *
1323
- * @internal
1324
- */
1325
889
  _setDisposed() {
1326
- this._flags |= F.DISPOSED;
890
+ this.flags |= F.DISPOSED;
1327
891
  }
1328
- /**
1329
- * Sets or clears the executing flag on this effect.
1330
- *
1331
- * @param value - `true` to mark as executing, `false` to clear
1332
- *
1333
- * @remarks
1334
- * Uses bitwise operations for efficient flag manipulation.
1335
- * This flag prevents re-entrant execution of the effect.
1336
- *
1337
- * @internal
1338
- */
1339
892
  _setExecuting(e) {
1340
893
  const t = F.EXECUTING;
1341
- this._flags = this._flags & ~t | -Number(e) & t;
894
+ this.flags = this.flags & ~t | -Number(e) & t;
1342
895
  }
1343
- /**
1344
- * Safely executes the cleanup function if one exists.
1345
- *
1346
- * @remarks
1347
- * This method:
1348
- * - Checks if a cleanup function exists and is callable
1349
- * - Wraps the cleanup call in a try-catch to prevent cleanup errors
1350
- * from breaking the effect lifecycle
1351
- * - Logs any cleanup errors to the console
1352
- * - Clears the cleanup reference after execution
1353
- *
1354
- * @internal
1355
- */
1356
896
  _safeCleanup() {
1357
897
  if (this._cleanup && typeof this._cleanup == "function") {
1358
898
  try {
1359
899
  this._cleanup();
1360
900
  } catch (e) {
1361
- console.error(R(e, S, a.EFFECT_CLEANUP_FAILED));
901
+ console.error(N(e, g, l.EFFECT_CLEANUP_FAILED));
1362
902
  }
1363
903
  this._cleanup = null;
1364
904
  }
1365
905
  }
1366
- /**
1367
- * Checks for infinite loop conditions using epoch-based detection.
1368
- * Falls back to timestamp-based detection in development mode.
1369
- *
1370
- * @throws {EffectError} When infinite loop is detected
1371
- * @internal
1372
- */
1373
906
  _checkInfiniteLoop() {
1374
- if (this._lastFlushEpoch !== A && (this._lastFlushEpoch = A, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), H() > U.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) {
1375
908
  const e = Date.now();
1376
- this._history.push(e), this._history.length > U.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);
1377
910
  }
1378
911
  }
1379
912
  _checkTimestampLoop(e) {
@@ -1384,83 +917,87 @@ class te {
1384
917
  for (let r = t.length - 1; r >= 0 && !(t[r] < s); r--)
1385
918
  n++;
1386
919
  if (n > this._maxExecutions) {
1387
- const r = new S(
920
+ const r = new g(
1388
921
  `Effect executed ${n} times within 1 second. Infinite loop suspected`
1389
922
  );
1390
- if (this.dispose(), console.error(r), w)
923
+ if (this.dispose(), console.error(r), d)
1391
924
  throw r;
1392
925
  }
1393
926
  }
1394
927
  _throwInfiniteLoopError(e) {
1395
- const t = new S(
1396
- `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${v}`
928
+ const t = new g(
929
+ `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${k}`
1397
930
  );
1398
931
  throw this.dispose(), console.error(t), t;
1399
932
  }
1400
- /**
1401
- * Checks for and warns about potential infinite loop patterns.
1402
- *
1403
- * @remarks
1404
- * When modification tracking is enabled and debug mode is active,
1405
- * this method checks if any dependencies were both read and modified
1406
- * during the effect execution. Such patterns often lead to infinite loops.
1407
- *
1408
- * Warnings are only emitted in debug mode to avoid performance overhead
1409
- * in production.
1410
- *
1411
- * @internal
1412
- */
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
+ }
1413
950
  _checkLoopWarnings() {
1414
- if (this._trackModifications && b.enabled) {
951
+ if (this._trackModifications && S.enabled) {
1415
952
  const e = this._dependencies;
1416
953
  for (let t = 0; t < e.length; t++) {
1417
954
  const s = e[t];
1418
- s && s._modifiedAtEpoch === this._currentEpoch && b.warn(
955
+ s && s._modifiedAtEpoch === this._currentEpoch && S.warn(
1419
956
  !0,
1420
- `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`
1421
958
  );
1422
959
  }
1423
960
  }
1424
961
  }
1425
962
  }
1426
- function he(i, e = {}) {
963
+ function de(i, e = {}) {
1427
964
  if (typeof i != "function")
1428
- throw new S(a.EFFECT_MUST_BE_FUNCTION);
1429
- const t = new te(i, e);
965
+ throw new g(l.EFFECT_MUST_BE_FUNCTION);
966
+ const t = new oe(i, e);
1430
967
  return t.execute(), t;
1431
968
  }
1432
- function se(i) {
969
+ function he(i) {
1433
970
  return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
1434
971
  }
1435
- function oe(i) {
1436
- if (b.enabled) {
1437
- const e = b.getDebugType(i);
972
+ function Ee(i) {
973
+ if (S.enabled) {
974
+ const e = S.getDebugType(i);
1438
975
  if (e)
1439
976
  return e === "computed";
1440
977
  }
1441
- return se(i) && "invalidate" in i && typeof i.invalidate == "function";
978
+ return he(i) && "invalidate" in i && typeof i.invalidate == "function";
1442
979
  }
1443
- function ae(i) {
980
+ function be(i) {
1444
981
  return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
1445
982
  }
1446
983
  export {
1447
- T as AsyncState,
1448
- d as AtomError,
1449
- D as ComputedError,
1450
- k as DEBUG_CONFIG,
1451
- b as DEBUG_RUNTIME,
1452
- S as EffectError,
1453
- ie as POOL_CONFIG,
1454
- U as SCHEDULER_CONFIG,
1455
- C as SchedulerError,
1456
- ce as atom,
1457
- ne as batch,
1458
- ue as computed,
1459
- he as effect,
1460
- se as isAtom,
1461
- oe as isComputed,
1462
- ae as isEffect,
1463
- m as scheduler,
1464
- re as untracked
984
+ O as AsyncState,
985
+ E as AtomError,
986
+ C as ComputedError,
987
+ j as DEBUG_CONFIG,
988
+ S as DEBUG_RUNTIME,
989
+ g as EffectError,
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
1465
1002
  };
1466
1003
  //# sourceMappingURL=index.mjs.map