44import { dev , is_ignored } from '../../../../../state.js' ;
55import { get_attribute_chunks , object } from '../../../../../utils/ast.js' ;
66import * as b from '#compiler/builders' ;
7- import {
8- build_bind_this ,
9- memoize_expression ,
10- validate_binding ,
11- add_svelte_meta
12- } from '../shared/utils.js' ;
7+ import { add_svelte_meta , build_bind_this , Memoizer , validate_binding } from '../shared/utils.js' ;
138import { build_attribute_value } from '../shared/element.js' ;
149import { build_event_handler } from './events.js' ;
1510import { determine_slot } from '../../../../../utils/slot.js' ;
@@ -48,6 +43,8 @@ export function build_component(node, component_name, context) {
4843 /** @type {Record<string, Expression[]> } */
4944 const events = { } ;
5045
46+ const memoizer = new Memoizer ( ) ;
47+
5148 /** @type {Property[] } */
5249 const custom_css_props = [ ] ;
5350
@@ -133,15 +130,13 @@ export function build_component(node, component_name, context) {
133130 } else if ( attribute . type === 'SpreadAttribute' ) {
134131 const expression = /** @type {Expression } */ ( context . visit ( attribute ) ) ;
135132 if ( attribute . metadata . expression . has_state ) {
136- let value = expression ;
137-
138- if ( attribute . metadata . expression . has_call ) {
139- const id = b . id ( context . state . scope . generate ( 'spread_element' ) ) ;
140- context . state . init . push ( b . var ( id , b . call ( '$.derived' , b . thunk ( value ) ) ) ) ;
141- value = b . call ( '$.get' , id ) ;
142- }
143-
144- props_and_spreads . push ( b . thunk ( value ) ) ;
133+ props_and_spreads . push (
134+ b . thunk (
135+ attribute . metadata . expression . has_call
136+ ? b . call ( '$.get' , memoizer . add ( expression ) )
137+ : expression
138+ )
139+ ) ;
145140 } else {
146141 props_and_spreads . push ( expression ) ;
147142 }
@@ -150,10 +145,10 @@ export function build_component(node, component_name, context) {
150145 custom_css_props . push (
151146 b . init (
152147 attribute . name ,
153- build_attribute_value ( attribute . value , context , ( value , metadata ) =>
148+ build_attribute_value ( attribute . value , context , ( value , metadata ) => {
154149 // TODO put the derived in the local block
155- metadata . has_call ? memoize_expression ( context . state , value ) : value
156- ) . value
150+ return metadata . has_call ? b . call ( '$.get' , memoizer . add ( value ) ) : value ;
151+ } ) . value
157152 )
158153 ) ;
159154 continue ;
@@ -184,7 +179,7 @@ export function build_component(node, component_name, context) {
184179 ) ;
185180 } ) ;
186181
187- return should_wrap_in_derived ? memoize_expression ( context . state , value ) : value ;
182+ return should_wrap_in_derived ? b . call ( '$.get' , memoizer . add ( value ) ) : value ;
188183 }
189184 ) ;
190185
@@ -444,7 +439,7 @@ export function build_component(node, component_name, context) {
444439 } ;
445440 }
446441
447- const statements = [ ...snippet_declarations ] ;
442+ const statements = [ ...snippet_declarations , ... memoizer . deriveds ( context . state . analysis . runes ) ] ;
448443
449444 if ( is_component_dynamic ) {
450445 const prev = fn ;
@@ -492,5 +487,7 @@ export function build_component(node, component_name, context) {
492487 statements . push ( add_svelte_meta ( fn ( anchor ) , node , 'component' , { componentTag : node . name } ) ) ;
493488 }
494489
490+ memoizer . apply ( ) ;
491+
495492 return statements . length > 1 ? b . block ( statements ) : statements [ 0 ] ;
496493}
0 commit comments