async-another-try
Simon Holthausen 3 days ago
parent 87a061a73f
commit 957330c89c
No known key found for this signature in database

@ -124,7 +124,11 @@ export class Batch {
linked = false;
/** @type {Batch | null} */
/**
* The batch into which this batch has been merged (because it finished and
* depended on a prior batch that needs to resolve first), if any.
* @type {Batch | null}
*/
merged_into = null;
/**
@ -161,23 +165,27 @@ export class Batch {
next = null;
/**
* Batches that depend on this batch.
* Lazily initialized for performance reasons.
* @type {Set<Batch> | null}
*/
#dependent = null;
/**
* Batches that depend on this batch.
* Lazily initialized for performance reasons.
*/
get dependent() {
return (this.#dependent ??= new Set());
}
/**
* All started async work in this batch.
* Lazily initialized for performance reasons.
* @type {Map<Effect, ReturnType<typeof deferred<any>>> | null}
*/
#async_deriveds = null;
/**
* All started async work in this batch.
* Lazily initialized for performance reasons.
*/
get async_deriveds() {
return (this.#async_deriveds ??= new Map());
}
@ -266,13 +274,15 @@ export class Batch {
#skipped_branches = new Map();
/**
* Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing.
* `true` indicates that this branch is new to the eyes of this fork but was already created before.
* Lazily initialized for performance reasons.
* @type {Map<Effect, boolean> | null}
*/
#unskipped_branches = null;
/**
* Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing.
* `true` indicates that this branch is new to the eyes of this fork but was already created before.
* Lazily initialized for performance reasons.
*/
get unskipped_branches() {
return (this.#unskipped_branches ??= new Map());
}
@ -589,7 +599,8 @@ export class Batch {
} else if (first_time) {
// We're seeing a fork-only branch for the first time in another fork. We need to traverse
// all effects inside it (they're all marked MAYBE_DIRTY). This is necessary because
// dependencies of the effects inside could've updated since the last time this branch ran.
// dependencies of the effects inside could've updated in the real world since the last time this branch ran.
// TODO this can overfire, maybe there's a way to detect which sources actually changed.
this.unskipped_branches.set(effect, false);
all_dirty ??= effect;
if (effect.f & CLEAN) effect.f ^= CLEAN;
@ -888,7 +899,7 @@ export class Batch {
const current = batch.current.get(source);
batch.current.delete(source);
if (![...batch.current.values()].some((value) => !value.is_derived)) {
if ([...batch.current.values()].every((value) => !value.is_derived)) {
// The real world has overtaken every write of this fork, so it is obsolete. Discard it
// right away (its speculative branches must not be adopted by anyone), and empty
// `current` so that `commit()` can tell this apart from a user-initiated discard
@ -1084,6 +1095,13 @@ export class Batch {
return current_batch;
}
/**
* - `include_earlier` false: batch_values etc should see the latest values up until itself,
* i.e. including latest value of all earlier batches; previous values only of later batches.
* - `include_earlier` true: the "world view" of batch_values is current values are only of this batch,
* previous values of all other batches.
* @param {boolean} include_earlier
*/
apply(include_earlier = false) {
if (!async_mode_flag || (!this.is_fork && this.prev === null && this.next === null)) {
batch_values = null;

Loading…
Cancel
Save