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

100% Statements 56/56
100% Branches 12/12
100% Functions 3/3
100% Lines 54/54

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 552x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 107x 107x 107x 8x 8x 8x 8x 14x 14x 14x 14x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 6x 8x 8x 8x 8x 8x 8x 8x 8x 8x 107x 99x 99x 99x 99x 99x 99x 99x 99x 99x 99x 107x  
/** @import { Expression } from 'estree' */
/** @import { Ast } from '#compiler' */
/** @import { ComponentContext } from '../types' */
import * as b from '../../../../utils/builders.js';
import { create_derived } from '../utils.js';
 
/**
 * @param {Ast.LetDirective} node
 * @param {ComponentContext} context
 */
export function LetDirective(node, context) {
	// let:x        -->  const x = $.derived(() => $$slotProps.x);
	// let:x={{y, z}}  -->  const derived_x = $.derived(() => { const { y, z } = $$slotProps.x; return { y, z }));
	if (node.expression && node.expression.type !== 'Identifier') {
		const name = context.state.scope.generate(node.name);
		const bindings = context.state.scope.get_bindings(node);
 
		for (const binding of bindings) {
			context.state.transform[binding.node.name] = {
				read: (node) => b.member(b.call('$.get', b.id(name)), node)
			};
		}
 
		return b.const(
			name,
			b.call(
				'$.derived',
				b.thunk(
					b.block([
						b.let(
							/** @type {Expression} */ (node.expression).type === 'ObjectExpression'
								? // @ts-expect-error types don't match, but it can't contain spread elements and the structure is otherwise fine
									b.object_pattern(node.expression.properties)
								: // @ts-expect-error types don't match, but it can't contain spread elements and the structure is otherwise fine
									b.array_pattern(node.expression.elements),
							b.member(b.id('$$slotProps'), node.name)
						),
						b.return(b.object(bindings.map((binding) => b.init(binding.node.name, binding.node))))
					])
				)
			)
		);
	} else {
		const name = node.expression === null ? node.name : node.expression.name;
		context.state.transform[name] = {
			read: (node) => b.call('$.get', node)
		};
 
		return b.const(
			name,
			create_derived(context.state, b.thunk(b.member(b.id('$$slotProps'), node.name)))
		);
	}
}