|  |  | @ -1,13 +1,19 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | /** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Pattern, Property, SequenceExpression, Statement } from 'estree' */ |  |  |  | /** @import { BlockStatement, Expression, ExpressionStatement, Identifier, MemberExpression, Pattern, Property, SequenceExpression, Statement } from 'estree' */ | 
			
		
	
		
		
			
				
					
					|  |  |  | /** @import { AST } from '#compiler' */ |  |  |  | /** @import { AST } from '#compiler' */ | 
			
		
	
		
		
			
				
					
					|  |  |  | /** @import { ComponentContext } from '../../types.js' */ |  |  |  | /** @import { ComponentContext, MemoizedExpression } from '../../types.js' */ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | import { dev, is_ignored } from '../../../../../state.js'; |  |  |  | import { dev, is_ignored } from '../../../../../state.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import { get_attribute_chunks, object } from '../../../../../utils/ast.js'; |  |  |  | import { get_attribute_chunks, object } from '../../../../../utils/ast.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import * as b from '../../../../../utils/builders.js'; |  |  |  | import * as b from '../../../../../utils/builders.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import { build_bind_this, memoize_expression, validate_binding } from '../shared/utils.js'; |  |  |  | import { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	build_bind_this, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	get_expression_id, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	memoize_expression, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	validate_binding | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } from '../shared/utils.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import { build_attribute_value } from '../shared/element.js'; |  |  |  | import { build_attribute_value } from '../shared/element.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import { build_event_handler } from './events.js'; |  |  |  | import { build_event_handler } from './events.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | import { determine_slot } from '../../../../../utils/slot.js'; |  |  |  | import { determine_slot } from '../../../../../utils/slot.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import { create_derived } from '../../utils.js'; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /** |  |  |  | /** | 
			
		
	
		
		
			
				
					
					|  |  |  |  * @param {AST.Component | AST.SvelteComponent | AST.SvelteSelf} node |  |  |  |  * @param {AST.Component | AST.SvelteComponent | AST.SvelteSelf} node | 
			
		
	
	
		
		
			
				
					|  |  | @ -40,6 +46,12 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/** @type {Record<string, Expression[]>} */ |  |  |  | 	/** @type {Record<string, Expression[]>} */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	const events = {}; |  |  |  | 	const events = {}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** @type {MemoizedExpression[]} */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	const expressions = []; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	/** @type {MemoizedExpression[]} */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	const async_expressions = []; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/** @type {Property[]} */ |  |  |  | 	/** @type {Property[]} */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	const custom_css_props = []; |  |  |  | 	const custom_css_props = []; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -115,16 +127,21 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 			(events[attribute.name] ||= []).push(handler); |  |  |  | 			(events[attribute.name] ||= []).push(handler); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else if (attribute.type === 'SpreadAttribute') { |  |  |  | 		} else if (attribute.type === 'SpreadAttribute') { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			const expression = /** @type {Expression} */ (context.visit(attribute)); |  |  |  | 			const expression = /** @type {Expression} */ (context.visit(attribute)); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (attribute.metadata.expression.has_state) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				let value = expression; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if (attribute.metadata.expression.has_call) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					const id = b.id(context.state.scope.generate('spread_element')); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					context.state.init.push(b.var(id, b.call('$.derived', b.thunk(value)))); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					value = b.call('$.get', id); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				props_and_spreads.push(b.thunk(value)); |  |  |  | 			if (attribute.metadata.expression.has_state) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				props_and_spreads.push( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					b.thunk( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						attribute.metadata.expression.is_async || attribute.metadata.expression.has_call | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							? b.call( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 									'$.get', | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 									get_expression_id( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 										attribute.metadata.expression.is_async ? async_expressions : expressions, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 										expression | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 									) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							: expression | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} else { |  |  |  | 			} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				props_and_spreads.push(expression); |  |  |  | 				props_and_spreads.push(expression); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
	
		
		
			
				
					|  |  | @ -133,10 +150,15 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 				custom_css_props.push( |  |  |  | 				custom_css_props.push( | 
			
		
	
		
		
			
				
					
					|  |  |  | 					b.init( |  |  |  | 					b.init( | 
			
		
	
		
		
			
				
					
					|  |  |  | 						attribute.name, |  |  |  | 						attribute.name, | 
			
		
	
		
		
			
				
					
					|  |  |  | 						build_attribute_value(attribute.value, context, (value, metadata) => |  |  |  | 						build_attribute_value(attribute.value, context, (value, metadata) => { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 							// TODO put the derived in the local block
 |  |  |  | 							// TODO put the derived in the local block
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 							metadata.has_call ? memoize_expression(context.state, value) : value |  |  |  | 							return metadata.has_call || metadata.is_async | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 						).value |  |  |  | 								? b.call( | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 										'$.get', | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 										get_expression_id(metadata.is_async ? async_expressions : expressions, value) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 									) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								: value; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						}).value | 
			
		
	
		
		
			
				
					
					|  |  |  | 					) |  |  |  | 					) | 
			
		
	
		
		
			
				
					
					|  |  |  | 				); |  |  |  | 				); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				continue; |  |  |  | 				continue; | 
			
		
	
	
		
		
			
				
					|  |  | @ -154,7 +176,7 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 				attribute.value, |  |  |  | 				attribute.value, | 
			
		
	
		
		
			
				
					
					|  |  |  | 				context, |  |  |  | 				context, | 
			
		
	
		
		
			
				
					
					|  |  |  | 				(value, metadata) => { |  |  |  | 				(value, metadata) => { | 
			
		
	
		
		
			
				
					
					|  |  |  | 					if (!metadata.has_state) return value; |  |  |  | 					if (!metadata.has_state && !metadata.is_async) return value; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					// When we have a non-simple computation, anything other than an Identifier or Member expression,
 |  |  |  | 					// When we have a non-simple computation, anything other than an Identifier or Member expression,
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					// then there's a good chance it needs to be memoized to avoid over-firing when read within the
 |  |  |  | 					// then there's a good chance it needs to be memoized to avoid over-firing when read within the
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -167,7 +189,12 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 						); |  |  |  | 						); | 
			
		
	
		
		
			
				
					
					|  |  |  | 					}); |  |  |  | 					}); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					return should_wrap_in_derived ? memoize_expression(context.state, value) : value; |  |  |  | 					return should_wrap_in_derived | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						? b.call( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								'$.get', | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 								get_expression_id(metadata.is_async ? async_expressions : expressions, value) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						: value; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 			); |  |  |  | 			); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -420,7 +447,12 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 		}; |  |  |  | 		}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	const statements = [...snippet_declarations]; |  |  |  | 	const statements = [ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		...snippet_declarations, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		...expressions.map((memo) => | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			b.let(memo.id, create_derived(context.state, b.thunk(memo.expression))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (node.type === 'SvelteComponent') { |  |  |  | 	if (node.type === 'SvelteComponent') { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const prev = fn; |  |  |  | 		const prev = fn; | 
			
		
	
	
		
		
			
				
					|  |  | @ -457,5 +489,20 @@ export function build_component(node, component_name, context, anchor = context. | 
			
		
	
		
		
			
				
					
					|  |  |  | 		statements.push(b.stmt(fn(anchor))); |  |  |  | 		statements.push(b.stmt(fn(anchor))); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	[...async_expressions, ...expressions].forEach((memo, i) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		memo.id.name = `$${i}`; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	}); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (async_expressions.length > 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return b.stmt( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			b.call( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				'$.async', | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				anchor, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				b.array(async_expressions.map(({ expression }) => b.thunk(expression, true))), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				b.arrow([b.id('$$anchor'), ...async_expressions.map(({ id }) => id)], b.block(statements)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return statements.length > 1 ? b.block(statements) : statements[0]; |  |  |  | 	return statements.length > 1 ? b.block(statements) : statements[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |