@but212/atom-effect 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  const ee = {
2
2
  /** One second in milliseconds */
3
3
  ONE_SECOND_MS: 1e3
4
- }, L = {
4
+ }, v = {
5
5
  IDLE: "idle",
6
6
  PENDING: "pending",
7
7
  RESOLVED: "resolved",
@@ -11,7 +11,7 @@ const ee = {
11
11
  // 0001 - Effect has been disposed
12
12
  EXECUTING: 2
13
13
  // 0010 - Effect is currently executing
14
- }, c = {
14
+ }, h = {
15
15
  DIRTY: 1,
16
16
  // 0001 - Needs recomputation
17
17
  IDLE: 2,
@@ -29,12 +29,12 @@ const ee = {
29
29
  }, T = {
30
30
  SYNC: 1,
31
31
  NOTIFICATION_SCHEDULED: 2
32
- }, ge = {
32
+ }, be = {
33
33
  /** Maximum number of pooled objects to prevent memory bloat */
34
34
  MAX_SIZE: 1e3,
35
35
  /** Number of objects to pre-allocate for performance-critical paths */
36
36
  WARMUP_SIZE: 100
37
- }, D = {
37
+ }, I = {
38
38
  /** Maximum effect executions per second to detect infinite loops (Legacy/Fallback) */
39
39
  MAX_EXECUTIONS_PER_SECOND: 1e3,
40
40
  /** Threshold for cleaning up old execution timestamps */
@@ -58,19 +58,19 @@ const ee = {
58
58
  MAX_DEPENDENCIES: 1e3,
59
59
  /** Enable infinite loop detection warnings */
60
60
  WARN_INFINITE_LOOP: !0
61
- }, y = 1073741823, l = typeof process < "u" && process.env && process.env.NODE_ENV !== "production", te = Object.freeze([]);
62
- class b extends Error {
61
+ }, b = 1073741823, w = 1 << 19, l = typeof process < "u" && process.env && process.env.NODE_ENV !== "production", te = Object.freeze([]);
62
+ class g extends Error {
63
63
  /**
64
64
  * Creates a new AtomError
65
65
  * @param message - Error message describing what went wrong
66
66
  * @param cause - Original error that caused this error
67
67
  * @param recoverable - Whether the operation can be retried
68
68
  */
69
- constructor(e, t = null, s = !0) {
70
- super(e), this.name = "AtomError", this.cause = t, this.recoverable = s, this.timestamp = /* @__PURE__ */ new Date();
69
+ constructor(e, t = null, i = !0) {
70
+ super(e), this.name = "AtomError", this.cause = t, this.recoverable = i, this.timestamp = /* @__PURE__ */ new Date();
71
71
  }
72
72
  }
73
- class N extends b {
73
+ class D extends g {
74
74
  /**
75
75
  * Creates a new ComputedError
76
76
  * @param message - Error message
@@ -80,7 +80,7 @@ class N extends b {
80
80
  super(e, t, !0), this.name = "ComputedError";
81
81
  }
82
82
  }
83
- class g extends b {
83
+ class y extends g {
84
84
  /**
85
85
  * Creates a new EffectError
86
86
  * @param message - Error message
@@ -90,7 +90,7 @@ class g extends b {
90
90
  super(e, t, !1), this.name = "EffectError";
91
91
  }
92
92
  }
93
- class U extends b {
93
+ class U extends g {
94
94
  /**
95
95
  * Creates a new SchedulerError
96
96
  * @param message - Error message
@@ -100,7 +100,7 @@ class U extends b {
100
100
  super(e, t, !1), this.name = "SchedulerError";
101
101
  }
102
102
  }
103
- const h = {
103
+ const u = {
104
104
  // ─────────────────────────────────────────────────────────────────
105
105
  // Computed errors
106
106
  // ─────────────────────────────────────────────────────────────────
@@ -152,67 +152,103 @@ const h = {
152
152
  * @remarks This prevents cascading failures from masking the original error.
153
153
  */
154
154
  CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
155
- }, V = /* @__PURE__ */ Symbol("debugName"), se = /* @__PURE__ */ Symbol("id"), w = /* @__PURE__ */ Symbol("type"), q = /* @__PURE__ */ Symbol("noDefaultValue");
156
- function ie(i) {
157
- return "dependencies" in i && Array.isArray(i.dependencies);
155
+ }, M = /* @__PURE__ */ Symbol("debugName"), se = /* @__PURE__ */ Symbol("id"), V = /* @__PURE__ */ Symbol("type"), k = /* @__PURE__ */ Symbol("noDefaultValue");
156
+ function ie(s) {
157
+ return "dependencies" in s && Array.isArray(s.dependencies);
158
158
  }
159
- let z = 0;
160
- function Y(i, e, t) {
161
- if (i._visitedEpoch !== t) {
162
- if (i._visitedEpoch = t, i === e)
163
- throw new N("Indirect circular dependency detected");
164
- if (ie(i)) {
165
- const s = i.dependencies;
166
- for (let r = 0; r < s.length; r++) {
167
- const n = s[r];
168
- n && Y(n, e, t);
159
+ let Q = 0;
160
+ function G(s, e, t) {
161
+ if (s._visitedEpoch !== t) {
162
+ if (s._visitedEpoch = t, s === e)
163
+ throw new D("Indirect circular dependency detected");
164
+ if (ie(s)) {
165
+ const i = s.dependencies;
166
+ for (let n = 0; n < i.length; n++) {
167
+ const r = i[n];
168
+ r && G(r, e, t);
169
169
  }
170
170
  }
171
171
  }
172
172
  }
173
- const E = {
173
+ const p = {
174
174
  enabled: typeof process < "u" && process.env?.NODE_ENV === "development",
175
175
  maxDependencies: B.MAX_DEPENDENCIES,
176
176
  warnInfiniteLoop: B.WARN_INFINITE_LOOP,
177
- warn(i, e) {
178
- this.enabled && i && console.warn(`[Atom Effect] ${e}`);
177
+ warn(s, e) {
178
+ this.enabled && s && console.warn(`[Atom Effect] ${e}`);
179
179
  },
180
180
  /**
181
181
  * Checks for circular dependencies.
182
182
  * Direct check runs always; indirect check only in dev mode.
183
183
  * @throws {ComputedError} When circular dependency detected
184
184
  */
185
- checkCircular(i, e) {
186
- if (i === e)
187
- throw new N("Direct circular dependency detected");
188
- this.enabled && (z++, Y(i, e, z));
185
+ checkCircular(s, e) {
186
+ if (s === e)
187
+ throw new D("Direct circular dependency detected");
188
+ this.enabled && (Q++, G(s, e, Q));
189
189
  },
190
- attachDebugInfo(i, e, t) {
190
+ attachDebugInfo(s, e, t) {
191
191
  if (!this.enabled)
192
192
  return;
193
- const s = i;
194
- s[V] = `${e}_${t}`, s[se] = t, s[w] = e;
193
+ const i = s;
194
+ i[M] = `${e}_${t}`, i[se] = t, i[V] = e;
195
195
  },
196
- getDebugName(i) {
197
- if (i != null && V in i)
198
- return i[V];
196
+ getDebugName(s) {
197
+ if (s != null && M in s)
198
+ return s[M];
199
199
  },
200
- getDebugType(i) {
201
- if (i != null && w in i)
202
- return i[w];
200
+ getDebugType(s) {
201
+ if (s != null && V in s)
202
+ return s[V];
203
203
  }
204
204
  };
205
- let re = 1;
206
- const ne = () => re++;
207
- class H {
205
+ let ne = 1;
206
+ const re = () => ne++;
207
+ class Y {
208
208
  constructor() {
209
- this.id = ne() & y, this.flags = 0;
209
+ this.flags = 0, this.version = 0, this._lastSeenEpoch = -1, this.id = re() & b;
210
210
  }
211
- }
212
- class Q extends H {
213
- constructor() {
214
- super(), this.version = 0, this._lastSeenEpoch = -1;
211
+ /**
212
+ * Rotates the phase by 1, automatically incrementing cycle on overflow.
213
+ *
214
+ * Performance Benefits:
215
+ * - Branchless: No conditional statements
216
+ * - O(1): Single bitwise AND operation
217
+ * - Smi-safe: Result always within 30-bit range (0x3fffffff)
218
+ *
219
+ * When Phase reaches 0xfffff (1,048,575), the next increment:
220
+ * - Overflows into Cycle bits
221
+ * - Phase resets to 0
222
+ * - Cycle increments by 1
223
+ *
224
+ * @returns The new version after phase rotation
225
+ */
226
+ rotatePhase() {
227
+ return this.version = this.version + 1 & b, this.version;
215
228
  }
229
+ /**
230
+ * Calculates the logical distance (shift) between current and cached version.
231
+ *
232
+ * Uses modular arithmetic to handle cycle wraparound correctly.
233
+ * The result represents how many phase rotations have occurred since
234
+ * the cached version was recorded.
235
+ *
236
+ * Performance Benefits:
237
+ * - Branchless: Single subtraction with mask
238
+ * - Handles wraparound: Works correctly even when version overflows
239
+ *
240
+ * Use Cases:
241
+ * - Scheduler priority: Large shifts indicate stale updates
242
+ * - Dependency staleness: Detect how outdated a cached value is
243
+ *
244
+ * @param cachedVersion - The previously cached version to compare against
245
+ * @returns Non-negative shift distance (0 to 0x3fffffff)
246
+ */
247
+ getShift(e) {
248
+ return this.version - e & b;
249
+ }
250
+ }
251
+ class H extends Y {
216
252
  /**
217
253
  * Subscribes a listener function or Subscriber object to value changes.
218
254
  *
@@ -222,16 +258,31 @@ class Q extends H {
222
258
  */
223
259
  subscribe(e) {
224
260
  if (typeof e == "object" && e !== null && "execute" in e)
225
- return this._objectSubscribers.add(e);
261
+ return this._addSubscriber(this._getObjSubs(), e);
226
262
  if (typeof e != "function")
227
- throw new b(h.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
228
- return this._functionSubscribers.add(e);
263
+ throw new g(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
264
+ return this._addSubscriber(this._getFnSubs(), e);
229
265
  }
230
266
  /**
231
267
  * Gets the total number of active subscribers.
232
268
  */
233
269
  subscriberCount() {
234
- return this._functionSubscribers.size + this._objectSubscribers.size;
270
+ return (this._fnSubs?.length ?? 0) + (this._objSubs?.length ?? 0);
271
+ }
272
+ _addSubscriber(e, t) {
273
+ if (e.indexOf(t) !== -1) return () => {
274
+ };
275
+ e.push(t);
276
+ let i = !1;
277
+ return () => {
278
+ if (i) return;
279
+ i = !0;
280
+ const n = e.indexOf(t);
281
+ if (n !== -1) {
282
+ const r = e.length - 1;
283
+ n !== r && (e[n] = e[r]), e.pop();
284
+ }
285
+ };
235
286
  }
236
287
  /**
237
288
  * Notifies all subscribers of a change.
@@ -240,66 +291,111 @@ class Q extends H {
240
291
  * @param oldValue - The old value
241
292
  */
242
293
  _notifySubscribers(e, t) {
243
- this._functionSubscribers.forEachSafe(
244
- (s) => s(e, t),
245
- (s) => console.error(new b(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
246
- ), this._objectSubscribers.forEachSafe(
247
- (s) => s.execute(),
248
- (s) => console.error(new b(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
249
- );
294
+ const i = this._fnSubs;
295
+ if (i)
296
+ for (let r = i.length - 1; r >= 0; r--)
297
+ try {
298
+ const o = i[r];
299
+ o && o(e, t);
300
+ } catch (o) {
301
+ console.error(
302
+ new g(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, o)
303
+ );
304
+ }
305
+ const n = this._objSubs;
306
+ if (n)
307
+ for (let r = n.length - 1; r >= 0; r--)
308
+ try {
309
+ const o = n[r];
310
+ o && o.execute();
311
+ } catch (o) {
312
+ console.error(
313
+ new g(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, o)
314
+ );
315
+ }
250
316
  }
251
317
  }
252
318
  let x = 0;
253
319
  function $() {
254
- return x = x + 1 & y || 1, x;
320
+ return x = x + 1 & b || 1, x;
255
321
  }
256
322
  function oe() {
257
323
  return x;
258
324
  }
259
- let F = 0, k = 0, v = !1;
260
- function G() {
261
- return v ? (l && console.warn(
325
+ let F = 0, z = 0, P = !1;
326
+ function q() {
327
+ return P ? (l && console.warn(
262
328
  "Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"
263
- ), !1) : (v = !0, F = F + 1 & y, k = 0, !0);
329
+ ), !1) : (P = !0, F = F + 1 & b, z = 0, !0);
264
330
  }
265
331
  function X() {
266
- v = !1;
332
+ P = !1;
267
333
  }
268
- function ce() {
269
- return v ? ++k : 0;
334
+ function he() {
335
+ return P ? ++z : 0;
270
336
  }
271
- class he {
337
+ class ue {
272
338
  constructor() {
273
- 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 = D.MAX_FLUSH_ITERATIONS;
339
+ this.queueA = [], this.queueB = [], this.queue = this.queueA, this.queueSize = 0, this.urgentQueueA = [], this.urgentQueueB = [], this.urgentQueue = this.urgentQueueA, this.urgentQueueSize = 0, this._epoch = 0, this.isProcessing = !1, this.isBatching = !1, this.batchDepth = 0, this.batchQueue = [], this.batchQueueSize = 0, this.isFlushingSync = !1, this.maxFlushIterations = I.MAX_FLUSH_ITERATIONS;
274
340
  }
275
341
  get phase() {
276
342
  return this.isProcessing || this.isFlushingSync ? 2 : this.isBatching ? 1 : 0;
277
343
  }
278
344
  /**
279
- * Schedules a task for execution.
280
- * Tasks are deduplicated within the same flush cycle using epoch tracking.
281
- * @param callback - The function to execute.
282
- * @throws {SchedulerError} If the callback is not a function.
345
+ * Schedules a task for execution with optional priority based on phase shift.
346
+ *
347
+ * Priority Calculation (Branchless):
348
+ * - If sourceNode and cachedVersion are provided, calculates shift
349
+ * - Jobs with shift >= PHASE_THRESHOLD go to urgentQueue
350
+ * - Uses branchless bit manipulation: ((shift - THRESHOLD) >>> 31) ^ 1
351
+ *
352
+ * @param callback - The function to execute
353
+ * @param sourceNode - Optional reactive node for shift calculation
354
+ * @throws {SchedulerError} If the callback is not a function
283
355
  */
284
- schedule(e) {
356
+ schedule(e, t) {
285
357
  if (typeof e != "function")
286
358
  throw new U("Scheduler callback must be a function");
287
- 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()));
359
+ if (e._nextEpoch !== this._epoch)
360
+ if (e._nextEpoch = this._epoch, this.isBatching || this.isFlushingSync)
361
+ this.batchQueue[this.batchQueueSize++] = e;
362
+ else {
363
+ const i = this._calculateUrgency(e, t);
364
+ this.urgentQueue[this.urgentQueueSize] = e, this.queue[this.queueSize] = e, this.urgentQueueSize += i, this.queueSize += i ^ 1, this.isProcessing || this.flush();
365
+ }
366
+ }
367
+ /**
368
+ * Calculates urgency flag using branchless bit manipulation.
369
+ *
370
+ * Formula: ((shift - PHASE_THRESHOLD) >>> 31) ^ 1
371
+ * - If shift >= THRESHOLD: (negative >>> 31) = 0, XOR 1 = 1 (urgent)
372
+ * - If shift < THRESHOLD: (positive >>> 31) = 0... wait, that's wrong
373
+ *
374
+ * Correct formula: (shift >= THRESHOLD) ? 1 : 0
375
+ * Branchless: ((PHASE_THRESHOLD - 1 - shift) >>> 31)
376
+ *
377
+ * @returns 1 if urgent, 0 if normal
378
+ */
379
+ _calculateUrgency(e, t) {
380
+ if (!t || e._cachedVersion === void 0)
381
+ return 0;
382
+ const i = t.getShift(e._cachedVersion);
383
+ return w - 1 - i >>> 31 & 1;
288
384
  }
289
385
  flush() {
290
- this.isProcessing || this.queueSize === 0 || (this.isProcessing = !0, queueMicrotask(() => {
386
+ this.isProcessing || this.queueSize === 0 && this.urgentQueueSize === 0 || (this.isProcessing = !0, queueMicrotask(() => {
291
387
  try {
292
- if (this.queueSize === 0) return;
293
- const e = G();
388
+ if (this.queueSize === 0 && this.urgentQueueSize === 0) return;
389
+ const e = q();
294
390
  this._drainQueue(), e && X();
295
391
  } finally {
296
- this.isProcessing = !1, this.queueSize > 0 && !this.isBatching && this.flush();
392
+ this.isProcessing = !1, (this.queueSize > 0 || this.urgentQueueSize > 0) && !this.isBatching && this.flush();
297
393
  }
298
394
  }));
299
395
  }
300
396
  flushSync() {
301
397
  this.isFlushingSync = !0;
302
- const e = G();
398
+ const e = q();
303
399
  try {
304
400
  this._mergeBatchQueue(), this._drainQueue();
305
401
  } finally {
@@ -315,16 +411,34 @@ class he {
315
411
  this.batchQueueSize = 0;
316
412
  }
317
413
  }
414
+ /**
415
+ * Drains all queues, processing urgent queue completely first.
416
+ *
417
+ * Processing Order:
418
+ * 1. Process all urgent jobs (high phase shift = stale updates)
419
+ * 2. Process normal jobs
420
+ * 3. Repeat until both queues are empty
421
+ *
422
+ * This ordering reduces glitches by ensuring that the most
423
+ * impactful state changes are propagated first.
424
+ */
318
425
  _drainQueue() {
319
426
  let e = 0;
320
- for (; this.queueSize > 0; ) {
427
+ for (; this.urgentQueueSize > 0 || this.queueSize > 0; ) {
321
428
  if (++e > this.maxFlushIterations) {
322
429
  this._handleFlushOverflow();
323
- break;
430
+ return;
324
431
  }
325
- this._processCurrentQueue(), this._mergeBatchQueue();
432
+ this.urgentQueueSize > 0 && this._processUrgentQueue(), this.queueSize > 0 && this._processCurrentQueue(), this._mergeBatchQueue();
326
433
  }
327
434
  }
435
+ /**
436
+ * Processes the urgent queue using double-buffering.
437
+ */
438
+ _processUrgentQueue() {
439
+ const e = this.urgentQueue, t = this.urgentQueueSize;
440
+ this.urgentQueue = this.urgentQueue === this.urgentQueueA ? this.urgentQueueB : this.urgentQueueA, this.urgentQueueSize = 0, this._epoch++, this._processJobs(e, t);
441
+ }
328
442
  _processCurrentQueue() {
329
443
  const e = this.queue, t = this.queueSize;
330
444
  this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++, this._processJobs(e, t);
@@ -334,17 +448,20 @@ class he {
334
448
  new U(
335
449
  `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`
336
450
  )
337
- ), this.queueSize = 0, this.queue.length = 0, this.batchQueueSize = 0;
451
+ ), this.queueSize = 0, this.queue.length = 0, this.urgentQueueSize = 0, this.urgentQueue.length = 0, this.batchQueueSize = 0;
338
452
  }
339
453
  _processJobs(e, t) {
340
- for (let s = 0; s < t; s++)
341
- try {
342
- e[s]?.();
343
- } catch (r) {
344
- console.error(
345
- new U("Error occurred during scheduler execution", r)
346
- );
347
- }
454
+ for (let i = 0; i < t; i++) {
455
+ const n = e[i];
456
+ if (n)
457
+ try {
458
+ n();
459
+ } catch (r) {
460
+ console.error(
461
+ new U("Error occurred during scheduler execution", r)
462
+ );
463
+ }
464
+ }
348
465
  e.length = 0;
349
466
  }
350
467
  /** Starts a new batch of updates. Updates will be deferred until endBatch is called. */
@@ -363,25 +480,25 @@ class he {
363
480
  * @param max - Maximum iterations count.
364
481
  */
365
482
  setMaxFlushIterations(e) {
366
- if (e < D.MIN_FLUSH_ITERATIONS)
483
+ if (e < I.MIN_FLUSH_ITERATIONS)
367
484
  throw new U(
368
- `Max flush iterations must be at least ${D.MIN_FLUSH_ITERATIONS}`
485
+ `Max flush iterations must be at least ${I.MIN_FLUSH_ITERATIONS}`
369
486
  );
370
487
  this.maxFlushIterations = e;
371
488
  }
372
489
  }
373
- const A = new he();
374
- function De(i) {
375
- if (typeof i != "function")
376
- throw new b("Batch callback must be a function");
377
- A.startBatch();
490
+ const N = new ue();
491
+ function ye(s) {
492
+ if (typeof s != "function")
493
+ throw new g("Batch callback must be a function");
494
+ N.startBatch();
378
495
  try {
379
- return i();
496
+ return s();
380
497
  } finally {
381
- A.endBatch();
498
+ N.endBatch();
382
499
  }
383
500
  }
384
- class ue {
501
+ class ce {
385
502
  constructor() {
386
503
  this.current = null;
387
504
  }
@@ -393,12 +510,12 @@ class ue {
393
510
  * @param fn - The function to execute.
394
511
  */
395
512
  run(e, t) {
396
- const s = this.current;
513
+ const i = this.current;
397
514
  this.current = e;
398
515
  try {
399
516
  return t();
400
517
  } finally {
401
- this.current = s;
518
+ this.current = i;
402
519
  }
403
520
  }
404
521
  /**
@@ -408,74 +525,18 @@ class ue {
408
525
  return this.current;
409
526
  }
410
527
  }
411
- const m = new ue();
412
- function ae(i) {
413
- if (typeof i != "function")
414
- throw new b("Untracked callback must be a function");
528
+ const m = new ce();
529
+ function _e(s) {
530
+ if (typeof s != "function")
531
+ throw new g("Untracked callback must be a function");
415
532
  const e = m.current;
416
533
  m.current = null;
417
534
  try {
418
- return i();
535
+ return s();
419
536
  } finally {
420
537
  m.current = e;
421
538
  }
422
539
  }
423
- class P {
424
- constructor() {
425
- this.subscribers = null;
426
- }
427
- /** Adds subscriber and returns unsubscribe function (idempotent) */
428
- add(e) {
429
- if (this.subscribers || (this.subscribers = []), this.subscribers.indexOf(e) !== -1)
430
- return () => {
431
- };
432
- this.subscribers.push(e);
433
- let t = !1;
434
- return () => {
435
- t || (t = !0, this.remove(e));
436
- };
437
- }
438
- /** Removes subscriber using swap-and-pop */
439
- remove(e) {
440
- if (!this.subscribers)
441
- return !1;
442
- const t = this.subscribers.indexOf(e);
443
- if (t === -1)
444
- return !1;
445
- const s = this.subscribers.length - 1;
446
- return t !== s && (this.subscribers[t] = this.subscribers[s]), this.subscribers.pop(), !0;
447
- }
448
- has(e) {
449
- return this.subscribers ? this.subscribers.indexOf(e) !== -1 : !1;
450
- }
451
- forEach(e) {
452
- if (this.subscribers)
453
- for (let t = 0; t < this.subscribers.length; t++)
454
- e(this.subscribers[t], t);
455
- }
456
- /** Iterates with error handling to prevent one failure from breaking the chain */
457
- forEachSafe(e, t) {
458
- if (this.subscribers)
459
- for (let s = 0; s < this.subscribers.length; s++)
460
- try {
461
- e(this.subscribers[s], s);
462
- } catch (r) {
463
- t ? t(r) : console.error("[SubscriberManager] Error in subscriber callback:", r);
464
- }
465
- }
466
- get size() {
467
- return this.subscribers?.length ?? 0;
468
- }
469
- get hasSubscribers() {
470
- return this.subscribers !== null && this.subscribers.length > 0;
471
- }
472
- clear() {
473
- this.subscribers = null;
474
- }
475
- toArray() {
476
- return this.subscribers ? [...this.subscribers] : [];
477
- }
478
- }
479
540
  class j {
480
541
  constructor() {
481
542
  this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = l ? {
@@ -514,12 +575,12 @@ class j {
514
575
  /** Returns current stats for the pool (dev mode only). */
515
576
  getStats() {
516
577
  if (!l || !this.stats) return null;
517
- const { acquired: e, released: t, rejected: s } = this.stats, r = s.frozen + s.tooLarge + s.poolFull;
578
+ const { acquired: e, released: t, rejected: i } = this.stats, n = i.frozen + i.tooLarge + i.poolFull;
518
579
  return {
519
580
  acquired: e,
520
581
  released: t,
521
- rejected: s,
522
- leaked: e - t - r,
582
+ rejected: i,
583
+ leaked: e - t - n,
523
584
  poolSize: this.pool.length
524
585
  };
525
586
  }
@@ -528,84 +589,85 @@ class j {
528
589
  this.pool.length = 0, l && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
529
590
  }
530
591
  }
531
- const u = Object.freeze([]), f = Object.freeze([]), a = Object.freeze([]), S = new j(), I = new j(), d = new j();
532
- function _e(i) {
533
- return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
592
+ const _ = Object.freeze([]), f = Object.freeze([]), a = Object.freeze([]), S = new j(), C = new j(), d = new j();
593
+ function ae(s) {
594
+ return s !== null && typeof s == "object" && "value" in s && "subscribe" in s && typeof s.subscribe == "function";
534
595
  }
535
- function Ie(i) {
536
- if (E.enabled && (i == null || typeof i == "object")) {
537
- const e = E.getDebugType(i);
596
+ function De(s) {
597
+ if (p.enabled && (s == null || typeof s == "object")) {
598
+ const e = p.getDebugType(s);
538
599
  if (e)
539
600
  return e === "computed";
540
601
  }
541
- return _e(i) && "invalidate" in i && typeof i.invalidate == "function";
602
+ return ae(s) && "invalidate" in s && typeof s.invalidate == "function";
542
603
  }
543
- function ye(i) {
544
- return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
604
+ function Ie(s) {
605
+ return s !== null && typeof s == "object" && "dispose" in s && "run" in s && typeof s.dispose == "function" && typeof s.run == "function";
545
606
  }
546
- function J(i) {
547
- return i != null && typeof i.then == "function";
607
+ function J(s) {
608
+ return s != null && typeof s.then == "function";
548
609
  }
549
- function le(i) {
550
- return typeof i == "object" && i !== null;
610
+ function le(s) {
611
+ return typeof s == "object" && s !== null;
551
612
  }
552
- function fe(i) {
553
- return (typeof i == "object" || typeof i == "function") && i !== null && typeof i.addDependency == "function";
613
+ function fe(s) {
614
+ return (typeof s == "object" || typeof s == "function") && s !== null && typeof s.addDependency == "function";
554
615
  }
555
- function de(i) {
556
- return typeof i == "function" && typeof i.addDependency != "function";
616
+ function de(s) {
617
+ return typeof s == "function" && typeof s.addDependency != "function";
557
618
  }
558
- function Ee(i) {
559
- return le(i) && typeof i.execute == "function";
619
+ function pe(s) {
620
+ return le(s) && typeof s.execute == "function";
560
621
  }
561
- function W(i, e, t, s) {
622
+ function W(s, e, t, i) {
562
623
  if (e) {
563
624
  if (fe(e)) {
564
- e.addDependency(i);
625
+ e.addDependency(s);
565
626
  return;
566
627
  }
567
628
  if (de(e)) {
568
- t.add(e);
629
+ const n = e;
630
+ t.indexOf(n) === -1 && t.push(n);
569
631
  return;
570
632
  }
571
- Ee(e) && s.add(e);
633
+ pe(e) && i.indexOf(e) === -1 && i.push(e);
572
634
  }
573
635
  }
574
- function pe(i, e, t, s) {
575
- if (e !== u && t !== f)
576
- for (let n = 0; n < e.length; n++) {
577
- const o = e[n];
578
- o && (o._tempUnsub = t[n]);
636
+ function Ee(s, e, t, i) {
637
+ if (e !== _ && t !== f)
638
+ for (let r = 0; r < e.length; r++) {
639
+ const o = e[r];
640
+ o && (o._tempUnsub = t[r]);
579
641
  }
580
- const r = I.acquire();
581
- r.length = i.length;
582
- for (let n = 0; n < i.length; n++) {
583
- const o = i[n];
584
- o && (o._tempUnsub ? (r[n] = o._tempUnsub, o._tempUnsub = void 0) : (E.checkCircular(o, s), r[n] = o.subscribe(s)));
585
- }
586
- if (e !== u)
587
- for (let n = 0; n < e.length; n++) {
588
- const o = e[n];
642
+ const n = C.acquire();
643
+ n.length = s.length;
644
+ for (let r = 0; r < s.length; r++) {
645
+ const o = s[r];
646
+ o && (o._tempUnsub ? (n[r] = o._tempUnsub, o._tempUnsub = void 0) : (p.checkCircular(o, i), n[r] = o.subscribe(i)));
647
+ }
648
+ if (e !== _)
649
+ for (let r = 0; r < e.length; r++) {
650
+ const o = e[r];
589
651
  o?._tempUnsub && (o._tempUnsub(), o._tempUnsub = void 0);
590
652
  }
591
- return t !== f && I.release(t), r;
653
+ return t !== f && C.release(t), n;
592
654
  }
593
- class be extends Q {
655
+ class ge extends H {
594
656
  constructor(e, t) {
595
- super(), this._functionSubscribersStore = null, this._objectSubscribersStore = null, this._value = e, t && (this.flags |= T.SYNC), E.attachDebugInfo(this, "atom", this.id);
657
+ super(), this._fnSubs = null, this._objSubs = null, this._value = e, t && (this.flags |= T.SYNC), p.attachDebugInfo(this, "atom", this.id);
596
658
  }
597
- get _functionSubscribers() {
598
- return this._functionSubscribersStore || (this._functionSubscribersStore = new P()), this._functionSubscribersStore;
659
+ _getFnSubs() {
660
+ return this._fnSubs ??= [], this._fnSubs;
599
661
  }
600
- get _objectSubscribers() {
601
- return this._objectSubscribersStore || (this._objectSubscribersStore = new P()), this._objectSubscribersStore;
662
+ _getObjSubs() {
663
+ return this._objSubs ??= [], this._objSubs;
602
664
  }
603
665
  /**
604
666
  * Returns the current value and registers the atom as a dependency if in a tracking context.
605
667
  */
606
668
  get value() {
607
669
  const e = m.current;
608
- return e && W(this, e, this._functionSubscribers, this._objectSubscribers), this._value;
670
+ return e && W(this, e, this._getFnSubs(), this._getObjSubs()), this._value;
609
671
  }
610
672
  /**
611
673
  * Sets a new value and schedules notifications if the value has changed.
@@ -613,73 +675,76 @@ class be extends Q {
613
675
  set value(e) {
614
676
  if (Object.is(this._value, e)) return;
615
677
  const t = this._value;
616
- this._value = e, this.version = this.version + 1 & y;
617
- const s = this._functionSubscribersStore?.hasSubscribers, r = this._objectSubscribersStore?.hasSubscribers;
618
- (s || r) && this._scheduleNotification(t);
678
+ this._value = e, this.rotatePhase(), ((this._fnSubs?.length ?? 0) > 0 || (this._objSubs?.length ?? 0) > 0) && this._scheduleNotification(t);
619
679
  }
620
680
  /**
621
681
  * Schedules or flushes notifications based on sync mode and batching state.
622
682
  */
623
683
  _scheduleNotification(e) {
624
- if (this.flags & T.NOTIFICATION_SCHEDULED || (this._pendingOldValue = e, this.flags |= T.NOTIFICATION_SCHEDULED), this.flags & T.SYNC && !A.isBatching) {
684
+ if (this.flags & T.NOTIFICATION_SCHEDULED || (this._pendingOldValue = e, this.flags |= T.NOTIFICATION_SCHEDULED), this.flags & T.SYNC && !N.isBatching) {
625
685
  this._flushNotifications();
626
686
  return;
627
687
  }
628
- this._notifyTask || (this._notifyTask = () => this._flushNotifications()), A.schedule(this._notifyTask);
688
+ this._notifyTask || (this._notifyTask = () => this._flushNotifications()), N.schedule(this._notifyTask);
629
689
  }
630
690
  _flushNotifications() {
631
691
  if (!(this.flags & T.NOTIFICATION_SCHEDULED)) return;
632
692
  const e = this._pendingOldValue, t = this._value;
633
693
  this._pendingOldValue = void 0, this.flags &= -3, this._notifySubscribers(t, e);
634
694
  }
635
- /**
636
- * Overridden to avoid unnecessary manager creation during notification loop.
637
- */
638
- _notifySubscribers(e, t) {
639
- this._functionSubscribersStore && this._functionSubscribersStore.forEachSafe((s) => s(e, t)), this._objectSubscribersStore && this._objectSubscribersStore.forEachSafe((s) => s.execute());
640
- }
641
695
  peek() {
642
696
  return this._value;
643
697
  }
644
698
  dispose() {
645
- this._functionSubscribersStore?.clear(), this._objectSubscribersStore?.clear(), this._value = void 0, this._notifyTask = void 0;
699
+ this._fnSubs = null, this._objSubs = null, this._value = void 0, this._notifyTask = void 0;
646
700
  }
647
701
  }
648
- function me(i, e = {}) {
649
- return new be(i, e.sync ?? !1);
702
+ function Ce(s, e = {}) {
703
+ return new ge(s, e.sync ?? !1);
650
704
  }
651
- function R(i, e, t) {
652
- if (i instanceof TypeError)
653
- return new e(`Type error (${t}): ${i.message}`, i);
654
- if (i instanceof ReferenceError)
655
- return new e(`Reference error (${t}): ${i.message}`, i);
656
- if (i instanceof b)
657
- return i;
658
- const s = i instanceof Error ? i.message : String(i), r = i instanceof Error ? i : null;
659
- return new e(`Unexpected error (${t}): ${s}`, r);
705
+ function A(s, e, t) {
706
+ if (s instanceof TypeError)
707
+ return new e(`Type error (${t}): ${s.message}`, s);
708
+ if (s instanceof ReferenceError)
709
+ return new e(`Reference error (${t}): ${s.message}`, s);
710
+ if (s instanceof g)
711
+ return s;
712
+ const i = s instanceof Error ? s.message : String(s), n = s instanceof Error ? s : null;
713
+ return new e(`Unexpected error (${t}): ${i}`, n);
660
714
  }
661
- const K = c.RESOLVED | c.PENDING | c.REJECTED, M = Array(K + 1).fill(L.IDLE);
662
- M[c.RESOLVED] = L.RESOLVED;
663
- M[c.PENDING] = L.PENDING;
664
- M[c.REJECTED] = L.REJECTED;
665
- class Z extends Q {
715
+ const K = h.RESOLVED | h.PENDING | h.REJECTED, L = Array(K + 1).fill(v.IDLE);
716
+ L[h.RESOLVED] = v.RESOLVED;
717
+ L[h.PENDING] = v.PENDING;
718
+ L[h.REJECTED] = v.REJECTED;
719
+ class Z extends H {
666
720
  constructor(e, t = {}) {
667
721
  if (typeof e != "function")
668
- throw new N(h.COMPUTED_MUST_BE_FUNCTION);
669
- if (super(), this._cachedErrors = null, this._errorCacheEpoch = -1, this._value = void 0, this.flags = c.DIRTY | c.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : q, this._hasDefaultValue = this._defaultValue !== q, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribersStore = new P(), this._objectSubscribersStore = new P(), this._dependencies = u, this._dependencyVersions = a, this._unsubscribes = f, this._notifyJob = () => {
670
- this._functionSubscribersStore.forEachSafe(
671
- (s) => s(),
672
- (s) => console.error(s)
673
- ), this._objectSubscribersStore.forEachSafe(
674
- (s) => s.execute(),
675
- (s) => console.error(s)
676
- );
722
+ throw new D(u.COMPUTED_MUST_BE_FUNCTION);
723
+ if (super(), this._fnSubs = null, this._objSubs = null, this._cachedErrors = null, this._errorCacheEpoch = -1, this._asyncStartAggregateVersion = 0, this._asyncRetryCount = 0, this.MAX_ASYNC_RETRIES = 3, this._value = void 0, this.flags = 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 : k, this._hasDefaultValue = this._defaultValue !== k, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._dependencies = _, this._dependencyVersions = a, this._unsubscribes = f, this._notifyJob = () => {
724
+ const i = this._fnSubs;
725
+ if (i)
726
+ for (let r = i.length - 1; r >= 0; r--)
727
+ try {
728
+ const o = i[r];
729
+ o && o(void 0, void 0);
730
+ } catch (o) {
731
+ console.error(o);
732
+ }
733
+ const n = this._objSubs;
734
+ if (n)
735
+ for (let r = n.length - 1; r >= 0; r--)
736
+ try {
737
+ const o = n[r];
738
+ o && o.execute();
739
+ } catch (o) {
740
+ console.error(o);
741
+ }
677
742
  }, this._trackable = Object.assign(() => this._markDirty(), {
678
- addDependency: (s) => {
743
+ addDependency: (i) => {
679
744
  }
680
- }), E.attachDebugInfo(this, "computed", this.id), E.enabled) {
681
- const s = this;
682
- s.subscriberCount = () => this._functionSubscribersStore.size + this._objectSubscribersStore.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencies, s.stateFlags = this._getFlagsAsString();
745
+ }), p.attachDebugInfo(this, "computed", this.id), p.enabled) {
746
+ const i = this;
747
+ i.subscriberCount = this.subscriberCount.bind(this), i.isDirty = () => this._isDirty(), i.dependencies = this._dependencies, i.stateFlags = this._getFlagsAsString();
683
748
  }
684
749
  if (t.lazy === !1)
685
750
  try {
@@ -687,11 +752,11 @@ class Z extends Q {
687
752
  } catch {
688
753
  }
689
754
  }
690
- get _functionSubscribers() {
691
- return this._functionSubscribersStore;
755
+ _getFnSubs() {
756
+ return this._fnSubs ??= [], this._fnSubs;
692
757
  }
693
- get _objectSubscribers() {
694
- return this._objectSubscribersStore;
758
+ _getObjSubs() {
759
+ return this._objSubs ??= [], this._objSubs;
695
760
  }
696
761
  get value() {
697
762
  return this._registerTracking(), this._computeValue();
@@ -723,13 +788,13 @@ class Z extends Q {
723
788
  return this._cachedErrors;
724
789
  const t = /* @__PURE__ */ new Set();
725
790
  this._error && t.add(this._error);
726
- for (let s = 0; s < this._dependencies.length; s++) {
727
- const r = this._dependencies[s];
728
- if (r && "errors" in r) {
729
- const n = r.errors;
730
- for (let o = 0; o < n.length; o++) {
731
- const _ = n[o];
732
- _ && t.add(_);
791
+ for (let i = 0; i < this._dependencies.length; i++) {
792
+ const n = this._dependencies[i];
793
+ if (n && "errors" in n) {
794
+ const r = n.errors;
795
+ for (let o = 0; o < r.length; o++) {
796
+ const c = r[o];
797
+ c && t.add(c);
733
798
  }
734
799
  }
735
800
  }
@@ -753,53 +818,53 @@ class Z extends Q {
753
818
  const t = this._unsubscribes[e];
754
819
  t && t();
755
820
  }
756
- I.release(this._unsubscribes), this._unsubscribes = f;
821
+ C.release(this._unsubscribes), this._unsubscribes = f;
757
822
  }
758
- this._dependencies !== u && (S.release(this._dependencies), this._dependencies = u), this._dependencyVersions !== a && (d.release(this._dependencyVersions), this._dependencyVersions = a), this._functionSubscribersStore.clear(), this._objectSubscribersStore.clear(), this.flags = c.DIRTY | c.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID, this._cachedErrors = null, this._errorCacheEpoch = -1;
823
+ this._dependencies !== _ && (S.release(this._dependencies), this._dependencies = _), this._dependencyVersions !== a && (d.release(this._dependencyVersions), this._dependencyVersions = a), this._fnSubs = null, this._objSubs = null, this.flags = h.DIRTY | h.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID, this._cachedErrors = null, this._errorCacheEpoch = -1;
759
824
  }
760
825
  // State flag operations
761
826
  _isDirty() {
762
- return (this.flags & c.DIRTY) !== 0;
827
+ return (this.flags & h.DIRTY) !== 0;
763
828
  }
764
829
  _setDirty() {
765
- this.flags |= c.DIRTY;
830
+ this.flags |= h.DIRTY;
766
831
  }
767
832
  _clearDirty() {
768
833
  this.flags &= -2;
769
834
  }
770
835
  _isIdle() {
771
- return (this.flags & c.IDLE) !== 0;
836
+ return (this.flags & h.IDLE) !== 0;
772
837
  }
773
838
  _setIdle() {
774
- this.flags |= c.IDLE, this.flags &= -29;
839
+ this.flags |= h.IDLE, this.flags &= -29;
775
840
  }
776
841
  _isPending() {
777
- return (this.flags & c.PENDING) !== 0;
842
+ return (this.flags & h.PENDING) !== 0;
778
843
  }
779
844
  _setPending() {
780
- this.flags |= c.PENDING, this.flags &= -27;
845
+ this.flags |= h.PENDING, this.flags &= -27;
781
846
  }
782
847
  _isResolved() {
783
- return (this.flags & c.RESOLVED) !== 0;
848
+ return (this.flags & h.RESOLVED) !== 0;
784
849
  }
785
850
  _setResolved() {
786
- this.flags |= c.RESOLVED, this.flags &= -87;
851
+ this.flags |= h.RESOLVED, this.flags &= -87;
787
852
  }
788
853
  _isRejected() {
789
- return (this.flags & c.REJECTED) !== 0;
854
+ return (this.flags & h.REJECTED) !== 0;
790
855
  }
791
856
  _setRejected() {
792
- this.flags |= c.REJECTED | c.HAS_ERROR, this.flags &= -15;
857
+ this.flags |= h.REJECTED | h.HAS_ERROR, this.flags &= -15;
793
858
  }
794
859
  _isRecomputing() {
795
- return (this.flags & c.RECOMPUTING) !== 0;
860
+ return (this.flags & h.RECOMPUTING) !== 0;
796
861
  }
797
862
  _setRecomputing(e) {
798
- const t = c.RECOMPUTING;
863
+ const t = h.RECOMPUTING;
799
864
  this.flags = this.flags & ~t | -Number(e) & t;
800
865
  }
801
866
  _getAsyncState() {
802
- return M[this.flags & K];
867
+ return L[this.flags & K];
803
868
  }
804
869
  _getFlagsAsString() {
805
870
  const e = [];
@@ -814,74 +879,134 @@ class Z extends Q {
814
879
  const e = this._prepareComputationContext();
815
880
  let t = !1;
816
881
  try {
817
- const s = m.run(this._trackable, this._fn);
818
- this._commitDependencies(e), t = !0, J(s) ? this._handleAsyncComputation(s) : this._handleSyncResult(s);
819
- } catch (s) {
882
+ const i = m.run(this._trackable, this._fn);
883
+ this._commitDependencies(e), t = !0, J(i) ? this._handleAsyncComputation(i) : this._handleSyncResult(i);
884
+ } catch (i) {
820
885
  if (!t)
821
886
  try {
822
887
  this._commitDependencies(e), t = !0;
823
- } catch (r) {
824
- this._handleComputationError(r);
888
+ } catch (n) {
889
+ this._handleComputationError(n);
825
890
  }
826
- this._handleComputationError(s);
891
+ this._handleComputationError(i);
827
892
  } finally {
828
893
  this._cleanupContext(e, t), this._setRecomputing(!1);
829
894
  }
830
895
  }
831
896
  _prepareComputationContext() {
832
- const e = this._dependencies, t = this._dependencyVersions, s = S.acquire(), r = d.acquire(), n = $(), o = { depCount: 0 }, _ = (p) => {
833
- p._lastSeenEpoch !== n && (p._lastSeenEpoch = n, o.depCount < s.length ? (s[o.depCount] = p, r[o.depCount] = p.version) : (s.push(p), r.push(p.version)), o.depCount++);
834
- }, C = this._trackable.addDependency;
835
- return this._trackable.addDependency = _, { prevDeps: e, prevVersions: t, nextDeps: s, nextVersions: r, originalAdd: C, state: o };
897
+ const e = this._dependencies, t = this._dependencyVersions, i = S.acquire(), n = d.acquire(), r = $(), o = { depCount: 0 }, c = (E) => {
898
+ E._lastSeenEpoch !== r && (E._lastSeenEpoch = r, o.depCount < i.length ? (i[o.depCount] = E, n[o.depCount] = E.version) : (i.push(E), n.push(E.version)), o.depCount++);
899
+ }, R = this._trackable.addDependency;
900
+ return this._trackable.addDependency = c, { prevDeps: e, prevVersions: t, nextDeps: i, nextVersions: n, originalAdd: R, state: o };
836
901
  }
837
902
  _commitDependencies(e) {
838
- const { nextDeps: t, nextVersions: s, state: r, prevDeps: n } = e;
839
- t.length = r.depCount, s.length = r.depCount, this._unsubscribes = pe(t, n, this._unsubscribes, this), this._dependencies = t, this._dependencyVersions = s;
903
+ const { nextDeps: t, nextVersions: i, state: n, prevDeps: r } = e;
904
+ t.length = n.depCount, i.length = n.depCount, this._unsubscribes = Ee(t, r, this._unsubscribes, this), this._dependencies = t, this._dependencyVersions = i;
840
905
  }
841
906
  _cleanupContext(e, t) {
842
- this._trackable.addDependency = e.originalAdd, t ? (e.prevDeps !== u && S.release(e.prevDeps), e.prevVersions !== a && d.release(e.prevVersions)) : (S.release(e.nextDeps), d.release(e.nextVersions));
907
+ this._trackable.addDependency = e.originalAdd, t ? (e.prevDeps !== _ && S.release(e.prevDeps), e.prevVersions !== a && d.release(e.prevVersions)) : (S.release(e.nextDeps), d.release(e.nextVersions));
908
+ }
909
+ /**
910
+ * Calculates aggregate shift from all dependencies.
911
+ * Used for scheduling priority in computed chains.
912
+ *
913
+ * Performance: O(N) where N = dependency count
914
+ * Branchless: Each dep.getShift uses modular arithmetic
915
+ *
916
+ * @returns Sum of all dependency shifts (capped at SMI_MAX)
917
+ */
918
+ _getAggregateShift() {
919
+ let e = 0;
920
+ const t = this._dependencies, i = this._dependencyVersions;
921
+ for (let n = 0; n < t.length; n++) {
922
+ const r = t[n], o = i[n];
923
+ r && o !== void 0 && (e = e + r.getShift(o) & b);
924
+ }
925
+ return e;
926
+ }
927
+ /**
928
+ * Checks if this computed should be scheduled with urgent priority.
929
+ * Based on aggregate shift from all dependencies.
930
+ *
931
+ * @returns true if aggregate shift exceeds PHASE_THRESHOLD
932
+ */
933
+ isUrgent() {
934
+ return this._getAggregateShift() >= w;
843
935
  }
844
936
  _handleSyncResult(e) {
845
- const t = !this._isResolved() || !this._equal(this._value, e);
846
- this.version = this.version + Number(t) & y, this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), this._cachedErrors = null, this._errorCacheEpoch = -1;
937
+ this._finalizeResolution(e);
847
938
  }
848
939
  _handleAsyncComputation(e) {
849
- this._setPending(), this._clearDirty(), this._notifyJob(), this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
940
+ this._setPending(), this._clearDirty(), this._notifyJob(), this._asyncStartAggregateVersion = this._captureVersionSnapshot(), this._asyncRetryCount = 0, this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
850
941
  const t = this._promiseId;
851
- e.then((s) => {
852
- t === this._promiseId && this._handleAsyncResolution(s);
853
- }).catch((s) => {
854
- t === this._promiseId && this._handleAsyncRejection(s);
942
+ e.then((i) => {
943
+ if (t !== this._promiseId) return;
944
+ const r = this._captureVersionSnapshot() - this._asyncStartAggregateVersion & b;
945
+ if (w - 1 - r >>> 31 & 1) {
946
+ if (this._asyncRetryCount < this.MAX_ASYNC_RETRIES) {
947
+ this._asyncRetryCount++, this._markDirty();
948
+ return;
949
+ }
950
+ const c = new D(
951
+ `Async drift exceeded threshold after ${this.MAX_ASYNC_RETRIES} retries. Dependencies changed too rapidly for stable computation.`
952
+ );
953
+ this._handleAsyncRejection(c);
954
+ return;
955
+ }
956
+ this._handleAsyncResolution(i);
957
+ }).catch((i) => {
958
+ t === this._promiseId && this._handleAsyncRejection(i);
855
959
  });
856
960
  }
961
+ /**
962
+ * Captures the aggregate version of all dependencies.
963
+ * Used for phase drift validation in async computations.
964
+ *
965
+ * @returns Sum of all dependency versions (capped at SMI_MAX)
966
+ */
967
+ _captureVersionSnapshot() {
968
+ let e = 0;
969
+ const t = this._dependencies;
970
+ for (let i = 0; i < t.length; i++) {
971
+ const n = t[i];
972
+ n && (e = e + n.version & b);
973
+ }
974
+ return e;
975
+ }
857
976
  _handleAsyncResolution(e) {
858
- const t = !this._isResolved() || !this._equal(this._value, e);
859
- this.version = this.version + Number(t) & y, this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), this._cachedErrors = null, this._errorCacheEpoch = -1, this._notifyJob();
977
+ this._finalizeResolution(e), this._notifyJob();
978
+ }
979
+ /**
980
+ * Unified success finalization for sync and async results.
981
+ * Handles phase rotation, state transition, and error cache clearing.
982
+ */
983
+ _finalizeResolution(e) {
984
+ (!this._isResolved() || !this._equal(this._value, e)) && this.rotatePhase(), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), this._cachedErrors = null, this._errorCacheEpoch = -1;
860
985
  }
861
986
  _handleAsyncRejection(e) {
862
- const t = R(e, N, h.COMPUTED_ASYNC_COMPUTATION_FAILED), s = !this._isRejected();
863
- if (this.version = this.version + Number(s) & y, this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError)
987
+ const t = A(e, D, u.COMPUTED_ASYNC_COMPUTATION_FAILED);
988
+ if (!this._isRejected() && this.rotatePhase(), this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError)
864
989
  try {
865
990
  this._onError(t);
866
- } catch (r) {
867
- console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, r);
991
+ } catch (n) {
992
+ console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER, n);
868
993
  }
869
994
  this._notifyJob();
870
995
  }
871
996
  _handleComputationError(e) {
872
- const t = R(e, N, h.COMPUTED_COMPUTATION_FAILED);
997
+ const t = A(e, D, u.COMPUTED_COMPUTATION_FAILED);
873
998
  if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError)
874
999
  try {
875
1000
  this._onError(t);
876
- } catch (s) {
877
- console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
1001
+ } catch (i) {
1002
+ console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER, i);
878
1003
  }
879
1004
  throw t;
880
1005
  }
881
1006
  _handlePending() {
882
1007
  if (this._hasDefaultValue)
883
1008
  return this._defaultValue;
884
- throw new N(h.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
1009
+ throw new D(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
885
1010
  }
886
1011
  _handleRejected() {
887
1012
  if (this._error?.recoverable && this._hasDefaultValue)
@@ -896,19 +1021,14 @@ class Z extends Q {
896
1021
  this._isRecomputing() || this._isDirty() || (this._setDirty(), this._notifyJob());
897
1022
  }
898
1023
  _registerTracking() {
899
- W(
900
- this,
901
- m.getCurrent(),
902
- this._functionSubscribersStore,
903
- this._objectSubscribersStore
904
- );
1024
+ W(this, m.getCurrent(), this._getFnSubs(), this._getObjSubs());
905
1025
  }
906
1026
  }
907
1027
  Object.freeze(Z.prototype);
908
- function Ce(i, e = {}) {
909
- return new Z(i, e);
1028
+ function me(s, e = {}) {
1029
+ return new Z(s, e);
910
1030
  }
911
- class Se extends H {
1031
+ class Se extends Y {
912
1032
  /**
913
1033
  * Creates a new EffectImpl instance.
914
1034
  * @param fn - The effect function to run.
@@ -917,58 +1037,58 @@ class Se extends H {
917
1037
  constructor(e, t = {}) {
918
1038
  super(), this.run = () => {
919
1039
  if (this.isDisposed)
920
- throw new g(h.EFFECT_MUST_BE_FUNCTION);
1040
+ throw new y(u.EFFECT_MUST_BE_FUNCTION);
921
1041
  this._dependencyVersions !== a && (d.release(this._dependencyVersions), this._dependencyVersions = a), this.execute();
922
1042
  }, this.dispose = () => {
923
1043
  if (!this.isDisposed) {
924
1044
  if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== f) {
925
- for (let r = 0; r < this._unsubscribes.length; r++) {
926
- const n = this._unsubscribes[r];
927
- n && n();
1045
+ for (let n = 0; n < this._unsubscribes.length; n++) {
1046
+ const r = this._unsubscribes[n];
1047
+ r && r();
928
1048
  }
929
- I.release(this._unsubscribes), this._unsubscribes = f;
1049
+ C.release(this._unsubscribes), this._unsubscribes = f;
930
1050
  }
931
- this._dependencies !== u && (S.release(this._dependencies), this._dependencies = u), this._dependencyVersions !== a && (d.release(this._dependencyVersions), this._dependencyVersions = a);
1051
+ this._dependencies !== _ && (S.release(this._dependencies), this._dependencies = _), this._dependencyVersions !== a && (d.release(this._dependencyVersions), this._dependencyVersions = a);
932
1052
  }
933
- }, this.addDependency = (r) => {
1053
+ }, this.addDependency = (n) => {
934
1054
  if (this.isExecuting && this._nextDeps && this._nextUnsubs && this._nextVersions) {
935
- const n = this._currentEpoch;
936
- if (r._lastSeenEpoch === n) return;
937
- r._lastSeenEpoch = n, this._nextDeps.push(r), this._nextVersions.push(r.version), r._tempUnsub ? (this._nextUnsubs.push(r._tempUnsub), r._tempUnsub = void 0) : this._subscribeTo(r);
1055
+ const r = this._currentEpoch;
1056
+ if (n._lastSeenEpoch === r) return;
1057
+ 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);
938
1058
  }
939
1059
  }, this.execute = () => {
940
1060
  if (this.isDisposed || this.isExecuting || !this._shouldExecute()) return;
941
1061
  this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup();
942
- const r = this._prepareEffectContext();
943
- let n = !1;
1062
+ const n = this._prepareEffectExecutionContext();
1063
+ let r = !1;
944
1064
  try {
945
1065
  const o = m.run(this, this._fn);
946
- this._commitEffect(r), n = !0, this._checkLoopWarnings(), J(o) ? o.then((_) => {
947
- !this.isDisposed && typeof _ == "function" && (this._cleanup = _);
948
- }).catch((_) => {
949
- this._handleExecutionError(_);
1066
+ this._commitEffect(n), r = !0, this._checkLoopWarnings(), J(o) ? o.then((c) => {
1067
+ !this.isDisposed && typeof c == "function" && (this._cleanup = c);
1068
+ }).catch((c) => {
1069
+ this._handleExecutionError(c);
950
1070
  }) : this._cleanup = typeof o == "function" ? o : null;
951
1071
  } catch (o) {
952
- n = !0, this._handleExecutionError(o), this._cleanup = null;
1072
+ r = !0, this._handleExecutionError(o), this._cleanup = null;
953
1073
  } finally {
954
- this._cleanupEffect(r, n), this._setExecuting(!1);
1074
+ this._cleanupEffect(n, r), this._setExecuting(!1);
955
1075
  }
956
- }, this._currentEpoch = -1, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? D.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? D.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = u, this._dependencyVersions = a, this._unsubscribes = f, this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, this._onError = t.onError ?? null, this._historyPtr = 0;
957
- const s = Number.isFinite(this._maxExecutions);
958
- this._historyCapacity = s ? Math.min(this._maxExecutions + 1, D.MAX_EXECUTIONS_PER_SECOND + 1) : 0, this._history = l && s && this._historyCapacity > 0 ? new Array(this._historyCapacity).fill(0) : null, this._executionCount = 0, E.attachDebugInfo(this, "effect", this.id);
1076
+ }, this._cleanup = null, this._dependencies = _, this._dependencyVersions = a, this._unsubscribes = f, this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, this._onError = t.onError ?? null, this._currentEpoch = -1, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? I.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? I.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._historyPtr = 0;
1077
+ const i = Number.isFinite(this._maxExecutions);
1078
+ this._historyCapacity = i ? Math.min(this._maxExecutions + 1, I.MAX_EXECUTIONS_PER_SECOND + 1) : 0, this._history = l && i && this._historyCapacity > 0 ? new Array(this._historyCapacity).fill(0) : null, this._executionCount = 0, p.attachDebugInfo(this, "effect", this.id);
959
1079
  }
960
1080
  /**
961
1081
  * Prepares the execution context by acquiring pools and setting up epoch.
962
- * @returns The prepared EffectContext.
1082
+ * @returns The prepared EffectExecutionContext.
963
1083
  */
964
- _prepareEffectContext() {
965
- const e = this._dependencies, t = this._dependencyVersions, s = this._unsubscribes, r = S.acquire(), n = d.acquire(), o = I.acquire(), _ = $();
966
- if (e !== u && s !== f)
967
- for (let C = 0; C < e.length; C++) {
968
- const p = e[C];
969
- p && (p._tempUnsub = s[C]);
1084
+ _prepareEffectExecutionContext() {
1085
+ const e = this._dependencies, t = this._dependencyVersions, i = this._unsubscribes, n = S.acquire(), r = d.acquire(), o = C.acquire(), c = $();
1086
+ if (e !== _ && i !== f)
1087
+ for (let R = 0; R < e.length; R++) {
1088
+ const E = e[R];
1089
+ E && (E._tempUnsub = i[R]);
970
1090
  }
971
- return this._nextDeps = r, this._nextVersions = n, this._nextUnsubs = o, this._currentEpoch = _, { prevDeps: e, prevVersions: t, prevUnsubs: s, nextDeps: r, nextVersions: n, nextUnsubs: o };
1091
+ return this._nextDeps = n, this._nextVersions = r, this._nextUnsubs = o, this._currentEpoch = c, { prevDeps: e, prevVersions: t, prevUnsubs: i, nextDeps: n, nextVersions: r, nextUnsubs: o };
972
1092
  }
973
1093
  /**
974
1094
  * Commits the tracked dependencies as the current active dependencies.
@@ -985,22 +1105,22 @@ class Se extends H {
985
1105
  */
986
1106
  _cleanupEffect(e, t) {
987
1107
  if (this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, t) {
988
- if (e.prevDeps !== u) {
989
- for (let s = 0; s < e.prevDeps.length; s++) {
990
- const r = e.prevDeps[s];
991
- r?._tempUnsub && (r._tempUnsub(), r._tempUnsub = void 0);
1108
+ if (e.prevDeps !== _) {
1109
+ for (let i = 0; i < e.prevDeps.length; i++) {
1110
+ const n = e.prevDeps[i];
1111
+ n?._tempUnsub && (n._tempUnsub(), n._tempUnsub = void 0);
992
1112
  }
993
1113
  S.release(e.prevDeps);
994
1114
  }
995
- e.prevUnsubs !== f && I.release(e.prevUnsubs), e.prevVersions !== a && d.release(e.prevVersions);
1115
+ e.prevUnsubs !== f && C.release(e.prevUnsubs), e.prevVersions !== a && d.release(e.prevVersions);
996
1116
  } else {
997
1117
  S.release(e.nextDeps), d.release(e.nextVersions);
998
- for (let s = 0; s < e.nextUnsubs.length; s++)
999
- e.nextUnsubs[s]?.();
1000
- if (I.release(e.nextUnsubs), e.prevDeps !== u)
1001
- for (let s = 0; s < e.prevDeps.length; s++) {
1002
- const r = e.prevDeps[s];
1003
- r && (r._tempUnsub = void 0);
1118
+ for (let i = 0; i < e.nextUnsubs.length; i++)
1119
+ e.nextUnsubs[i]?.();
1120
+ if (C.release(e.nextUnsubs), e.prevDeps !== _)
1121
+ for (let i = 0; i < e.prevDeps.length; i++) {
1122
+ const n = e.prevDeps[i];
1123
+ n && (n._tempUnsub = void 0);
1004
1124
  }
1005
1125
  }
1006
1126
  }
@@ -1011,11 +1131,11 @@ class Se extends H {
1011
1131
  _subscribeTo(e) {
1012
1132
  try {
1013
1133
  const t = e.subscribe(() => {
1014
- this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : A.schedule(this.execute);
1134
+ this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : N.schedule(this.execute);
1015
1135
  });
1016
1136
  this._nextUnsubs && this._nextUnsubs.push(t);
1017
1137
  } catch (t) {
1018
- console.error(R(t, g, h.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
1138
+ console.error(A(t, y, u.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
1019
1139
  });
1020
1140
  }
1021
1141
  }
@@ -1052,7 +1172,7 @@ class Se extends H {
1052
1172
  try {
1053
1173
  this._cleanup();
1054
1174
  } catch (e) {
1055
- console.error(R(e, g, h.EFFECT_CLEANUP_FAILED));
1175
+ console.error(A(e, y, u.EFFECT_CLEANUP_FAILED));
1056
1176
  }
1057
1177
  this._cleanup = null;
1058
1178
  }
@@ -1062,13 +1182,13 @@ class Se extends H {
1062
1182
  * @throws {EffectError} If an infinite loop is detected.
1063
1183
  */
1064
1184
  _checkInfiniteLoop() {
1065
- if (this._lastFlushEpoch !== F && (this._lastFlushEpoch = F, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), ce() > D.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history && this._maxExecutions > 0) {
1066
- const e = Date.now(), t = this._historyPtr, s = this._historyCapacity;
1185
+ if (this._lastFlushEpoch !== F && (this._lastFlushEpoch = F, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), he() > I.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history && this._maxExecutions > 0) {
1186
+ const e = Date.now(), t = this._historyPtr, i = this._historyCapacity;
1067
1187
  this._history[t] = e;
1068
- const r = (t + 1) % s, n = this._history[r] ?? 0;
1069
- if (this._historyPtr = r, n > 0 && e - n < ee.ONE_SECOND_MS) {
1070
- const o = new g(
1071
- `Effect executed ${s} times within 1 second. Infinite loop suspected`
1188
+ const n = (t + 1) % i, r = this._history[n] ?? 0;
1189
+ if (this._historyPtr = n, r > 0 && e - r < ee.ONE_SECOND_MS) {
1190
+ const o = new y(
1191
+ `Effect executed ${i} times within 1 second. Infinite loop suspected`
1072
1192
  );
1073
1193
  if (this.dispose(), console.error(o), this._onError && this._onError(o), l)
1074
1194
  throw o;
@@ -1076,8 +1196,8 @@ class Se extends H {
1076
1196
  }
1077
1197
  }
1078
1198
  _throwInfiniteLoopError(e) {
1079
- const t = new g(
1080
- `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${k}`
1199
+ const t = new y(
1200
+ `Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${z}`
1081
1201
  );
1082
1202
  throw this.dispose(), console.error(t), t;
1083
1203
  }
@@ -1086,14 +1206,14 @@ class Se extends H {
1086
1206
  * @returns true if any dependency has changed or if it's the first run.
1087
1207
  */
1088
1208
  _shouldExecute() {
1089
- if (this._dependencies === u || this._dependencyVersions === a)
1209
+ if (this._dependencies === _ || this._dependencyVersions === a)
1090
1210
  return !0;
1091
1211
  for (let e = 0; e < this._dependencies.length; e++) {
1092
1212
  const t = this._dependencies[e];
1093
1213
  if (t) {
1094
1214
  if ("value" in t)
1095
1215
  try {
1096
- ae(() => t.value);
1216
+ _e(() => t.value);
1097
1217
  } catch {
1098
1218
  return !0;
1099
1219
  }
@@ -1108,7 +1228,7 @@ class Se extends H {
1108
1228
  * Wraps the error, logs it to console, and calls onError callback if provided.
1109
1229
  */
1110
1230
  _handleExecutionError(e) {
1111
- const t = R(e, g, h.EFFECT_EXECUTION_FAILED);
1231
+ const t = A(e, y, u.EFFECT_EXECUTION_FAILED);
1112
1232
  console.error(t), this._onError && this._onError(t);
1113
1233
  }
1114
1234
  /**
@@ -1116,42 +1236,42 @@ class Se extends H {
1116
1236
  * Only active if trackModifications is enabled and debug is on.
1117
1237
  */
1118
1238
  _checkLoopWarnings() {
1119
- if (this._trackModifications && E.enabled) {
1239
+ if (this._trackModifications && p.enabled) {
1120
1240
  const e = this._dependencies;
1121
1241
  for (let t = 0; t < e.length; t++) {
1122
- const s = e[t];
1123
- s && s._modifiedAtEpoch === this._currentEpoch && E.warn(
1242
+ const i = e[t];
1243
+ i && i._modifiedAtEpoch === this._currentEpoch && p.warn(
1124
1244
  !0,
1125
- `Effect is reading a dependency (${E.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
1245
+ `Effect is reading a dependency (${p.getDebugName(i) || "unknown"}) that it just modified. Infinite loop may occur`
1126
1246
  );
1127
1247
  }
1128
1248
  }
1129
1249
  }
1130
1250
  }
1131
- function Ne(i, e = {}) {
1132
- if (typeof i != "function")
1133
- throw new g(h.EFFECT_MUST_BE_FUNCTION);
1134
- const t = new Se(i, e);
1251
+ function Re(s, e = {}) {
1252
+ if (typeof s != "function")
1253
+ throw new y(u.EFFECT_MUST_BE_FUNCTION);
1254
+ const t = new Se(s, e);
1135
1255
  return t.execute(), t;
1136
1256
  }
1137
1257
  export {
1138
- L as AsyncState,
1139
- b as AtomError,
1140
- N as ComputedError,
1258
+ v as AsyncState,
1259
+ g as AtomError,
1260
+ D as ComputedError,
1141
1261
  B as DEBUG_CONFIG,
1142
- E as DEBUG_RUNTIME,
1143
- g as EffectError,
1144
- ge as POOL_CONFIG,
1145
- D as SCHEDULER_CONFIG,
1262
+ p as DEBUG_RUNTIME,
1263
+ y as EffectError,
1264
+ be as POOL_CONFIG,
1265
+ I as SCHEDULER_CONFIG,
1146
1266
  U as SchedulerError,
1147
- me as atom,
1148
- De as batch,
1149
- Ce as computed,
1150
- Ne as effect,
1151
- _e as isAtom,
1152
- Ie as isComputed,
1153
- ye as isEffect,
1154
- A as scheduler,
1155
- ae as untracked
1267
+ Ce as atom,
1268
+ ye as batch,
1269
+ me as computed,
1270
+ Re as effect,
1271
+ ae as isAtom,
1272
+ De as isComputed,
1273
+ Ie as isEffect,
1274
+ N as scheduler,
1275
+ _e as untracked
1156
1276
  };
1157
1277
  //# sourceMappingURL=index.mjs.map