@fluixi/reactive 1.0.0-alpha.104 → 1.0.0-alpha.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/reactive.cjs +74 -34
- package/dist/cdn/reactive.global.js +2 -2
- package/dist/cdn/reactive.mjs +74 -34
- package/dist/cdn/signal.cjs +23 -3
- package/dist/cdn/signal.global.js +2 -2
- package/dist/cdn/signal.mjs +23 -3
- package/dist/index.cjs +74 -34
- package/dist/index.mjs +74 -34
- package/dist/lib/index.cjs +75 -35
- package/dist/lib/index.mjs +75 -35
- package/dist/lib/observable/index.cjs +1 -1
- package/dist/lib/observable/index.mjs +1 -1
- package/dist/lib/signal/api.cjs +40 -14
- package/dist/lib/signal/api.mjs +40 -14
- package/dist/lib/signal/cached-resource.cjs +36 -13
- package/dist/lib/signal/cached-resource.mjs +36 -13
- package/dist/lib/signal/graph/children.cjs +25 -6
- package/dist/lib/signal/graph/children.mjs +25 -6
- package/dist/lib/signal/graph/compat.cjs +41 -15
- package/dist/lib/signal/graph/compat.d.ts.map +1 -1
- package/dist/lib/signal/graph/compat.js +20 -11
- package/dist/lib/signal/graph/compat.mjs +41 -15
- package/dist/lib/signal/graph/context-children.cjs +1 -1
- package/dist/lib/signal/graph/context-children.mjs +1 -1
- package/dist/lib/signal/graph/core.cjs +24 -4
- package/dist/lib/signal/graph/core.d.ts +10 -0
- package/dist/lib/signal/graph/core.d.ts.map +1 -1
- package/dist/lib/signal/graph/core.js +27 -2
- package/dist/lib/signal/graph/core.mjs +24 -4
- package/dist/lib/signal/graph/debounced.cjs +35 -12
- package/dist/lib/signal/graph/debounced.mjs +35 -12
- package/dist/lib/signal/graph/derived.cjs +35 -12
- package/dist/lib/signal/graph/derived.mjs +35 -12
- package/dist/lib/signal/graph/detect.cjs +1 -1
- package/dist/lib/signal/graph/detect.mjs +1 -1
- package/dist/lib/signal/graph/error-boundary.cjs +10 -8
- package/dist/lib/signal/graph/error-boundary.mjs +10 -8
- package/dist/lib/signal/graph/index.cjs +24 -4
- package/dist/lib/signal/graph/index.mjs +24 -4
- package/dist/lib/signal/graph/observe.cjs +1 -1
- package/dist/lib/signal/graph/observe.mjs +1 -1
- package/dist/lib/signal/graph/resource.cjs +35 -12
- package/dist/lib/signal/graph/resource.mjs +35 -12
- package/dist/lib/signal/graph/runtime.cjs +29 -5
- package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
- package/dist/lib/signal/graph/runtime.js +5 -3
- package/dist/lib/signal/graph/runtime.mjs +29 -5
- package/dist/lib/signal/graph/signal-next.cjs +67 -29
- package/dist/lib/signal/graph/signal-next.mjs +67 -29
- package/dist/lib/signal/graph/state.cjs +1 -1
- package/dist/lib/signal/graph/state.mjs +1 -1
- package/dist/lib/signal/graph/suspense.cjs +10 -8
- package/dist/lib/signal/graph/suspense.mjs +10 -8
- package/dist/lib/signal/index-legacy.cjs +67 -29
- package/dist/lib/signal/index-legacy.mjs +67 -29
- package/dist/lib/signal/index.cjs +67 -29
- package/dist/lib/signal/index.mjs +67 -29
- package/dist/lib/signal/list.cjs +58 -25
- package/dist/lib/signal/list.d.ts +3 -8
- package/dist/lib/signal/list.d.ts.map +1 -1
- package/dist/lib/signal/list.js +40 -18
- package/dist/lib/signal/list.mjs +58 -25
- package/dist/lib/signal/resource-api.cjs +35 -12
- package/dist/lib/signal/resource-api.mjs +35 -12
- package/dist/lib/signal/signal.cjs +41 -15
- package/dist/lib/signal/signal.mjs +41 -15
- package/dist/lib/signal/utilities.cjs +41 -15
- package/dist/lib/signal/utilities.mjs +41 -15
- package/dist/lib/store/api.cjs +9 -7
- package/dist/lib/store/api.mjs +9 -7
- package/dist/lib/store/index.cjs +10 -8
- package/dist/lib/store/index.mjs +10 -8
- package/dist/lib/store/store.cjs +9 -7
- package/dist/lib/store/store.d.ts.map +1 -1
- package/dist/lib/store/store.js +8 -6
- package/dist/lib/store/store.mjs +9 -7
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/version.generated.cjs +2 -2
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/version.generated.mjs +2 -2
- package/package.json +2 -2
|
@@ -25,7 +25,7 @@ __export(resource_api_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(resource_api_exports);
|
|
26
26
|
|
|
27
27
|
// src/version.generated.ts
|
|
28
|
-
var VERSION = "1.0.0-alpha.
|
|
28
|
+
var VERSION = "1.0.0-alpha.106";
|
|
29
29
|
|
|
30
30
|
// src/lib/signal/graph/state.ts
|
|
31
31
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -167,6 +167,7 @@ var Computed = class extends Source {
|
|
|
167
167
|
super();
|
|
168
168
|
this._threw = false;
|
|
169
169
|
this._initialized = false;
|
|
170
|
+
this._disposed = false;
|
|
170
171
|
this.state = DIRTY;
|
|
171
172
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
172
173
|
this.sources = null;
|
|
@@ -182,8 +183,23 @@ var Computed = class extends Source {
|
|
|
182
183
|
if (this._threw) throw this._error;
|
|
183
184
|
return this._value;
|
|
184
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
188
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
189
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
190
|
+
* The last value stays readable; the node simply never updates again.
|
|
191
|
+
*/
|
|
192
|
+
dispose() {
|
|
193
|
+
if (this._disposed) return;
|
|
194
|
+
this._disposed = true;
|
|
195
|
+
if (this.sources) {
|
|
196
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
197
|
+
this.sources = null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
185
200
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
186
201
|
updateIfNecessary() {
|
|
202
|
+
if (this._disposed) return;
|
|
187
203
|
if (this.state === CHECK) {
|
|
188
204
|
if (this.sources) {
|
|
189
205
|
for (const s of this.sources) {
|
|
@@ -227,7 +243,7 @@ var Computed = class extends Source {
|
|
|
227
243
|
reportReactiveRun(this);
|
|
228
244
|
if (changed) {
|
|
229
245
|
this.version++;
|
|
230
|
-
if (this.observers) for (const o of
|
|
246
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
231
247
|
notifyWatchers(this);
|
|
232
248
|
}
|
|
233
249
|
}
|
|
@@ -241,7 +257,7 @@ var Computed = class extends Source {
|
|
|
241
257
|
const wasClean = this.state === CLEAN;
|
|
242
258
|
this.state = level;
|
|
243
259
|
if (wasClean) {
|
|
244
|
-
if (this.observers) for (const o of
|
|
260
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
245
261
|
notifyWatchers(this);
|
|
246
262
|
}
|
|
247
263
|
}
|
|
@@ -280,6 +296,10 @@ var Watcher = class {
|
|
|
280
296
|
this._pending.clear();
|
|
281
297
|
return out;
|
|
282
298
|
}
|
|
299
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
300
|
+
clearPending() {
|
|
301
|
+
this._pending.clear();
|
|
302
|
+
}
|
|
283
303
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
284
304
|
_notify(node) {
|
|
285
305
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -397,14 +417,14 @@ var EffectNode = class {
|
|
|
397
417
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
398
418
|
});
|
|
399
419
|
});
|
|
400
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
420
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
401
421
|
this.watcher = new Watcher(() => enqueue(this));
|
|
402
422
|
this.run();
|
|
403
423
|
this.watcher.watch(this.computed);
|
|
404
424
|
}
|
|
405
425
|
run() {
|
|
406
426
|
if (this.disposed) return;
|
|
407
|
-
this.watcher.
|
|
427
|
+
this.watcher.clearPending();
|
|
408
428
|
try {
|
|
409
429
|
this.computed.get();
|
|
410
430
|
} catch (e) {
|
|
@@ -421,6 +441,7 @@ var EffectNode = class {
|
|
|
421
441
|
this.disposed = true;
|
|
422
442
|
reportReactiveDispose(this.computed);
|
|
423
443
|
this.watcher.unwatch(this.computed);
|
|
444
|
+
this.computed.dispose();
|
|
424
445
|
disposeOwner(this.owner);
|
|
425
446
|
}
|
|
426
447
|
};
|
|
@@ -455,13 +476,15 @@ function createSignal(value, options) {
|
|
|
455
476
|
},
|
|
456
477
|
enumerable: false
|
|
457
478
|
});
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
479
|
+
if (isObserved()) {
|
|
480
|
+
reportReactiveNode({
|
|
481
|
+
kind: "signal",
|
|
482
|
+
node: state,
|
|
483
|
+
handle: read,
|
|
484
|
+
name: options?.name,
|
|
485
|
+
set: write
|
|
486
|
+
});
|
|
487
|
+
}
|
|
465
488
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
466
489
|
return [read, write];
|
|
467
490
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.generated.ts
|
|
2
|
-
var VERSION = "1.0.0-alpha.
|
|
2
|
+
var VERSION = "1.0.0-alpha.106";
|
|
3
3
|
|
|
4
4
|
// src/lib/signal/graph/state.ts
|
|
5
5
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -141,6 +141,7 @@ var Computed = class extends Source {
|
|
|
141
141
|
super();
|
|
142
142
|
this._threw = false;
|
|
143
143
|
this._initialized = false;
|
|
144
|
+
this._disposed = false;
|
|
144
145
|
this.state = DIRTY;
|
|
145
146
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
146
147
|
this.sources = null;
|
|
@@ -156,8 +157,23 @@ var Computed = class extends Source {
|
|
|
156
157
|
if (this._threw) throw this._error;
|
|
157
158
|
return this._value;
|
|
158
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
162
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
163
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
164
|
+
* The last value stays readable; the node simply never updates again.
|
|
165
|
+
*/
|
|
166
|
+
dispose() {
|
|
167
|
+
if (this._disposed) return;
|
|
168
|
+
this._disposed = true;
|
|
169
|
+
if (this.sources) {
|
|
170
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
171
|
+
this.sources = null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
159
174
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
160
175
|
updateIfNecessary() {
|
|
176
|
+
if (this._disposed) return;
|
|
161
177
|
if (this.state === CHECK) {
|
|
162
178
|
if (this.sources) {
|
|
163
179
|
for (const s of this.sources) {
|
|
@@ -201,7 +217,7 @@ var Computed = class extends Source {
|
|
|
201
217
|
reportReactiveRun(this);
|
|
202
218
|
if (changed) {
|
|
203
219
|
this.version++;
|
|
204
|
-
if (this.observers) for (const o of
|
|
220
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
205
221
|
notifyWatchers(this);
|
|
206
222
|
}
|
|
207
223
|
}
|
|
@@ -215,7 +231,7 @@ var Computed = class extends Source {
|
|
|
215
231
|
const wasClean = this.state === CLEAN;
|
|
216
232
|
this.state = level;
|
|
217
233
|
if (wasClean) {
|
|
218
|
-
if (this.observers) for (const o of
|
|
234
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
219
235
|
notifyWatchers(this);
|
|
220
236
|
}
|
|
221
237
|
}
|
|
@@ -254,6 +270,10 @@ var Watcher = class {
|
|
|
254
270
|
this._pending.clear();
|
|
255
271
|
return out;
|
|
256
272
|
}
|
|
273
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
274
|
+
clearPending() {
|
|
275
|
+
this._pending.clear();
|
|
276
|
+
}
|
|
257
277
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
258
278
|
_notify(node) {
|
|
259
279
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -371,14 +391,14 @@ var EffectNode = class {
|
|
|
371
391
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
372
392
|
});
|
|
373
393
|
});
|
|
374
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
394
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
375
395
|
this.watcher = new Watcher(() => enqueue(this));
|
|
376
396
|
this.run();
|
|
377
397
|
this.watcher.watch(this.computed);
|
|
378
398
|
}
|
|
379
399
|
run() {
|
|
380
400
|
if (this.disposed) return;
|
|
381
|
-
this.watcher.
|
|
401
|
+
this.watcher.clearPending();
|
|
382
402
|
try {
|
|
383
403
|
this.computed.get();
|
|
384
404
|
} catch (e) {
|
|
@@ -395,6 +415,7 @@ var EffectNode = class {
|
|
|
395
415
|
this.disposed = true;
|
|
396
416
|
reportReactiveDispose(this.computed);
|
|
397
417
|
this.watcher.unwatch(this.computed);
|
|
418
|
+
this.computed.dispose();
|
|
398
419
|
disposeOwner(this.owner);
|
|
399
420
|
}
|
|
400
421
|
};
|
|
@@ -429,13 +450,15 @@ function createSignal(value, options) {
|
|
|
429
450
|
},
|
|
430
451
|
enumerable: false
|
|
431
452
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
453
|
+
if (isObserved()) {
|
|
454
|
+
reportReactiveNode({
|
|
455
|
+
kind: "signal",
|
|
456
|
+
node: state,
|
|
457
|
+
handle: read,
|
|
458
|
+
name: options?.name,
|
|
459
|
+
set: write
|
|
460
|
+
});
|
|
461
|
+
}
|
|
439
462
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
440
463
|
return [read, write];
|
|
441
464
|
}
|
|
@@ -434,7 +434,7 @@ var Observable = class extends Subscription {
|
|
|
434
434
|
|
|
435
435
|
// src/lib/signal/graph/detect.ts
|
|
436
436
|
var __BROWSER_PROD__ = typeof window === "undefined" ? false : window.__FLUIXI_PROD__ === true;
|
|
437
|
-
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ :
|
|
437
|
+
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ : process.env.NODE_ENV !== "production";
|
|
438
438
|
var $SIGNAL = /* @__PURE__ */ Symbol.for("signal");
|
|
439
439
|
var $MEMO = /* @__PURE__ */ Symbol.for("memo");
|
|
440
440
|
var $RESOURCE = /* @__PURE__ */ Symbol.for("resource");
|
|
@@ -468,7 +468,7 @@ function makeArrayFlat(values) {
|
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
// src/version.generated.ts
|
|
471
|
-
var VERSION = "1.0.0-alpha.
|
|
471
|
+
var VERSION = "1.0.0-alpha.106";
|
|
472
472
|
|
|
473
473
|
// src/lib/signal/graph/state.ts
|
|
474
474
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -610,6 +610,7 @@ var Computed = class extends Source {
|
|
|
610
610
|
super();
|
|
611
611
|
this._threw = false;
|
|
612
612
|
this._initialized = false;
|
|
613
|
+
this._disposed = false;
|
|
613
614
|
this.state = DIRTY;
|
|
614
615
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
615
616
|
this.sources = null;
|
|
@@ -625,8 +626,23 @@ var Computed = class extends Source {
|
|
|
625
626
|
if (this._threw) throw this._error;
|
|
626
627
|
return this._value;
|
|
627
628
|
}
|
|
629
|
+
/**
|
|
630
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
631
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
632
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
633
|
+
* The last value stays readable; the node simply never updates again.
|
|
634
|
+
*/
|
|
635
|
+
dispose() {
|
|
636
|
+
if (this._disposed) return;
|
|
637
|
+
this._disposed = true;
|
|
638
|
+
if (this.sources) {
|
|
639
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
640
|
+
this.sources = null;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
628
643
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
629
644
|
updateIfNecessary() {
|
|
645
|
+
if (this._disposed) return;
|
|
630
646
|
if (this.state === CHECK) {
|
|
631
647
|
if (this.sources) {
|
|
632
648
|
for (const s of this.sources) {
|
|
@@ -670,7 +686,7 @@ var Computed = class extends Source {
|
|
|
670
686
|
reportReactiveRun(this);
|
|
671
687
|
if (changed) {
|
|
672
688
|
this.version++;
|
|
673
|
-
if (this.observers) for (const o of
|
|
689
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
674
690
|
notifyWatchers(this);
|
|
675
691
|
}
|
|
676
692
|
}
|
|
@@ -684,7 +700,7 @@ var Computed = class extends Source {
|
|
|
684
700
|
const wasClean = this.state === CLEAN;
|
|
685
701
|
this.state = level;
|
|
686
702
|
if (wasClean) {
|
|
687
|
-
if (this.observers) for (const o of
|
|
703
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
688
704
|
notifyWatchers(this);
|
|
689
705
|
}
|
|
690
706
|
}
|
|
@@ -723,6 +739,10 @@ var Watcher = class {
|
|
|
723
739
|
this._pending.clear();
|
|
724
740
|
return out;
|
|
725
741
|
}
|
|
742
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
743
|
+
clearPending() {
|
|
744
|
+
this._pending.clear();
|
|
745
|
+
}
|
|
726
746
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
727
747
|
_notify(node) {
|
|
728
748
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -833,14 +853,14 @@ var EffectNode = class {
|
|
|
833
853
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
834
854
|
});
|
|
835
855
|
});
|
|
836
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
856
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
837
857
|
this.watcher = new Watcher(() => enqueue(this));
|
|
838
858
|
this.run();
|
|
839
859
|
this.watcher.watch(this.computed);
|
|
840
860
|
}
|
|
841
861
|
run() {
|
|
842
862
|
if (this.disposed) return;
|
|
843
|
-
this.watcher.
|
|
863
|
+
this.watcher.clearPending();
|
|
844
864
|
try {
|
|
845
865
|
this.computed.get();
|
|
846
866
|
} catch (e) {
|
|
@@ -857,6 +877,7 @@ var EffectNode = class {
|
|
|
857
877
|
this.disposed = true;
|
|
858
878
|
reportReactiveDispose(this.computed);
|
|
859
879
|
this.watcher.unwatch(this.computed);
|
|
880
|
+
this.computed.dispose();
|
|
860
881
|
disposeOwner(this.owner);
|
|
861
882
|
}
|
|
862
883
|
};
|
|
@@ -895,13 +916,15 @@ function createSignal(value, options) {
|
|
|
895
916
|
},
|
|
896
917
|
enumerable: false
|
|
897
918
|
});
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
919
|
+
if (isObserved()) {
|
|
920
|
+
reportReactiveNode({
|
|
921
|
+
kind: "signal",
|
|
922
|
+
node: state,
|
|
923
|
+
handle: read,
|
|
924
|
+
name: options?.name,
|
|
925
|
+
set: write
|
|
926
|
+
});
|
|
927
|
+
}
|
|
905
928
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
906
929
|
return [read, write];
|
|
907
930
|
}
|
|
@@ -925,8 +948,11 @@ function createMemo(fn, value, options) {
|
|
|
925
948
|
const read = (() => c.get());
|
|
926
949
|
Object.defineProperty(read, $SIGNAL2, { value: true, enumerable: true });
|
|
927
950
|
Object.defineProperty(read, $MEMO2, { value: true, enumerable: true });
|
|
928
|
-
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
929
|
-
|
|
951
|
+
if (isObserved()) reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
952
|
+
onCleanup(() => {
|
|
953
|
+
c.dispose();
|
|
954
|
+
if (isObserved()) reportReactiveDispose(c);
|
|
955
|
+
});
|
|
930
956
|
return read;
|
|
931
957
|
}
|
|
932
958
|
function createEffect(fn, value, options) {
|
|
@@ -356,7 +356,7 @@ var Observable = class extends Subscription {
|
|
|
356
356
|
|
|
357
357
|
// src/lib/signal/graph/detect.ts
|
|
358
358
|
var __BROWSER_PROD__ = typeof window === "undefined" ? false : window.__FLUIXI_PROD__ === true;
|
|
359
|
-
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ :
|
|
359
|
+
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ : process.env.NODE_ENV !== "production";
|
|
360
360
|
var $SIGNAL = /* @__PURE__ */ Symbol.for("signal");
|
|
361
361
|
var $MEMO = /* @__PURE__ */ Symbol.for("memo");
|
|
362
362
|
var $RESOURCE = /* @__PURE__ */ Symbol.for("resource");
|
|
@@ -390,7 +390,7 @@ function makeArrayFlat(values) {
|
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
// src/version.generated.ts
|
|
393
|
-
var VERSION = "1.0.0-alpha.
|
|
393
|
+
var VERSION = "1.0.0-alpha.106";
|
|
394
394
|
|
|
395
395
|
// src/lib/signal/graph/state.ts
|
|
396
396
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -532,6 +532,7 @@ var Computed = class extends Source {
|
|
|
532
532
|
super();
|
|
533
533
|
this._threw = false;
|
|
534
534
|
this._initialized = false;
|
|
535
|
+
this._disposed = false;
|
|
535
536
|
this.state = DIRTY;
|
|
536
537
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
537
538
|
this.sources = null;
|
|
@@ -547,8 +548,23 @@ var Computed = class extends Source {
|
|
|
547
548
|
if (this._threw) throw this._error;
|
|
548
549
|
return this._value;
|
|
549
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
553
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
554
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
555
|
+
* The last value stays readable; the node simply never updates again.
|
|
556
|
+
*/
|
|
557
|
+
dispose() {
|
|
558
|
+
if (this._disposed) return;
|
|
559
|
+
this._disposed = true;
|
|
560
|
+
if (this.sources) {
|
|
561
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
562
|
+
this.sources = null;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
550
565
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
551
566
|
updateIfNecessary() {
|
|
567
|
+
if (this._disposed) return;
|
|
552
568
|
if (this.state === CHECK) {
|
|
553
569
|
if (this.sources) {
|
|
554
570
|
for (const s of this.sources) {
|
|
@@ -592,7 +608,7 @@ var Computed = class extends Source {
|
|
|
592
608
|
reportReactiveRun(this);
|
|
593
609
|
if (changed) {
|
|
594
610
|
this.version++;
|
|
595
|
-
if (this.observers) for (const o of
|
|
611
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
596
612
|
notifyWatchers(this);
|
|
597
613
|
}
|
|
598
614
|
}
|
|
@@ -606,7 +622,7 @@ var Computed = class extends Source {
|
|
|
606
622
|
const wasClean = this.state === CLEAN;
|
|
607
623
|
this.state = level;
|
|
608
624
|
if (wasClean) {
|
|
609
|
-
if (this.observers) for (const o of
|
|
625
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
610
626
|
notifyWatchers(this);
|
|
611
627
|
}
|
|
612
628
|
}
|
|
@@ -645,6 +661,10 @@ var Watcher = class {
|
|
|
645
661
|
this._pending.clear();
|
|
646
662
|
return out;
|
|
647
663
|
}
|
|
664
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
665
|
+
clearPending() {
|
|
666
|
+
this._pending.clear();
|
|
667
|
+
}
|
|
648
668
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
649
669
|
_notify(node) {
|
|
650
670
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -755,14 +775,14 @@ var EffectNode = class {
|
|
|
755
775
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
756
776
|
});
|
|
757
777
|
});
|
|
758
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
778
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
759
779
|
this.watcher = new Watcher(() => enqueue(this));
|
|
760
780
|
this.run();
|
|
761
781
|
this.watcher.watch(this.computed);
|
|
762
782
|
}
|
|
763
783
|
run() {
|
|
764
784
|
if (this.disposed) return;
|
|
765
|
-
this.watcher.
|
|
785
|
+
this.watcher.clearPending();
|
|
766
786
|
try {
|
|
767
787
|
this.computed.get();
|
|
768
788
|
} catch (e) {
|
|
@@ -779,6 +799,7 @@ var EffectNode = class {
|
|
|
779
799
|
this.disposed = true;
|
|
780
800
|
reportReactiveDispose(this.computed);
|
|
781
801
|
this.watcher.unwatch(this.computed);
|
|
802
|
+
this.computed.dispose();
|
|
782
803
|
disposeOwner(this.owner);
|
|
783
804
|
}
|
|
784
805
|
};
|
|
@@ -817,13 +838,15 @@ function createSignal(value, options) {
|
|
|
817
838
|
},
|
|
818
839
|
enumerable: false
|
|
819
840
|
});
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
841
|
+
if (isObserved()) {
|
|
842
|
+
reportReactiveNode({
|
|
843
|
+
kind: "signal",
|
|
844
|
+
node: state,
|
|
845
|
+
handle: read,
|
|
846
|
+
name: options?.name,
|
|
847
|
+
set: write
|
|
848
|
+
});
|
|
849
|
+
}
|
|
827
850
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
828
851
|
return [read, write];
|
|
829
852
|
}
|
|
@@ -847,8 +870,11 @@ function createMemo(fn, value, options) {
|
|
|
847
870
|
const read = (() => c.get());
|
|
848
871
|
Object.defineProperty(read, $SIGNAL2, { value: true, enumerable: true });
|
|
849
872
|
Object.defineProperty(read, $MEMO2, { value: true, enumerable: true });
|
|
850
|
-
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
851
|
-
|
|
873
|
+
if (isObserved()) reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
874
|
+
onCleanup(() => {
|
|
875
|
+
c.dispose();
|
|
876
|
+
if (isObserved()) reportReactiveDispose(c);
|
|
877
|
+
});
|
|
852
878
|
return read;
|
|
853
879
|
}
|
|
854
880
|
function createEffect(fn, value, options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/reactive v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/reactive v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -45,7 +45,7 @@ __export(utilities_exports, {
|
|
|
45
45
|
module.exports = __toCommonJS(utilities_exports);
|
|
46
46
|
|
|
47
47
|
// src/version.generated.ts
|
|
48
|
-
var VERSION = "1.0.0-alpha.
|
|
48
|
+
var VERSION = "1.0.0-alpha.106";
|
|
49
49
|
|
|
50
50
|
// src/lib/signal/graph/state.ts
|
|
51
51
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -187,6 +187,7 @@ var Computed = class extends Source {
|
|
|
187
187
|
super();
|
|
188
188
|
this._threw = false;
|
|
189
189
|
this._initialized = false;
|
|
190
|
+
this._disposed = false;
|
|
190
191
|
this.state = DIRTY;
|
|
191
192
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
192
193
|
this.sources = null;
|
|
@@ -202,8 +203,23 @@ var Computed = class extends Source {
|
|
|
202
203
|
if (this._threw) throw this._error;
|
|
203
204
|
return this._value;
|
|
204
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
208
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
209
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
210
|
+
* The last value stays readable; the node simply never updates again.
|
|
211
|
+
*/
|
|
212
|
+
dispose() {
|
|
213
|
+
if (this._disposed) return;
|
|
214
|
+
this._disposed = true;
|
|
215
|
+
if (this.sources) {
|
|
216
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
217
|
+
this.sources = null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
205
220
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
206
221
|
updateIfNecessary() {
|
|
222
|
+
if (this._disposed) return;
|
|
207
223
|
if (this.state === CHECK) {
|
|
208
224
|
if (this.sources) {
|
|
209
225
|
for (const s of this.sources) {
|
|
@@ -247,7 +263,7 @@ var Computed = class extends Source {
|
|
|
247
263
|
reportReactiveRun(this);
|
|
248
264
|
if (changed) {
|
|
249
265
|
this.version++;
|
|
250
|
-
if (this.observers) for (const o of
|
|
266
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
251
267
|
notifyWatchers(this);
|
|
252
268
|
}
|
|
253
269
|
}
|
|
@@ -261,7 +277,7 @@ var Computed = class extends Source {
|
|
|
261
277
|
const wasClean = this.state === CLEAN;
|
|
262
278
|
this.state = level;
|
|
263
279
|
if (wasClean) {
|
|
264
|
-
if (this.observers) for (const o of
|
|
280
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
265
281
|
notifyWatchers(this);
|
|
266
282
|
}
|
|
267
283
|
}
|
|
@@ -300,6 +316,10 @@ var Watcher = class {
|
|
|
300
316
|
this._pending.clear();
|
|
301
317
|
return out;
|
|
302
318
|
}
|
|
319
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
320
|
+
clearPending() {
|
|
321
|
+
this._pending.clear();
|
|
322
|
+
}
|
|
303
323
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
304
324
|
_notify(node) {
|
|
305
325
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -410,14 +430,14 @@ var EffectNode = class {
|
|
|
410
430
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
411
431
|
});
|
|
412
432
|
});
|
|
413
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
433
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
414
434
|
this.watcher = new Watcher(() => enqueue(this));
|
|
415
435
|
this.run();
|
|
416
436
|
this.watcher.watch(this.computed);
|
|
417
437
|
}
|
|
418
438
|
run() {
|
|
419
439
|
if (this.disposed) return;
|
|
420
|
-
this.watcher.
|
|
440
|
+
this.watcher.clearPending();
|
|
421
441
|
try {
|
|
422
442
|
this.computed.get();
|
|
423
443
|
} catch (e) {
|
|
@@ -434,6 +454,7 @@ var EffectNode = class {
|
|
|
434
454
|
this.disposed = true;
|
|
435
455
|
reportReactiveDispose(this.computed);
|
|
436
456
|
this.watcher.unwatch(this.computed);
|
|
457
|
+
this.computed.dispose();
|
|
437
458
|
disposeOwner(this.owner);
|
|
438
459
|
}
|
|
439
460
|
};
|
|
@@ -472,13 +493,15 @@ function createSignal(value, options) {
|
|
|
472
493
|
},
|
|
473
494
|
enumerable: false
|
|
474
495
|
});
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
496
|
+
if (isObserved()) {
|
|
497
|
+
reportReactiveNode({
|
|
498
|
+
kind: "signal",
|
|
499
|
+
node: state,
|
|
500
|
+
handle: read,
|
|
501
|
+
name: options?.name,
|
|
502
|
+
set: write
|
|
503
|
+
});
|
|
504
|
+
}
|
|
482
505
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
483
506
|
return [read, write];
|
|
484
507
|
}
|
|
@@ -502,8 +525,11 @@ function createMemo(fn, value, options) {
|
|
|
502
525
|
const read = (() => c.get());
|
|
503
526
|
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
504
527
|
Object.defineProperty(read, $MEMO, { value: true, enumerable: true });
|
|
505
|
-
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
506
|
-
|
|
528
|
+
if (isObserved()) reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
529
|
+
onCleanup(() => {
|
|
530
|
+
c.dispose();
|
|
531
|
+
if (isObserved()) reportReactiveDispose(c);
|
|
532
|
+
});
|
|
507
533
|
return read;
|
|
508
534
|
}
|
|
509
535
|
function createEffect(fn, value, options) {
|