only suspend in top-level async deriveds

aa-coordination
Rich Harris 8 months ago
parent 80b713a85e
commit 0dc84ab2a2

@ -29,6 +29,7 @@ import { get_stack } from '../dev/tracing.js';
import { tracing_mode_flag } from '../../flags/index.js';
import { capture, suspend } from '../dom/blocks/boundary.js';
import { component_context } from '../context.js';
import { noop } from '../../shared/utils.js';
/** @type {Effect | null} */
export let from_async_derived = null;
@ -100,6 +101,9 @@ export function async_derived(fn, detect_waterfall = true) {
var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined));
var value = source(/** @type {V} */ (undefined));
// only suspend in async deriveds created on initialisation
var should_suspend = !active_reaction;
// TODO this isn't a block
block(async () => {
if (DEV) from_async_derived = active_effect;
@ -107,7 +111,7 @@ export function async_derived(fn, detect_waterfall = true) {
if (DEV) from_async_derived = null;
var restore = capture();
var unsuspend = suspend();
var unsuspend = should_suspend ? suspend() : noop;
try {
var v = await promise;

@ -0,0 +1,11 @@
<script>
let { count } = $props();
async function x() {
let d = $derived(await new Promise((f) => {}));
}
let indirect = $derived(x() && count);
</script>
<p>{indirect}</p>

@ -0,0 +1,14 @@
import { flushSync, tick } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
await tick();
assert.htmlEqual(target.innerHTML, '<button>0</button><p>0</p>');
const button = target.querySelector('button');
flushSync(() => button?.click());
assert.htmlEqual(target.innerHTML, '<button>1</button><p>1</p>');
}
});

@ -0,0 +1,17 @@
<script>
import Child from './Child.svelte';
let count = $state(0);
</script>
<button onclick={() => count += 1}>{count}</button>
<svelte:boundary>
<Child {count} />
{#snippet pending()}
<p>pending</p>
{/snippet}
</svelte:boundary>
{console.log(`outside boundary ${count}`)}
Loading…
Cancel
Save