Skip to content

Commit 3b7715c

Browse files
authored
Revert "breaking: avoid flushing queued updates on mount/hydrate (#12587)"
This reverts commit 20b8797.
1 parent 7a5c6b5 commit 3b7715c

File tree

7 files changed

+35
-40
lines changed

7 files changed

+35
-40
lines changed

.changeset/slow-gorillas-yawn.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/svelte/src/internal/client/render.js

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export function set_text(text, value) {
7979
*/
8080
export function mount(component, options) {
8181
const anchor = options.anchor ?? options.target.appendChild(empty());
82-
return _mount(component, { ...options, anchor });
82+
// Don't flush previous effects to ensure order of outer effects stays consistent
83+
return flush_sync(() => _mount(component, { ...options, anchor }), false);
8384
}
8485

8586
/**
@@ -112,35 +113,40 @@ export function hydrate(component, options) {
112113
const previous_hydrate_node = hydrate_node;
113114

114115
try {
115-
var anchor = /** @type {import('#client').TemplateNode} */ (target.firstChild);
116-
while (
117-
anchor &&
118-
(anchor.nodeType !== 8 || /** @type {Comment} */ (anchor).data !== HYDRATION_START)
119-
) {
120-
anchor = /** @type {import('#client').TemplateNode} */ (anchor.nextSibling);
121-
}
116+
// Don't flush previous effects to ensure order of outer effects stays consistent
117+
return flush_sync(() => {
118+
var anchor = /** @type {import('#client').TemplateNode} */ (target.firstChild);
119+
while (
120+
anchor &&
121+
(anchor.nodeType !== 8 || /** @type {Comment} */ (anchor).data !== HYDRATION_START)
122+
) {
123+
anchor = /** @type {import('#client').TemplateNode} */ (anchor.nextSibling);
124+
}
122125

123-
if (!anchor) {
124-
throw HYDRATION_ERROR;
125-
}
126+
if (!anchor) {
127+
throw HYDRATION_ERROR;
128+
}
126129

127-
set_hydrating(true);
128-
set_hydrate_node(/** @type {Comment} */ (anchor));
129-
hydrate_next();
130+
set_hydrating(true);
131+
set_hydrate_node(/** @type {Comment} */ (anchor));
132+
hydrate_next();
130133

131-
const instance = _mount(component, { ...options, anchor });
134+
const instance = _mount(component, { ...options, anchor });
132135

133-
if (
134-
hydrate_node.nodeType !== 8 ||
135-
/** @type {Comment} */ (hydrate_node).data !== HYDRATION_END
136-
) {
137-
w.hydration_mismatch();
138-
throw HYDRATION_ERROR;
139-
}
136+
if (
137+
hydrate_node.nodeType !== 8 ||
138+
/** @type {Comment} */ (hydrate_node).data !== HYDRATION_END
139+
) {
140+
w.hydration_mismatch();
141+
throw HYDRATION_ERROR;
142+
}
140143

141-
set_hydrating(false);
144+
// flush_sync will run this callback and then synchronously run any pending effects,
145+
// which don't belong to the hydration phase anymore - therefore reset it here
146+
set_hydrating(false);
142147

143-
return /** @type {Exports} */ (instance);
148+
return instance;
149+
}, false);
144150
} catch (error) {
145151
if (error === HYDRATION_ERROR) {
146152
// TODO it's possible for event listeners to have been added and

packages/svelte/src/internal/client/runtime.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,10 @@ function process_effects(effect, collected_effects) {
670670
* Internal version of `flushSync` with the option to not flush previous effects.
671671
* Returns the result of the passed function, if given.
672672
* @param {() => any} [fn]
673+
* @param {boolean} [flush_previous]
673674
* @returns {any}
674675
*/
675-
export function flush_sync(fn) {
676+
export function flush_sync(fn, flush_previous = true) {
676677
var previous_scheduler_mode = current_scheduler_mode;
677678
var previous_queued_root_effects = current_queued_root_effects;
678679

@@ -686,7 +687,9 @@ export function flush_sync(fn) {
686687
current_queued_root_effects = root_effects;
687688
is_micro_task_queued = false;
688689

689-
flush_queued_root_effects(previous_queued_root_effects);
690+
if (flush_previous) {
691+
flush_queued_root_effects(previous_queued_root_effects);
692+
}
690693

691694
var result = fn?.();
692695

packages/svelte/tests/hydration/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { suite, assert_ok, type BaseTest } from '../suite.js';
88
import { createClassComponent } from 'svelte/legacy';
99
import { render } from 'svelte/server';
1010
import type { CompileOptions } from '#compiler';
11-
import { flushSync } from 'svelte';
1211

1312
interface HydrationTest extends BaseTest {
1413
load_compiled?: boolean;
@@ -115,7 +114,6 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
115114

116115
if (!override) {
117116
const expected = read(`${cwd}/_expected.html`) ?? rendered.html;
118-
flushSync();
119117
assert.equal(target.innerHTML.trim(), expected.trim());
120118
}
121119

packages/svelte/tests/runtime-browser/driver.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import config from '__CONFIG__';
55
// @ts-expect-error
66
import * as assert from 'assert.js';
77
import { createClassComponent } from 'svelte/legacy';
8-
import { flushSync } from 'svelte';
98

109
/** @param {HTMLElement} target */
1110
export default async function (target) {
@@ -46,8 +45,6 @@ export default async function (target) {
4645
} while (new Date().getTime() <= start + ms);
4746
};
4847

49-
flushSync();
50-
5148
if (config.html) {
5249
assert.htmlEqual(target.innerHTML, config.html);
5350
}

packages/svelte/tests/runtime-runes/samples/hydrate-modified-input-group/_config.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { flushSync } from 'svelte';
21
import { test } from '../../test';
32

43
export default test({
@@ -10,7 +9,6 @@ export default test({
109
inputs[1].dispatchEvent(new window.Event('change'));
1110
// Hydration shouldn't reset the value to 1
1211
hydrate();
13-
flushSync();
1412

1513
assert.htmlEqual(
1614
target.innerHTML,

packages/svelte/tests/runtime-runes/samples/hydrate-modified-input/_config.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { flushSync } from 'svelte';
21
import { test } from '../../test';
32

43
export default test({
@@ -10,7 +9,6 @@ export default test({
109
input.dispatchEvent(new window.Event('input'));
1110
// Hydration shouldn't reset the value to empty
1211
hydrate();
13-
flushSync();
1412

1513
assert.htmlEqual(target.innerHTML, '<input type="text">\nfoo');
1614
}

0 commit comments

Comments
 (0)