@but212/atom-effect 0.3.0 → 0.3.2
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/README.md +8 -7
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.mjs +299 -251
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const
|
|
1
|
+
const T = {
|
|
2
2
|
IDLE: "idle",
|
|
3
3
|
PENDING: "pending",
|
|
4
4
|
RESOLVED: "resolved",
|
|
5
5
|
REJECTED: "rejected"
|
|
6
|
-
},
|
|
6
|
+
}, F = {
|
|
7
7
|
DISPOSED: 1,
|
|
8
8
|
// 0001 - Effect has been disposed
|
|
9
9
|
EXECUTING: 2
|
|
10
10
|
// 0010 - Effect is currently executing
|
|
11
|
-
},
|
|
11
|
+
}, h = {
|
|
12
12
|
DIRTY: 1,
|
|
13
13
|
// 0001 - Needs recomputation
|
|
14
14
|
IDLE: 2,
|
|
@@ -23,12 +23,12 @@ const R = {
|
|
|
23
23
|
// 100000 - Currently recomputing
|
|
24
24
|
HAS_ERROR: 64
|
|
25
25
|
// 1000000 - Has error state
|
|
26
|
-
},
|
|
26
|
+
}, ie = {
|
|
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
|
-
},
|
|
31
|
+
}, A = {
|
|
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 R = {
|
|
|
43
43
|
* Increased from 1000 to 5000 based on evaluation report
|
|
44
44
|
*/
|
|
45
45
|
MAX_EXECUTIONS_PER_FLUSH: 5e3
|
|
46
|
-
},
|
|
46
|
+
}, k = {
|
|
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
|
-
},
|
|
52
|
-
class
|
|
51
|
+
}, D = 1073741823, M = typeof process < "u" && process.env && process.env.NODE_ENV !== "production";
|
|
52
|
+
class d 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 _ 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
|
|
63
|
+
class I extends d {
|
|
64
64
|
/**
|
|
65
65
|
* Creates a new ComputedError
|
|
66
66
|
* @param message - Error message
|
|
@@ -70,7 +70,7 @@ class b extends _ {
|
|
|
70
70
|
super(e, t, !0), this.name = "ComputedError";
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
class
|
|
73
|
+
class g extends d {
|
|
74
74
|
/**
|
|
75
75
|
* Creates a new EffectError
|
|
76
76
|
* @param message - Error message
|
|
@@ -80,7 +80,7 @@ class E extends _ {
|
|
|
80
80
|
super(e, t, !1), this.name = "EffectError";
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
class
|
|
83
|
+
class C extends d {
|
|
84
84
|
/**
|
|
85
85
|
* Creates a new SchedulerError
|
|
86
86
|
* @param message - Error message
|
|
@@ -90,20 +90,20 @@ class y extends _ {
|
|
|
90
90
|
super(e, t, !1), this.name = "SchedulerError";
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function R(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
|
|
98
|
+
if (i instanceof d)
|
|
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
|
|
103
|
+
function X(i) {
|
|
104
104
|
return i != null && typeof i.then == "function";
|
|
105
105
|
}
|
|
106
|
-
const
|
|
106
|
+
const a = {
|
|
107
107
|
// ─────────────────────────────────────────────────────────────────
|
|
108
108
|
// Computed errors
|
|
109
109
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -112,9 +112,9 @@ const h = {
|
|
|
112
112
|
*/
|
|
113
113
|
COMPUTED_MUST_BE_FUNCTION: "Computed function must be a function",
|
|
114
114
|
/**
|
|
115
|
-
* Error thrown when subscribe() receives
|
|
115
|
+
* Error thrown when subscribe() receives an invalid listener.
|
|
116
116
|
*/
|
|
117
|
-
COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION: "Subscriber listener must be a function",
|
|
117
|
+
COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION: "Subscriber listener must be a function or Subscriber object",
|
|
118
118
|
/**
|
|
119
119
|
* Error thrown when accessing a pending async computed without a default value.
|
|
120
120
|
*/
|
|
@@ -135,9 +135,9 @@ const h = {
|
|
|
135
135
|
// Atom errors
|
|
136
136
|
// ─────────────────────────────────────────────────────────────────
|
|
137
137
|
/**
|
|
138
|
-
* Error thrown when atom.subscribe() receives
|
|
138
|
+
* Error thrown when atom.subscribe() receives an invalid listener.
|
|
139
139
|
*/
|
|
140
|
-
ATOM_SUBSCRIBER_MUST_BE_FUNCTION: "Subscription listener must be a function",
|
|
140
|
+
ATOM_SUBSCRIBER_MUST_BE_FUNCTION: "Subscription listener must be a function or Subscriber object",
|
|
141
141
|
/**
|
|
142
142
|
* Error thrown when the atom subscriber notification process fails.
|
|
143
143
|
*/
|
|
@@ -188,23 +188,23 @@ const h = {
|
|
|
188
188
|
*/
|
|
189
189
|
CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
|
|
190
190
|
};
|
|
191
|
-
let
|
|
192
|
-
function
|
|
193
|
-
return
|
|
191
|
+
let P = 0;
|
|
192
|
+
function G() {
|
|
193
|
+
return P = (P + 1 | 0) & D, P;
|
|
194
194
|
}
|
|
195
|
-
let
|
|
196
|
-
function
|
|
197
|
-
return
|
|
195
|
+
let U = 0, w = 0, O = !1;
|
|
196
|
+
function q() {
|
|
197
|
+
return O ? (M && console.warn(
|
|
198
198
|
"Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"
|
|
199
|
-
), !1) : (
|
|
199
|
+
), !1) : (O = !0, U = U + 1 & D, w = 0, !0);
|
|
200
200
|
}
|
|
201
|
-
function
|
|
202
|
-
|
|
201
|
+
function z() {
|
|
202
|
+
O = !1;
|
|
203
203
|
}
|
|
204
|
-
function
|
|
205
|
-
return
|
|
204
|
+
function H() {
|
|
205
|
+
return O ? ++w : 0;
|
|
206
206
|
}
|
|
207
|
-
class
|
|
207
|
+
class J {
|
|
208
208
|
constructor() {
|
|
209
209
|
this.queueA = [], this.queueB = [], this.queue = this.queueA, this.queueSize = 0, this._epoch = 0, this.isProcessing = !1, this.isBatching = !1, this.batchDepth = 0, this.batchQueue = [], this.batchQueueSize = 0, this.isFlushingSync = !1, this.maxFlushIterations = 1e3;
|
|
210
210
|
}
|
|
@@ -234,7 +234,7 @@ class X {
|
|
|
234
234
|
*/
|
|
235
235
|
schedule(e) {
|
|
236
236
|
if (typeof e != "function")
|
|
237
|
-
throw new
|
|
237
|
+
throw new C("Scheduler callback must be a function");
|
|
238
238
|
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
239
|
}
|
|
240
240
|
/**
|
|
@@ -254,16 +254,16 @@ class X {
|
|
|
254
254
|
this.isProcessing = !0;
|
|
255
255
|
const e = this.queue, t = this.queueSize;
|
|
256
256
|
this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++, queueMicrotask(() => {
|
|
257
|
-
const s =
|
|
257
|
+
const s = q();
|
|
258
258
|
for (let n = 0; n < t; n++)
|
|
259
259
|
try {
|
|
260
260
|
e[n]?.();
|
|
261
261
|
} catch (r) {
|
|
262
262
|
console.error(
|
|
263
|
-
new
|
|
263
|
+
new C("Error occurred during scheduler execution", r)
|
|
264
264
|
);
|
|
265
265
|
}
|
|
266
|
-
e.length = 0, this.isProcessing = !1, s &&
|
|
266
|
+
e.length = 0, this.isProcessing = !1, s && z(), this.queueSize > 0 && !this.isBatching && this.flush();
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
269
|
/**
|
|
@@ -281,7 +281,7 @@ class X {
|
|
|
281
281
|
*/
|
|
282
282
|
flushSync() {
|
|
283
283
|
this.isFlushingSync = !0;
|
|
284
|
-
const e =
|
|
284
|
+
const e = q();
|
|
285
285
|
try {
|
|
286
286
|
if (this._epoch++, this.batchQueueSize > 0) {
|
|
287
287
|
for (let s = 0; s < this.batchQueueSize; s++) {
|
|
@@ -294,7 +294,7 @@ class X {
|
|
|
294
294
|
for (; this.queueSize > 0; ) {
|
|
295
295
|
if (++t > this.maxFlushIterations) {
|
|
296
296
|
console.error(
|
|
297
|
-
new
|
|
297
|
+
new C(
|
|
298
298
|
`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`
|
|
299
299
|
)
|
|
300
300
|
), this.queueSize = 0, this.queue.length = 0, this.batchQueueSize = 0;
|
|
@@ -305,9 +305,9 @@ class X {
|
|
|
305
305
|
for (let r = 0; r < n; r++)
|
|
306
306
|
try {
|
|
307
307
|
s[r]?.();
|
|
308
|
-
} catch (
|
|
308
|
+
} catch (c) {
|
|
309
309
|
console.error(
|
|
310
|
-
new
|
|
310
|
+
new C("Error occurred during batch execution", c)
|
|
311
311
|
);
|
|
312
312
|
}
|
|
313
313
|
if (s.length = 0, this.batchQueueSize > 0) {
|
|
@@ -317,7 +317,7 @@ class X {
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
} finally {
|
|
320
|
-
this.isFlushingSync = !1, e &&
|
|
320
|
+
this.isFlushingSync = !1, e && z();
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
/**
|
|
@@ -381,24 +381,24 @@ class X {
|
|
|
381
381
|
*/
|
|
382
382
|
setMaxFlushIterations(e) {
|
|
383
383
|
if (e < 10)
|
|
384
|
-
throw new
|
|
384
|
+
throw new C("Max flush iterations must be at least 10");
|
|
385
385
|
this.maxFlushIterations = e;
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
-
const
|
|
389
|
-
function
|
|
388
|
+
const N = new J();
|
|
389
|
+
function ne(i) {
|
|
390
390
|
if (typeof i != "function")
|
|
391
|
-
throw new
|
|
392
|
-
|
|
391
|
+
throw new d("Batch callback must be a function");
|
|
392
|
+
N.startBatch();
|
|
393
393
|
try {
|
|
394
394
|
return i();
|
|
395
395
|
} catch (e) {
|
|
396
|
-
throw new
|
|
396
|
+
throw new d("Error occurred during batch execution", e);
|
|
397
397
|
} finally {
|
|
398
|
-
|
|
398
|
+
N.endBatch();
|
|
399
399
|
}
|
|
400
400
|
}
|
|
401
|
-
const
|
|
401
|
+
const m = {
|
|
402
402
|
/** @inheritdoc */
|
|
403
403
|
current: null,
|
|
404
404
|
/**
|
|
@@ -419,24 +419,37 @@ const S = {
|
|
|
419
419
|
return this.current;
|
|
420
420
|
}
|
|
421
421
|
};
|
|
422
|
-
function
|
|
422
|
+
function re(i) {
|
|
423
423
|
if (typeof i != "function")
|
|
424
|
-
throw new
|
|
425
|
-
const e =
|
|
426
|
-
|
|
424
|
+
throw new d("Untracked callback must be a function");
|
|
425
|
+
const e = m.current;
|
|
426
|
+
m.current = null;
|
|
427
427
|
try {
|
|
428
428
|
return i();
|
|
429
429
|
} catch (t) {
|
|
430
|
-
throw new
|
|
430
|
+
throw new d("Error occurred during untracked execution", t);
|
|
431
431
|
} finally {
|
|
432
|
-
|
|
432
|
+
m.current = e;
|
|
433
433
|
}
|
|
434
434
|
}
|
|
435
|
-
const
|
|
436
|
-
function
|
|
437
|
-
return i !== null && typeof i == "object" && "dependencies" in i && i.dependencies
|
|
435
|
+
const v = /* @__PURE__ */ Symbol("debugName"), W = /* @__PURE__ */ Symbol("id"), L = /* @__PURE__ */ Symbol("type"), V = /* @__PURE__ */ Symbol("noDefaultValue");
|
|
436
|
+
function K(i) {
|
|
437
|
+
return i !== null && typeof i == "object" && "dependencies" in i && Array.isArray(i.dependencies);
|
|
438
438
|
}
|
|
439
|
-
|
|
439
|
+
let j = 0;
|
|
440
|
+
function Y(i, e, t) {
|
|
441
|
+
const s = i;
|
|
442
|
+
if (s._visitedEpoch !== t) {
|
|
443
|
+
if (s._visitedEpoch = t, i === e)
|
|
444
|
+
throw new I("Indirect circular dependency detected");
|
|
445
|
+
if (K(i)) {
|
|
446
|
+
const n = i.dependencies;
|
|
447
|
+
for (let r = 0; r < n.length; r++)
|
|
448
|
+
Y(n[r], e, t);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
const b = {
|
|
440
453
|
/**
|
|
441
454
|
* Whether debug mode is enabled.
|
|
442
455
|
*
|
|
@@ -450,13 +463,13 @@ const f = {
|
|
|
450
463
|
*
|
|
451
464
|
* @see {@link DEBUG_CONFIG.MAX_DEPENDENCIES}
|
|
452
465
|
*/
|
|
453
|
-
maxDependencies:
|
|
466
|
+
maxDependencies: k.MAX_DEPENDENCIES,
|
|
454
467
|
/**
|
|
455
468
|
* Whether to warn about potential infinite loops.
|
|
456
469
|
*
|
|
457
470
|
* @see {@link DEBUG_CONFIG.WARN_INFINITE_LOOP}
|
|
458
471
|
*/
|
|
459
|
-
warnInfiniteLoop:
|
|
472
|
+
warnInfiniteLoop: k.WARN_INFINITE_LOOP,
|
|
460
473
|
/**
|
|
461
474
|
* Logs a warning message when condition is true and debug is enabled.
|
|
462
475
|
*
|
|
@@ -499,16 +512,10 @@ const f = {
|
|
|
499
512
|
* debug.checkCircular(computedC, computedA);
|
|
500
513
|
* ```
|
|
501
514
|
*/
|
|
502
|
-
checkCircular(i, e, t
|
|
515
|
+
checkCircular(i, e, t) {
|
|
503
516
|
if (i === e)
|
|
504
|
-
throw new
|
|
505
|
-
|
|
506
|
-
if (t.has(i))
|
|
507
|
-
throw new b("Indirect circular dependency detected");
|
|
508
|
-
if (t.add(i), G(i))
|
|
509
|
-
for (const s of i.dependencies)
|
|
510
|
-
this.checkCircular(s, e, t);
|
|
511
|
-
}
|
|
517
|
+
throw new I("Direct circular dependency detected");
|
|
518
|
+
this.enabled && (j++, Y(i, e, j));
|
|
512
519
|
},
|
|
513
520
|
/**
|
|
514
521
|
* Attaches debug metadata to a reactive object.
|
|
@@ -534,7 +541,7 @@ const f = {
|
|
|
534
541
|
if (!this.enabled)
|
|
535
542
|
return;
|
|
536
543
|
const s = i;
|
|
537
|
-
s[
|
|
544
|
+
s[v] = `${e}_${t}`, s[W] = t, s[L] = e;
|
|
538
545
|
},
|
|
539
546
|
/**
|
|
540
547
|
* Retrieves the debug display name from a reactive object.
|
|
@@ -549,8 +556,8 @@ const f = {
|
|
|
549
556
|
* ```
|
|
550
557
|
*/
|
|
551
558
|
getDebugName(i) {
|
|
552
|
-
if (i !== null && typeof i == "object" &&
|
|
553
|
-
return i[
|
|
559
|
+
if (i !== null && typeof i == "object" && v in i)
|
|
560
|
+
return i[v];
|
|
554
561
|
},
|
|
555
562
|
/**
|
|
556
563
|
* Retrieves the debug type from a reactive object.
|
|
@@ -567,13 +574,13 @@ const f = {
|
|
|
567
574
|
* ```
|
|
568
575
|
*/
|
|
569
576
|
getDebugType(i) {
|
|
570
|
-
if (i !== null && typeof i == "object" &&
|
|
571
|
-
return i[
|
|
577
|
+
if (i !== null && typeof i == "object" && L in i)
|
|
578
|
+
return i[L];
|
|
572
579
|
}
|
|
573
580
|
};
|
|
574
|
-
let
|
|
575
|
-
const
|
|
576
|
-
class
|
|
581
|
+
let Z = 1;
|
|
582
|
+
const B = () => Z++;
|
|
583
|
+
class x {
|
|
577
584
|
constructor() {
|
|
578
585
|
this.subscribers = null;
|
|
579
586
|
}
|
|
@@ -706,7 +713,7 @@ class F {
|
|
|
706
713
|
return this.subscribers ? [...this.subscribers] : [];
|
|
707
714
|
}
|
|
708
715
|
}
|
|
709
|
-
class
|
|
716
|
+
class ee {
|
|
710
717
|
/**
|
|
711
718
|
* Creates a new AtomImpl instance.
|
|
712
719
|
*
|
|
@@ -714,7 +721,7 @@ class Y {
|
|
|
714
721
|
* @param sync - Whether to notify subscribers synchronously
|
|
715
722
|
*/
|
|
716
723
|
constructor(e, t) {
|
|
717
|
-
this._isNotificationScheduled = !1, this.id =
|
|
724
|
+
this._isNotificationScheduled = !1, this.id = B() & D, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = e, this._functionSubscribers = new x(), this._objectSubscribers = new x(), this._sync = t, this._notifyTask = this._flushNotifications.bind(this), b.attachDebugInfo(this, "atom", this.id);
|
|
718
725
|
}
|
|
719
726
|
/**
|
|
720
727
|
* Gets the current value and registers the atom as a dependency
|
|
@@ -727,7 +734,7 @@ class Y {
|
|
|
727
734
|
* a computed or effect context.
|
|
728
735
|
*/
|
|
729
736
|
get value() {
|
|
730
|
-
const e =
|
|
737
|
+
const e = m.getCurrent();
|
|
731
738
|
return e != null && this._track(e), this._value;
|
|
732
739
|
}
|
|
733
740
|
/**
|
|
@@ -743,7 +750,7 @@ class Y {
|
|
|
743
750
|
set value(e) {
|
|
744
751
|
if (Object.is(this._value, e)) return;
|
|
745
752
|
const t = this._value;
|
|
746
|
-
this.version = this.version + 1 &
|
|
753
|
+
this.version = this.version + 1 & D;
|
|
747
754
|
const s = this.version;
|
|
748
755
|
this._value = e, !(!this._functionSubscribers.hasSubscribers && !this._objectSubscribers.hasSubscribers) && this._notify(e, t, s);
|
|
749
756
|
}
|
|
@@ -783,7 +790,7 @@ class Y {
|
|
|
783
790
|
* but don't schedule a new task. The pending task will see the latest value.
|
|
784
791
|
*/
|
|
785
792
|
_notify(e, t, s) {
|
|
786
|
-
this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !
|
|
793
|
+
this._isNotificationScheduled || (this._pendingOldValue = t, this._isNotificationScheduled = !0), this._sync && !N.isBatching ? this._flushNotifications() : N.schedule(this._notifyTask);
|
|
787
794
|
}
|
|
788
795
|
/**
|
|
789
796
|
* Executes the pending notifications.
|
|
@@ -794,18 +801,18 @@ class Y {
|
|
|
794
801
|
const e = this._pendingOldValue, t = this._value;
|
|
795
802
|
this._pendingOldValue = void 0, this._isNotificationScheduled = !1, this._functionSubscribers.forEachSafe(
|
|
796
803
|
(s) => s(t, e),
|
|
797
|
-
(s) => console.error(new
|
|
804
|
+
(s) => console.error(new d(a.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
|
|
798
805
|
), this._objectSubscribers.forEachSafe(
|
|
799
806
|
(s) => s.execute(),
|
|
800
|
-
(s) => console.error(new
|
|
807
|
+
(s) => console.error(new d(a.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, s))
|
|
801
808
|
);
|
|
802
809
|
}
|
|
803
810
|
/**
|
|
804
|
-
* Subscribes a listener function to value changes.
|
|
811
|
+
* Subscribes a listener function or Subscriber object to value changes.
|
|
805
812
|
*
|
|
806
|
-
* @param listener - Function to call when the value changes
|
|
813
|
+
* @param listener - Function or Subscriber object to call when the value changes
|
|
807
814
|
* @returns An unsubscribe function
|
|
808
|
-
* @throws {AtomError} If listener is not a function
|
|
815
|
+
* @throws {AtomError} If listener is not a function or Subscriber
|
|
809
816
|
*
|
|
810
817
|
* @example
|
|
811
818
|
* ```ts
|
|
@@ -816,8 +823,10 @@ class Y {
|
|
|
816
823
|
* ```
|
|
817
824
|
*/
|
|
818
825
|
subscribe(e) {
|
|
826
|
+
if (typeof e == "object" && e !== null && "execute" in e)
|
|
827
|
+
return this._objectSubscribers.add(e);
|
|
819
828
|
if (typeof e != "function")
|
|
820
|
-
throw new
|
|
829
|
+
throw new d(a.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);
|
|
821
830
|
return this._functionSubscribers.add(e);
|
|
822
831
|
}
|
|
823
832
|
/**
|
|
@@ -851,40 +860,40 @@ class Y {
|
|
|
851
860
|
return this._functionSubscribers.size + this._objectSubscribers.size;
|
|
852
861
|
}
|
|
853
862
|
}
|
|
854
|
-
function
|
|
855
|
-
return new
|
|
863
|
+
function ce(i, e = {}) {
|
|
864
|
+
return new ee(i, e.sync ?? !1);
|
|
856
865
|
}
|
|
857
|
-
const
|
|
858
|
-
class
|
|
866
|
+
const p = process.env.NODE_ENV !== "production", f = Object.freeze([]), E = Object.freeze([]);
|
|
867
|
+
class $ {
|
|
859
868
|
constructor() {
|
|
860
|
-
this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats =
|
|
869
|
+
this.pool = [], this.maxPoolSize = 50, this.maxReusableCapacity = 256, this.stats = p ? {
|
|
861
870
|
acquired: 0,
|
|
862
871
|
released: 0,
|
|
863
872
|
rejected: { frozen: 0, tooLarge: 0, poolFull: 0 }
|
|
864
873
|
} : null;
|
|
865
874
|
}
|
|
866
875
|
acquire() {
|
|
867
|
-
return
|
|
876
|
+
return p && this.stats && this.stats.acquired++, this.pool.pop() ?? [];
|
|
868
877
|
}
|
|
869
878
|
release(e, t) {
|
|
870
879
|
if (!(t && e === t)) {
|
|
871
880
|
if (Object.isFrozen(e)) {
|
|
872
|
-
|
|
881
|
+
p && this.stats && this.stats.rejected.frozen++;
|
|
873
882
|
return;
|
|
874
883
|
}
|
|
875
884
|
if (e.length > this.maxReusableCapacity) {
|
|
876
|
-
|
|
885
|
+
p && this.stats && this.stats.rejected.tooLarge++;
|
|
877
886
|
return;
|
|
878
887
|
}
|
|
879
888
|
if (this.pool.length >= this.maxPoolSize) {
|
|
880
|
-
|
|
889
|
+
p && this.stats && this.stats.rejected.poolFull++;
|
|
881
890
|
return;
|
|
882
891
|
}
|
|
883
|
-
e.length = 0, this.pool.push(e),
|
|
892
|
+
e.length = 0, this.pool.push(e), p && this.stats && this.stats.released++;
|
|
884
893
|
}
|
|
885
894
|
}
|
|
886
895
|
getStats() {
|
|
887
|
-
if (!
|
|
896
|
+
if (!p || !this.stats) return null;
|
|
888
897
|
const { acquired: e, released: t, rejected: s } = this.stats, n = s.frozen + s.tooLarge + s.poolFull;
|
|
889
898
|
return {
|
|
890
899
|
acquired: e,
|
|
@@ -895,21 +904,15 @@ class Q {
|
|
|
895
904
|
};
|
|
896
905
|
}
|
|
897
906
|
reset() {
|
|
898
|
-
this.pool.length = 0,
|
|
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 });
|
|
899
908
|
}
|
|
900
909
|
}
|
|
901
|
-
const
|
|
902
|
-
class
|
|
910
|
+
const S = new $(), y = new $();
|
|
911
|
+
class Q {
|
|
903
912
|
constructor(e, t = {}) {
|
|
904
913
|
if (typeof e != "function")
|
|
905
|
-
throw new
|
|
906
|
-
if (this.id =
|
|
907
|
-
if (this._isDirty())
|
|
908
|
-
try {
|
|
909
|
-
this._recompute();
|
|
910
|
-
} catch {
|
|
911
|
-
}
|
|
912
|
-
}, this._notifyJob = () => {
|
|
914
|
+
throw new I(a.COMPUTED_MUST_BE_FUNCTION);
|
|
915
|
+
if (this.id = B() & D, this.version = 0, this.flags = 0, this._lastSeenEpoch = -1, this._value = void 0, this._stateFlags = h.DIRTY | h.IDLE, this._error = null, this._promiseId = 0, this._equal = t.equal ?? Object.is, this._fn = e, this._defaultValue = "defaultValue" in t ? t.defaultValue : V, this._hasDefaultValue = this._defaultValue !== V, this._onError = t.onError ?? null, this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1, this._functionSubscribers = new x(), this._objectSubscribers = new x(), this._dependencies = f, this._unsubscribes = E, this._notifyJob = () => {
|
|
913
916
|
this._functionSubscribers.forEachSafe(
|
|
914
917
|
(s) => s(),
|
|
915
918
|
(s) => console.error(s)
|
|
@@ -920,7 +923,7 @@ class z {
|
|
|
920
923
|
}, this._trackable = Object.assign(() => this._markDirty(), {
|
|
921
924
|
addDependency: (s) => {
|
|
922
925
|
}
|
|
923
|
-
}),
|
|
926
|
+
}), b.attachDebugInfo(this, "computed", this.id), b.enabled) {
|
|
924
927
|
const s = this;
|
|
925
928
|
s.subscriberCount = () => this._functionSubscribers.size + this._objectSubscribers.size, s.isDirty = () => this._isDirty(), s.dependencies = this._dependencies, s.stateFlags = this._getFlagsAsString();
|
|
926
929
|
}
|
|
@@ -932,14 +935,16 @@ class z {
|
|
|
932
935
|
}
|
|
933
936
|
// === PUBLIC API ===
|
|
934
937
|
get value() {
|
|
935
|
-
if ((this._stateFlags & (
|
|
938
|
+
if ((this._stateFlags & (h.RESOLVED | h.DIRTY)) === h.RESOLVED)
|
|
936
939
|
return this._registerTracking(), this._value;
|
|
937
940
|
const t = this._computeValue();
|
|
938
941
|
return this._registerTracking(), t;
|
|
939
942
|
}
|
|
940
943
|
subscribe(e) {
|
|
944
|
+
if (typeof e == "object" && e !== null && "execute" in e)
|
|
945
|
+
return this._objectSubscribers.add(e);
|
|
941
946
|
if (typeof e != "function")
|
|
942
|
-
throw new
|
|
947
|
+
throw new I(a.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);
|
|
943
948
|
return this._functionSubscribers.add(e);
|
|
944
949
|
}
|
|
945
950
|
peek() {
|
|
@@ -964,58 +969,58 @@ class z {
|
|
|
964
969
|
this._markDirty();
|
|
965
970
|
}
|
|
966
971
|
dispose() {
|
|
967
|
-
if (this.
|
|
968
|
-
for (
|
|
969
|
-
const t = this.
|
|
970
|
-
t && t()
|
|
972
|
+
if (this._unsubscribes !== E) {
|
|
973
|
+
for (let e = 0; e < this._unsubscribes.length; e++) {
|
|
974
|
+
const t = this._unsubscribes[e];
|
|
975
|
+
t && t();
|
|
971
976
|
}
|
|
972
|
-
|
|
977
|
+
y.release(this._unsubscribes), this._unsubscribes = E;
|
|
973
978
|
}
|
|
974
|
-
this._dependencies =
|
|
979
|
+
this._dependencies !== f && (S.release(this._dependencies), this._dependencies = f), this._functionSubscribers.clear(), this._objectSubscribers.clear(), this._stateFlags = h.DIRTY | h.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;
|
|
975
980
|
}
|
|
976
981
|
// === PRIVATE: State Flag Operations (inlined for performance) ===
|
|
977
982
|
_isDirty() {
|
|
978
|
-
return (this._stateFlags &
|
|
983
|
+
return (this._stateFlags & h.DIRTY) !== 0;
|
|
979
984
|
}
|
|
980
985
|
_setDirty() {
|
|
981
|
-
this._stateFlags |=
|
|
986
|
+
this._stateFlags |= h.DIRTY;
|
|
982
987
|
}
|
|
983
988
|
_clearDirty() {
|
|
984
989
|
this._stateFlags &= -2;
|
|
985
990
|
}
|
|
986
991
|
_isIdle() {
|
|
987
|
-
return (this._stateFlags &
|
|
992
|
+
return (this._stateFlags & h.IDLE) !== 0;
|
|
988
993
|
}
|
|
989
994
|
_setIdle() {
|
|
990
|
-
this._stateFlags |=
|
|
995
|
+
this._stateFlags |= h.IDLE, this._stateFlags &= -29;
|
|
991
996
|
}
|
|
992
997
|
_isPending() {
|
|
993
|
-
return (this._stateFlags &
|
|
998
|
+
return (this._stateFlags & h.PENDING) !== 0;
|
|
994
999
|
}
|
|
995
1000
|
_setPending() {
|
|
996
|
-
this._stateFlags |=
|
|
1001
|
+
this._stateFlags |= h.PENDING, this._stateFlags &= -27;
|
|
997
1002
|
}
|
|
998
1003
|
_isResolved() {
|
|
999
|
-
return (this._stateFlags &
|
|
1004
|
+
return (this._stateFlags & h.RESOLVED) !== 0;
|
|
1000
1005
|
}
|
|
1001
1006
|
_setResolved() {
|
|
1002
|
-
this._stateFlags |=
|
|
1007
|
+
this._stateFlags |= h.RESOLVED, this._stateFlags &= -87;
|
|
1003
1008
|
}
|
|
1004
1009
|
_isRejected() {
|
|
1005
|
-
return (this._stateFlags &
|
|
1010
|
+
return (this._stateFlags & h.REJECTED) !== 0;
|
|
1006
1011
|
}
|
|
1007
1012
|
_setRejected() {
|
|
1008
|
-
this._stateFlags |=
|
|
1013
|
+
this._stateFlags |= h.REJECTED | h.HAS_ERROR, this._stateFlags &= -15;
|
|
1009
1014
|
}
|
|
1010
1015
|
_isRecomputing() {
|
|
1011
|
-
return (this._stateFlags &
|
|
1016
|
+
return (this._stateFlags & h.RECOMPUTING) !== 0;
|
|
1012
1017
|
}
|
|
1013
1018
|
_setRecomputing(e) {
|
|
1014
|
-
const t =
|
|
1019
|
+
const t = h.RECOMPUTING;
|
|
1015
1020
|
this._stateFlags = this._stateFlags & ~t | -Number(e) & t;
|
|
1016
1021
|
}
|
|
1017
1022
|
_getAsyncState() {
|
|
1018
|
-
return this._isPending() ?
|
|
1023
|
+
return this._isPending() ? T.PENDING : this._isResolved() ? T.RESOLVED : this._isRejected() ? T.REJECTED : T.IDLE;
|
|
1019
1024
|
}
|
|
1020
1025
|
_getFlagsAsString() {
|
|
1021
1026
|
const e = [];
|
|
@@ -1029,51 +1034,55 @@ class z {
|
|
|
1029
1034
|
if (!this._isDirty() && this._isResolved())
|
|
1030
1035
|
return;
|
|
1031
1036
|
this._setRecomputing(!0);
|
|
1032
|
-
const e = this._dependencies, t =
|
|
1037
|
+
const e = this._dependencies, t = S.acquire(), s = G();
|
|
1033
1038
|
let n = 0;
|
|
1034
|
-
const r = (
|
|
1035
|
-
|
|
1036
|
-
},
|
|
1039
|
+
const r = (_) => {
|
|
1040
|
+
_._lastSeenEpoch !== s && (_._lastSeenEpoch = s, n < t.length ? t[n] = _ : t.push(_), n++);
|
|
1041
|
+
}, c = this._trackable.addDependency;
|
|
1037
1042
|
this._trackable.addDependency = r;
|
|
1038
|
-
let
|
|
1043
|
+
let o = !1;
|
|
1039
1044
|
try {
|
|
1040
|
-
const
|
|
1041
|
-
if (t.length = n,
|
|
1042
|
-
this._syncDependencies(e, t, s), this._dependencies = t,
|
|
1045
|
+
const _ = m.run(this._trackable, this._fn);
|
|
1046
|
+
if (t.length = n, X(_)) {
|
|
1047
|
+
this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, o = !0, this._handleAsyncComputation(_), this._setRecomputing(!1);
|
|
1043
1048
|
return;
|
|
1044
1049
|
}
|
|
1045
|
-
this._syncDependencies(e, t, s), this._dependencies = t,
|
|
1046
|
-
} catch (
|
|
1047
|
-
t.length = n, this._syncDependencies(e, t, s), this._dependencies = t,
|
|
1050
|
+
this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, o = !0, this._handleSyncResult(_);
|
|
1051
|
+
} catch (_) {
|
|
1052
|
+
t.length = n, this._syncDependencies(e, t, this._unsubscribes, s), this._dependencies = t, this._handleComputationError(_);
|
|
1048
1053
|
} finally {
|
|
1049
|
-
this._trackable.addDependency =
|
|
1054
|
+
this._trackable.addDependency = c, o ? e !== f && S.release(e) : S.release(t);
|
|
1050
1055
|
}
|
|
1051
1056
|
}
|
|
1052
1057
|
/**
|
|
1053
1058
|
* Synchronizes subscriptions based on dependency changes.
|
|
1054
1059
|
* O(N) Diff using Epoch.
|
|
1055
1060
|
*/
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
for (let n = 0; n < t.length; n++) {
|
|
1066
|
-
const r = t[n];
|
|
1067
|
-
if (r && !this._subscriptions.has(r.id)) {
|
|
1068
|
-
f.checkCircular(r, this);
|
|
1069
|
-
const u = r.subscribe(() => this._markDirty());
|
|
1070
|
-
this._subscriptions.set(r.id, u);
|
|
1061
|
+
/**
|
|
1062
|
+
* Synchronizes subscriptions based on dependency changes using O(N) strategy.
|
|
1063
|
+
* Maps unsubs 1:1 with dependencies array.
|
|
1064
|
+
*/
|
|
1065
|
+
_syncDependencies(e, t, s, n) {
|
|
1066
|
+
if (e !== f && s !== E)
|
|
1067
|
+
for (let c = 0; c < e.length; c++) {
|
|
1068
|
+
const o = e[c];
|
|
1069
|
+
o && (o._tempUnsub = s[c]);
|
|
1071
1070
|
}
|
|
1071
|
+
const r = y.acquire();
|
|
1072
|
+
r.length = t.length;
|
|
1073
|
+
for (let c = 0; c < t.length; c++) {
|
|
1074
|
+
const o = t[c];
|
|
1075
|
+
o && (o._tempUnsub ? (r[c] = o._tempUnsub, o._tempUnsub = void 0) : (b.checkCircular(o, this), r[c] = o.subscribe(this)));
|
|
1072
1076
|
}
|
|
1077
|
+
if (e !== f)
|
|
1078
|
+
for (let c = 0; c < e.length; c++) {
|
|
1079
|
+
const o = e[c];
|
|
1080
|
+
o?._tempUnsub && (o._tempUnsub(), o._tempUnsub = void 0);
|
|
1081
|
+
}
|
|
1082
|
+
s !== E && y.release(s), this._unsubscribes = r;
|
|
1073
1083
|
}
|
|
1074
1084
|
_handleSyncResult(e) {
|
|
1075
|
-
|
|
1076
|
-
this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
|
|
1085
|
+
(!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & D), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
|
|
1077
1086
|
}
|
|
1078
1087
|
_handleAsyncComputation(e) {
|
|
1079
1088
|
this._setPending(), this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
|
|
@@ -1085,33 +1094,32 @@ class z {
|
|
|
1085
1094
|
});
|
|
1086
1095
|
}
|
|
1087
1096
|
_handleAsyncResolution(e) {
|
|
1088
|
-
|
|
1089
|
-
this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), t && this._notifySubscribers();
|
|
1097
|
+
(!this._isResolved() || !this._equal(this._value, e)) && (this.version = this.version + 1 & D), this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1);
|
|
1090
1098
|
}
|
|
1091
1099
|
_handleAsyncRejection(e) {
|
|
1092
|
-
const t =
|
|
1100
|
+
const t = R(e, I, a.COMPUTED_ASYNC_COMPUTATION_FAILED);
|
|
1093
1101
|
if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
|
|
1094
1102
|
try {
|
|
1095
1103
|
this._onError(t);
|
|
1096
1104
|
} catch (s) {
|
|
1097
|
-
console.error(
|
|
1105
|
+
console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
|
|
1098
1106
|
}
|
|
1099
1107
|
this._notifySubscribers();
|
|
1100
1108
|
}
|
|
1101
1109
|
_handleComputationError(e) {
|
|
1102
|
-
const t =
|
|
1110
|
+
const t = R(e, I, a.COMPUTED_COMPUTATION_FAILED);
|
|
1103
1111
|
if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError && typeof this._onError == "function")
|
|
1104
1112
|
try {
|
|
1105
1113
|
this._onError(t);
|
|
1106
1114
|
} catch (s) {
|
|
1107
|
-
console.error(
|
|
1115
|
+
console.error(a.CALLBACK_ERROR_IN_ERROR_HANDLER, s);
|
|
1108
1116
|
}
|
|
1109
1117
|
throw t;
|
|
1110
1118
|
}
|
|
1111
1119
|
_handlePending() {
|
|
1112
1120
|
if (this._hasDefaultValue)
|
|
1113
1121
|
return this._defaultValue;
|
|
1114
|
-
throw new
|
|
1122
|
+
throw new I(a.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
|
|
1115
1123
|
}
|
|
1116
1124
|
_handleRejected() {
|
|
1117
1125
|
if (this._error?.recoverable && this._hasDefaultValue)
|
|
@@ -1121,14 +1129,36 @@ class z {
|
|
|
1121
1129
|
// === PRIVATE: Dependency Management ===
|
|
1122
1130
|
// (Replaced by _syncDependencies and inline pool logic)
|
|
1123
1131
|
// === PRIVATE: Subscriber Management ===
|
|
1132
|
+
/**
|
|
1133
|
+
* Subscriber interface implementation (Zero-Allocation pattern)
|
|
1134
|
+
* Called by dependencies when they change - delegates to _markDirty
|
|
1135
|
+
*/
|
|
1136
|
+
execute() {
|
|
1137
|
+
this._markDirty();
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Push-State, Pull-Value pattern:
|
|
1141
|
+
* Marks this computed as dirty and propagates to all subscribers.
|
|
1142
|
+
* - Object subscribers (Computed atoms): will mark themselves dirty
|
|
1143
|
+
* - Function subscribers (Effects): will schedule their execution
|
|
1144
|
+
* Actual recomputation happens lazily when .value is accessed (Pull).
|
|
1145
|
+
*/
|
|
1124
1146
|
_markDirty() {
|
|
1125
|
-
this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(),
|
|
1147
|
+
this._isRecomputing() || this._isDirty() || (this._setDirty(), this._setIdle(), this._notifyJob());
|
|
1126
1148
|
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Notifies function subscribers (Effects) of state changes.
|
|
1151
|
+
* Currently only called from _handleAsyncRejection to notify Effects of errors.
|
|
1152
|
+
* In normal operation, Effects are notified via _markDirty during dirty propagation.
|
|
1153
|
+
*/
|
|
1127
1154
|
_notifySubscribers() {
|
|
1128
|
-
|
|
1155
|
+
this._functionSubscribers.hasSubscribers && this._functionSubscribers.forEachSafe(
|
|
1156
|
+
(e) => e(),
|
|
1157
|
+
(e) => console.error(e)
|
|
1158
|
+
);
|
|
1129
1159
|
}
|
|
1130
1160
|
_registerTracking() {
|
|
1131
|
-
const e =
|
|
1161
|
+
const e = m.getCurrent();
|
|
1132
1162
|
if (e)
|
|
1133
1163
|
if (typeof e == "object" && e !== null && e.addDependency)
|
|
1134
1164
|
e.addDependency(this);
|
|
@@ -1138,49 +1168,75 @@ class z {
|
|
|
1138
1168
|
} else e.execute && this._objectSubscribers.add(e);
|
|
1139
1169
|
}
|
|
1140
1170
|
}
|
|
1141
|
-
Object.freeze(
|
|
1142
|
-
function
|
|
1143
|
-
return new
|
|
1171
|
+
Object.freeze(Q.prototype);
|
|
1172
|
+
function ue(i, e = {}) {
|
|
1173
|
+
return new Q(i, e);
|
|
1144
1174
|
}
|
|
1145
|
-
class
|
|
1175
|
+
class te {
|
|
1146
1176
|
constructor(e, t = {}) {
|
|
1147
1177
|
this.run = () => {
|
|
1148
1178
|
if (this.isDisposed)
|
|
1149
|
-
throw new
|
|
1179
|
+
throw new g(a.EFFECT_MUST_BE_FUNCTION);
|
|
1150
1180
|
this.execute();
|
|
1151
1181
|
}, this.dispose = () => {
|
|
1152
|
-
if (!this.isDisposed
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1182
|
+
if (!this.isDisposed) {
|
|
1183
|
+
if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== E) {
|
|
1184
|
+
for (let s = 0; s < this._unsubscribes.length; s++) {
|
|
1185
|
+
const n = this._unsubscribes[s];
|
|
1186
|
+
n && n();
|
|
1187
|
+
}
|
|
1188
|
+
y.release(this._unsubscribes), this._unsubscribes = E;
|
|
1156
1189
|
}
|
|
1157
|
-
|
|
1190
|
+
this._dependencies !== f && (S.release(this._dependencies), this._dependencies = f);
|
|
1158
1191
|
}
|
|
1159
1192
|
}, this.addDependency = (s) => {
|
|
1160
|
-
if (this.isExecuting && this._nextDeps) {
|
|
1193
|
+
if (this.isExecuting && this._nextDeps && this._nextUnsubs) {
|
|
1161
1194
|
const n = s, r = this._currentEpoch;
|
|
1162
1195
|
if (n._lastSeenEpoch === r) return;
|
|
1163
|
-
n._lastSeenEpoch = r, this._nextDeps.push(n), this.
|
|
1196
|
+
n._lastSeenEpoch = r, this._nextDeps.push(n), n._tempUnsub ? (this._nextUnsubs.push(n._tempUnsub), n._tempUnsub = void 0) : this._subscribeTo(n);
|
|
1164
1197
|
}
|
|
1165
1198
|
}, this.execute = () => {
|
|
1166
1199
|
if (this.isDisposed || this.isExecuting) return;
|
|
1167
|
-
this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup()
|
|
1168
|
-
const s = this._dependencies, n =
|
|
1169
|
-
|
|
1170
|
-
|
|
1200
|
+
this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup();
|
|
1201
|
+
const s = this._dependencies, n = this._unsubscribes, r = S.acquire(), c = y.acquire(), o = G();
|
|
1202
|
+
if (s !== f && n !== E)
|
|
1203
|
+
for (let u = 0; u < s.length; u++) {
|
|
1204
|
+
const l = s[u];
|
|
1205
|
+
l && (l._tempUnsub = n[u]);
|
|
1206
|
+
}
|
|
1207
|
+
this._nextDeps = r, this._nextUnsubs = c, this._currentEpoch = o;
|
|
1208
|
+
let _ = !1;
|
|
1171
1209
|
try {
|
|
1172
|
-
const
|
|
1173
|
-
this.
|
|
1174
|
-
!this.isDisposed && typeof
|
|
1175
|
-
}).catch((
|
|
1176
|
-
console.error(
|
|
1177
|
-
}) : this._cleanup = typeof
|
|
1178
|
-
} catch (
|
|
1179
|
-
|
|
1210
|
+
const u = m.run(this, this._fn);
|
|
1211
|
+
this._dependencies = r, this._unsubscribes = c, _ = !0, this._checkLoopWarnings(), X(u) ? u.then((l) => {
|
|
1212
|
+
!this.isDisposed && typeof l == "function" && (this._cleanup = l);
|
|
1213
|
+
}).catch((l) => {
|
|
1214
|
+
console.error(R(l, g, a.EFFECT_EXECUTION_FAILED));
|
|
1215
|
+
}) : this._cleanup = typeof u == "function" ? u : null;
|
|
1216
|
+
} catch (u) {
|
|
1217
|
+
_ = !0, console.error(R(u, g, a.EFFECT_EXECUTION_FAILED)), this._cleanup = null;
|
|
1180
1218
|
} finally {
|
|
1181
|
-
this._setExecuting(!1), this._nextDeps = null,
|
|
1219
|
+
if (this._setExecuting(!1), this._nextDeps = null, this._nextUnsubs = null, _) {
|
|
1220
|
+
if (s !== f) {
|
|
1221
|
+
for (let u = 0; u < s.length; u++) {
|
|
1222
|
+
const l = s[u];
|
|
1223
|
+
l?._tempUnsub && (l._tempUnsub(), l._tempUnsub = void 0);
|
|
1224
|
+
}
|
|
1225
|
+
S.release(s);
|
|
1226
|
+
}
|
|
1227
|
+
n !== E && y.release(n);
|
|
1228
|
+
} else {
|
|
1229
|
+
S.release(r);
|
|
1230
|
+
for (let u = 0; u < c.length; u++)
|
|
1231
|
+
c[u]?.();
|
|
1232
|
+
if (y.release(c), s !== f)
|
|
1233
|
+
for (let u = 0; u < s.length; u++) {
|
|
1234
|
+
const l = s[u];
|
|
1235
|
+
l && (l._tempUnsub = void 0);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1182
1238
|
}
|
|
1183
|
-
}, this._id =
|
|
1239
|
+
}, this._id = B() & D, this._flags = 0, this._currentEpoch = -1, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ?? A.MAX_EXECUTIONS_PER_SECOND, this._maxExecutionsPerFlush = t.maxExecutionsPerFlush ?? A.MAX_EXECUTIONS_PER_EFFECT, this._trackModifications = t.trackModifications ?? !1, this._cleanup = null, this._dependencies = f, this._unsubscribes = E, this._nextDeps = null, this._nextUnsubs = null, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._history = M ? [] : null, this._executionCount = 0, b.attachDebugInfo(this, "effect", this._id);
|
|
1184
1240
|
}
|
|
1185
1241
|
/**
|
|
1186
1242
|
* Synchronizes subscriptions by unsubscribing from removed dependencies.
|
|
@@ -1189,24 +1245,16 @@ class H {
|
|
|
1189
1245
|
* @param prevDeps - Previous dependency array
|
|
1190
1246
|
* @param epoch - Current execution epoch for staleness detection
|
|
1191
1247
|
*/
|
|
1192
|
-
_syncDependencies(
|
|
1193
|
-
if (e !== l)
|
|
1194
|
-
for (let s = 0; s < e.length; s++) {
|
|
1195
|
-
const n = e[s];
|
|
1196
|
-
if (n && n._lastSeenEpoch !== t) {
|
|
1197
|
-
const r = this._subscriptions.get(n.id);
|
|
1198
|
-
r && (r(), this._subscriptions.delete(n.id));
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1248
|
+
// _syncDependencies removed (inline logic in execute)
|
|
1202
1249
|
_subscribeTo(e) {
|
|
1203
1250
|
try {
|
|
1204
1251
|
const t = e.subscribe(() => {
|
|
1205
|
-
this._trackModifications && this.isExecuting && this.
|
|
1252
|
+
this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : N.schedule(this.execute);
|
|
1206
1253
|
});
|
|
1207
|
-
this.
|
|
1254
|
+
this._nextUnsubs && this._nextUnsubs.push(t);
|
|
1208
1255
|
} catch (t) {
|
|
1209
|
-
console.error(
|
|
1256
|
+
console.error(R(t, g, a.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
|
|
1257
|
+
});
|
|
1210
1258
|
}
|
|
1211
1259
|
}
|
|
1212
1260
|
/**
|
|
@@ -1228,7 +1276,7 @@ class H {
|
|
|
1228
1276
|
* ```
|
|
1229
1277
|
*/
|
|
1230
1278
|
get isDisposed() {
|
|
1231
|
-
return (this._flags &
|
|
1279
|
+
return (this._flags & F.DISPOSED) !== 0;
|
|
1232
1280
|
}
|
|
1233
1281
|
/**
|
|
1234
1282
|
* Returns the total number of times this effect has been executed.
|
|
@@ -1270,7 +1318,7 @@ class H {
|
|
|
1270
1318
|
* ```
|
|
1271
1319
|
*/
|
|
1272
1320
|
get isExecuting() {
|
|
1273
|
-
return (this._flags &
|
|
1321
|
+
return (this._flags & F.EXECUTING) !== 0;
|
|
1274
1322
|
}
|
|
1275
1323
|
/**
|
|
1276
1324
|
* Sets the disposed flag on this effect.
|
|
@@ -1282,7 +1330,7 @@ class H {
|
|
|
1282
1330
|
* @internal
|
|
1283
1331
|
*/
|
|
1284
1332
|
_setDisposed() {
|
|
1285
|
-
this._flags |=
|
|
1333
|
+
this._flags |= F.DISPOSED;
|
|
1286
1334
|
}
|
|
1287
1335
|
/**
|
|
1288
1336
|
* Sets or clears the executing flag on this effect.
|
|
@@ -1296,7 +1344,7 @@ class H {
|
|
|
1296
1344
|
* @internal
|
|
1297
1345
|
*/
|
|
1298
1346
|
_setExecuting(e) {
|
|
1299
|
-
const t =
|
|
1347
|
+
const t = F.EXECUTING;
|
|
1300
1348
|
this._flags = this._flags & ~t | -Number(e) & t;
|
|
1301
1349
|
}
|
|
1302
1350
|
/**
|
|
@@ -1317,7 +1365,7 @@ class H {
|
|
|
1317
1365
|
try {
|
|
1318
1366
|
this._cleanup();
|
|
1319
1367
|
} catch (e) {
|
|
1320
|
-
console.error(
|
|
1368
|
+
console.error(R(e, g, a.EFFECT_CLEANUP_FAILED));
|
|
1321
1369
|
}
|
|
1322
1370
|
this._cleanup = null;
|
|
1323
1371
|
}
|
|
@@ -1330,9 +1378,9 @@ class H {
|
|
|
1330
1378
|
* @internal
|
|
1331
1379
|
*/
|
|
1332
1380
|
_checkInfiniteLoop() {
|
|
1333
|
-
if (this._lastFlushEpoch !==
|
|
1381
|
+
if (this._lastFlushEpoch !== U && (this._lastFlushEpoch = U, this._executionsInEpoch = 0), this._executionsInEpoch++, this._executionsInEpoch > this._maxExecutionsPerFlush && this._throwInfiniteLoopError("per-effect"), H() > A.MAX_EXECUTIONS_PER_FLUSH && this._throwInfiniteLoopError("global"), this._executionCount++, this._history) {
|
|
1334
1382
|
const e = Date.now();
|
|
1335
|
-
this._history.push(e), this._history.length >
|
|
1383
|
+
this._history.push(e), this._history.length > A.MAX_EXECUTIONS_PER_SECOND + 10 && this._history.shift(), this._checkTimestampLoop(e);
|
|
1336
1384
|
}
|
|
1337
1385
|
}
|
|
1338
1386
|
_checkTimestampLoop(e) {
|
|
@@ -1343,16 +1391,16 @@ class H {
|
|
|
1343
1391
|
for (let r = t.length - 1; r >= 0 && !(t[r] < s); r--)
|
|
1344
1392
|
n++;
|
|
1345
1393
|
if (n > this._maxExecutions) {
|
|
1346
|
-
const r = new
|
|
1394
|
+
const r = new g(
|
|
1347
1395
|
`Effect executed ${n} times within 1 second. Infinite loop suspected`
|
|
1348
1396
|
);
|
|
1349
|
-
if (this.dispose(), console.error(r),
|
|
1397
|
+
if (this.dispose(), console.error(r), M)
|
|
1350
1398
|
throw r;
|
|
1351
1399
|
}
|
|
1352
1400
|
}
|
|
1353
1401
|
_throwInfiniteLoopError(e) {
|
|
1354
|
-
const t = new
|
|
1355
|
-
`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${
|
|
1402
|
+
const t = new g(
|
|
1403
|
+
`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${w}`
|
|
1356
1404
|
);
|
|
1357
1405
|
throw this.dispose(), console.error(t), t;
|
|
1358
1406
|
}
|
|
@@ -1370,56 +1418,56 @@ class H {
|
|
|
1370
1418
|
* @internal
|
|
1371
1419
|
*/
|
|
1372
1420
|
_checkLoopWarnings() {
|
|
1373
|
-
if (this._trackModifications &&
|
|
1421
|
+
if (this._trackModifications && b.enabled) {
|
|
1374
1422
|
const e = this._dependencies;
|
|
1375
1423
|
for (let t = 0; t < e.length; t++) {
|
|
1376
1424
|
const s = e[t];
|
|
1377
|
-
s && this.
|
|
1425
|
+
s && s._modifiedAtEpoch === this._currentEpoch && b.warn(
|
|
1378
1426
|
!0,
|
|
1379
|
-
`Effect is reading a dependency (${
|
|
1427
|
+
`Effect is reading a dependency (${b.getDebugName(s) || "unknown"}) that it just modified. Infinite loop may occur`
|
|
1380
1428
|
);
|
|
1381
1429
|
}
|
|
1382
1430
|
}
|
|
1383
1431
|
}
|
|
1384
1432
|
}
|
|
1385
|
-
function
|
|
1433
|
+
function he(i, e = {}) {
|
|
1386
1434
|
if (typeof i != "function")
|
|
1387
|
-
throw new
|
|
1388
|
-
const t = new
|
|
1435
|
+
throw new g(a.EFFECT_MUST_BE_FUNCTION);
|
|
1436
|
+
const t = new te(i, e);
|
|
1389
1437
|
return t.execute(), t;
|
|
1390
1438
|
}
|
|
1391
|
-
function
|
|
1439
|
+
function se(i) {
|
|
1392
1440
|
return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
|
|
1393
1441
|
}
|
|
1394
|
-
function
|
|
1395
|
-
if (
|
|
1396
|
-
const e =
|
|
1442
|
+
function oe(i) {
|
|
1443
|
+
if (b.enabled) {
|
|
1444
|
+
const e = b.getDebugType(i);
|
|
1397
1445
|
if (e)
|
|
1398
1446
|
return e === "computed";
|
|
1399
1447
|
}
|
|
1400
|
-
return
|
|
1448
|
+
return se(i) && "invalidate" in i && typeof i.invalidate == "function";
|
|
1401
1449
|
}
|
|
1402
|
-
function
|
|
1450
|
+
function ae(i) {
|
|
1403
1451
|
return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
|
|
1404
1452
|
}
|
|
1405
1453
|
export {
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1454
|
+
T as AsyncState,
|
|
1455
|
+
d as AtomError,
|
|
1456
|
+
I as ComputedError,
|
|
1457
|
+
k as DEBUG_CONFIG,
|
|
1458
|
+
b as DEBUG_RUNTIME,
|
|
1459
|
+
g as EffectError,
|
|
1460
|
+
ie as POOL_CONFIG,
|
|
1461
|
+
A as SCHEDULER_CONFIG,
|
|
1462
|
+
C as SchedulerError,
|
|
1463
|
+
ce as atom,
|
|
1464
|
+
ne as batch,
|
|
1465
|
+
ue as computed,
|
|
1466
|
+
he as effect,
|
|
1467
|
+
se as isAtom,
|
|
1468
|
+
oe as isComputed,
|
|
1469
|
+
ae as isEffect,
|
|
1470
|
+
N as scheduler,
|
|
1471
|
+
re as untracked
|
|
1424
1472
|
};
|
|
1425
1473
|
//# sourceMappingURL=index.mjs.map
|