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