All files / src/compiler/phases/3-transform/client/visitors AwaitBlock.js

100% Statements 69/69
100% Branches 13/13
100% Functions 1/1
100% Lines 67/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 682x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 90x 90x 90x 90x 90x 90x 90x 90x 90x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 78x 90x 90x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x  
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types' */
import * as b from '../../../../utils/builders.js';
import { create_derived_block_argument } from '../utils.js';
 
/**
 * @param {AST.AwaitBlock} node
 * @param {ComponentContext} context
 */
export function AwaitBlock(node, context) {
	context.state.template.push('<!>');
 
	// Visit {#await <expression>} first to ensure that scopes are in the correct order
	const expression = b.thunk(/** @type {Expression} */ (context.visit(node.expression)));
 
	let then_block;
	let catch_block;
 
	if (node.then) {
		const then_context = {
			...context,
			state: { ...context.state, transform: { ...context.state.transform } }
		};
		const argument = node.value && create_derived_block_argument(node.value, then_context);
 
		/** @type {Pattern[]} */
		const args = [b.id('$$anchor')];
		if (argument) args.push(argument.id);
 
		const declarations = argument?.declarations ?? [];
		const block = /** @type {BlockStatement} */ (then_context.visit(node.then, then_context.state));
 
		then_block = b.arrow(args, b.block([...declarations, ...block.body]));
	}
 
	if (node.catch) {
		const catch_context = { ...context, state: { ...context.state } };
		const argument = node.error && create_derived_block_argument(node.error, catch_context);
 
		/** @type {Pattern[]} */
		const args = [b.id('$$anchor')];
		if (argument) args.push(argument.id);
 
		const declarations = argument?.declarations ?? [];
		const block = /** @type {BlockStatement} */ (
			catch_context.visit(node.catch, catch_context.state)
		);
 
		catch_block = b.arrow(args, b.block([...declarations, ...block.body]));
	}
 
	context.state.init.push(
		b.stmt(
			b.call(
				'$.await',
				context.state.node,
				expression,
				node.pending
					? b.arrow([b.id('$$anchor')], /** @type {BlockStatement} */ (context.visit(node.pending)))
					: b.literal(null),
				then_block,
				catch_block
			)
		)
	);
}