fix: reset hydrate_node after `hydrate(...)` (#12512)

pull/12517/head
Rich Harris 5 months ago committed by GitHub
parent 30b143cef0
commit f402d01454
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: reset hydrate node after `hydrate(...)`

@ -119,6 +119,7 @@ export function hydrate(component, options) {
options.intro = options.intro ?? false; options.intro = options.intro ?? false;
const target = options.target; const target = options.target;
const was_hydrating = hydrating; const was_hydrating = hydrating;
const previous_hydrate_node = hydrate_node;
try { try {
// Don't flush previous effects to ensure order of outer effects stays consistent // Don't flush previous effects to ensure order of outer effects stays consistent
@ -175,6 +176,7 @@ export function hydrate(component, options) {
throw error; throw error;
} finally { } finally {
set_hydrating(was_hydrating); set_hydrating(was_hydrating);
set_hydrate_node(previous_hydrate_node);
reset_head_anchor(); reset_head_anchor();
} }
} }

@ -35,6 +35,7 @@ export interface RuntimeTest<Props extends Record<string, any> = Record<string,
ssrHtml?: string; ssrHtml?: string;
compileOptions?: Partial<CompileOptions>; compileOptions?: Partial<CompileOptions>;
props?: Props; props?: Props;
server_props?: Props;
before_test?: () => void; before_test?: () => void;
after_test?: () => void; after_test?: () => void;
test?: (args: { test?: (args: {
@ -256,7 +257,9 @@ async function run_test_variant(
config.before_test?.(); config.before_test?.();
// ssr into target // ssr into target
const SsrSvelteComponent = (await import(`${cwd}/_output/server/main.svelte.js`)).default; const SsrSvelteComponent = (await import(`${cwd}/_output/server/main.svelte.js`)).default;
const { html, head } = render(SsrSvelteComponent, { props: config.props || {} }); const { html, head } = render(SsrSvelteComponent, {
props: config.server_props ?? config.props ?? {}
});
fs.writeFileSync(`${cwd}/_output/rendered.html`, html); fs.writeFileSync(`${cwd}/_output/rendered.html`, html);
target.innerHTML = html; target.innerHTML = html;

@ -0,0 +1,7 @@
<script>
let count = $state(0);
</script>
<button onclick={() => (count += 1)}>
clicks: {count}
</button>

@ -0,0 +1,21 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
props: {
browser: true
},
server_props: {
browser: false
},
html: `<div><button>clicks: 0</button></div>`,
test({ target, assert }) {
const button = target.querySelector('button');
flushSync(() => button?.click());
assert.htmlEqual(target.innerHTML, `<div><button>clicks: 1</button></div>`);
}
});

@ -0,0 +1,20 @@
<script>
import { createRawSnippet, hydrate } from 'svelte';
import { render } from 'svelte/server';
import Child from './Child.svelte';
let { browser } = $props();
let count = $state(0);
const hello = createRawSnippet((count) => ({
render: () => `
<div>${browser ? '' : render(Child).body}</div>
`,
setup(target) {
hydrate(Child, { target })
}
}));
</script>
{@render hello()}
Loading…
Cancel
Save