|
|
|
|
@ -501,89 +501,6 @@ export class Batch {
|
|
|
|
|
batches.delete(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< async-derived-coordinate-batches
|
|
|
|
|
=======
|
|
|
|
|
#commit() {
|
|
|
|
|
// If there are other pending batches, they now need to be 'rebased' —
|
|
|
|
|
// in other words, we re-run block/async effects with the newly
|
|
|
|
|
// committed state, unless the batch in question has a more
|
|
|
|
|
// recent value for a given source
|
|
|
|
|
for (const batch of batches) {
|
|
|
|
|
var is_earlier = batch.id < this.id;
|
|
|
|
|
|
|
|
|
|
/** @type {Source[]} */
|
|
|
|
|
var sources = [];
|
|
|
|
|
|
|
|
|
|
for (const [source, [value, is_derived]] of this.current) {
|
|
|
|
|
if (batch.current.has(source)) {
|
|
|
|
|
var batch_value = /** @type {[any, boolean]} */ (batch.current.get(source))[0]; // faster than destructuring
|
|
|
|
|
|
|
|
|
|
if (is_earlier && value !== batch_value) {
|
|
|
|
|
// bring the value up to date
|
|
|
|
|
batch.current.set(source, [value, is_derived]);
|
|
|
|
|
} else {
|
|
|
|
|
// same value or later batch has more recent value,
|
|
|
|
|
// no need to re-run these effects
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sources.push(source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Re-run async/block effects that depend on distinct values changed in both batches
|
|
|
|
|
var others = [...batch.current.keys()].filter((s) => !this.current.has(s));
|
|
|
|
|
|
|
|
|
|
if (others.length === 0) {
|
|
|
|
|
if (is_earlier) {
|
|
|
|
|
// this batch is now obsolete and can be discarded
|
|
|
|
|
batch.discard();
|
|
|
|
|
}
|
|
|
|
|
} else if (sources.length > 0) {
|
|
|
|
|
if (DEV) {
|
|
|
|
|
invariant(batch.#roots.length === 0, 'Batch has scheduled roots');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
batch.activate();
|
|
|
|
|
|
|
|
|
|
/** @type {Set<Value>} */
|
|
|
|
|
var marked = new Set();
|
|
|
|
|
|
|
|
|
|
/** @type {Map<Reaction, boolean>} */
|
|
|
|
|
var checked = new Map();
|
|
|
|
|
|
|
|
|
|
for (var source of sources) {
|
|
|
|
|
mark_effects(source, others, marked, checked);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only apply and traverse when we know we triggered async work with marking the effects
|
|
|
|
|
if (batch.#roots.length > 0) {
|
|
|
|
|
batch.apply();
|
|
|
|
|
|
|
|
|
|
for (var root of batch.#roots) {
|
|
|
|
|
batch.#traverse(root, [], []);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
batch.#roots = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
batch.deactivate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const batch of batches) {
|
|
|
|
|
if (batch.#blockers.has(this)) {
|
|
|
|
|
batch.#blockers.delete(this);
|
|
|
|
|
|
|
|
|
|
if (batch.#blockers.size === 0 && !batch.#is_deferred()) {
|
|
|
|
|
batch.activate();
|
|
|
|
|
batch.#process();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
>>>>>>> main
|
|
|
|
|
/**
|
|
|
|
|
* @param {boolean} blocking
|
|
|
|
|
* @param {Effect} effect
|
|
|
|
|
|