@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
|
@@ -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;
|
|
@@ -42,7 +42,7 @@ __export(compat_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(compat_exports);
|
|
43
43
|
|
|
44
44
|
// src/version.generated.ts
|
|
45
|
-
var VERSION = "1.0.0-alpha.
|
|
45
|
+
var VERSION = "1.0.0-alpha.106";
|
|
46
46
|
|
|
47
47
|
// src/lib/signal/graph/state.ts
|
|
48
48
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -184,6 +184,7 @@ var Computed = class extends Source {
|
|
|
184
184
|
super();
|
|
185
185
|
this._threw = false;
|
|
186
186
|
this._initialized = false;
|
|
187
|
+
this._disposed = false;
|
|
187
188
|
this.state = DIRTY;
|
|
188
189
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
189
190
|
this.sources = null;
|
|
@@ -199,8 +200,23 @@ var Computed = class extends Source {
|
|
|
199
200
|
if (this._threw) throw this._error;
|
|
200
201
|
return this._value;
|
|
201
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
205
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
206
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
207
|
+
* The last value stays readable; the node simply never updates again.
|
|
208
|
+
*/
|
|
209
|
+
dispose() {
|
|
210
|
+
if (this._disposed) return;
|
|
211
|
+
this._disposed = true;
|
|
212
|
+
if (this.sources) {
|
|
213
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
214
|
+
this.sources = null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
202
217
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
203
218
|
updateIfNecessary() {
|
|
219
|
+
if (this._disposed) return;
|
|
204
220
|
if (this.state === CHECK) {
|
|
205
221
|
if (this.sources) {
|
|
206
222
|
for (const s of this.sources) {
|
|
@@ -244,7 +260,7 @@ var Computed = class extends Source {
|
|
|
244
260
|
reportReactiveRun(this);
|
|
245
261
|
if (changed) {
|
|
246
262
|
this.version++;
|
|
247
|
-
if (this.observers) for (const o of
|
|
263
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
248
264
|
notifyWatchers(this);
|
|
249
265
|
}
|
|
250
266
|
}
|
|
@@ -258,7 +274,7 @@ var Computed = class extends Source {
|
|
|
258
274
|
const wasClean = this.state === CLEAN;
|
|
259
275
|
this.state = level;
|
|
260
276
|
if (wasClean) {
|
|
261
|
-
if (this.observers) for (const o of
|
|
277
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
262
278
|
notifyWatchers(this);
|
|
263
279
|
}
|
|
264
280
|
}
|
|
@@ -297,6 +313,10 @@ var Watcher = class {
|
|
|
297
313
|
this._pending.clear();
|
|
298
314
|
return out;
|
|
299
315
|
}
|
|
316
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
317
|
+
clearPending() {
|
|
318
|
+
this._pending.clear();
|
|
319
|
+
}
|
|
300
320
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
301
321
|
_notify(node) {
|
|
302
322
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -440,14 +460,14 @@ var EffectNode = class {
|
|
|
440
460
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
441
461
|
});
|
|
442
462
|
});
|
|
443
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
463
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
444
464
|
this.watcher = new Watcher(() => enqueue(this));
|
|
445
465
|
this.run();
|
|
446
466
|
this.watcher.watch(this.computed);
|
|
447
467
|
}
|
|
448
468
|
run() {
|
|
449
469
|
if (this.disposed) return;
|
|
450
|
-
this.watcher.
|
|
470
|
+
this.watcher.clearPending();
|
|
451
471
|
try {
|
|
452
472
|
this.computed.get();
|
|
453
473
|
} catch (e) {
|
|
@@ -464,6 +484,7 @@ var EffectNode = class {
|
|
|
464
484
|
this.disposed = true;
|
|
465
485
|
reportReactiveDispose(this.computed);
|
|
466
486
|
this.watcher.unwatch(this.computed);
|
|
487
|
+
this.computed.dispose();
|
|
467
488
|
disposeOwner(this.owner);
|
|
468
489
|
}
|
|
469
490
|
};
|
|
@@ -502,13 +523,15 @@ function createSignal(value, options) {
|
|
|
502
523
|
},
|
|
503
524
|
enumerable: false
|
|
504
525
|
});
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
526
|
+
if (isObserved()) {
|
|
527
|
+
reportReactiveNode({
|
|
528
|
+
kind: "signal",
|
|
529
|
+
node: state,
|
|
530
|
+
handle: read,
|
|
531
|
+
name: options?.name,
|
|
532
|
+
set: write
|
|
533
|
+
});
|
|
534
|
+
}
|
|
512
535
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
513
536
|
return [read, write];
|
|
514
537
|
}
|
|
@@ -532,8 +555,11 @@ function createMemo(fn, value, options) {
|
|
|
532
555
|
const read = (() => c.get());
|
|
533
556
|
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
534
557
|
Object.defineProperty(read, $MEMO, { value: true, enumerable: true });
|
|
535
|
-
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
536
|
-
|
|
558
|
+
if (isObserved()) reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
559
|
+
onCleanup(() => {
|
|
560
|
+
c.dispose();
|
|
561
|
+
if (isObserved()) reportReactiveDispose(c);
|
|
562
|
+
});
|
|
537
563
|
return read;
|
|
538
564
|
}
|
|
539
565
|
function createEffect(fn, value, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/compat.ts"],"names":[],"mappings":"AAkBA,OAAO,EAKL,SAAS,EAKV,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAgBvF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AAClC,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAC3D,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,KAAK,CAAC;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,CAAC;CACb;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/compat.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,13 +57,17 @@ export function createSignal(value, options) {
|
|
|
57
57
|
},
|
|
58
58
|
enumerable: false,
|
|
59
59
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
// The report object is built only when someone is listening: at list scale
|
|
61
|
+
// an unobserved build per signal is creation cost with no reader.
|
|
62
|
+
if (isObserved()) {
|
|
63
|
+
reportReactiveNode({
|
|
64
|
+
kind: 'signal',
|
|
65
|
+
node: state,
|
|
66
|
+
handle: read,
|
|
67
|
+
name: options?.name,
|
|
68
|
+
set: write,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
67
71
|
// A signal goes when its owner does, the same as a memo. A list rebuilt without a key
|
|
68
72
|
// makes one per row per update, and a watcher that is never told keeps every one of them.
|
|
69
73
|
if (isObserved())
|
|
@@ -99,11 +103,16 @@ export function createMemo(fn, value, options) {
|
|
|
99
103
|
// as reactive, caches it as a component, and freezes it -> updates never apply.
|
|
100
104
|
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
101
105
|
Object.defineProperty(read, $MEMO, { value: true, enumerable: true });
|
|
102
|
-
reportReactiveNode({ kind: 'memo', node: c, handle: read, name: options?.name });
|
|
103
|
-
// A memo has no dispose of its own, it goes when its owner does. Without saying so, a
|
|
104
|
-
// list that re-renders leaves every row it ever had in a watcher's graph.
|
|
105
106
|
if (isObserved())
|
|
106
|
-
|
|
107
|
+
reportReactiveNode({ kind: 'memo', node: c, handle: read, name: options?.name });
|
|
108
|
+
// A memo goes when its owner does: unlink it from its sources, or a signal
|
|
109
|
+
// that outlives the list keeps every row it ever had in its observers set.
|
|
110
|
+
// Registered whether or not a watcher is looking; the report itself is not.
|
|
111
|
+
l1onCleanup(() => {
|
|
112
|
+
c.dispose();
|
|
113
|
+
if (isObserved())
|
|
114
|
+
reportReactiveDispose(c);
|
|
115
|
+
});
|
|
107
116
|
return read;
|
|
108
117
|
}
|
|
109
118
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
|
3
3
|
// src/version.generated.ts
|
|
4
|
-
var VERSION = "1.0.0-alpha.
|
|
4
|
+
var VERSION = "1.0.0-alpha.106";
|
|
5
5
|
|
|
6
6
|
// src/lib/signal/graph/state.ts
|
|
7
7
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -143,6 +143,7 @@ var Computed = class extends Source {
|
|
|
143
143
|
super();
|
|
144
144
|
this._threw = false;
|
|
145
145
|
this._initialized = false;
|
|
146
|
+
this._disposed = false;
|
|
146
147
|
this.state = DIRTY;
|
|
147
148
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
148
149
|
this.sources = null;
|
|
@@ -158,8 +159,23 @@ var Computed = class extends Source {
|
|
|
158
159
|
if (this._threw) throw this._error;
|
|
159
160
|
return this._value;
|
|
160
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
164
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
165
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
166
|
+
* The last value stays readable; the node simply never updates again.
|
|
167
|
+
*/
|
|
168
|
+
dispose() {
|
|
169
|
+
if (this._disposed) return;
|
|
170
|
+
this._disposed = true;
|
|
171
|
+
if (this.sources) {
|
|
172
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
173
|
+
this.sources = null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
161
176
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
162
177
|
updateIfNecessary() {
|
|
178
|
+
if (this._disposed) return;
|
|
163
179
|
if (this.state === CHECK) {
|
|
164
180
|
if (this.sources) {
|
|
165
181
|
for (const s of this.sources) {
|
|
@@ -203,7 +219,7 @@ var Computed = class extends Source {
|
|
|
203
219
|
reportReactiveRun(this);
|
|
204
220
|
if (changed) {
|
|
205
221
|
this.version++;
|
|
206
|
-
if (this.observers) for (const o of
|
|
222
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
207
223
|
notifyWatchers(this);
|
|
208
224
|
}
|
|
209
225
|
}
|
|
@@ -217,7 +233,7 @@ var Computed = class extends Source {
|
|
|
217
233
|
const wasClean = this.state === CLEAN;
|
|
218
234
|
this.state = level;
|
|
219
235
|
if (wasClean) {
|
|
220
|
-
if (this.observers) for (const o of
|
|
236
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
221
237
|
notifyWatchers(this);
|
|
222
238
|
}
|
|
223
239
|
}
|
|
@@ -256,6 +272,10 @@ var Watcher = class {
|
|
|
256
272
|
this._pending.clear();
|
|
257
273
|
return out;
|
|
258
274
|
}
|
|
275
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
276
|
+
clearPending() {
|
|
277
|
+
this._pending.clear();
|
|
278
|
+
}
|
|
259
279
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
260
280
|
_notify(node) {
|
|
261
281
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -399,14 +419,14 @@ var EffectNode = class {
|
|
|
399
419
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
400
420
|
});
|
|
401
421
|
});
|
|
402
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
422
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
403
423
|
this.watcher = new Watcher(() => enqueue(this));
|
|
404
424
|
this.run();
|
|
405
425
|
this.watcher.watch(this.computed);
|
|
406
426
|
}
|
|
407
427
|
run() {
|
|
408
428
|
if (this.disposed) return;
|
|
409
|
-
this.watcher.
|
|
429
|
+
this.watcher.clearPending();
|
|
410
430
|
try {
|
|
411
431
|
this.computed.get();
|
|
412
432
|
} catch (e) {
|
|
@@ -423,6 +443,7 @@ var EffectNode = class {
|
|
|
423
443
|
this.disposed = true;
|
|
424
444
|
reportReactiveDispose(this.computed);
|
|
425
445
|
this.watcher.unwatch(this.computed);
|
|
446
|
+
this.computed.dispose();
|
|
426
447
|
disposeOwner(this.owner);
|
|
427
448
|
}
|
|
428
449
|
};
|
|
@@ -461,13 +482,15 @@ function createSignal(value, options) {
|
|
|
461
482
|
},
|
|
462
483
|
enumerable: false
|
|
463
484
|
});
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
485
|
+
if (isObserved()) {
|
|
486
|
+
reportReactiveNode({
|
|
487
|
+
kind: "signal",
|
|
488
|
+
node: state,
|
|
489
|
+
handle: read,
|
|
490
|
+
name: options?.name,
|
|
491
|
+
set: write
|
|
492
|
+
});
|
|
493
|
+
}
|
|
471
494
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
472
495
|
return [read, write];
|
|
473
496
|
}
|
|
@@ -491,8 +514,11 @@ function createMemo(fn, value, options) {
|
|
|
491
514
|
const read = (() => c.get());
|
|
492
515
|
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
493
516
|
Object.defineProperty(read, $MEMO, { value: true, enumerable: true });
|
|
494
|
-
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
495
|
-
|
|
517
|
+
if (isObserved()) reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
518
|
+
onCleanup(() => {
|
|
519
|
+
c.dispose();
|
|
520
|
+
if (isObserved()) reportReactiveDispose(c);
|
|
521
|
+
});
|
|
496
522
|
return read;
|
|
497
523
|
}
|
|
498
524
|
function createEffect(fn, value, options) {
|
|
@@ -25,7 +25,7 @@ __export(context_children_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(context_children_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];
|
|
@@ -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;
|
|
@@ -31,7 +31,7 @@ __export(core_exports, {
|
|
|
31
31
|
module.exports = __toCommonJS(core_exports);
|
|
32
32
|
|
|
33
33
|
// src/version.generated.ts
|
|
34
|
-
var VERSION = "1.0.0-alpha.
|
|
34
|
+
var VERSION = "1.0.0-alpha.106";
|
|
35
35
|
|
|
36
36
|
// src/lib/signal/graph/state.ts
|
|
37
37
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -157,6 +157,7 @@ var Computed = class extends Source {
|
|
|
157
157
|
super();
|
|
158
158
|
this._threw = false;
|
|
159
159
|
this._initialized = false;
|
|
160
|
+
this._disposed = false;
|
|
160
161
|
this.state = DIRTY;
|
|
161
162
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
162
163
|
this.sources = null;
|
|
@@ -172,8 +173,23 @@ var Computed = class extends Source {
|
|
|
172
173
|
if (this._threw) throw this._error;
|
|
173
174
|
return this._value;
|
|
174
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
178
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
179
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
180
|
+
* The last value stays readable; the node simply never updates again.
|
|
181
|
+
*/
|
|
182
|
+
dispose() {
|
|
183
|
+
if (this._disposed) return;
|
|
184
|
+
this._disposed = true;
|
|
185
|
+
if (this.sources) {
|
|
186
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
187
|
+
this.sources = null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
175
190
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
176
191
|
updateIfNecessary() {
|
|
192
|
+
if (this._disposed) return;
|
|
177
193
|
if (this.state === CHECK) {
|
|
178
194
|
if (this.sources) {
|
|
179
195
|
for (const s of this.sources) {
|
|
@@ -217,7 +233,7 @@ var Computed = class extends Source {
|
|
|
217
233
|
reportReactiveRun(this);
|
|
218
234
|
if (changed) {
|
|
219
235
|
this.version++;
|
|
220
|
-
if (this.observers) for (const o of
|
|
236
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
221
237
|
notifyWatchers(this);
|
|
222
238
|
}
|
|
223
239
|
}
|
|
@@ -231,7 +247,7 @@ var Computed = class extends Source {
|
|
|
231
247
|
const wasClean = this.state === CLEAN;
|
|
232
248
|
this.state = level;
|
|
233
249
|
if (wasClean) {
|
|
234
|
-
if (this.observers) for (const o of
|
|
250
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
235
251
|
notifyWatchers(this);
|
|
236
252
|
}
|
|
237
253
|
}
|
|
@@ -270,6 +286,10 @@ var Watcher = class {
|
|
|
270
286
|
this._pending.clear();
|
|
271
287
|
return out;
|
|
272
288
|
}
|
|
289
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
290
|
+
clearPending() {
|
|
291
|
+
this._pending.clear();
|
|
292
|
+
}
|
|
273
293
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
274
294
|
_notify(node) {
|
|
275
295
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -52,6 +52,7 @@ export declare class Computed<T> extends Source {
|
|
|
52
52
|
private _error;
|
|
53
53
|
private _threw;
|
|
54
54
|
private _initialized;
|
|
55
|
+
private _disposed;
|
|
55
56
|
state: NodeState;
|
|
56
57
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
57
58
|
sources: Set<Source> | null;
|
|
@@ -61,6 +62,13 @@ export declare class Computed<T> extends Source {
|
|
|
61
62
|
equals?: ((a: T, b: T) => boolean) | false;
|
|
62
63
|
});
|
|
63
64
|
get(): T;
|
|
65
|
+
/**
|
|
66
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
67
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
68
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
69
|
+
* The last value stays readable; the node simply never updates again.
|
|
70
|
+
*/
|
|
71
|
+
dispose(): void;
|
|
64
72
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
65
73
|
updateIfNecessary(): void;
|
|
66
74
|
private recompute;
|
|
@@ -86,6 +94,8 @@ export declare class Watcher {
|
|
|
86
94
|
unwatch(...nodes: Source[]): void;
|
|
87
95
|
/** Watched nodes that may have changed since the last getPending(). */
|
|
88
96
|
getPending(): Source[];
|
|
97
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
98
|
+
clearPending(): void;
|
|
89
99
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
90
100
|
_notify(node: Source): void;
|
|
91
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH,QAAA,MAAM,KAAK,IAAI,CAAC;AAChB,QAAA,MAAM,KAAK,IAAI,CAAC;AAChB,QAAA,MAAM,KAAK,IAAI,CAAC;AAChB,KAAK,SAAS,GAAG,OAAO,KAAK,GAAG,OAAO,KAAK,GAAG,OAAO,KAAK,CAAC;AAK5D,gFAAgF;AAChF,uBAAe,MAAM;IACnB,0DAA0D;IAE1D,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAQ;IAC5C,yFAAyF;IACzF,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAQ;IACrC,2EAA2E;IAC3E,OAAO,SAAK;IAEZ,yFAAyF;IACzF,iBAAiB,IAAI,IAAI;IAEzB,sEAAsE;IACtE,SAAS,CAAC,KAAK,IAAI,IAAI;CAOxB;AAED,qBAAa,KAAK,CAAC,CAAC,CAAE,SAAQ,MAAM;IAClC,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;gBAEtC,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,KAAK,CAAA;KAAE;IAM9E,GAAG,IAAI,CAAC;IAKR,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAclB,uCAAuC;IACvC,IAAI,IAAI,CAAC;CAGV;AAED,qBAAa,QAAQ,CAAC,CAAC,CAAE,SAAQ,MAAM;IACrC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAS;IAC7B,KAAK,EAAE,SAAS,CAAS;IACzB,yEAAyE;IACzE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;gBAEtC,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,KAAK,CAAA;KAAE;IAMjF,GAAG,IAAI,CAAC;IAWR,4EAA4E;IACnE,iBAAiB,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -91,6 +91,7 @@ export class Computed extends Source {
|
|
|
91
91
|
_error;
|
|
92
92
|
_threw = false;
|
|
93
93
|
_initialized = false;
|
|
94
|
+
_disposed = false;
|
|
94
95
|
state = DIRTY;
|
|
95
96
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
96
97
|
sources = null;
|
|
@@ -112,8 +113,26 @@ export class Computed extends Source {
|
|
|
112
113
|
throw this._error;
|
|
113
114
|
return this._value;
|
|
114
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
118
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
119
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
120
|
+
* The last value stays readable; the node simply never updates again.
|
|
121
|
+
*/
|
|
122
|
+
dispose() {
|
|
123
|
+
if (this._disposed)
|
|
124
|
+
return;
|
|
125
|
+
this._disposed = true;
|
|
126
|
+
if (this.sources) {
|
|
127
|
+
for (const s of this.sources)
|
|
128
|
+
s.observers?.delete(this);
|
|
129
|
+
this.sources = null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
115
132
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
116
133
|
updateIfNecessary() {
|
|
134
|
+
if (this._disposed)
|
|
135
|
+
return;
|
|
117
136
|
if (this.state === CHECK) {
|
|
118
137
|
// Pull each source; if one recomputes to a new value it will have flipped
|
|
119
138
|
// us to DIRTY (markDirty), so stop early.
|
|
@@ -169,8 +188,10 @@ export class Computed extends Source {
|
|
|
169
188
|
if (changed) {
|
|
170
189
|
this.version++;
|
|
171
190
|
// Our value moved -> observers that were merely CHECK must now recompute.
|
|
191
|
+
// Marking runs no user code and never recomputes, so the set is walked
|
|
192
|
+
// as it stands; State.set is the loop that needs a copy, not this one.
|
|
172
193
|
if (this.observers)
|
|
173
|
-
for (const o of
|
|
194
|
+
for (const o of this.observers)
|
|
174
195
|
o.markDirty(DIRTY);
|
|
175
196
|
notifyWatchers(this);
|
|
176
197
|
}
|
|
@@ -187,7 +208,7 @@ export class Computed extends Source {
|
|
|
187
208
|
this.state = level;
|
|
188
209
|
if (wasClean) {
|
|
189
210
|
if (this.observers)
|
|
190
|
-
for (const o of
|
|
211
|
+
for (const o of this.observers)
|
|
191
212
|
o.markDirty(CHECK);
|
|
192
213
|
notifyWatchers(this);
|
|
193
214
|
}
|
|
@@ -236,6 +257,10 @@ export class Watcher {
|
|
|
236
257
|
this._pending.clear();
|
|
237
258
|
return out;
|
|
238
259
|
}
|
|
260
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
261
|
+
clearPending() {
|
|
262
|
+
this._pending.clear();
|
|
263
|
+
}
|
|
239
264
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
240
265
|
_notify(node) {
|
|
241
266
|
if (!this._watched.has(node) || this._pending.has(node))
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
|
3
3
|
// src/version.generated.ts
|
|
4
|
-
var VERSION = "1.0.0-alpha.
|
|
4
|
+
var VERSION = "1.0.0-alpha.106";
|
|
5
5
|
|
|
6
6
|
// src/lib/signal/graph/state.ts
|
|
7
7
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -127,6 +127,7 @@ var Computed = class extends Source {
|
|
|
127
127
|
super();
|
|
128
128
|
this._threw = false;
|
|
129
129
|
this._initialized = false;
|
|
130
|
+
this._disposed = false;
|
|
130
131
|
this.state = DIRTY;
|
|
131
132
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
132
133
|
this.sources = null;
|
|
@@ -142,8 +143,23 @@ var Computed = class extends Source {
|
|
|
142
143
|
if (this._threw) throw this._error;
|
|
143
144
|
return this._value;
|
|
144
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
148
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
149
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
150
|
+
* The last value stays readable; the node simply never updates again.
|
|
151
|
+
*/
|
|
152
|
+
dispose() {
|
|
153
|
+
if (this._disposed) return;
|
|
154
|
+
this._disposed = true;
|
|
155
|
+
if (this.sources) {
|
|
156
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
157
|
+
this.sources = null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
145
160
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
146
161
|
updateIfNecessary() {
|
|
162
|
+
if (this._disposed) return;
|
|
147
163
|
if (this.state === CHECK) {
|
|
148
164
|
if (this.sources) {
|
|
149
165
|
for (const s of this.sources) {
|
|
@@ -187,7 +203,7 @@ var Computed = class extends Source {
|
|
|
187
203
|
reportReactiveRun(this);
|
|
188
204
|
if (changed) {
|
|
189
205
|
this.version++;
|
|
190
|
-
if (this.observers) for (const o of
|
|
206
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
191
207
|
notifyWatchers(this);
|
|
192
208
|
}
|
|
193
209
|
}
|
|
@@ -201,7 +217,7 @@ var Computed = class extends Source {
|
|
|
201
217
|
const wasClean = this.state === CLEAN;
|
|
202
218
|
this.state = level;
|
|
203
219
|
if (wasClean) {
|
|
204
|
-
if (this.observers) for (const o of
|
|
220
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
205
221
|
notifyWatchers(this);
|
|
206
222
|
}
|
|
207
223
|
}
|
|
@@ -240,6 +256,10 @@ var Watcher = class {
|
|
|
240
256
|
this._pending.clear();
|
|
241
257
|
return out;
|
|
242
258
|
}
|
|
259
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
260
|
+
clearPending() {
|
|
261
|
+
this._pending.clear();
|
|
262
|
+
}
|
|
243
263
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
244
264
|
_notify(node) {
|
|
245
265
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|