Skip to content

fix: batch views of reactions - #19030

Open
dummdidumm wants to merge 13 commits into
mainfrom
batch-views
Open

dummdidumm wants to merge 13 commits into
mainfrom
batch-views

Conversation

@dummdidumm

@dummdidumm dummdidumm commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

This changes the async reactivity system when multiple batches are active such that they check if they need to be re-executed in a batch by comparing the write versions of the dependencies they last saw with the ones they have now - if there's any difference, they re-execute. These write version arrays, the value, the dependencies that batch sees - all is stored in a record local to the batch. Logic exists to promote them to the real world if we know the derived was computed from real-world/latest dependencies only, and async/block effects promote once the batch commits.

This introduces some complexity, on the other hand various things are simplified or removed (#commit for example got easier).

This is WIP, but I've commited a readme that gives a good overview of how the system works in more detail and the gaps vs async-reactivity-another-try-pt-1

@pkg-svelte-dev

pkg-svelte-dev Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Install the latest version of svelte from 7e395a1:

pnpm add https://pkg.svelte.dev/svelte/c/7e395a152fc55123d78f31d49b2b8871472da8ed

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/svelte/pr/19030

@changeset-bot

changeset-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7e395a1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

Comment on lines +112 to +114
if ((onscreen.f & EFFECT_OFFSCREEN) !== 0) {
onscreen.f ^= EFFECT_OFFSCREEN;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor thing but we have a mix of styles in the codebase, should we standardise on the one-liner? i think it's probably more efficient anyway — a bitwise comparison plus a numeric comparison, then if the condition is true another bitwise operation and an assignment, versus two bitwise operations and an assignment

Suggested change
if ((onscreen.f & EFFECT_OFFSCREEN) !== 0) {
onscreen.f ^= EFFECT_OFFSCREEN;
}
onscreen.f &= ~EFFECT_OFFSCREEN;

(unless the assignment is the costly part, i guess?)


/**
* The run of `reaction` that applies in the active view of the world: the record of a block or async
* effect in the active batch, if it has one (see `update_record`), or else the reaction itself — whose

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* effect in the active batch, if it has one (see `update_record`), or else the reaction itself — whose
* effect in the active batch, if it has one (see {@link update_record}), or else the reaction itself — whose

* If it is MAYBE_DIRTY, will set the status to CLEAN
* If it is MAYBE_DIRTY, will set the status to CLEAN.
* Deriveds are only checked like this in the real world — within the view of a batch,
* see `view_entry`. Effects are checked against the run that applies (see `run_of`).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* see `view_entry`. Effects are checked against the run that applies (see `run_of`).
* see {@link view_entry}. Effects are checked against the run that applies (see {@link run_of}).


/**
* True while the batch commits, i.e. while it updates the DOM and runs effects.
* Effects that run then do so for the real world

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this right? if A and B are in-flight and A commits, don't effects run in A's world?


/**
* Effects to (re-)validate when this batch is processed next, and their status (DIRTY or MAYBE_DIRTY):
* those that were scheduled while it wasn't being processed (see `schedule`), and those whose run

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sadly we can't do this for private methods (i.e. #defer_effects on the next line) but we can at least make this cmd-clickable

Suggested change
* those that were scheduled while it wasn't being processed (see `schedule`), and those whose run
* those that were scheduled while it wasn't being processed (see {@link schedule}), and those whose run

* so they can be rescheduled if the branch survives.
* @type {Map<Effect, { d: Effect[], m: Effect[] }>}
* Branches that still exist, but will be destroyed when this batch
* is committed — we skip over these during `process`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* is committed — we skip over these during `process`
* is committed — we skip over these during `#process`

Comment on lines +255 to +259
// pending work inside a skipped branch doesn't block, the branch is going to be destroyed
if (!this.#is_skipped(effect)) {
return true;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good candidate for merging into main independently

…ause testing special cases of pt1, but commit for now either way because good for comparison)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants