From 2ad519542dcba2d7802394068d412bb73d9cb803 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 21 Jan 2025 11:02:34 +0000 Subject: [PATCH 1/3] fix: ensure untrack correctly retains the active reaction (#15065) * fix: ensure untrack correctly retains the active reaction * fix: ensure untrack correctly retains the active reaction --- .changeset/fresh-cycles-sneeze.md | 5 +++ .../src/internal/client/reactivity/effects.js | 8 ++-- .../src/internal/client/reactivity/sources.js | 4 +- .../svelte/src/internal/client/runtime.js | 13 ++++-- packages/svelte/tests/signals/test.ts | 40 +++++++++++++++++++ 5 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 .changeset/fresh-cycles-sneeze.md diff --git a/.changeset/fresh-cycles-sneeze.md b/.changeset/fresh-cycles-sneeze.md new file mode 100644 index 0000000000..e91168d7fd --- /dev/null +++ b/.changeset/fresh-cycles-sneeze.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure untrack correctly retains the active reaction diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index e854633150..1faf9a47a0 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -16,7 +16,8 @@ import { set_is_flushing_effect, set_signal_status, untrack, - skip_reaction + skip_reaction, + untracking } from '../runtime.js'; import { DIRTY, @@ -43,8 +44,7 @@ import * as e from '../errors.js'; import { DEV } from 'esm-env'; import { define_property } from '../../shared/utils.js'; import { get_next_sibling } from '../dom/operations.js'; -import { derived, derived_safe_equal, destroy_derived } from './deriveds.js'; -import { legacy_mode_flag } from '../../flags/index.js'; +import { derived, destroy_derived } from './deriveds.js'; /** * @param {'$effect' | '$effect.pre' | '$inspect'} rune @@ -166,7 +166,7 @@ function create_effect(type, fn, sync, push = true) { * @returns {boolean} */ export function effect_tracking() { - if (active_reaction === null) { + if (active_reaction === null || untracking) { return false; } diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 4500a7c5a8..d10008dae2 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -17,7 +17,8 @@ import { set_derived_sources, check_dirtiness, set_is_flushing_effect, - is_flushing_effect + is_flushing_effect, + untracking } from '../runtime.js'; import { equals, safe_equals } from './equality.js'; import { @@ -148,6 +149,7 @@ export function mutate(source, value) { export function set(source, value) { if ( active_reaction !== null && + !untracking && is_runes() && (active_reaction.f & (DERIVED | BLOCK_EFFECT)) !== 0 && // If the source was created locally within the current derived, then diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index eca5ee94f9..1d695e1fee 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -78,6 +78,8 @@ let dev_effect_stack = []; /** @type {null | Reaction} */ export let active_reaction = null; +export let untracking = false; + /** @param {null | Reaction} reaction */ export function set_active_reaction(reaction) { active_reaction = reaction; @@ -423,6 +425,7 @@ export function update_reaction(reaction) { var previous_skip_reaction = skip_reaction; var prev_derived_sources = derived_sources; var previous_component_context = component_context; + var previous_untracking = untracking; var flags = reaction.f; new_deps = /** @type {null | Value[]} */ (null); @@ -432,6 +435,7 @@ export function update_reaction(reaction) { skip_reaction = !is_flushing_effect && (flags & UNOWNED) !== 0; derived_sources = null; component_context = reaction.ctx; + untracking = false; read_version++; try { @@ -495,6 +499,7 @@ export function update_reaction(reaction) { skip_reaction = previous_skip_reaction; derived_sources = prev_derived_sources; component_context = previous_component_context; + untracking = previous_untracking; } } @@ -934,7 +939,7 @@ export function get(signal) { } // Register the dependency on the current reaction signal. - if (active_reaction !== null) { + if (active_reaction !== null && !untracking) { if (derived_sources !== null && derived_sources.includes(signal)) { e.state_unsafe_local_read(); } @@ -1085,12 +1090,12 @@ export function invalidate_inner_signals(fn) { * @returns {T} */ export function untrack(fn) { - const previous_reaction = active_reaction; + var previous_untracking = untracking; try { - active_reaction = null; + untracking = true; return fn(); } finally { - active_reaction = previous_reaction; + untracking = previous_untracking; } } diff --git a/packages/svelte/tests/signals/test.ts b/packages/svelte/tests/signals/test.ts index a9d29920cf..e147fd1d0d 100644 --- a/packages/svelte/tests/signals/test.ts +++ b/packages/svelte/tests/signals/test.ts @@ -803,6 +803,46 @@ describe('signals', () => { }; }); + test('deriveds containing effects work correctly when used with untrack', () => { + return () => { + let a = render_effect(() => {}); + let b = state(0); + let c; + let effects = []; + + const destroy = effect_root(() => { + a = render_effect(() => { + c = derived(() => { + $.untrack(() => { + effects.push( + effect(() => { + $.get(b); + }) + ); + }); + $.get(b); + }); + $.get(c); + }); + }); + + assert.deepEqual(c!.children?.length, 1); + assert.deepEqual(a.first, a.last); + + set(b, 1); + + flushSync(); + + assert.deepEqual(c!.children?.length, 1); + assert.deepEqual(a.first, a.last); + + destroy(); + + assert.deepEqual(a.deriveds, null); + assert.deepEqual(a.first, null); + }; + }); + test('bigint states update correctly', () => { return () => { const count = state(0n); From 5ad6a0cdc37413e2c31994e7402d24ec4853fad7 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Tue, 21 Jan 2025 12:04:48 +0100 Subject: [PATCH 2/3] fix: initialize `files` bind on hydration (#15059) --- .changeset/happy-ants-grin.md | 5 +++++ .../src/internal/client/dom/elements/bindings/input.js | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 .changeset/happy-ants-grin.md diff --git a/.changeset/happy-ants-grin.md b/.changeset/happy-ants-grin.md new file mode 100644 index 0000000000..c80b2eb40c --- /dev/null +++ b/.changeset/happy-ants-grin.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: initialize `files` bind on hydration diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/input.js b/packages/svelte/src/internal/client/dom/elements/bindings/input.js index ec123d3968..3ea1a24d7e 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/input.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/input.js @@ -259,6 +259,15 @@ export function bind_files(input, get, set = get) { set(input.files); }); + if ( + // If we are hydrating and the value has since changed, + // then use the updated value from the input instead. + hydrating && + input.files + ) { + set(input.files); + } + render_effect(() => { input.files = get(); }); From c75f1f5f2f4883fc45ff9c66b294a7c59f417945 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:06:50 +0000 Subject: [PATCH 3/3] Version Packages (#15052) Co-authored-by: github-actions[bot] --- .changeset/cuddly-walls-pretend.md | 5 ----- .changeset/cyan-games-cheat.md | 5 ----- .changeset/fresh-cycles-sneeze.md | 5 ----- .changeset/happy-ants-grin.md | 5 ----- packages/svelte/CHANGELOG.md | 12 ++++++++++++ packages/svelte/package.json | 2 +- packages/svelte/src/version.js | 2 +- 7 files changed, 14 insertions(+), 22 deletions(-) delete mode 100644 .changeset/cuddly-walls-pretend.md delete mode 100644 .changeset/cyan-games-cheat.md delete mode 100644 .changeset/fresh-cycles-sneeze.md delete mode 100644 .changeset/happy-ants-grin.md diff --git a/.changeset/cuddly-walls-pretend.md b/.changeset/cuddly-walls-pretend.md deleted file mode 100644 index f51147a30c..0000000000 --- a/.changeset/cuddly-walls-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: omit unnecessary nullish coallescing in template expressions diff --git a/.changeset/cyan-games-cheat.md b/.changeset/cyan-games-cheat.md deleted file mode 100644 index d90901783b..0000000000 --- a/.changeset/cyan-games-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: more efficient template effect grouping diff --git a/.changeset/fresh-cycles-sneeze.md b/.changeset/fresh-cycles-sneeze.md deleted file mode 100644 index e91168d7fd..0000000000 --- a/.changeset/fresh-cycles-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: ensure untrack correctly retains the active reaction diff --git a/.changeset/happy-ants-grin.md b/.changeset/happy-ants-grin.md deleted file mode 100644 index c80b2eb40c..0000000000 --- a/.changeset/happy-ants-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: initialize `files` bind on hydration diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 59ac9f2864..d16bdbc327 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,17 @@ # svelte +## 5.19.1 + +### Patch Changes + +- fix: omit unnecessary nullish coallescing in template expressions ([#15056](https://github.com/sveltejs/svelte/pull/15056)) + +- fix: more efficient template effect grouping ([#15050](https://github.com/sveltejs/svelte/pull/15050)) + +- fix: ensure untrack correctly retains the active reaction ([#15065](https://github.com/sveltejs/svelte/pull/15065)) + +- fix: initialize `files` bind on hydration ([#15059](https://github.com/sveltejs/svelte/pull/15059)) + ## 5.19.0 ### Minor Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 95e7a7319d..b725e52fed 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.19.0", + "version": "5.19.1", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 7347e7546d..b0ea99b6f4 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.19.0'; +export const VERSION = '5.19.1'; export const PUBLIC_VERSION = '5';