diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js index d6834c5ab0..71e8b2ad77 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RenderTag.js @@ -23,10 +23,10 @@ export function RenderTag(node, context) { const arg = /** @type {Expression} */ (call.arguments[i]); const metadata = node.metadata.arguments[i]; - let expression = build_expression(context, arg, metadata); + let expression = memoizer.add(build_expression(context, arg, metadata), metadata); if (metadata.has_await || metadata.has_call) { - expression = b.call('$.get', memoizer.add(expression, metadata)); + expression = b.call('$.get', expression); } args.push(b.thunk(expression)); diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js index 132a83ec60..b8d2e42144 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js @@ -25,8 +25,12 @@ export function AwaitBlock(node, context) { ) ); - if (node.metadata.expression.has_await) { - statement = create_async_block(b.block([statement])); + if (node.metadata.expression.is_async()) { + statement = create_async_block( + b.block([statement]), + node.metadata.expression.blockers(), + node.metadata.expression.has_await + ); } context.state.template.push(statement, block_close); diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js index 4ec686bb89..6d7cef0d95 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js @@ -3,32 +3,48 @@ /** @import { ComponentContext } from '../types.js' */ import { unwrap_optional } from '../../../../utils/ast.js'; import * as b from '#compiler/builders'; -import { empty_comment } from './shared/utils.js'; +import { create_async_block, empty_comment, PromiseOptimiser } from './shared/utils.js'; /** * @param {AST.RenderTag} node * @param {ComponentContext} context */ export function RenderTag(node, context) { + const optimiser = new PromiseOptimiser(); + const callee = unwrap_optional(node.expression).callee; const raw_args = unwrap_optional(node.expression).arguments; - const snippet_function = /** @type {Expression} */ (context.visit(callee)); + const snippet_function = optimiser.transform( + /** @type {Expression} */ (context.visit(callee)), + node.metadata.expression + ); - const snippet_args = raw_args.map((arg) => { - return /** @type {Expression} */ (context.visit(arg)); + const snippet_args = raw_args.map((arg, i) => { + return optimiser.transform( + /** @type {Expression} */ (context.visit(arg)), + node.metadata.arguments[i] + ); }); - context.state.template.push( - b.stmt( - (node.expression.type === 'CallExpression' ? b.call : b.maybe_call)( - snippet_function, - b.id('$$renderer'), - ...snippet_args - ) + let statement = b.stmt( + (node.expression.type === 'CallExpression' ? b.call : b.maybe_call)( + snippet_function, + b.id('$$renderer'), + ...snippet_args ) ); + if (optimiser.is_async()) { + statement = create_async_block( + b.block([optimiser.apply(), statement]), + optimiser.blockers(), + optimiser.has_await + ); + } + + context.state.template.push(statement); + if (!context.state.skip_hydration_boundaries) { context.state.template.push(empty_comment); } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js index 5841aa44d8..d0f8e25d02 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js @@ -65,10 +65,13 @@ export function SlotElement(node, context) { fallback ); - const statement = - optimiser.expressions.length > 0 - ? create_async_block(b.block([optimiser.apply(), b.stmt(slot)])) - : b.stmt(slot); + const statement = optimiser.is_async() + ? create_async_block( + b.block([optimiser.apply(), b.stmt(slot)]), + optimiser.blockers(), + optimiser.has_await + ) + : b.stmt(slot); context.state.template.push(block_open, statement, block_close); }