From 5620882d6e6626775a6f10cc868a506318a1554f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 15:43:42 +0100 Subject: [PATCH 1/2] Version Packages (next) (#11807) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 6 ++++++ packages/svelte/CHANGELOG.md | 16 ++++++++++++++++ packages/svelte/package.json | 2 +- packages/svelte/src/version.js | 2 +- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 6465fa00e4..0f251c3472 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -13,6 +13,7 @@ "afraid-geckos-dance", "afraid-kids-hide", "afraid-moose-matter", + "afraid-worms-drum", "angry-books-jam", "angry-plums-punch", "angry-wasps-help", @@ -140,6 +141,7 @@ "fifty-steaks-float", "five-tigers-search", "flat-melons-protect", + "flat-olives-live", "fluffy-dolls-share", "fluffy-humans-worry", "fluffy-ravens-juggle", @@ -281,6 +283,7 @@ "mean-jokes-exist", "metal-clouds-raise", "metal-lobsters-burn", + "metal-pans-trade", "mighty-cooks-scream", "mighty-files-hammer", "mighty-frogs-obey", @@ -427,6 +430,7 @@ "sixty-pandas-rush", "sleepy-cats-eat", "slimy-clouds-talk", + "slimy-hairs-impress", "slimy-laws-explode", "slimy-onions-approve", "slimy-walls-draw", @@ -468,6 +472,7 @@ "stale-fans-rest", "stale-jeans-refuse", "strange-apricots-happen", + "strange-roses-brake", "strong-apricots-destroy", "strong-gifts-smoke", "strong-lemons-provide", @@ -527,6 +532,7 @@ "tiny-meals-deliver", "tiny-moose-kiss", "tough-radios-punch", + "tough-tomatoes-explain", "twelve-beans-drive", "twelve-dragons-join", "twelve-onions-juggle", diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 72575a548e..995ca6c436 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,21 @@ # svelte +## 5.0.0-next.144 + +### Patch Changes + +- fix: address derived memory leak on disconnection from reactive graph ([#11819](https://github.com/sveltejs/svelte/pull/11819)) + +- fix: set correct scope for `@const` tags within slots ([#11798](https://github.com/sveltejs/svelte/pull/11798)) + +- fix: better support for onwheel events in chrome ([#11808](https://github.com/sveltejs/svelte/pull/11808)) + +- fix: coherent infinite loop guard ([#11815](https://github.com/sveltejs/svelte/pull/11815)) + +- fix: make prop fallback values deeply reactive if needed ([#11804](https://github.com/sveltejs/svelte/pull/11804)) + +- fix: robustify initial scroll value detection when scroll is smooth ([#11802](https://github.com/sveltejs/svelte/pull/11802)) + ## 5.0.0-next.143 ### Patch Changes diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 0278b4639f..5b13ffcb5c 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.0.0-next.143", + "version": "5.0.0-next.144", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index c7f389a513..0a83d5c087 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -6,5 +6,5 @@ * https://svelte.dev/docs/svelte-compiler#svelte-version * @type {string} */ -export const VERSION = '5.0.0-next.143'; +export const VERSION = '5.0.0-next.144'; export const PUBLIC_VERSION = '5'; From 5f7bfac59aa3199a445401beb2fec1f7f19b5cb0 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Wed, 29 May 2024 16:09:54 +0100 Subject: [PATCH 2/2] chore: cleanup event changes (#11821) Takes some changes from #11810 that are only cleanup/renaming. --- .../client/dom/elements/bindings/input.js | 14 +++++++----- .../client/dom/elements/bindings/media.js | 22 +++++++++---------- .../client/dom/elements/bindings/navigator.js | 4 ++-- .../client/dom/elements/bindings/select.js | 4 ++-- .../client/dom/elements/bindings/size.js | 6 ++--- .../client/dom/elements/bindings/this.js | 4 ++-- .../client/dom/elements/bindings/window.js | 6 ++--- .../internal/client/dom/elements/events.js | 6 ++--- .../svelte/src/internal/client/runtime.js | 4 +++- .../binding-input-group-each-7/_config.js | 16 +++++++++----- .../samples/binding-input-number-2/_config.js | 4 ++++ 11 files changed, 51 insertions(+), 39 deletions(-) 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 7c099a47e2..203f911ac5 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/input.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/input.js @@ -4,7 +4,7 @@ import { stringify } from '../../../render.js'; import { listen_to_event_and_reset_event } from './shared.js'; import * as e from '../../../errors.js'; import { get_proxied_value, is } from '../../../proxy.js'; -import { yield_updates } from '../../../runtime.js'; +import { yield_event_updates } from '../../../runtime.js'; /** * @param {HTMLInputElement} input @@ -19,7 +19,9 @@ export function bind_value(input, get_value, update) { e.bind_invalid_checkbox_value(); } - yield_updates(() => update(is_numberlike_input(input) ? to_number(input.value) : input.value)); + yield_event_updates(() => + update(is_numberlike_input(input) ? to_number(input.value) : input.value) + ); }); render_effect(() => { @@ -85,10 +87,10 @@ export function bind_group(inputs, group_index, input, get_value, update) { value = get_binding_group_value(binding_group, value, input.checked); } - yield_updates(() => update(value)); + yield_event_updates(() => update(value)); }, // TODO better default value handling - () => yield_updates(() => update(is_checkbox ? [] : null)) + () => yield_event_updates(() => update(is_checkbox ? [] : null)) ); render_effect(() => { @@ -129,7 +131,7 @@ export function bind_group(inputs, group_index, input, get_value, update) { export function bind_checked(input, get_value, update) { listen_to_event_and_reset_event(input, 'change', () => { var value = input.checked; - yield_updates(() => update(value)); + yield_event_updates(() => update(value)); }); if (get_value() == undefined) { @@ -188,7 +190,7 @@ function to_number(value) { */ export function bind_files(input, get_value, update) { listen_to_event_and_reset_event(input, 'change', () => { - yield_updates(() => update(input.files)); + yield_event_updates(() => update(input.files)); }); render_effect(() => { input.files = get_value(); diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/media.js b/packages/svelte/src/internal/client/dom/elements/bindings/media.js index c47ee7a99c..000443763b 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/media.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/media.js @@ -1,7 +1,7 @@ import { hydrating } from '../../hydration.js'; import { render_effect, effect } from '../../../reactivity/effects.js'; import { listen } from './shared.js'; -import { yield_updates } from '../../../runtime.js'; +import { yield_event_updates } from '../../../runtime.js'; /** @param {TimeRanges} ranges */ function time_ranges_to_array(ranges) { @@ -36,7 +36,7 @@ export function bind_current_time(media, get_value, update) { } updating = true; - yield_updates(() => update(media.currentTime)); + yield_event_updates(() => update(media.currentTime)); }; raf_id = requestAnimationFrame(callback); @@ -62,7 +62,7 @@ export function bind_current_time(media, get_value, update) { */ export function bind_buffered(media, update) { listen(media, ['loadedmetadata', 'progress'], () => - yield_updates(() => update(time_ranges_to_array(media.buffered))) + yield_event_updates(() => update(time_ranges_to_array(media.buffered))) ); } @@ -80,7 +80,7 @@ export function bind_seekable(media, update) { */ export function bind_played(media, update) { listen(media, ['timeupdate'], () => - yield_updates(() => update(time_ranges_to_array(media.played))) + yield_event_updates(() => update(time_ranges_to_array(media.played))) ); } @@ -89,7 +89,7 @@ export function bind_played(media, update) { * @param {(seeking: boolean) => void} update */ export function bind_seeking(media, update) { - listen(media, ['seeking', 'seeked'], () => yield_updates(() => update(media.seeking))); + listen(media, ['seeking', 'seeked'], () => yield_event_updates(() => update(media.seeking))); } /** @@ -97,7 +97,7 @@ export function bind_seeking(media, update) { * @param {(seeking: boolean) => void} update */ export function bind_ended(media, update) { - listen(media, ['timeupdate', 'ended'], () => yield_updates(() => update(media.ended))); + listen(media, ['timeupdate', 'ended'], () => yield_event_updates(() => update(media.ended))); } /** @@ -108,7 +108,7 @@ export function bind_ready_state(media, update) { listen( media, ['loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'emptied'], - () => yield_updates(() => update(media.readyState)) + () => yield_event_updates(() => update(media.readyState)) ); } @@ -132,7 +132,7 @@ export function bind_playback_rate(media, get_value, update) { } listen(media, ['ratechange'], () => { - if (!updating) yield_updates(() => update(media.playbackRate)); + if (!updating) yield_event_updates(() => update(media.playbackRate)); updating = false; }); }); @@ -150,7 +150,7 @@ export function bind_paused(media, get_value, update) { var callback = () => { if (paused !== media.paused) { paused = media.paused; - yield_updates(() => update((paused = media.paused))); + yield_event_updates(() => update((paused = media.paused))); } }; @@ -175,7 +175,7 @@ export function bind_paused(media, get_value, update) { media.pause(); } else { media.play().catch(() => { - yield_updates(() => update((paused = true))); + yield_event_updates(() => update((paused = true))); }); } }; @@ -239,7 +239,7 @@ export function bind_muted(media, get_value, update) { var callback = () => { updating = true; - yield_updates(() => update(media.muted)); + yield_event_updates(() => update(media.muted)); }; if (get_value() == null) { diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/navigator.js b/packages/svelte/src/internal/client/dom/elements/bindings/navigator.js index 28d6bf9926..39a7e60527 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/navigator.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/navigator.js @@ -1,4 +1,4 @@ -import { yield_updates } from '../../../runtime.js'; +import { yield_event_updates } from '../../../runtime.js'; import { listen } from './shared.js'; /** @@ -7,6 +7,6 @@ import { listen } from './shared.js'; */ export function bind_online(update) { listen(window, ['online', 'offline'], () => { - yield_updates(() => update(navigator.onLine)); + yield_event_updates(() => update(navigator.onLine)); }); } diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/select.js b/packages/svelte/src/internal/client/dom/elements/bindings/select.js index 624c77abb0..5891aa5f81 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/select.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/select.js @@ -1,6 +1,6 @@ import { effect } from '../../../reactivity/effects.js'; import { listen_to_event_and_reset_event } from './shared.js'; -import { untrack, yield_updates } from '../../../runtime.js'; +import { untrack, yield_event_updates } from '../../../runtime.js'; import { is } from '../../../proxy.js'; /** @@ -90,7 +90,7 @@ export function bind_select_value(select, get_value, update) { value = selected_option && get_option_value(selected_option); } - yield_updates(() => update(value)); + yield_event_updates(() => update(value)); }); // Needs to be an effect, not a render_effect, so that in case of each loops the logic runs after the each block has updated diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/size.js b/packages/svelte/src/internal/client/dom/elements/bindings/size.js index 771975d7a3..5ade7d5a7e 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/size.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/size.js @@ -1,5 +1,5 @@ import { effect, render_effect } from '../../../reactivity/effects.js'; -import { untrack, yield_updates } from '../../../runtime.js'; +import { untrack, yield_event_updates } from '../../../runtime.js'; /** * Resize observer singleton. @@ -90,7 +90,7 @@ export function bind_resize_observer(element, type, update) { var unsub = observer.observe( element, - /** @param {any} entry */ (entry) => yield_updates(() => update(entry[type])) + /** @param {any} entry */ (entry) => yield_event_updates(() => update(entry[type])) ); render_effect(() => unsub); } @@ -104,7 +104,7 @@ export function bind_element_size(element, type, update) { var unsub = resize_observer_border_box.observe(element, () => update(element[type])); effect(() => { - yield_updates(() => untrack(() => update(element[type]))); + yield_event_updates(() => untrack(() => update(element[type]))); return unsub; }); } diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/this.js b/packages/svelte/src/internal/client/dom/elements/bindings/this.js index 125ead6cd2..df06c46f2f 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/this.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/this.js @@ -1,6 +1,6 @@ import { STATE_SYMBOL } from '../../../constants.js'; import { effect, render_effect } from '../../../reactivity/effects.js'; -import { untrack, yield_updates } from '../../../runtime.js'; +import { untrack, yield_event_updates } from '../../../runtime.js'; import { queue_micro_task } from '../../task.js'; /** @@ -37,7 +37,7 @@ export function bind_this(element_or_component, update, get_value, get_parts) { untrack(() => { if (element_or_component !== get_value(...parts)) { - yield_updates(() => { + yield_event_updates(() => { update(element_or_component, ...parts); // If this is an effect rerun (cause: each block context changes), then nullfiy the binding at // the previous position if it isn't already taken over by a different effect. diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/window.js b/packages/svelte/src/internal/client/dom/elements/bindings/window.js index 13fa9d4225..511f2d5666 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/window.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/window.js @@ -1,5 +1,5 @@ import { effect, render_effect } from '../../../reactivity/effects.js'; -import { yield_updates } from '../../../runtime.js'; +import { yield_event_updates } from '../../../runtime.js'; import { listen } from './shared.js'; /** @@ -16,7 +16,7 @@ export function bind_window_scroll(type, get_value, update) { clearTimeout(timeout); timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?) - yield_updates(() => update(window[is_scrolling_x ? 'scrollX' : 'scrollY'])); + yield_event_updates(() => update(window[is_scrolling_x ? 'scrollX' : 'scrollY'])); }; addEventListener('scroll', target_handler, { @@ -64,5 +64,5 @@ export function bind_window_scroll(type, get_value, update) { * @param {(size: number) => void} update */ export function bind_window_size(type, update) { - listen(window, ['resize'], () => yield_updates(() => update(window[type]))); + listen(window, ['resize'], () => yield_event_updates(() => update(window[type]))); } diff --git a/packages/svelte/src/internal/client/dom/elements/events.js b/packages/svelte/src/internal/client/dom/elements/events.js index fb2cf88c37..1f94162064 100644 --- a/packages/svelte/src/internal/client/dom/elements/events.js +++ b/packages/svelte/src/internal/client/dom/elements/events.js @@ -1,6 +1,6 @@ import { render_effect } from '../../reactivity/effects.js'; import { all_registered_events, root_event_handles } from '../../render.js'; -import { yield_updates } from '../../runtime.js'; +import { yield_event_updates } from '../../runtime.js'; import { define_property, is_array } from '../../utils.js'; import { hydrating } from '../hydration.js'; import { queue_micro_task } from '../task.js'; @@ -48,7 +48,7 @@ export function create_event(event_name, dom, handler, options) { handle_event_propagation(dom, event); } if (!event.cancelBubble) { - return yield_updates(() => handler.call(this, event)); + return yield_event_updates(() => handler.call(this, event)); } } @@ -204,7 +204,7 @@ export function handle_event_propagation(handler_element, event) { } try { - yield_updates(() => next(/** @type {Element} */ (current_target))); + yield_event_updates(() => next(/** @type {Element} */ (current_target))); } finally { // @ts-expect-error is used above event.__root = handler_element; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 4c341e5cfc..1f0a0bfdab 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -738,7 +738,7 @@ function process_effects(effect, collected_effects) { /** * @param {{ (): void; (): any; }} fn */ -export function yield_updates(fn) { +export function yield_event_updates(fn) { const previous_scheduler_mode = current_scheduler_mode; try { current_scheduler_mode = FLUSH_YIELD; @@ -767,6 +767,8 @@ export function flush_sync(fn, flush_previous = true) { current_scheduler_mode = FLUSH_SYNC; current_queued_root_effects = root_effects; + is_yield_task_queued = false; + is_micro_task_queued = false; if (flush_previous) { flush_queued_root_effects(previous_queued_root_effects); diff --git a/packages/svelte/tests/runtime-legacy/samples/binding-input-group-each-7/_config.js b/packages/svelte/tests/runtime-legacy/samples/binding-input-group-each-7/_config.js index d3737b0a2a..f51154ef00 100644 --- a/packages/svelte/tests/runtime-legacy/samples/binding-input-group-each-7/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/binding-input-group-each-7/_config.js @@ -1,3 +1,4 @@ +import { flushSync } from 'svelte'; import { test } from '../../test'; export default test({ @@ -22,15 +23,15 @@ export default test({ `, - async test({ assert, target, window }) { + test({ assert, target, window }) { const inputs = target.querySelectorAll('input'); const checked = new Set(); /** @param {number} i */ - const checkInbox = async (i) => { + const checkInbox = (i) => { checked.add(i); inputs[i].checked = true; - await inputs[i].dispatchEvent(event); + inputs[i].dispatchEvent(event); }; for (let i = 0; i < 18; i++) { @@ -39,17 +40,20 @@ export default test({ const event = new window.Event('change'); - await checkInbox(2); + checkInbox(2); + flushSync(); for (let i = 0; i < 18; i++) { assert.equal(inputs[i].checked, checked.has(i)); } - await checkInbox(12); + checkInbox(12); + flushSync(); for (let i = 0; i < 18; i++) { assert.equal(inputs[i].checked, checked.has(i)); } - await checkInbox(8); + checkInbox(8); + flushSync(); for (let i = 0; i < 18; i++) { assert.equal(inputs[i].checked, checked.has(i)); } diff --git a/packages/svelte/tests/runtime-legacy/samples/binding-input-number-2/_config.js b/packages/svelte/tests/runtime-legacy/samples/binding-input-number-2/_config.js index 264982c365..e6b235676d 100644 --- a/packages/svelte/tests/runtime-legacy/samples/binding-input-number-2/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/binding-input-number-2/_config.js @@ -1,3 +1,4 @@ +import { flushSync } from 'svelte'; import { ok, test } from '../../test'; export default test({ @@ -16,6 +17,7 @@ export default test({ input.value = '5.'; input.dispatchEvent(inputEvent); + flushSync(); // input type number has value === "" if ends with dot/comma assert.equal(component.value, undefined); @@ -23,12 +25,14 @@ export default test({ input.value = '5.5'; input.dispatchEvent(inputEvent); + flushSync(); assert.equal(component.value, 5.5); assert.equal(input.value, '5.5'); input.value = '5.50'; input.dispatchEvent(inputEvent); + flushSync(); assert.equal(component.value, 5.5); assert.equal(input.value, '5.50');