@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
|
@@ -45,7 +45,7 @@ __export(observe_exports, {
|
|
|
45
45
|
module.exports = __toCommonJS(observe_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];
|
|
@@ -25,7 +25,7 @@ __export(resource_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(resource_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
|
}
|
|
@@ -44,7 +44,7 @@ __export(runtime_exports, {
|
|
|
44
44
|
module.exports = __toCommonJS(runtime_exports);
|
|
45
45
|
|
|
46
46
|
// src/version.generated.ts
|
|
47
|
-
var VERSION = "1.0.0-alpha.
|
|
47
|
+
var VERSION = "1.0.0-alpha.106";
|
|
48
48
|
|
|
49
49
|
// src/lib/signal/graph/state.ts
|
|
50
50
|
var MAJOR = VERSION.split(".")[0];
|
|
@@ -133,6 +133,9 @@ if (typeof hook?.inject === "function") {
|
|
|
133
133
|
} catch {
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
function isObserved() {
|
|
137
|
+
return G.observer != null;
|
|
138
|
+
}
|
|
136
139
|
|
|
137
140
|
// src/lib/signal/graph/core.ts
|
|
138
141
|
var CLEAN = 0;
|
|
@@ -165,6 +168,7 @@ var Computed = class extends Source {
|
|
|
165
168
|
super();
|
|
166
169
|
this._threw = false;
|
|
167
170
|
this._initialized = false;
|
|
171
|
+
this._disposed = false;
|
|
168
172
|
this.state = DIRTY;
|
|
169
173
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
170
174
|
this.sources = null;
|
|
@@ -180,8 +184,23 @@ var Computed = class extends Source {
|
|
|
180
184
|
if (this._threw) throw this._error;
|
|
181
185
|
return this._value;
|
|
182
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
|
+
}
|
|
183
201
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
184
202
|
updateIfNecessary() {
|
|
203
|
+
if (this._disposed) return;
|
|
185
204
|
if (this.state === CHECK) {
|
|
186
205
|
if (this.sources) {
|
|
187
206
|
for (const s of this.sources) {
|
|
@@ -225,7 +244,7 @@ var Computed = class extends Source {
|
|
|
225
244
|
reportReactiveRun(this);
|
|
226
245
|
if (changed) {
|
|
227
246
|
this.version++;
|
|
228
|
-
if (this.observers) for (const o of
|
|
247
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
229
248
|
notifyWatchers(this);
|
|
230
249
|
}
|
|
231
250
|
}
|
|
@@ -239,7 +258,7 @@ var Computed = class extends Source {
|
|
|
239
258
|
const wasClean = this.state === CLEAN;
|
|
240
259
|
this.state = level;
|
|
241
260
|
if (wasClean) {
|
|
242
|
-
if (this.observers) for (const o of
|
|
261
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
243
262
|
notifyWatchers(this);
|
|
244
263
|
}
|
|
245
264
|
}
|
|
@@ -278,6 +297,10 @@ var Watcher = class {
|
|
|
278
297
|
this._pending.clear();
|
|
279
298
|
return out;
|
|
280
299
|
}
|
|
300
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
301
|
+
clearPending() {
|
|
302
|
+
this._pending.clear();
|
|
303
|
+
}
|
|
281
304
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
282
305
|
_notify(node) {
|
|
283
306
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -489,14 +512,14 @@ var EffectNode = class {
|
|
|
489
512
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
490
513
|
});
|
|
491
514
|
});
|
|
492
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
515
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
493
516
|
this.watcher = new Watcher(() => enqueue(this));
|
|
494
517
|
this.run();
|
|
495
518
|
this.watcher.watch(this.computed);
|
|
496
519
|
}
|
|
497
520
|
run() {
|
|
498
521
|
if (this.disposed) return;
|
|
499
|
-
this.watcher.
|
|
522
|
+
this.watcher.clearPending();
|
|
500
523
|
try {
|
|
501
524
|
this.computed.get();
|
|
502
525
|
} catch (e) {
|
|
@@ -513,6 +536,7 @@ var EffectNode = class {
|
|
|
513
536
|
this.disposed = true;
|
|
514
537
|
reportReactiveDispose(this.computed);
|
|
515
538
|
this.watcher.unwatch(this.computed);
|
|
539
|
+
this.computed.dispose();
|
|
516
540
|
disposeOwner(this.owner);
|
|
517
541
|
}
|
|
518
542
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { Computed, Watcher, untrack } from './core.js';
|
|
22
22
|
import { G } from './state.js';
|
|
23
|
-
import { reportReactiveContext, reportReactiveContextCreated, reportReactiveDispose, reportReactiveNode, } from './observe.js';
|
|
23
|
+
import { isObserved, reportReactiveContext, reportReactiveContextCreated, reportReactiveDispose, reportReactiveNode, } from './observe.js';
|
|
24
24
|
/**
|
|
25
25
|
* A child scope of `parent`, attached so the parent's teardown disposes it too.
|
|
26
26
|
*
|
|
@@ -313,7 +313,8 @@ class EffectNode {
|
|
|
313
313
|
// Before the first run, so a watcher counts that run like every later one. A render
|
|
314
314
|
// effect is reported too, marked as plumbing: it is not worth drawing, but a node made
|
|
315
315
|
// inside one has to be able to find its way back to the component that caused it.
|
|
316
|
-
|
|
316
|
+
if (isObserved())
|
|
317
|
+
reportReactiveNode({ kind: 'effect', node: this.computed, handle: this, internal: !report, ...(name ? { name } : {}) });
|
|
317
318
|
// The watcher only schedules; the recompute happens on flush.
|
|
318
319
|
this.watcher = new Watcher(() => enqueue(this));
|
|
319
320
|
this.run(); // initial synchronous run (Solid semantics)
|
|
@@ -322,7 +323,7 @@ class EffectNode {
|
|
|
322
323
|
run() {
|
|
323
324
|
if (this.disposed)
|
|
324
325
|
return;
|
|
325
|
-
this.watcher.
|
|
326
|
+
this.watcher.clearPending(); // clear pending; reading re-arms the watcher
|
|
326
327
|
try {
|
|
327
328
|
this.computed.get(); // recompute if dirty (re-runs the effect body)
|
|
328
329
|
}
|
|
@@ -346,6 +347,7 @@ class EffectNode {
|
|
|
346
347
|
this.disposed = true;
|
|
347
348
|
reportReactiveDispose(this.computed);
|
|
348
349
|
this.watcher.unwatch(this.computed);
|
|
350
|
+
this.computed.dispose();
|
|
349
351
|
disposeOwner(this.owner);
|
|
350
352
|
}
|
|
351
353
|
}
|
|
@@ -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];
|
|
@@ -88,6 +88,9 @@ if (typeof hook?.inject === "function") {
|
|
|
88
88
|
} catch {
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
function isObserved() {
|
|
92
|
+
return G.observer != null;
|
|
93
|
+
}
|
|
91
94
|
|
|
92
95
|
// src/lib/signal/graph/core.ts
|
|
93
96
|
var CLEAN = 0;
|
|
@@ -120,6 +123,7 @@ var Computed = class extends Source {
|
|
|
120
123
|
super();
|
|
121
124
|
this._threw = false;
|
|
122
125
|
this._initialized = false;
|
|
126
|
+
this._disposed = false;
|
|
123
127
|
this.state = DIRTY;
|
|
124
128
|
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
125
129
|
this.sources = null;
|
|
@@ -135,8 +139,23 @@ var Computed = class extends Source {
|
|
|
135
139
|
if (this._threw) throw this._error;
|
|
136
140
|
return this._value;
|
|
137
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Unlink from every source, for good. Without this, a source outlives the
|
|
144
|
+
* computation and keeps it (and everything its function captured) reachable
|
|
145
|
+
* through its observers set: a disposed list row stayed in memory that way.
|
|
146
|
+
* The last value stays readable; the node simply never updates again.
|
|
147
|
+
*/
|
|
148
|
+
dispose() {
|
|
149
|
+
if (this._disposed) return;
|
|
150
|
+
this._disposed = true;
|
|
151
|
+
if (this.sources) {
|
|
152
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
153
|
+
this.sources = null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
138
156
|
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
139
157
|
updateIfNecessary() {
|
|
158
|
+
if (this._disposed) return;
|
|
140
159
|
if (this.state === CHECK) {
|
|
141
160
|
if (this.sources) {
|
|
142
161
|
for (const s of this.sources) {
|
|
@@ -180,7 +199,7 @@ var Computed = class extends Source {
|
|
|
180
199
|
reportReactiveRun(this);
|
|
181
200
|
if (changed) {
|
|
182
201
|
this.version++;
|
|
183
|
-
if (this.observers) for (const o of
|
|
202
|
+
if (this.observers) for (const o of this.observers) o.markDirty(DIRTY);
|
|
184
203
|
notifyWatchers(this);
|
|
185
204
|
}
|
|
186
205
|
}
|
|
@@ -194,7 +213,7 @@ var Computed = class extends Source {
|
|
|
194
213
|
const wasClean = this.state === CLEAN;
|
|
195
214
|
this.state = level;
|
|
196
215
|
if (wasClean) {
|
|
197
|
-
if (this.observers) for (const o of
|
|
216
|
+
if (this.observers) for (const o of this.observers) o.markDirty(CHECK);
|
|
198
217
|
notifyWatchers(this);
|
|
199
218
|
}
|
|
200
219
|
}
|
|
@@ -233,6 +252,10 @@ var Watcher = class {
|
|
|
233
252
|
this._pending.clear();
|
|
234
253
|
return out;
|
|
235
254
|
}
|
|
255
|
+
/** Drain pending without the array, for callers that only need it empty. */
|
|
256
|
+
clearPending() {
|
|
257
|
+
this._pending.clear();
|
|
258
|
+
}
|
|
236
259
|
/** @internal, a watched node became non-clean. Edge-triggered: notify once. */
|
|
237
260
|
_notify(node) {
|
|
238
261
|
if (!this._watched.has(node) || this._pending.has(node)) return;
|
|
@@ -444,14 +467,14 @@ var EffectNode = class {
|
|
|
444
467
|
if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
|
|
445
468
|
});
|
|
446
469
|
});
|
|
447
|
-
reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
470
|
+
if (isObserved()) reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
|
|
448
471
|
this.watcher = new Watcher(() => enqueue(this));
|
|
449
472
|
this.run();
|
|
450
473
|
this.watcher.watch(this.computed);
|
|
451
474
|
}
|
|
452
475
|
run() {
|
|
453
476
|
if (this.disposed) return;
|
|
454
|
-
this.watcher.
|
|
477
|
+
this.watcher.clearPending();
|
|
455
478
|
try {
|
|
456
479
|
this.computed.get();
|
|
457
480
|
} catch (e) {
|
|
@@ -468,6 +491,7 @@ var EffectNode = class {
|
|
|
468
491
|
this.disposed = true;
|
|
469
492
|
reportReactiveDispose(this.computed);
|
|
470
493
|
this.watcher.unwatch(this.computed);
|
|
494
|
+
this.computed.dispose();
|
|
471
495
|
disposeOwner(this.owner);
|
|
472
496
|
}
|
|
473
497
|
};
|