pull/16200/merge
Rich Harris 1 week ago
parent 4e847cfd14
commit 523c85bd3d

@ -1,5 +0,0 @@
---
'svelte': patch
---
fix: coordinate mount of snippets with await expressions

@ -30,7 +30,6 @@ import {
skip_nodes,
set_hydrate_node
} from '../hydration.js';
import { create_text } from '../operations.js';
import { queue_micro_task } from '../task.js';
import * as e from '../../errors.js';
import * as w from '../../warnings.js';
@ -93,9 +92,6 @@ export class Boundary {
/** @type {DocumentFragment | null} */
#offscreen_fragment = null;
/** @type {TemplateNode | null} */
#pending_anchor = null;
#local_pending_count = 0;
#pending_count = 0;
@ -159,17 +155,8 @@ export class Boundary {
this.#hydrate_resolved_content();
}
} else {
var anchor = this.#anchor;
if (this.#pending) {
this.#pending_anchor = create_text();
this.#anchor.before(this.#pending_anchor);
anchor = this.#pending_anchor;
}
try {
this.#main_effect = branch(() => children(anchor));
this.#main_effect = branch(() => children(this.#anchor));
} catch (error) {
this.error(error);
}
@ -178,7 +165,6 @@ export class Boundary {
this.#show_pending_snippet();
} else {
this.#pending = false;
this.#pending_anchor?.remove();
}
}
}, flags);
@ -208,18 +194,9 @@ export class Boundary {
this.#pending_effect = branch(() => pending(this.#anchor));
Batch.enqueue(() => {
var anchor = this.#anchor;
if (this.#pending) {
this.#pending_anchor = create_text();
this.#anchor.before(this.#pending_anchor);
anchor = this.#pending_anchor;
}
this.#main_effect = this.#run(() => {
Batch.ensure();
return branch(() => this.#children(anchor));
return branch(() => this.#children(this.#anchor));
});
if (this.#pending_count > 0) {
@ -230,7 +207,6 @@ export class Boundary {
});
this.#pending = false;
this.#pending_anchor?.remove();
}
});
}
@ -276,7 +252,6 @@ export class Boundary {
if (this.#main_effect !== null) {
this.#offscreen_fragment = document.createDocumentFragment();
this.#offscreen_fragment.append(/** @type {TemplateNode} */ (this.#pending_anchor));
move_effect(this.#main_effect, this.#offscreen_fragment);
}
@ -312,7 +287,6 @@ export class Boundary {
}
if (this.#offscreen_fragment) {
this.#pending_anchor?.remove();
this.#anchor.before(this.#offscreen_fragment);
this.#offscreen_fragment = null;
}

@ -1,8 +0,0 @@
<script>
let { children, push } = $props();
let message = await push('hello from child');
</script>
<p>message: {message}</p>
{@render children()}

@ -1,25 +0,0 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
const [shift] = target.querySelectorAll('button');
shift.click();
await tick();
assert.htmlEqual(target.innerHTML, `<button>shift</button><p>loading...</p>`);
shift.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>shift</button>
<p>message: hello from child</p>
<p>hello from parent</p>
`
);
}
});

@ -1,23 +0,0 @@
<script>
import Child from './Child.svelte';
const resolvers = [];
function push(value) {
const { promise, resolve } = Promise.withResolvers();
resolvers.push(() => resolve(value));
return promise;
}
</script>
<button onclick={() => resolvers.shift()?.()}>shift</button>
<svelte:boundary>
<Child {push}>
<p>{await push('hello from parent')}</p>
</Child>
{#snippet pending()}
<p>loading...</p>
{/snippet}
</svelte:boundary>
Loading…
Cancel
Save