restore stale_effects

Needed on async-another-try-pt-2/pt-3: recording stale effects, the wv override in apply(),
and marking them maybe-dirty in later batches are all required by fork tests there
(e.g. async-fork-effect-write-version, async-state-new-branch-fork-5).
async-another-try-pt-1-prune
Rich Harris 2 days ago
parent f60f99e6d8
commit cc8b5d7089
No known key found for this signature in database

@ -129,6 +129,20 @@ export class Batch {
*/
merged_into = null;
/**
* @type {Map<Effect, number> | null}
*/
#stale_effects = null;
/**
* Effects that were executed with stale values. Its wv is written into the map.
* Lazily initialized for performance reasons.
* @type {Map<Effect, number>}
*/
get stale_effects() {
return (this.#stale_effects ??= new Map());
}
/** @type {Batch | null} */
prev = null;
@ -958,6 +972,10 @@ export class Batch {
wv_values.set(source, current.wv);
}
for (const [effect, wv] of this.#stale_effects ?? []) {
wv_values.set(effect, wv);
}
for (let batch = first_batch; batch !== null; batch = batch.next) {
if (batch === this) continue;

@ -490,16 +490,25 @@ export function update_effect(effect) {
// Did the effect see the latest value of all its dependencies, or (partly) its batch's view
// of them, i.e. did `batch_values` hand it a value that differs from the real one? We only
// need to look one level deep: a derived that was itself computed from such a value was not
// written to the real world either, so it differs as well. If it saw its batch's view, we
// don't update its write version.
// written to the real world either, so it differs as well.
var own_batch = previous_batch ?? current_batch; // can be null inside flush_eager_effects
var is_latest_value =
(previous_batch === null && current_batch === null) || // e.g. inside flush_eager_effects
own_batch === null ||
batch_values === null ||
effect.deps === null ||
!effect.deps.some((d) => batch_values?.has(d) && batch_values.get(d) !== d.v);
if (is_latest_value) {
effect.wv = write_version;
} else {
// The effect ran with values that are not the latest ones (it saw its own batch's view).
// Don't update its write version — instead remember it so that the batch can bring it
// up to date on commit, and tell all subsequent batches that it may need to re-run in their view.
var own = /** @type {Batch} */ (own_batch);
own.stale_effects.set(effect, write_version);
for (var batch = own.next; batch !== null; batch = batch.next) {
batch.add_dirty_reaction(effect, MAYBE_DIRTY);
}
}
// In DEV, increment versions of any sources that were written to during the effect,

Loading…
Cancel
Save