From 6e571dc9095e292bd58e69846ac93aa2660258a7 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Sun, 16 Nov 2025 03:19:30 +0100 Subject: [PATCH 1/2] fix: ensure deferred effects can be rescheduled later on (#17147) When deferring effects we didn't unmark the deriveds that lead to those effects. This means that they might not be reached in subsequent runs of `mark_reactions`. Fixes https://github.com/sveltejs/svelte/issues/17118#issuecomment-3521488865 --- .changeset/grumpy-gifts-sit.md | 5 ++ .../src/internal/client/reactivity/batch.js | 24 ++++++++- .../async-fork-update-same-state/_config.js | 49 +++++++++++++++++++ .../async-fork-update-same-state/main.svelte | 37 ++++++++++++++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 .changeset/grumpy-gifts-sit.md create mode 100644 packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/main.svelte diff --git a/.changeset/grumpy-gifts-sit.md b/.changeset/grumpy-gifts-sit.md new file mode 100644 index 0000000000..fab1bd9ccc --- /dev/null +++ b/.changeset/grumpy-gifts-sit.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure deferred effects can be rescheduled later on diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index ab5bd0b788..03a0721057 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -16,7 +16,8 @@ import { BOUNDARY_EFFECT, EAGER_EFFECT, HEAD_EFFECT, - ERROR_VALUE + ERROR_VALUE, + WAS_MARKED } from '#client/constants'; import { async_mode_flag } from '../../flags/index.js'; import { deferred, define_property } from '../../shared/utils.js'; @@ -274,11 +275,32 @@ export class Batch { const target = (e.f & DIRTY) !== 0 ? this.#dirty_effects : this.#maybe_dirty_effects; target.push(e); + // Since we're not executing these effects now, we need to clear any WAS_MARKED flags + // so that other batches can correctly reach these effects during their own traversal + this.#clear_marked(e.deps); + // mark as clean so they get scheduled if they depend on pending async state set_signal_status(e, CLEAN); } } + /** + * @param {Value[] | null} deps + */ + #clear_marked(deps) { + if (deps === null) return; + + for (const dep of deps) { + if ((dep.f & DERIVED) === 0 || (dep.f & WAS_MARKED) === 0) { + continue; + } + + dep.f ^= WAS_MARKED; + + this.#clear_marked(/** @type {Derived} */ (dep).deps); + } + } + /** * Associate a change to a given source with the current * batch, noting its previous and current values diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/_config.js new file mode 100644 index 0000000000..b3e04204b4 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/_config.js @@ -0,0 +1,49 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target, logs }) { + assert.deepEqual(logs, [0]); + + const [fork1, fork2, commit] = target.querySelectorAll('button'); + + fork1.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + + +
0
+ ` + ); + assert.deepEqual(logs, [0]); + + fork2.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + + +0
+ ` + ); + assert.deepEqual(logs, [0]); + + commit.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + + +1
+ ` + ); + assert.deepEqual(logs, [0, 1]); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/main.svelte new file mode 100644 index 0000000000..45645b4085 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-update-same-state/main.svelte @@ -0,0 +1,37 @@ + + + + + + + + +{count}
From 1e0c8c544ca18c9102babb963969af996a28b3a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 15 Nov 2025 21:23:10 -0500 Subject: [PATCH 2/2] Version Packages (#17159) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/cold-beds-look.md | 5 ----- .changeset/grumpy-gifts-sit.md | 5 ----- .changeset/ready-flies-invite.md | 5 ----- packages/svelte/CHANGELOG.md | 10 ++++++++++ packages/svelte/package.json | 2 +- packages/svelte/src/version.js | 2 +- 6 files changed, 12 insertions(+), 17 deletions(-) delete mode 100644 .changeset/cold-beds-look.md delete mode 100644 .changeset/grumpy-gifts-sit.md delete mode 100644 .changeset/ready-flies-invite.md diff --git a/.changeset/cold-beds-look.md b/.changeset/cold-beds-look.md deleted file mode 100644 index 0929e42a89..0000000000 --- a/.changeset/cold-beds-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: properly defer document title until async work is complete diff --git a/.changeset/grumpy-gifts-sit.md b/.changeset/grumpy-gifts-sit.md deleted file mode 100644 index fab1bd9ccc..0000000000 --- a/.changeset/grumpy-gifts-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: ensure deferred effects can be rescheduled later on diff --git a/.changeset/ready-flies-invite.md b/.changeset/ready-flies-invite.md deleted file mode 100644 index 660fa0d67e..0000000000 --- a/.changeset/ready-flies-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: take blockers of components into account diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 10ea609b04..8bceee7a32 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,15 @@ # svelte +## 5.43.7 + +### Patch Changes + +- fix: properly defer document title until async work is complete ([#17158](https://github.com/sveltejs/svelte/pull/17158)) + +- fix: ensure deferred effects can be rescheduled later on ([#17147](https://github.com/sveltejs/svelte/pull/17147)) + +- fix: take blockers of components into account ([#17153](https://github.com/sveltejs/svelte/pull/17153)) + ## 5.43.6 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 731ae6f004..330c5e3ca5 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.43.6", + "version": "5.43.7", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 81bd62b554..7472a6d612 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -4,5 +4,5 @@ * The current version, as set in package.json. * @type {string} */ -export const VERSION = '5.43.6'; +export const VERSION = '5.43.7'; export const PUBLIC_VERSION = '5';