fix: resolve boundary in correct batch when hydrating (#17914)

Fixes #17907. When hydrating, we were resolving the boundary in the
hydration batch rather than the batch created inside the
`queue_micro_task` inside `#hydrate_pending_content`. This meant that
effects got scheduled inside a batch that was already resolved.

### Before submitting the PR, please make sure you do the following

- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).

### Tests and linting

- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
pull/17901/head
Rich Harris 5 days ago committed by GitHub
parent 667896a753
commit 7c9ff8fc69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: resolve boundary in correct batch when hydrating

@ -218,8 +218,6 @@ export class Boundary {
this.is_pending = true;
this.#pending_effect = branch(() => pending(this.#anchor));
var batch = /** @type {Batch} */ (current_batch);
queue_micro_task(() => {
var fragment = (this.#offscreen_fragment = document.createDocumentFragment());
var anchor = create_text();
@ -238,14 +236,12 @@ export class Boundary {
this.#pending_effect = null;
});
this.#resolve(batch);
this.#resolve(/** @type {Batch} */ (current_batch));
}
});
}
#render() {
var batch = /** @type {Batch} */ (current_batch);
try {
this.is_pending = this.has_pending_snippet();
this.#pending_count = 0;
@ -262,7 +258,7 @@ export class Boundary {
const pending = /** @type {(anchor: Node) => void} */ (this.#props.pending);
this.#pending_effect = branch(() => pending(this.#anchor));
} else {
this.#resolve(batch);
this.#resolve(/** @type {Batch} */ (current_batch));
}
} catch (error) {
this.error(error);

@ -0,0 +1,5 @@
<script lang="ts">
$effect(() => {
console.log('hello from child');
});
</script>

@ -0,0 +1,7 @@
import { test } from '../../test';
export default test({
async test({ assert, logs }) {
assert.deepEqual(logs, ['hello from child']);
}
});

@ -0,0 +1,11 @@
<script>
import Child from './Child.svelte';
</script>
<svelte:boundary>
<Child />
{#snippet pending()}
<p>Loading...</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save