pull/17038/head
Rich Harris 4 weeks ago
parent 47f0ae5773
commit b7510b016d

@ -23,12 +23,20 @@ export function IfBlock(node, context) {
/** @type {Statement} */
let statement = b.if(test, consequent, alternate);
if (
const is_async = node.metadata.expression.is_async();
const has_await =
node.metadata.expression.has_await ||
// TODO get rid of this stuff
node.consequent.metadata.has_await ||
node.alternate?.metadata.has_await
) {
statement = create_async_block(b.block([statement]));
node.alternate?.metadata.has_await;
if (is_async || has_await) {
statement = create_async_block(
b.block([statement]),
node.metadata.expression.blockers(),
!!has_await
);
}
context.state.template.push(statement, block_close);

@ -1,4 +1,4 @@
/** @import { Expression, Identifier, Node, Statement, BlockStatement } from 'estree' */
/** @import { Expression, Identifier, Node, Statement, BlockStatement, ArrayExpression } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext, ServerTransformState } from '../../types.js' */
@ -275,9 +275,13 @@ export function create_child_block(body, async) {
/**
* Creates a `$$renderer.async(...)` expression statement
* @param {BlockStatement | Expression} body
* @param {ArrayExpression} blockers
* @param {boolean} has_await
*/
export function create_async_block(body) {
return b.stmt(b.call('$$renderer.async', b.arrow([b.id('$$renderer')], body, true)));
export function create_async_block(body, blockers, has_await) {
return b.stmt(
b.call('$$renderer.async', blockers, b.arrow([b.id('$$renderer')], body, has_await))
);
}
/**

@ -100,18 +100,41 @@ export class Renderer {
}
/**
* @param {Array<Promise<void>>} blockers
* @param {(renderer: Renderer) => void} fn
*/
async(fn) {
async(blockers, fn) {
this.#out.push(BLOCK_OPEN);
this.child(fn);
this.child(
blockers.length > 0 ? (renderer) => Promise.all(blockers).then(() => fn(renderer)) : fn
);
this.#out.push(BLOCK_CLOSE);
}
/**
* @param {Array<() => void>} thunks
*/
run(thunks) {}
run(thunks) {
const context = ssr_context;
let promise = Promise.resolve(thunks[0]());
const promises = [promise];
for (const fn of thunks.slice(1)) {
promise = promise.then(() => {
const previous_ssr_context = ssr_context;
set_ssr_context(context);
try {
return fn();
} finally {
set_ssr_context(previous_ssr_context);
}
});
}
return promises;
}
/**
* Create a child renderer. The child renderer inherits the state from the parent,

@ -0,0 +1,16 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
skip_mode: ['server'],
ssrHtml: '<p>yep</p>',
async test({ assert, target, variant }) {
if (variant === 'dom') {
await tick();
}
assert.htmlEqual(target.innerHTML, '<p>yep</p>');
}
});

@ -0,0 +1,10 @@
<script>
await 0;
const condition = await true;
</script>
{#if condition}
<p>yep</p>
{:else}
<p>nope</p>
{/if}
Loading…
Cancel
Save