@but212/atom-effect 0.10.0 → 0.11.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/README.md +9 -8
- package/dist/atom-effect.min.js +1 -1
- package/dist/atom-effect.min.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +79 -21
- package/dist/index.mjs +408 -262
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const
|
|
1
|
+
const te = {
|
|
2
2
|
/** One second in milliseconds */
|
|
3
3
|
ONE_SECOND_MS: 1e3
|
|
4
|
-
},
|
|
4
|
+
}, M = {
|
|
5
5
|
IDLE: "idle",
|
|
6
6
|
PENDING: "pending",
|
|
7
7
|
RESOLVED: "resolved",
|
|
8
8
|
REJECTED: "rejected"
|
|
9
|
-
},
|
|
9
|
+
}, O = {
|
|
10
10
|
DISPOSED: 1,
|
|
11
11
|
// 0001 - Effect has been disposed
|
|
12
12
|
EXECUTING: 2
|
|
13
13
|
// 0010 - Effect is currently executing
|
|
14
|
-
},
|
|
14
|
+
}, u = {
|
|
15
15
|
DIRTY: 1,
|
|
16
16
|
// 0001 - Needs recomputation
|
|
17
17
|
IDLE: 2,
|
|
@@ -26,12 +26,15 @@ const Z = {
|
|
|
26
26
|
// 100000 - Currently recomputing
|
|
27
27
|
HAS_ERROR: 64
|
|
28
28
|
// 1000000 - Has error state
|
|
29
|
-
},
|
|
29
|
+
}, A = {
|
|
30
|
+
SYNC: 1,
|
|
31
|
+
NOTIFICATION_SCHEDULED: 2
|
|
32
|
+
}, ye = {
|
|
30
33
|
/** Maximum number of pooled objects to prevent memory bloat */
|
|
31
34
|
MAX_SIZE: 1e3,
|
|
32
35
|
/** Number of objects to pre-allocate for performance-critical paths */
|
|
33
36
|
WARMUP_SIZE: 100
|
|
34
|
-
},
|
|
37
|
+
}, I = {
|
|
35
38
|
/** Maximum effect executions per second to detect infinite loops (Legacy/Fallback) */
|
|
36
39
|
MAX_EXECUTIONS_PER_SECOND: 1e3,
|
|
37
40
|
/** Threshold for cleaning up old execution timestamps */
|
|
@@ -55,7 +58,7 @@ const Z = {
|
|
|
55
58
|
MAX_DEPENDENCIES: 1e3,
|
|
56
59
|
/** Enable infinite loop detection warnings */
|
|
57
60
|
WARN_INFINITE_LOOP: !0
|
|
58
|
-
},
|
|
61
|
+
}, S = 1073741823, z = 1 << 19, l = typeof process < "u" && process.env && process.env.NODE_ENV !== "production", se = Object.freeze([]);
|
|
59
62
|
class b extends Error {
|
|
60
63
|
/**
|
|
61
64
|
* Creates a new AtomError
|
|
@@ -67,7 +70,7 @@ class b extends Error {
|
|
|
67
70
|
super(e), this.name = "AtomError", this.cause = t, this.recoverable = s, this.timestamp = /* @__PURE__ */ new Date();
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
class
|
|
73
|
+
class D extends b {
|
|
71
74
|
/**
|
|
72
75
|
* Creates a new ComputedError
|
|
73
76
|
* @param message - Error message
|
|
@@ -77,7 +80,7 @@ class N extends b {
|
|
|
77
80
|
super(e, t, !0), this.name = "ComputedError";
|
|
78
81
|
}
|
|
79
82
|
}
|
|
80
|
-
class
|
|
83
|
+
class y extends b {
|
|
81
84
|
/**
|
|
82
85
|
* Creates a new EffectError
|
|
83
86
|
* @param message - Error message
|
|
@@ -87,7 +90,7 @@ class g extends b {
|
|
|
87
90
|
super(e, t, !1), this.name = "EffectError";
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
|
-
class
|
|
93
|
+
class U extends b {
|
|
91
94
|
/**
|
|
92
95
|
* Creates a new SchedulerError
|
|
93
96
|
* @param message - Error message
|
|
@@ -149,20 +152,20 @@ const h = {
|
|
|
149
152
|
* @remarks This prevents cascading failures from masking the original error.
|
|
150
153
|
*/
|
|
151
154
|
CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution"
|
|
152
|
-
},
|
|
153
|
-
function
|
|
155
|
+
}, V = /* @__PURE__ */ Symbol("debugName"), ie = /* @__PURE__ */ Symbol("id"), w = /* @__PURE__ */ Symbol("type"), Q = /* @__PURE__ */ Symbol("noDefaultValue");
|
|
156
|
+
function re(i) {
|
|
154
157
|
return "dependencies" in i && Array.isArray(i.dependencies);
|
|
155
158
|
}
|
|
156
159
|
let q = 0;
|
|
157
|
-
function
|
|
160
|
+
function Y(i, e, t) {
|
|
158
161
|
if (i._visitedEpoch !== t) {
|
|
159
162
|
if (i._visitedEpoch = t, i === e)
|
|
160
|
-
throw new
|
|
161
|
-
if (
|
|
163
|
+
throw new D("Indirect circular dependency detected");
|
|
164
|
+
if (re(i)) {
|
|
162
165
|
const s = i.dependencies;
|
|
163
|
-
for (let
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
+
for (let r = 0; r < s.length; r++) {
|
|
167
|
+
const n = s[r];
|
|
168
|
+
n && Y(n, e, t);
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
171
|
}
|
|
@@ -181,34 +184,73 @@ const E = {
|
|
|
181
184
|
*/
|
|
182
185
|
checkCircular(i, e) {
|
|
183
186
|
if (i === e)
|
|
184
|
-
throw new
|
|
185
|
-
this.enabled && (q++,
|
|
187
|
+
throw new D("Direct circular dependency detected");
|
|
188
|
+
this.enabled && (q++, Y(i, e, q));
|
|
186
189
|
},
|
|
187
190
|
attachDebugInfo(i, e, t) {
|
|
188
191
|
if (!this.enabled)
|
|
189
192
|
return;
|
|
190
193
|
const s = i;
|
|
191
|
-
s[
|
|
194
|
+
s[V] = `${e}_${t}`, s[ie] = t, s[w] = e;
|
|
192
195
|
},
|
|
193
196
|
getDebugName(i) {
|
|
194
|
-
if (i != null && L in i)
|
|
195
|
-
return i[L];
|
|
196
|
-
},
|
|
197
|
-
getDebugType(i) {
|
|
198
197
|
if (i != null && V in i)
|
|
199
198
|
return i[V];
|
|
199
|
+
},
|
|
200
|
+
getDebugType(i) {
|
|
201
|
+
if (i != null && w in i)
|
|
202
|
+
return i[w];
|
|
200
203
|
}
|
|
201
204
|
};
|
|
202
|
-
let
|
|
203
|
-
const
|
|
204
|
-
class
|
|
205
|
+
let ne = 1;
|
|
206
|
+
const oe = () => ne++;
|
|
207
|
+
class H {
|
|
205
208
|
constructor() {
|
|
206
|
-
this.id =
|
|
209
|
+
this.id = oe() & S, this.flags = 0, this.version = 0;
|
|
210
|
+
}
|
|
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 & S, this.version;
|
|
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 & S;
|
|
207
249
|
}
|
|
208
250
|
}
|
|
209
|
-
class
|
|
251
|
+
class $ extends H {
|
|
210
252
|
constructor() {
|
|
211
|
-
super(), this.
|
|
253
|
+
super(), this._lastSeenEpoch = -1;
|
|
212
254
|
}
|
|
213
255
|
/**
|
|
214
256
|
* Subscribes a listener function or Subscriber object to value changes.
|
|
@@ -247,60 +289,90 @@ class Q extends Y {
|
|
|
247
289
|
}
|
|
248
290
|
}
|
|
249
291
|
let x = 0;
|
|
250
|
-
function
|
|
251
|
-
return x = x + 1 &
|
|
292
|
+
function J() {
|
|
293
|
+
return x = x + 1 & S || 1, x;
|
|
252
294
|
}
|
|
253
|
-
function
|
|
295
|
+
function ue() {
|
|
254
296
|
return x;
|
|
255
297
|
}
|
|
256
|
-
let
|
|
257
|
-
function
|
|
258
|
-
return
|
|
298
|
+
let F = 0, j = 0, P = !1;
|
|
299
|
+
function X() {
|
|
300
|
+
return P ? (l && console.warn(
|
|
259
301
|
"Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"
|
|
260
|
-
), !1) : (
|
|
302
|
+
), !1) : (P = !0, F = F + 1 & S, j = 0, !0);
|
|
261
303
|
}
|
|
262
|
-
function
|
|
263
|
-
|
|
304
|
+
function G() {
|
|
305
|
+
P = !1;
|
|
264
306
|
}
|
|
265
|
-
function
|
|
266
|
-
return
|
|
307
|
+
function he() {
|
|
308
|
+
return P ? ++j : 0;
|
|
267
309
|
}
|
|
268
310
|
class ce {
|
|
269
311
|
constructor() {
|
|
270
|
-
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 =
|
|
312
|
+
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;
|
|
271
313
|
}
|
|
272
314
|
get phase() {
|
|
273
315
|
return this.isProcessing || this.isFlushingSync ? 2 : this.isBatching ? 1 : 0;
|
|
274
316
|
}
|
|
275
317
|
/**
|
|
276
|
-
* Schedules a task for execution.
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
318
|
+
* Schedules a task for execution with optional priority based on phase shift.
|
|
319
|
+
*
|
|
320
|
+
* Priority Calculation (Branchless):
|
|
321
|
+
* - If sourceNode and cachedVersion are provided, calculates shift
|
|
322
|
+
* - Jobs with shift >= PHASE_THRESHOLD go to urgentQueue
|
|
323
|
+
* - Uses branchless bit manipulation: ((shift - THRESHOLD) >>> 31) ^ 1
|
|
324
|
+
*
|
|
325
|
+
* @param callback - The function to execute
|
|
326
|
+
* @param sourceNode - Optional reactive node for shift calculation
|
|
327
|
+
* @throws {SchedulerError} If the callback is not a function
|
|
280
328
|
*/
|
|
281
|
-
schedule(e) {
|
|
329
|
+
schedule(e, t) {
|
|
282
330
|
if (typeof e != "function")
|
|
283
|
-
throw new
|
|
284
|
-
|
|
331
|
+
throw new U("Scheduler callback must be a function");
|
|
332
|
+
if (e._nextEpoch !== this._epoch)
|
|
333
|
+
if (e._nextEpoch = this._epoch, this.isBatching || this.isFlushingSync)
|
|
334
|
+
this.batchQueue[this.batchQueueSize++] = e;
|
|
335
|
+
else {
|
|
336
|
+
const s = this._calculateUrgency(e, t);
|
|
337
|
+
this.urgentQueue[this.urgentQueueSize] = e, this.queue[this.queueSize] = e, this.urgentQueueSize += s, this.queueSize += s ^ 1, this.isProcessing || this.flush();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Calculates urgency flag using branchless bit manipulation.
|
|
342
|
+
*
|
|
343
|
+
* Formula: ((shift - PHASE_THRESHOLD) >>> 31) ^ 1
|
|
344
|
+
* - If shift >= THRESHOLD: (negative >>> 31) = 0, XOR 1 = 1 (urgent)
|
|
345
|
+
* - If shift < THRESHOLD: (positive >>> 31) = 0... wait, that's wrong
|
|
346
|
+
*
|
|
347
|
+
* Correct formula: (shift >= THRESHOLD) ? 1 : 0
|
|
348
|
+
* Branchless: ((PHASE_THRESHOLD - 1 - shift) >>> 31)
|
|
349
|
+
*
|
|
350
|
+
* @returns 1 if urgent, 0 if normal
|
|
351
|
+
*/
|
|
352
|
+
_calculateUrgency(e, t) {
|
|
353
|
+
if (!t || e._cachedVersion === void 0)
|
|
354
|
+
return 0;
|
|
355
|
+
const s = t.getShift(e._cachedVersion);
|
|
356
|
+
return z - 1 - s >>> 31 & 1;
|
|
285
357
|
}
|
|
286
358
|
flush() {
|
|
287
|
-
this.isProcessing || this.queueSize === 0 || (this.isProcessing = !0, queueMicrotask(() => {
|
|
359
|
+
this.isProcessing || this.queueSize === 0 && this.urgentQueueSize === 0 || (this.isProcessing = !0, queueMicrotask(() => {
|
|
288
360
|
try {
|
|
289
|
-
if (this.queueSize === 0) return;
|
|
290
|
-
const e =
|
|
291
|
-
this._drainQueue(), e &&
|
|
361
|
+
if (this.queueSize === 0 && this.urgentQueueSize === 0) return;
|
|
362
|
+
const e = X();
|
|
363
|
+
this._drainQueue(), e && G();
|
|
292
364
|
} finally {
|
|
293
|
-
this.isProcessing = !1, this.queueSize > 0 && !this.isBatching && this.flush();
|
|
365
|
+
this.isProcessing = !1, (this.queueSize > 0 || this.urgentQueueSize > 0) && !this.isBatching && this.flush();
|
|
294
366
|
}
|
|
295
367
|
}));
|
|
296
368
|
}
|
|
297
369
|
flushSync() {
|
|
298
370
|
this.isFlushingSync = !0;
|
|
299
|
-
const e =
|
|
371
|
+
const e = X();
|
|
300
372
|
try {
|
|
301
373
|
this._mergeBatchQueue(), this._drainQueue();
|
|
302
374
|
} finally {
|
|
303
|
-
this.isFlushingSync = !1, e &&
|
|
375
|
+
this.isFlushingSync = !1, e && G();
|
|
304
376
|
}
|
|
305
377
|
}
|
|
306
378
|
_mergeBatchQueue() {
|
|
@@ -312,34 +384,52 @@ class ce {
|
|
|
312
384
|
this.batchQueueSize = 0;
|
|
313
385
|
}
|
|
314
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Drains all queues, processing urgent queue completely first.
|
|
389
|
+
*
|
|
390
|
+
* Processing Order:
|
|
391
|
+
* 1. Process all urgent jobs (high phase shift = stale updates)
|
|
392
|
+
* 2. Process normal jobs
|
|
393
|
+
* 3. Repeat until both queues are empty
|
|
394
|
+
*
|
|
395
|
+
* This ordering reduces glitches by ensuring that the most
|
|
396
|
+
* impactful state changes are propagated first.
|
|
397
|
+
*/
|
|
315
398
|
_drainQueue() {
|
|
316
399
|
let e = 0;
|
|
317
|
-
for (; this.queueSize > 0; ) {
|
|
400
|
+
for (; this.urgentQueueSize > 0 || this.queueSize > 0; ) {
|
|
318
401
|
if (++e > this.maxFlushIterations) {
|
|
319
402
|
this._handleFlushOverflow();
|
|
320
403
|
break;
|
|
321
404
|
}
|
|
322
|
-
this._processCurrentQueue(), this._mergeBatchQueue();
|
|
405
|
+
this.urgentQueueSize > 0 && this._processUrgentQueue(), this.queueSize > 0 && this._processCurrentQueue(), this._mergeBatchQueue();
|
|
323
406
|
}
|
|
324
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Processes the urgent queue using double-buffering.
|
|
410
|
+
*/
|
|
411
|
+
_processUrgentQueue() {
|
|
412
|
+
const e = this.urgentQueue, t = this.urgentQueueSize;
|
|
413
|
+
this.urgentQueue = this.urgentQueue === this.urgentQueueA ? this.urgentQueueB : this.urgentQueueA, this.urgentQueueSize = 0, this._epoch++, this._processJobs(e, t);
|
|
414
|
+
}
|
|
325
415
|
_processCurrentQueue() {
|
|
326
416
|
const e = this.queue, t = this.queueSize;
|
|
327
417
|
this.queue = this.queue === this.queueA ? this.queueB : this.queueA, this.queueSize = 0, this._epoch++, this._processJobs(e, t);
|
|
328
418
|
}
|
|
329
419
|
_handleFlushOverflow() {
|
|
330
420
|
console.error(
|
|
331
|
-
new
|
|
421
|
+
new U(
|
|
332
422
|
`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`
|
|
333
423
|
)
|
|
334
|
-
), this.queueSize = 0, this.queue.length = 0, this.batchQueueSize = 0;
|
|
424
|
+
), this.queueSize = 0, this.queue.length = 0, this.urgentQueueSize = 0, this.urgentQueue.length = 0, this.batchQueueSize = 0;
|
|
335
425
|
}
|
|
336
426
|
_processJobs(e, t) {
|
|
337
427
|
for (let s = 0; s < t; s++)
|
|
338
428
|
try {
|
|
339
429
|
e[s]?.();
|
|
340
|
-
} catch (
|
|
430
|
+
} catch (r) {
|
|
341
431
|
console.error(
|
|
342
|
-
new
|
|
432
|
+
new U("Error occurred during scheduler execution", r)
|
|
343
433
|
);
|
|
344
434
|
}
|
|
345
435
|
e.length = 0;
|
|
@@ -360,25 +450,25 @@ class ce {
|
|
|
360
450
|
* @param max - Maximum iterations count.
|
|
361
451
|
*/
|
|
362
452
|
setMaxFlushIterations(e) {
|
|
363
|
-
if (e <
|
|
364
|
-
throw new
|
|
365
|
-
`Max flush iterations must be at least ${
|
|
453
|
+
if (e < I.MIN_FLUSH_ITERATIONS)
|
|
454
|
+
throw new U(
|
|
455
|
+
`Max flush iterations must be at least ${I.MIN_FLUSH_ITERATIONS}`
|
|
366
456
|
);
|
|
367
457
|
this.maxFlushIterations = e;
|
|
368
458
|
}
|
|
369
459
|
}
|
|
370
|
-
const
|
|
371
|
-
function
|
|
460
|
+
const N = new ce();
|
|
461
|
+
function De(i) {
|
|
372
462
|
if (typeof i != "function")
|
|
373
463
|
throw new b("Batch callback must be a function");
|
|
374
|
-
|
|
464
|
+
N.startBatch();
|
|
375
465
|
try {
|
|
376
466
|
return i();
|
|
377
467
|
} finally {
|
|
378
|
-
|
|
468
|
+
N.endBatch();
|
|
379
469
|
}
|
|
380
470
|
}
|
|
381
|
-
class
|
|
471
|
+
class ae {
|
|
382
472
|
constructor() {
|
|
383
473
|
this.current = null;
|
|
384
474
|
}
|
|
@@ -405,8 +495,8 @@ class he {
|
|
|
405
495
|
return this.current;
|
|
406
496
|
}
|
|
407
497
|
}
|
|
408
|
-
const m = new
|
|
409
|
-
function
|
|
498
|
+
const m = new ae();
|
|
499
|
+
function _e(i) {
|
|
410
500
|
if (typeof i != "function")
|
|
411
501
|
throw new b("Untracked callback must be a function");
|
|
412
502
|
const e = m.current;
|
|
@@ -456,8 +546,8 @@ class v {
|
|
|
456
546
|
for (let s = 0; s < this.subscribers.length; s++)
|
|
457
547
|
try {
|
|
458
548
|
e(this.subscribers[s], s);
|
|
459
|
-
} catch (
|
|
460
|
-
t ? t(
|
|
549
|
+
} catch (r) {
|
|
550
|
+
t ? t(r) : console.error("[SubscriberManager] Error in subscriber callback:", r);
|
|
461
551
|
}
|
|
462
552
|
}
|
|
463
553
|
get size() {
|
|
@@ -511,12 +601,12 @@ class k {
|
|
|
511
601
|
/** Returns current stats for the pool (dev mode only). */
|
|
512
602
|
getStats() {
|
|
513
603
|
if (!l || !this.stats) return null;
|
|
514
|
-
const { acquired: e, released: t, rejected: s } = this.stats,
|
|
604
|
+
const { acquired: e, released: t, rejected: s } = this.stats, r = s.frozen + s.tooLarge + s.poolFull;
|
|
515
605
|
return {
|
|
516
606
|
acquired: e,
|
|
517
607
|
released: t,
|
|
518
608
|
rejected: s,
|
|
519
|
-
leaked: e - t -
|
|
609
|
+
leaked: e - t - r,
|
|
520
610
|
poolSize: this.pool.length
|
|
521
611
|
};
|
|
522
612
|
}
|
|
@@ -525,142 +615,145 @@ class k {
|
|
|
525
615
|
this.pool.length = 0, l && this.stats && (this.stats.acquired = 0, this.stats.released = 0, this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 });
|
|
526
616
|
}
|
|
527
617
|
}
|
|
528
|
-
const
|
|
529
|
-
function
|
|
618
|
+
const a = Object.freeze([]), f = Object.freeze([]), _ = Object.freeze([]), g = new k(), C = new k(), d = new k();
|
|
619
|
+
function le(i) {
|
|
530
620
|
return i !== null && typeof i == "object" && "value" in i && "subscribe" in i && typeof i.subscribe == "function";
|
|
531
621
|
}
|
|
532
|
-
function
|
|
622
|
+
function Ie(i) {
|
|
533
623
|
if (E.enabled && (i == null || typeof i == "object")) {
|
|
534
624
|
const e = E.getDebugType(i);
|
|
535
625
|
if (e)
|
|
536
626
|
return e === "computed";
|
|
537
627
|
}
|
|
538
|
-
return
|
|
628
|
+
return le(i) && "invalidate" in i && typeof i.invalidate == "function";
|
|
539
629
|
}
|
|
540
|
-
function
|
|
630
|
+
function Ce(i) {
|
|
541
631
|
return i !== null && typeof i == "object" && "dispose" in i && "run" in i && typeof i.dispose == "function" && typeof i.run == "function";
|
|
542
632
|
}
|
|
543
|
-
function
|
|
633
|
+
function W(i) {
|
|
544
634
|
return i != null && typeof i.then == "function";
|
|
545
635
|
}
|
|
546
|
-
function
|
|
636
|
+
function fe(i) {
|
|
547
637
|
return typeof i == "object" && i !== null;
|
|
548
638
|
}
|
|
549
|
-
function
|
|
639
|
+
function de(i) {
|
|
550
640
|
return (typeof i == "object" || typeof i == "function") && i !== null && typeof i.addDependency == "function";
|
|
551
641
|
}
|
|
552
|
-
function
|
|
642
|
+
function Ee(i) {
|
|
553
643
|
return typeof i == "function" && typeof i.addDependency != "function";
|
|
554
644
|
}
|
|
555
|
-
function
|
|
556
|
-
return
|
|
645
|
+
function pe(i) {
|
|
646
|
+
return fe(i) && typeof i.execute == "function";
|
|
557
647
|
}
|
|
558
|
-
function
|
|
648
|
+
function K(i, e, t, s) {
|
|
559
649
|
if (e) {
|
|
560
|
-
if (
|
|
650
|
+
if (de(e)) {
|
|
561
651
|
e.addDependency(i);
|
|
562
652
|
return;
|
|
563
653
|
}
|
|
564
|
-
if (
|
|
654
|
+
if (Ee(e)) {
|
|
565
655
|
t.add(e);
|
|
566
656
|
return;
|
|
567
657
|
}
|
|
568
|
-
|
|
658
|
+
pe(e) && s.add(e);
|
|
569
659
|
}
|
|
570
660
|
}
|
|
571
|
-
function
|
|
572
|
-
if (e !==
|
|
573
|
-
for (let
|
|
574
|
-
const o = e[
|
|
575
|
-
o && (o._tempUnsub = t[
|
|
661
|
+
function be(i, e, t, s) {
|
|
662
|
+
if (e !== a && t !== f)
|
|
663
|
+
for (let n = 0; n < e.length; n++) {
|
|
664
|
+
const o = e[n];
|
|
665
|
+
o && (o._tempUnsub = t[n]);
|
|
576
666
|
}
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
for (let
|
|
580
|
-
const o = i[
|
|
581
|
-
o && (o._tempUnsub ? (n
|
|
582
|
-
}
|
|
583
|
-
if (e !==
|
|
584
|
-
for (let
|
|
585
|
-
const o = e[
|
|
667
|
+
const r = C.acquire();
|
|
668
|
+
r.length = i.length;
|
|
669
|
+
for (let n = 0; n < i.length; n++) {
|
|
670
|
+
const o = i[n];
|
|
671
|
+
o && (o._tempUnsub ? (r[n] = o._tempUnsub, o._tempUnsub = void 0) : (E.checkCircular(o, s), r[n] = o.subscribe(s)));
|
|
672
|
+
}
|
|
673
|
+
if (e !== a)
|
|
674
|
+
for (let n = 0; n < e.length; n++) {
|
|
675
|
+
const o = e[n];
|
|
586
676
|
o?._tempUnsub && (o._tempUnsub(), o._tempUnsub = void 0);
|
|
587
677
|
}
|
|
588
|
-
return t !== f &&
|
|
678
|
+
return t !== f && C.release(t), r;
|
|
589
679
|
}
|
|
590
|
-
class
|
|
680
|
+
class ge extends $ {
|
|
591
681
|
constructor(e, t) {
|
|
592
|
-
super(), this.
|
|
682
|
+
super(), this._functionSubscribersStore = null, this._objectSubscribersStore = null, this._value = e, t && (this.flags |= A.SYNC), E.attachDebugInfo(this, "atom", this.id);
|
|
593
683
|
}
|
|
594
|
-
/** Gets the manager for function-based subscribers. */
|
|
595
684
|
get _functionSubscribers() {
|
|
596
|
-
return this._functionSubscribersStore;
|
|
685
|
+
return this._functionSubscribersStore || (this._functionSubscribersStore = new v()), this._functionSubscribersStore;
|
|
597
686
|
}
|
|
598
|
-
/** Gets the manager for object-based subscribers. */
|
|
599
687
|
get _objectSubscribers() {
|
|
600
|
-
return this._objectSubscribersStore;
|
|
688
|
+
return this._objectSubscribersStore || (this._objectSubscribersStore = new v()), this._objectSubscribersStore;
|
|
601
689
|
}
|
|
602
690
|
/**
|
|
603
|
-
* Returns the current value and registers the atom as a dependency in
|
|
691
|
+
* Returns the current value and registers the atom as a dependency if in a tracking context.
|
|
604
692
|
*/
|
|
605
693
|
get value() {
|
|
606
|
-
const e = m.
|
|
607
|
-
return e && this.
|
|
694
|
+
const e = m.current;
|
|
695
|
+
return e && K(this, e, this._functionSubscribers, this._objectSubscribers), this._value;
|
|
608
696
|
}
|
|
609
697
|
/**
|
|
610
698
|
* Sets a new value and schedules notifications if the value has changed.
|
|
611
|
-
* Uses `Object.is` for comparison.
|
|
612
699
|
*/
|
|
613
700
|
set value(e) {
|
|
614
701
|
if (Object.is(this._value, e)) return;
|
|
615
702
|
const t = this._value;
|
|
616
|
-
this.
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
J(this, e, this._functionSubscribersStore, this._objectSubscribersStore);
|
|
703
|
+
this._value = e, this.rotatePhase();
|
|
704
|
+
const s = this._functionSubscribersStore?.hasSubscribers, r = this._objectSubscribersStore?.hasSubscribers;
|
|
705
|
+
(s || r) && this._scheduleNotification(t);
|
|
620
706
|
}
|
|
707
|
+
/**
|
|
708
|
+
* Schedules or flushes notifications based on sync mode and batching state.
|
|
709
|
+
*/
|
|
621
710
|
_scheduleNotification(e) {
|
|
622
|
-
this.
|
|
711
|
+
if (this.flags & A.NOTIFICATION_SCHEDULED || (this._pendingOldValue = e, this.flags |= A.NOTIFICATION_SCHEDULED), this.flags & A.SYNC && !N.isBatching) {
|
|
712
|
+
this._flushNotifications();
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
this._notifyTask || (this._notifyTask = () => this._flushNotifications()), N.schedule(this._notifyTask);
|
|
623
716
|
}
|
|
624
717
|
_flushNotifications() {
|
|
625
|
-
if (!this.
|
|
718
|
+
if (!(this.flags & A.NOTIFICATION_SCHEDULED)) return;
|
|
626
719
|
const e = this._pendingOldValue, t = this._value;
|
|
627
|
-
this._pendingOldValue = void 0, this.
|
|
720
|
+
this._pendingOldValue = void 0, this.flags &= -3, this._notifySubscribers(t, e);
|
|
628
721
|
}
|
|
629
722
|
/**
|
|
630
|
-
*
|
|
723
|
+
* Overridden to avoid unnecessary manager creation during notification loop.
|
|
631
724
|
*/
|
|
725
|
+
_notifySubscribers(e, t) {
|
|
726
|
+
this._functionSubscribersStore && this._functionSubscribersStore.forEachSafe((s) => s(e, t)), this._objectSubscribersStore && this._objectSubscribersStore.forEachSafe((s) => s.execute());
|
|
727
|
+
}
|
|
632
728
|
peek() {
|
|
633
729
|
return this._value;
|
|
634
730
|
}
|
|
635
|
-
/**
|
|
636
|
-
* Disposes of the atom, clearing all subscribers and resetting the value.
|
|
637
|
-
*/
|
|
638
731
|
dispose() {
|
|
639
|
-
this._functionSubscribersStore
|
|
732
|
+
this._functionSubscribersStore?.clear(), this._objectSubscribersStore?.clear(), this._value = void 0, this._notifyTask = void 0;
|
|
640
733
|
}
|
|
641
734
|
}
|
|
642
|
-
function
|
|
643
|
-
return new
|
|
735
|
+
function me(i, e = {}) {
|
|
736
|
+
return new ge(i, e.sync ?? !1);
|
|
644
737
|
}
|
|
645
|
-
function
|
|
738
|
+
function T(i, e, t) {
|
|
646
739
|
if (i instanceof TypeError)
|
|
647
740
|
return new e(`Type error (${t}): ${i.message}`, i);
|
|
648
741
|
if (i instanceof ReferenceError)
|
|
649
742
|
return new e(`Reference error (${t}): ${i.message}`, i);
|
|
650
743
|
if (i instanceof b)
|
|
651
744
|
return i;
|
|
652
|
-
const s = i instanceof Error ? i.message : String(i),
|
|
653
|
-
return new e(`Unexpected error (${t}): ${s}`,
|
|
745
|
+
const s = i instanceof Error ? i.message : String(i), r = i instanceof Error ? i : null;
|
|
746
|
+
return new e(`Unexpected error (${t}): ${s}`, r);
|
|
654
747
|
}
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
class
|
|
748
|
+
const Z = u.RESOLVED | u.PENDING | u.REJECTED, L = Array(Z + 1).fill(M.IDLE);
|
|
749
|
+
L[u.RESOLVED] = M.RESOLVED;
|
|
750
|
+
L[u.PENDING] = M.PENDING;
|
|
751
|
+
L[u.REJECTED] = M.REJECTED;
|
|
752
|
+
class ee extends $ {
|
|
660
753
|
constructor(e, t = {}) {
|
|
661
754
|
if (typeof e != "function")
|
|
662
|
-
throw new
|
|
663
|
-
if (super(), this._cachedErrors = null, this._errorCacheEpoch = -1, this._value = void 0, this.flags =
|
|
755
|
+
throw new D(h.COMPUTED_MUST_BE_FUNCTION);
|
|
756
|
+
if (super(), this._cachedErrors = null, this._errorCacheEpoch = -1, this._asyncStartAggregateVersion = 0, this._asyncRetryCount = 0, this.MAX_ASYNC_RETRIES = 3, this._value = void 0, this.flags = u.DIRTY | u.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 v(), this._objectSubscribersStore = new v(), this._dependencies = a, this._dependencyVersions = _, this._unsubscribes = f, this._notifyJob = () => {
|
|
664
757
|
this._functionSubscribersStore.forEachSafe(
|
|
665
758
|
(s) => s(),
|
|
666
759
|
(s) => console.error(s)
|
|
@@ -711,19 +804,19 @@ class K extends Q {
|
|
|
711
804
|
}
|
|
712
805
|
get errors() {
|
|
713
806
|
if (this._registerTracking(), !this.hasError)
|
|
714
|
-
return
|
|
715
|
-
const e =
|
|
807
|
+
return se;
|
|
808
|
+
const e = ue();
|
|
716
809
|
if (this._errorCacheEpoch === e && this._cachedErrors !== null)
|
|
717
810
|
return this._cachedErrors;
|
|
718
811
|
const t = /* @__PURE__ */ new Set();
|
|
719
812
|
this._error && t.add(this._error);
|
|
720
813
|
for (let s = 0; s < this._dependencies.length; s++) {
|
|
721
|
-
const
|
|
722
|
-
if (
|
|
723
|
-
const
|
|
724
|
-
for (let o = 0; o <
|
|
725
|
-
const
|
|
726
|
-
|
|
814
|
+
const r = this._dependencies[s];
|
|
815
|
+
if (r && "errors" in r) {
|
|
816
|
+
const n = r.errors;
|
|
817
|
+
for (let o = 0; o < n.length; o++) {
|
|
818
|
+
const c = n[o];
|
|
819
|
+
c && t.add(c);
|
|
727
820
|
}
|
|
728
821
|
}
|
|
729
822
|
}
|
|
@@ -739,7 +832,7 @@ class K extends Q {
|
|
|
739
832
|
return this._registerTracking(), this._isResolved();
|
|
740
833
|
}
|
|
741
834
|
invalidate() {
|
|
742
|
-
this._markDirty(), this._dependencyVersions !==
|
|
835
|
+
this._markDirty(), this._dependencyVersions !== _ && (d.release(this._dependencyVersions), this._dependencyVersions = _), this._errorCacheEpoch = -1, this._cachedErrors = null;
|
|
743
836
|
}
|
|
744
837
|
dispose() {
|
|
745
838
|
if (this._unsubscribes !== f) {
|
|
@@ -747,53 +840,53 @@ class K extends Q {
|
|
|
747
840
|
const t = this._unsubscribes[e];
|
|
748
841
|
t && t();
|
|
749
842
|
}
|
|
750
|
-
|
|
843
|
+
C.release(this._unsubscribes), this._unsubscribes = f;
|
|
751
844
|
}
|
|
752
|
-
this._dependencies !==
|
|
845
|
+
this._dependencies !== a && (g.release(this._dependencies), this._dependencies = a), this._dependencyVersions !== _ && (d.release(this._dependencyVersions), this._dependencyVersions = _), this._functionSubscribersStore.clear(), this._objectSubscribersStore.clear(), this.flags = u.DIRTY | u.IDLE, this._error = null, this._value = void 0, this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID, this._cachedErrors = null, this._errorCacheEpoch = -1;
|
|
753
846
|
}
|
|
754
847
|
// State flag operations
|
|
755
848
|
_isDirty() {
|
|
756
|
-
return (this.flags &
|
|
849
|
+
return (this.flags & u.DIRTY) !== 0;
|
|
757
850
|
}
|
|
758
851
|
_setDirty() {
|
|
759
|
-
this.flags |=
|
|
852
|
+
this.flags |= u.DIRTY;
|
|
760
853
|
}
|
|
761
854
|
_clearDirty() {
|
|
762
855
|
this.flags &= -2;
|
|
763
856
|
}
|
|
764
857
|
_isIdle() {
|
|
765
|
-
return (this.flags &
|
|
858
|
+
return (this.flags & u.IDLE) !== 0;
|
|
766
859
|
}
|
|
767
860
|
_setIdle() {
|
|
768
|
-
this.flags |=
|
|
861
|
+
this.flags |= u.IDLE, this.flags &= -29;
|
|
769
862
|
}
|
|
770
863
|
_isPending() {
|
|
771
|
-
return (this.flags &
|
|
864
|
+
return (this.flags & u.PENDING) !== 0;
|
|
772
865
|
}
|
|
773
866
|
_setPending() {
|
|
774
|
-
this.flags |=
|
|
867
|
+
this.flags |= u.PENDING, this.flags &= -27;
|
|
775
868
|
}
|
|
776
869
|
_isResolved() {
|
|
777
|
-
return (this.flags &
|
|
870
|
+
return (this.flags & u.RESOLVED) !== 0;
|
|
778
871
|
}
|
|
779
872
|
_setResolved() {
|
|
780
|
-
this.flags |=
|
|
873
|
+
this.flags |= u.RESOLVED, this.flags &= -87;
|
|
781
874
|
}
|
|
782
875
|
_isRejected() {
|
|
783
|
-
return (this.flags &
|
|
876
|
+
return (this.flags & u.REJECTED) !== 0;
|
|
784
877
|
}
|
|
785
878
|
_setRejected() {
|
|
786
|
-
this.flags |=
|
|
879
|
+
this.flags |= u.REJECTED | u.HAS_ERROR, this.flags &= -15;
|
|
787
880
|
}
|
|
788
881
|
_isRecomputing() {
|
|
789
|
-
return (this.flags &
|
|
882
|
+
return (this.flags & u.RECOMPUTING) !== 0;
|
|
790
883
|
}
|
|
791
884
|
_setRecomputing(e) {
|
|
792
|
-
const t =
|
|
885
|
+
const t = u.RECOMPUTING;
|
|
793
886
|
this.flags = this.flags & ~t | -Number(e) & t;
|
|
794
887
|
}
|
|
795
888
|
_getAsyncState() {
|
|
796
|
-
return
|
|
889
|
+
return L[this.flags & Z];
|
|
797
890
|
}
|
|
798
891
|
_getFlagsAsString() {
|
|
799
892
|
const e = [];
|
|
@@ -809,13 +902,13 @@ class K extends Q {
|
|
|
809
902
|
let t = !1;
|
|
810
903
|
try {
|
|
811
904
|
const s = m.run(this._trackable, this._fn);
|
|
812
|
-
this._commitDependencies(e), t = !0,
|
|
905
|
+
this._commitDependencies(e), t = !0, W(s) ? this._handleAsyncComputation(s) : this._handleSyncResult(s);
|
|
813
906
|
} catch (s) {
|
|
814
907
|
if (!t)
|
|
815
908
|
try {
|
|
816
909
|
this._commitDependencies(e), t = !0;
|
|
817
|
-
} catch (
|
|
818
|
-
this._handleComputationError(
|
|
910
|
+
} catch (r) {
|
|
911
|
+
this._handleComputationError(r);
|
|
819
912
|
}
|
|
820
913
|
this._handleComputationError(s);
|
|
821
914
|
} finally {
|
|
@@ -823,47 +916,100 @@ class K extends Q {
|
|
|
823
916
|
}
|
|
824
917
|
}
|
|
825
918
|
_prepareComputationContext() {
|
|
826
|
-
const e = this._dependencies, t = this._dependencyVersions, s =
|
|
827
|
-
p._lastSeenEpoch !==
|
|
828
|
-
},
|
|
829
|
-
return this._trackable.addDependency =
|
|
919
|
+
const e = this._dependencies, t = this._dependencyVersions, s = g.acquire(), r = d.acquire(), n = J(), o = { depCount: 0 }, c = (p) => {
|
|
920
|
+
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++);
|
|
921
|
+
}, R = this._trackable.addDependency;
|
|
922
|
+
return this._trackable.addDependency = c, { prevDeps: e, prevVersions: t, nextDeps: s, nextVersions: r, originalAdd: R, state: o };
|
|
830
923
|
}
|
|
831
924
|
_commitDependencies(e) {
|
|
832
|
-
const { nextDeps: t, nextVersions: s, state:
|
|
833
|
-
t.length =
|
|
925
|
+
const { nextDeps: t, nextVersions: s, state: r, prevDeps: n } = e;
|
|
926
|
+
t.length = r.depCount, s.length = r.depCount, this._unsubscribes = be(t, n, this._unsubscribes, this), this._dependencies = t, this._dependencyVersions = s;
|
|
834
927
|
}
|
|
835
928
|
_cleanupContext(e, t) {
|
|
836
|
-
this._trackable.addDependency = e.originalAdd, t ? (e.prevDeps !==
|
|
929
|
+
this._trackable.addDependency = e.originalAdd, t ? (e.prevDeps !== a && g.release(e.prevDeps), e.prevVersions !== _ && d.release(e.prevVersions)) : (g.release(e.nextDeps), d.release(e.nextVersions));
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Calculates aggregate shift from all dependencies.
|
|
933
|
+
* Used for scheduling priority in computed chains.
|
|
934
|
+
*
|
|
935
|
+
* Performance: O(N) where N = dependency count
|
|
936
|
+
* Branchless: Each dep.getShift uses modular arithmetic
|
|
937
|
+
*
|
|
938
|
+
* @returns Sum of all dependency shifts (capped at SMI_MAX)
|
|
939
|
+
*/
|
|
940
|
+
_getAggregateShift() {
|
|
941
|
+
let e = 0;
|
|
942
|
+
const t = this._dependencies, s = this._dependencyVersions;
|
|
943
|
+
for (let r = 0; r < t.length; r++) {
|
|
944
|
+
const n = t[r], o = s[r];
|
|
945
|
+
n && o !== void 0 && (e = e + n.getShift(o) & S);
|
|
946
|
+
}
|
|
947
|
+
return e;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Checks if this computed should be scheduled with urgent priority.
|
|
951
|
+
* Based on aggregate shift from all dependencies.
|
|
952
|
+
*
|
|
953
|
+
* @returns true if aggregate shift exceeds PHASE_THRESHOLD
|
|
954
|
+
*/
|
|
955
|
+
isUrgent() {
|
|
956
|
+
return this._getAggregateShift() >= z;
|
|
837
957
|
}
|
|
838
958
|
_handleSyncResult(e) {
|
|
839
|
-
|
|
840
|
-
this.version = this.version + Number(t) & I, this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), this._cachedErrors = null, this._errorCacheEpoch = -1;
|
|
959
|
+
(!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;
|
|
841
960
|
}
|
|
842
961
|
_handleAsyncComputation(e) {
|
|
843
|
-
this._setPending(), this._clearDirty(), this._notifyJob(), this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;
|
|
962
|
+
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;
|
|
844
963
|
const t = this._promiseId;
|
|
845
964
|
e.then((s) => {
|
|
846
|
-
t
|
|
965
|
+
if (t !== this._promiseId) return;
|
|
966
|
+
const n = this._captureVersionSnapshot() - this._asyncStartAggregateVersion & S;
|
|
967
|
+
if (z - 1 - n >>> 31 & 1) {
|
|
968
|
+
if (this._asyncRetryCount < this.MAX_ASYNC_RETRIES) {
|
|
969
|
+
this._asyncRetryCount++, this._markDirty();
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const c = new D(
|
|
973
|
+
`Async drift exceeded threshold after ${this.MAX_ASYNC_RETRIES} retries. Dependencies changed too rapidly for stable computation.`
|
|
974
|
+
);
|
|
975
|
+
this._handleAsyncRejection(c);
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
this._handleAsyncResolution(s);
|
|
847
979
|
}).catch((s) => {
|
|
848
980
|
t === this._promiseId && this._handleAsyncRejection(s);
|
|
849
981
|
});
|
|
850
982
|
}
|
|
983
|
+
/**
|
|
984
|
+
* Captures the aggregate version of all dependencies.
|
|
985
|
+
* Used for phase drift validation in async computations.
|
|
986
|
+
*
|
|
987
|
+
* @returns Sum of all dependency versions (capped at SMI_MAX)
|
|
988
|
+
*/
|
|
989
|
+
_captureVersionSnapshot() {
|
|
990
|
+
let e = 0;
|
|
991
|
+
const t = this._dependencies;
|
|
992
|
+
for (let s = 0; s < t.length; s++) {
|
|
993
|
+
const r = t[s];
|
|
994
|
+
r && (e = e + r.version & S);
|
|
995
|
+
}
|
|
996
|
+
return e;
|
|
997
|
+
}
|
|
851
998
|
_handleAsyncResolution(e) {
|
|
852
|
-
|
|
853
|
-
this.version = this.version + Number(t) & I, this._value = e, this._clearDirty(), this._setResolved(), this._error = null, this._setRecomputing(!1), this._cachedErrors = null, this._errorCacheEpoch = -1, this._notifyJob();
|
|
999
|
+
(!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, this._notifyJob();
|
|
854
1000
|
}
|
|
855
1001
|
_handleAsyncRejection(e) {
|
|
856
|
-
const t =
|
|
857
|
-
if (this.
|
|
1002
|
+
const t = T(e, D, h.COMPUTED_ASYNC_COMPUTATION_FAILED);
|
|
1003
|
+
if (!this._isRejected() && this.rotatePhase(), this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError)
|
|
858
1004
|
try {
|
|
859
1005
|
this._onError(t);
|
|
860
|
-
} catch (
|
|
861
|
-
console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER,
|
|
1006
|
+
} catch (r) {
|
|
1007
|
+
console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER, r);
|
|
862
1008
|
}
|
|
863
1009
|
this._notifyJob();
|
|
864
1010
|
}
|
|
865
1011
|
_handleComputationError(e) {
|
|
866
|
-
const t =
|
|
1012
|
+
const t = T(e, D, h.COMPUTED_COMPUTATION_FAILED);
|
|
867
1013
|
if (this._error = t, this._setRejected(), this._clearDirty(), this._setRecomputing(!1), this._onError)
|
|
868
1014
|
try {
|
|
869
1015
|
this._onError(t);
|
|
@@ -875,7 +1021,7 @@ class K extends Q {
|
|
|
875
1021
|
_handlePending() {
|
|
876
1022
|
if (this._hasDefaultValue)
|
|
877
1023
|
return this._defaultValue;
|
|
878
|
-
throw new
|
|
1024
|
+
throw new D(h.COMPUTED_ASYNC_PENDING_NO_DEFAULT);
|
|
879
1025
|
}
|
|
880
1026
|
_handleRejected() {
|
|
881
1027
|
if (this._error?.recoverable && this._hasDefaultValue)
|
|
@@ -890,7 +1036,7 @@ class K extends Q {
|
|
|
890
1036
|
this._isRecomputing() || this._isDirty() || (this._setDirty(), this._notifyJob());
|
|
891
1037
|
}
|
|
892
1038
|
_registerTracking() {
|
|
893
|
-
|
|
1039
|
+
K(
|
|
894
1040
|
this,
|
|
895
1041
|
m.getCurrent(),
|
|
896
1042
|
this._functionSubscribersStore,
|
|
@@ -898,11 +1044,11 @@ class K extends Q {
|
|
|
898
1044
|
);
|
|
899
1045
|
}
|
|
900
1046
|
}
|
|
901
|
-
Object.freeze(
|
|
902
|
-
function
|
|
903
|
-
return new
|
|
1047
|
+
Object.freeze(ee.prototype);
|
|
1048
|
+
function Re(i, e = {}) {
|
|
1049
|
+
return new ee(i, e);
|
|
904
1050
|
}
|
|
905
|
-
class
|
|
1051
|
+
class Se extends H {
|
|
906
1052
|
/**
|
|
907
1053
|
* Creates a new EffectImpl instance.
|
|
908
1054
|
* @param fn - The effect function to run.
|
|
@@ -911,58 +1057,58 @@ class be extends Y {
|
|
|
911
1057
|
constructor(e, t = {}) {
|
|
912
1058
|
super(), this.run = () => {
|
|
913
1059
|
if (this.isDisposed)
|
|
914
|
-
throw new
|
|
915
|
-
this._dependencyVersions !==
|
|
1060
|
+
throw new y(h.EFFECT_MUST_BE_FUNCTION);
|
|
1061
|
+
this._dependencyVersions !== _ && (d.release(this._dependencyVersions), this._dependencyVersions = _), this.execute();
|
|
916
1062
|
}, this.dispose = () => {
|
|
917
1063
|
if (!this.isDisposed) {
|
|
918
1064
|
if (this._setDisposed(), this._safeCleanup(), this._unsubscribes !== f) {
|
|
919
|
-
for (let
|
|
920
|
-
const
|
|
921
|
-
|
|
1065
|
+
for (let r = 0; r < this._unsubscribes.length; r++) {
|
|
1066
|
+
const n = this._unsubscribes[r];
|
|
1067
|
+
n && n();
|
|
922
1068
|
}
|
|
923
|
-
|
|
1069
|
+
C.release(this._unsubscribes), this._unsubscribes = f;
|
|
924
1070
|
}
|
|
925
|
-
this._dependencies !==
|
|
1071
|
+
this._dependencies !== a && (g.release(this._dependencies), this._dependencies = a), this._dependencyVersions !== _ && (d.release(this._dependencyVersions), this._dependencyVersions = _);
|
|
926
1072
|
}
|
|
927
|
-
}, this.addDependency = (
|
|
1073
|
+
}, this.addDependency = (r) => {
|
|
928
1074
|
if (this.isExecuting && this._nextDeps && this._nextUnsubs && this._nextVersions) {
|
|
929
|
-
const
|
|
930
|
-
if (
|
|
931
|
-
|
|
1075
|
+
const n = this._currentEpoch;
|
|
1076
|
+
if (r._lastSeenEpoch === n) return;
|
|
1077
|
+
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);
|
|
932
1078
|
}
|
|
933
1079
|
}, this.execute = () => {
|
|
934
1080
|
if (this.isDisposed || this.isExecuting || !this._shouldExecute()) return;
|
|
935
1081
|
this._checkInfiniteLoop(), this._setExecuting(!0), this._safeCleanup();
|
|
936
|
-
const
|
|
937
|
-
let
|
|
1082
|
+
const r = this._prepareEffectContext();
|
|
1083
|
+
let n = !1;
|
|
938
1084
|
try {
|
|
939
1085
|
const o = m.run(this, this._fn);
|
|
940
|
-
this._commitEffect(
|
|
941
|
-
!this.isDisposed && typeof
|
|
942
|
-
}).catch((
|
|
943
|
-
this._handleExecutionError(
|
|
1086
|
+
this._commitEffect(r), n = !0, this._checkLoopWarnings(), W(o) ? o.then((c) => {
|
|
1087
|
+
!this.isDisposed && typeof c == "function" && (this._cleanup = c);
|
|
1088
|
+
}).catch((c) => {
|
|
1089
|
+
this._handleExecutionError(c);
|
|
944
1090
|
}) : this._cleanup = typeof o == "function" ? o : null;
|
|
945
1091
|
} catch (o) {
|
|
946
|
-
|
|
1092
|
+
n = !0, this._handleExecutionError(o), this._cleanup = null;
|
|
947
1093
|
} finally {
|
|
948
|
-
this._cleanupEffect(
|
|
1094
|
+
this._cleanupEffect(r, n), this._setExecuting(!1);
|
|
949
1095
|
}
|
|
950
|
-
}, this._currentEpoch = -1, this._lastFlushEpoch = -1, this._executionsInEpoch = 0, this._fn = e, this._sync = t.sync ?? !1, this._maxExecutions = t.maxExecutionsPerSecond ??
|
|
1096
|
+
}, 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._cleanup = null, this._dependencies = a, this._dependencyVersions = _, this._unsubscribes = f, this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, this._onError = t.onError ?? null, this._historyPtr = 0;
|
|
951
1097
|
const s = Number.isFinite(this._maxExecutions);
|
|
952
|
-
this._historyCapacity = s ? Math.min(this._maxExecutions + 1,
|
|
1098
|
+
this._historyCapacity = s ? Math.min(this._maxExecutions + 1, I.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);
|
|
953
1099
|
}
|
|
954
1100
|
/**
|
|
955
1101
|
* Prepares the execution context by acquiring pools and setting up epoch.
|
|
956
1102
|
* @returns The prepared EffectContext.
|
|
957
1103
|
*/
|
|
958
1104
|
_prepareEffectContext() {
|
|
959
|
-
const e = this._dependencies, t = this._dependencyVersions, s = this._unsubscribes,
|
|
960
|
-
if (e !==
|
|
961
|
-
for (let
|
|
962
|
-
const p = e[
|
|
963
|
-
p && (p._tempUnsub = s[
|
|
1105
|
+
const e = this._dependencies, t = this._dependencyVersions, s = this._unsubscribes, r = g.acquire(), n = d.acquire(), o = C.acquire(), c = J();
|
|
1106
|
+
if (e !== a && s !== f)
|
|
1107
|
+
for (let R = 0; R < e.length; R++) {
|
|
1108
|
+
const p = e[R];
|
|
1109
|
+
p && (p._tempUnsub = s[R]);
|
|
964
1110
|
}
|
|
965
|
-
return this._nextDeps =
|
|
1111
|
+
return this._nextDeps = r, this._nextVersions = n, this._nextUnsubs = o, this._currentEpoch = c, { prevDeps: e, prevVersions: t, prevUnsubs: s, nextDeps: r, nextVersions: n, nextUnsubs: o };
|
|
966
1112
|
}
|
|
967
1113
|
/**
|
|
968
1114
|
* Commits the tracked dependencies as the current active dependencies.
|
|
@@ -979,22 +1125,22 @@ class be extends Y {
|
|
|
979
1125
|
*/
|
|
980
1126
|
_cleanupEffect(e, t) {
|
|
981
1127
|
if (this._nextDeps = null, this._nextVersions = null, this._nextUnsubs = null, t) {
|
|
982
|
-
if (e.prevDeps !==
|
|
1128
|
+
if (e.prevDeps !== a) {
|
|
983
1129
|
for (let s = 0; s < e.prevDeps.length; s++) {
|
|
984
|
-
const
|
|
985
|
-
|
|
1130
|
+
const r = e.prevDeps[s];
|
|
1131
|
+
r?._tempUnsub && (r._tempUnsub(), r._tempUnsub = void 0);
|
|
986
1132
|
}
|
|
987
|
-
|
|
1133
|
+
g.release(e.prevDeps);
|
|
988
1134
|
}
|
|
989
|
-
e.prevUnsubs !== f &&
|
|
1135
|
+
e.prevUnsubs !== f && C.release(e.prevUnsubs), e.prevVersions !== _ && d.release(e.prevVersions);
|
|
990
1136
|
} else {
|
|
991
|
-
|
|
1137
|
+
g.release(e.nextDeps), d.release(e.nextVersions);
|
|
992
1138
|
for (let s = 0; s < e.nextUnsubs.length; s++)
|
|
993
1139
|
e.nextUnsubs[s]?.();
|
|
994
|
-
if (
|
|
1140
|
+
if (C.release(e.nextUnsubs), e.prevDeps !== a)
|
|
995
1141
|
for (let s = 0; s < e.prevDeps.length; s++) {
|
|
996
|
-
const
|
|
997
|
-
|
|
1142
|
+
const r = e.prevDeps[s];
|
|
1143
|
+
r && (r._tempUnsub = void 0);
|
|
998
1144
|
}
|
|
999
1145
|
}
|
|
1000
1146
|
}
|
|
@@ -1005,11 +1151,11 @@ class be extends Y {
|
|
|
1005
1151
|
_subscribeTo(e) {
|
|
1006
1152
|
try {
|
|
1007
1153
|
const t = e.subscribe(() => {
|
|
1008
|
-
this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() :
|
|
1154
|
+
this._trackModifications && this.isExecuting && (e._modifiedAtEpoch = this._currentEpoch), this._sync ? this.execute() : N.schedule(this.execute);
|
|
1009
1155
|
});
|
|
1010
1156
|
this._nextUnsubs && this._nextUnsubs.push(t);
|
|
1011
1157
|
} catch (t) {
|
|
1012
|
-
console.error(
|
|
1158
|
+
console.error(T(t, y, h.EFFECT_EXECUTION_FAILED)), this._nextUnsubs && this._nextUnsubs.push(() => {
|
|
1013
1159
|
});
|
|
1014
1160
|
}
|
|
1015
1161
|
}
|
|
@@ -1017,7 +1163,7 @@ class be extends Y {
|
|
|
1017
1163
|
* Whether the effect has been disposed.
|
|
1018
1164
|
*/
|
|
1019
1165
|
get isDisposed() {
|
|
1020
|
-
return (this.flags &
|
|
1166
|
+
return (this.flags & O.DISPOSED) !== 0;
|
|
1021
1167
|
}
|
|
1022
1168
|
/**
|
|
1023
1169
|
* Total number of times this effect has executed.
|
|
@@ -1029,13 +1175,13 @@ class be extends Y {
|
|
|
1029
1175
|
* Whether the effect is currently executing.
|
|
1030
1176
|
*/
|
|
1031
1177
|
get isExecuting() {
|
|
1032
|
-
return (this.flags &
|
|
1178
|
+
return (this.flags & O.EXECUTING) !== 0;
|
|
1033
1179
|
}
|
|
1034
1180
|
_setDisposed() {
|
|
1035
|
-
this.flags |=
|
|
1181
|
+
this.flags |= O.DISPOSED;
|
|
1036
1182
|
}
|
|
1037
1183
|
_setExecuting(e) {
|
|
1038
|
-
const t =
|
|
1184
|
+
const t = O.EXECUTING;
|
|
1039
1185
|
this.flags = this.flags & ~t | -Number(e) & t;
|
|
1040
1186
|
}
|
|
1041
1187
|
/**
|
|
@@ -1046,7 +1192,7 @@ class be extends Y {
|
|
|
1046
1192
|
try {
|
|
1047
1193
|
this._cleanup();
|
|
1048
1194
|
} catch (e) {
|
|
1049
|
-
console.error(
|
|
1195
|
+
console.error(T(e, y, h.EFFECT_CLEANUP_FAILED));
|
|
1050
1196
|
}
|
|
1051
1197
|
this._cleanup = null;
|
|
1052
1198
|
}
|
|
@@ -1056,12 +1202,12 @@ class be extends Y {
|
|
|
1056
1202
|
* @throws {EffectError} If an infinite loop is detected.
|
|
1057
1203
|
*/
|
|
1058
1204
|
_checkInfiniteLoop() {
|
|
1059
|
-
if (this._lastFlushEpoch !==
|
|
1205
|
+
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) {
|
|
1060
1206
|
const e = Date.now(), t = this._historyPtr, s = this._historyCapacity;
|
|
1061
1207
|
this._history[t] = e;
|
|
1062
|
-
const
|
|
1063
|
-
if (this._historyPtr =
|
|
1064
|
-
const o = new
|
|
1208
|
+
const r = (t + 1) % s, n = this._history[r] ?? 0;
|
|
1209
|
+
if (this._historyPtr = r, n > 0 && e - n < te.ONE_SECOND_MS) {
|
|
1210
|
+
const o = new y(
|
|
1065
1211
|
`Effect executed ${s} times within 1 second. Infinite loop suspected`
|
|
1066
1212
|
);
|
|
1067
1213
|
if (this.dispose(), console.error(o), this._onError && this._onError(o), l)
|
|
@@ -1070,8 +1216,8 @@ class be extends Y {
|
|
|
1070
1216
|
}
|
|
1071
1217
|
}
|
|
1072
1218
|
_throwInfiniteLoopError(e) {
|
|
1073
|
-
const t = new
|
|
1074
|
-
`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${
|
|
1219
|
+
const t = new y(
|
|
1220
|
+
`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${j}`
|
|
1075
1221
|
);
|
|
1076
1222
|
throw this.dispose(), console.error(t), t;
|
|
1077
1223
|
}
|
|
@@ -1080,14 +1226,14 @@ class be extends Y {
|
|
|
1080
1226
|
* @returns true if any dependency has changed or if it's the first run.
|
|
1081
1227
|
*/
|
|
1082
1228
|
_shouldExecute() {
|
|
1083
|
-
if (this._dependencies ===
|
|
1229
|
+
if (this._dependencies === a || this._dependencyVersions === _)
|
|
1084
1230
|
return !0;
|
|
1085
1231
|
for (let e = 0; e < this._dependencies.length; e++) {
|
|
1086
1232
|
const t = this._dependencies[e];
|
|
1087
1233
|
if (t) {
|
|
1088
1234
|
if ("value" in t)
|
|
1089
1235
|
try {
|
|
1090
|
-
|
|
1236
|
+
_e(() => t.value);
|
|
1091
1237
|
} catch {
|
|
1092
1238
|
return !0;
|
|
1093
1239
|
}
|
|
@@ -1102,7 +1248,7 @@ class be extends Y {
|
|
|
1102
1248
|
* Wraps the error, logs it to console, and calls onError callback if provided.
|
|
1103
1249
|
*/
|
|
1104
1250
|
_handleExecutionError(e) {
|
|
1105
|
-
const t =
|
|
1251
|
+
const t = T(e, y, h.EFFECT_EXECUTION_FAILED);
|
|
1106
1252
|
console.error(t), this._onError && this._onError(t);
|
|
1107
1253
|
}
|
|
1108
1254
|
/**
|
|
@@ -1122,30 +1268,30 @@ class be extends Y {
|
|
|
1122
1268
|
}
|
|
1123
1269
|
}
|
|
1124
1270
|
}
|
|
1125
|
-
function
|
|
1271
|
+
function Ae(i, e = {}) {
|
|
1126
1272
|
if (typeof i != "function")
|
|
1127
|
-
throw new
|
|
1128
|
-
const t = new
|
|
1273
|
+
throw new y(h.EFFECT_MUST_BE_FUNCTION);
|
|
1274
|
+
const t = new Se(i, e);
|
|
1129
1275
|
return t.execute(), t;
|
|
1130
1276
|
}
|
|
1131
1277
|
export {
|
|
1132
|
-
|
|
1278
|
+
M as AsyncState,
|
|
1133
1279
|
b as AtomError,
|
|
1134
|
-
|
|
1280
|
+
D as ComputedError,
|
|
1135
1281
|
B as DEBUG_CONFIG,
|
|
1136
1282
|
E as DEBUG_RUNTIME,
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1283
|
+
y as EffectError,
|
|
1284
|
+
ye as POOL_CONFIG,
|
|
1285
|
+
I as SCHEDULER_CONFIG,
|
|
1286
|
+
U as SchedulerError,
|
|
1287
|
+
me as atom,
|
|
1288
|
+
De as batch,
|
|
1289
|
+
Re as computed,
|
|
1290
|
+
Ae as effect,
|
|
1291
|
+
le as isAtom,
|
|
1292
|
+
Ie as isComputed,
|
|
1293
|
+
Ce as isEffect,
|
|
1294
|
+
N as scheduler,
|
|
1295
|
+
_e as untracked
|
|
1150
1296
|
};
|
|
1151
1297
|
//# sourceMappingURL=index.mjs.map
|