@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
|
@@ -26,7 +26,7 @@ __export(debounced_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(debounced_exports);
|
|
27
27
|
|
|
28
28
|
// src/version.generated.ts
|
|
29
|
-
var VERSION = "1.0.0-alpha.
|
|
29
|
+
var VERSION = "1.0.0-alpha.106";
|
|
30
30
|
|
|
31
31
|
// src/lib/signal/graph/state.ts
|
|
32
32
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -168,6 +168,7 @@ var Computed = class extends Source {
|
|
|
168
168
|
super();
|
|
169
169
|
this._threw = false;
|
|
170
170
|
this._initialized = false;
|
|
171
|
+
this._disposed = false;
|
|
171
172
|
this.state = DIRTY;
|
|
172
173
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
173
174
|
this.sources = null;
|
|
@@ -183,8 +184,23 @@ var Computed = class extends Source {
|
|
|
183
184
|
if (this._threw) throw this._error;
|
|
184
185
|
return this._value;
|
|
185
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
189
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
190
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
191
|
+
* The last value stays readable; the node simply never updates again.
|
|
192
|
+
*/
|
|
193
|
+
dispose() {
|
|
194
|
+
if (this._disposed) return;
|
|
195
|
+
this._disposed = true;
|
|
196
|
+
if (this.sources) {
|
|
197
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
198
|
+
this.sources = null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
186
201
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
187
202
|
updateIfNecessary() {
|
|
203
|
+
if (this._disposed) return;
|
|
188
204
|
if (this.state === CHECK) {
|
|
189
205
|
if (this.sources) {
|
|
190
206
|
for (const s of this.sources) {
|
|
@@ -228,7 +244,7 @@ var Computed = class extends Source {
|
|
|
228
244
|
reportReactiveRun(this);
|
|
229
245
|
if (changed) {
|
|
230
246
|
this.version++;
|
|
231
|
-
if (this.observers) for (const o of
|
|
247
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
232
248
|
notifyWatchers(this);
|
|
233
249
|
}
|
|
234
250
|
}
|
|
@@ -242,7 +258,7 @@ var Computed = class extends Source {
|
|
|
242
258
|
const wasClean = this.state === CLEAN;
|
|
243
259
|
this.state = level;
|
|
244
260
|
if (wasClean) {
|
|
245
|
-
if (this.observers) for (const o of
|
|
261
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
246
262
|
notifyWatchers(this);
|
|
247
263
|
}
|
|
248
264
|
}
|
|
@@ -281,6 +297,10 @@ var Watcher = class {
|
|
|
281
297
|
this._pending.clear();
|
|
282
298
|
return out;
|
|
283
299
|
}
|
|
300
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
301
|
+
clearPending() {
|
|
302
|
+
this._pending.clear();
|
|
303
|
+
}
|
|
284
304
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
285
305
|
_notify(node) {
|
|
286
306
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -398,14 +418,14 @@ var EffectNode = class {
|
|
|
398
418
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
399
419
|
});
|
|
400
420
|
});
|
|
401
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
421
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
402
422
|
this.watcher = new Watcher(() => enqueue(this));
|
|
403
423
|
this.run();
|
|
404
424
|
this.watcher.watch(this.computed);
|
|
405
425
|
}
|
|
406
426
|
run() {
|
|
407
427
|
if (this.disposed) return;
|
|
408
|
-
this.watcher.
|
|
428
|
+
this.watcher.clearPending();
|
|
409
429
|
try {
|
|
410
430
|
this.computed.get();
|
|
411
431
|
} catch (e) {
|
|
@@ -422,6 +442,7 @@ var EffectNode = class {
|
|
|
422
442
|
this.disposed = true;
|
|
423
443
|
reportReactiveDispose(this.computed);
|
|
424
444
|
this.watcher.unwatch(this.computed);
|
|
445
|
+
this.computed.dispose();
|
|
425
446
|
disposeOwner(this.owner);
|
|
426
447
|
}
|
|
427
448
|
};
|
|
@@ -456,13 +477,15 @@ function createSignal(value, options) {
|
|
|
456
477
|
},
|
|
457
478
|
enumerable: false
|
|
458
479
|
});
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
480
|
+
if (isObserved()) {
|
|
481
|
+
reportReactiveNode({
|
|
482
|
+
kind: "signal",
|
|
483
|
+
node: state,
|
|
484
|
+
handle: read,
|
|
485
|
+
name: options?.name,
|
|
486
|
+
set: write
|
|
487
|
+
});
|
|
488
|
+
}
|
|
466
489
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
467
490
|
return [read, write];
|
|
468
491
|
}
|
|
@@ -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
|
}
|
|
@@ -27,7 +27,7 @@ __export(derived_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(derived_exports);
|
|
28
28
|
|
|
29
29
|
// src/version.generated.ts
|
|
30
|
-
var VERSION = "1.0.0-alpha.
|
|
30
|
+
var VERSION = "1.0.0-alpha.106";
|
|
31
31
|
|
|
32
32
|
// src/lib/signal/graph/state.ts
|
|
33
33
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -169,6 +169,7 @@ var Computed = class extends Source {
|
|
|
169
169
|
super();
|
|
170
170
|
this._threw = false;
|
|
171
171
|
this._initialized = false;
|
|
172
|
+
this._disposed = false;
|
|
172
173
|
this.state = DIRTY;
|
|
173
174
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
174
175
|
this.sources = null;
|
|
@@ -184,8 +185,23 @@ var Computed = class extends Source {
|
|
|
184
185
|
if (this._threw) throw this._error;
|
|
185
186
|
return this._value;
|
|
186
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
190
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
191
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
192
|
+
* The last value stays readable; the node simply never updates again.
|
|
193
|
+
*/
|
|
194
|
+
dispose() {
|
|
195
|
+
if (this._disposed) return;
|
|
196
|
+
this._disposed = true;
|
|
197
|
+
if (this.sources) {
|
|
198
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
199
|
+
this.sources = null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
187
202
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
188
203
|
updateIfNecessary() {
|
|
204
|
+
if (this._disposed) return;
|
|
189
205
|
if (this.state === CHECK) {
|
|
190
206
|
if (this.sources) {
|
|
191
207
|
for (const s of this.sources) {
|
|
@@ -229,7 +245,7 @@ var Computed = class extends Source {
|
|
|
229
245
|
reportReactiveRun(this);
|
|
230
246
|
if (changed) {
|
|
231
247
|
this.version++;
|
|
232
|
-
if (this.observers) for (const o of
|
|
248
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
233
249
|
notifyWatchers(this);
|
|
234
250
|
}
|
|
235
251
|
}
|
|
@@ -243,7 +259,7 @@ var Computed = class extends Source {
|
|
|
243
259
|
const wasClean = this.state === CLEAN;
|
|
244
260
|
this.state = level;
|
|
245
261
|
if (wasClean) {
|
|
246
|
-
if (this.observers) for (const o of
|
|
262
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
247
263
|
notifyWatchers(this);
|
|
248
264
|
}
|
|
249
265
|
}
|
|
@@ -282,6 +298,10 @@ var Watcher = class {
|
|
|
282
298
|
this._pending.clear();
|
|
283
299
|
return out;
|
|
284
300
|
}
|
|
301
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
302
|
+
clearPending() {
|
|
303
|
+
this._pending.clear();
|
|
304
|
+
}
|
|
285
305
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
286
306
|
_notify(node) {
|
|
287
307
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -382,14 +402,14 @@ var EffectNode = class {
|
|
|
382
402
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
383
403
|
});
|
|
384
404
|
});
|
|
385
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
405
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
386
406
|
this.watcher = new Watcher(() => enqueue(this));
|
|
387
407
|
this.run();
|
|
388
408
|
this.watcher.watch(this.computed);
|
|
389
409
|
}
|
|
390
410
|
run() {
|
|
391
411
|
if (this.disposed) return;
|
|
392
|
-
this.watcher.
|
|
412
|
+
this.watcher.clearPending();
|
|
393
413
|
try {
|
|
394
414
|
this.computed.get();
|
|
395
415
|
} catch (e) {
|
|
@@ -406,6 +426,7 @@ var EffectNode = class {
|
|
|
406
426
|
this.disposed = true;
|
|
407
427
|
reportReactiveDispose(this.computed);
|
|
408
428
|
this.watcher.unwatch(this.computed);
|
|
429
|
+
this.computed.dispose();
|
|
409
430
|
disposeOwner(this.owner);
|
|
410
431
|
}
|
|
411
432
|
};
|
|
@@ -440,13 +461,15 @@ function createSignal(value, options) {
|
|
|
440
461
|
},
|
|
441
462
|
enumerable: false
|
|
442
463
|
});
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
464
|
+
if (isObserved()) {
|
|
465
|
+
reportReactiveNode({
|
|
466
|
+
kind: "signal",
|
|
467
|
+
node: state,
|
|
468
|
+
handle: read,
|
|
469
|
+
name: options?.name,
|
|
470
|
+
set: write
|
|
471
|
+
});
|
|
472
|
+
}
|
|
450
473
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
451
474
|
return [read, write];
|
|
452
475
|
}
|
|
@@ -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;
|
|
@@ -354,14 +374,14 @@ var EffectNode = class {
|
|
|
354
374
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
355
375
|
});
|
|
356
376
|
});
|
|
357
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
377
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
358
378
|
this.watcher = new Watcher(() => enqueue(this));
|
|
359
379
|
this.run();
|
|
360
380
|
this.watcher.watch(this.computed);
|
|
361
381
|
}
|
|
362
382
|
run() {
|
|
363
383
|
if (this.disposed) return;
|
|
364
|
-
this.watcher.
|
|
384
|
+
this.watcher.clearPending();
|
|
365
385
|
try {
|
|
366
386
|
this.computed.get();
|
|
367
387
|
} catch (e) {
|
|
@@ -378,6 +398,7 @@ var EffectNode = class {
|
|
|
378
398
|
this.disposed = true;
|
|
379
399
|
reportReactiveDispose(this.computed);
|
|
380
400
|
this.watcher.unwatch(this.computed);
|
|
401
|
+
this.computed.dispose();
|
|
381
402
|
disposeOwner(this.owner);
|
|
382
403
|
}
|
|
383
404
|
};
|
|
@@ -412,13 +433,15 @@ function createSignal(value, options) {
|
|
|
412
433
|
},
|
|
413
434
|
enumerable: false
|
|
414
435
|
});
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
436
|
+
if (isObserved()) {
|
|
437
|
+
reportReactiveNode({
|
|
438
|
+
kind: "signal",
|
|
439
|
+
node: state,
|
|
440
|
+
handle: read,
|
|
441
|
+
name: options?.name,
|
|
442
|
+
set: write
|
|
443
|
+
});
|
|
444
|
+
}
|
|
422
445
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
423
446
|
return [read, write];
|
|
424
447
|
}
|
|
@@ -32,7 +32,7 @@ __export(detect_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(detect_exports);
|
|
34
34
|
var __BROWSER_PROD__ = typeof window === "undefined" ? false : window.__FLUIXI_PROD__ === true;
|
|
35
|
-
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ :
|
|
35
|
+
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ : process.env.NODE_ENV !== "production";
|
|
36
36
|
var $SIGNAL = /* @__PURE__ */ Symbol.for("signal");
|
|
37
37
|
var $MEMO = /* @__PURE__ */ Symbol.for("memo");
|
|
38
38
|
var $RESOURCE = /* @__PURE__ */ Symbol.for("resource");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/lib/signal/graph/detect.ts
|
|
2
2
|
var __BROWSER_PROD__ = typeof window === "undefined" ? false : window.__FLUIXI_PROD__ === true;
|
|
3
|
-
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ :
|
|
3
|
+
var __DEV__ = typeof process === "undefined" ? __BROWSER_PROD__ : process.env.NODE_ENV !== "production";
|
|
4
4
|
var $SIGNAL = /* @__PURE__ */ Symbol.for("signal");
|
|
5
5
|
var $MEMO = /* @__PURE__ */ Symbol.for("memo");
|
|
6
6
|
var $RESOURCE = /* @__PURE__ */ Symbol.for("resource");
|
|
@@ -27,7 +27,7 @@ __export(error_boundary_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(error_boundary_exports);
|
|
28
28
|
|
|
29
29
|
// src/version.generated.ts
|
|
30
|
-
var VERSION = "1.0.0-alpha.
|
|
30
|
+
var VERSION = "1.0.0-alpha.106";
|
|
31
31
|
|
|
32
32
|
// src/lib/signal/graph/state.ts
|
|
33
33
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -280,13 +280,15 @@ function createSignal(value, options) {
|
|
|
280
280
|
},
|
|
281
281
|
enumerable: false
|
|
282
282
|
});
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
283
|
+
if (isObserved()) {
|
|
284
|
+
reportReactiveNode({
|
|
285
|
+
kind: "signal",
|
|
286
|
+
node: state,
|
|
287
|
+
handle: read,
|
|
288
|
+
name: options?.name,
|
|
289
|
+
set: write
|
|
290
|
+
});
|
|
291
|
+
}
|
|
290
292
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
291
293
|
return [read, write];
|
|
292
294
|
}
|
|
@@ -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];
|
|
@@ -252,13 +252,15 @@ function createSignal(value, options) {
|
|
|
252
252
|
},
|
|
253
253
|
enumerable: false
|
|
254
254
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
255
|
+
if (isObserved()) {
|
|
256
|
+
reportReactiveNode({
|
|
257
|
+
kind: "signal",
|
|
258
|
+
node: state,
|
|
259
|
+
handle: read,
|
|
260
|
+
name: options?.name,
|
|
261
|
+
set: write
|
|
262
|
+
});
|
|
263
|
+
}
|
|
262
264
|
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
263
265
|
return [read, write];
|
|
264
266
|
}
|
|
@@ -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;
|
|
@@ -29,7 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(index_exports);
|
|
30
30
|
|
|
31
31
|
// src/version.generated.ts
|
|
32
|
-
var VERSION = "1.0.0-alpha.
|
|
32
|
+
var VERSION = "1.0.0-alpha.106";
|
|
33
33
|
|
|
34
34
|
// src/lib/signal/graph/state.ts
|
|
35
35
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -155,6 +155,7 @@ var Computed = class extends Source {
|
|
|
155
155
|
super();
|
|
156
156
|
this._threw = false;
|
|
157
157
|
this._initialized = false;
|
|
158
|
+
this._disposed = false;
|
|
158
159
|
this.state = DIRTY;
|
|
159
160
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
160
161
|
this.sources = null;
|
|
@@ -170,8 +171,23 @@ var Computed = class extends Source {
|
|
|
170
171
|
if (this._threw) throw this._error;
|
|
171
172
|
return this._value;
|
|
172
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
176
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
177
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
178
|
+
* The last value stays readable; the node simply never updates again.
|
|
179
|
+
*/
|
|
180
|
+
dispose() {
|
|
181
|
+
if (this._disposed) return;
|
|
182
|
+
this._disposed = true;
|
|
183
|
+
if (this.sources) {
|
|
184
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
185
|
+
this.sources = null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
173
188
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
174
189
|
updateIfNecessary() {
|
|
190
|
+
if (this._disposed) return;
|
|
175
191
|
if (this.state === CHECK) {
|
|
176
192
|
if (this.sources) {
|
|
177
193
|
for (const s of this.sources) {
|
|
@@ -215,7 +231,7 @@ var Computed = class extends Source {
|
|
|
215
231
|
reportReactiveRun(this);
|
|
216
232
|
if (changed) {
|
|
217
233
|
this.version++;
|
|
218
|
-
if (this.observers) for (const o of
|
|
234
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
219
235
|
notifyWatchers(this);
|
|
220
236
|
}
|
|
221
237
|
}
|
|
@@ -229,7 +245,7 @@ var Computed = class extends Source {
|
|
|
229
245
|
const wasClean = this.state === CLEAN;
|
|
230
246
|
this.state = level;
|
|
231
247
|
if (wasClean) {
|
|
232
|
-
if (this.observers) for (const o of
|
|
248
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
233
249
|
notifyWatchers(this);
|
|
234
250
|
}
|
|
235
251
|
}
|
|
@@ -268,6 +284,10 @@ var Watcher = class {
|
|
|
268
284
|
this._pending.clear();
|
|
269
285
|
return out;
|
|
270
286
|
}
|
|
287
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
288
|
+
clearPending() {
|
|
289
|
+
this._pending.clear();
|
|
290
|
+
}
|
|
271
291
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
272
292
|
_notify(node) {
|
|
273
293
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -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;
|