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 89x 89x 89x 89x 89x 89x 89x 89x 89x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 77x 89x 89x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 50x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x 89x  
/** @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
			)
		)
	);
}