4
4
import { dev , is_ignored } from '../../../../../state.js' ;
5
5
import { get_attribute_chunks , object } from '../../../../../utils/ast.js' ;
6
6
import * 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' ;
13
8
import { build_attribute_value } from '../shared/element.js' ;
14
9
import { build_event_handler } from './events.js' ;
15
10
import { determine_slot } from '../../../../../utils/slot.js' ;
@@ -48,6 +43,8 @@ export function build_component(node, component_name, context) {
48
43
/** @type {Record<string, Expression[]> } */
49
44
const events = { } ;
50
45
46
+ const memoizer = new Memoizer ( ) ;
47
+
51
48
/** @type {Property[] } */
52
49
const custom_css_props = [ ] ;
53
50
@@ -133,15 +130,13 @@ export function build_component(node, component_name, context) {
133
130
} else if ( attribute . type === 'SpreadAttribute' ) {
134
131
const expression = /** @type {Expression } */ ( context . visit ( attribute ) ) ;
135
132
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
+ ) ;
145
140
} else {
146
141
props_and_spreads . push ( expression ) ;
147
142
}
@@ -150,10 +145,10 @@ export function build_component(node, component_name, context) {
150
145
custom_css_props . push (
151
146
b . init (
152
147
attribute . name ,
153
- build_attribute_value ( attribute . value , context , ( value , metadata ) =>
148
+ build_attribute_value ( attribute . value , context , ( value , metadata ) => {
154
149
// 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
157
152
)
158
153
) ;
159
154
continue ;
@@ -184,7 +179,7 @@ export function build_component(node, component_name, context) {
184
179
) ;
185
180
} ) ;
186
181
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 ;
188
183
}
189
184
) ;
190
185
@@ -444,7 +439,7 @@ export function build_component(node, component_name, context) {
444
439
} ;
445
440
}
446
441
447
- const statements = [ ...snippet_declarations ] ;
442
+ const statements = [ ...snippet_declarations , ... memoizer . deriveds ( context . state . analysis . runes ) ] ;
448
443
449
444
if ( is_component_dynamic ) {
450
445
const prev = fn ;
@@ -492,5 +487,7 @@ export function build_component(node, component_name, context) {
492
487
statements . push ( add_svelte_meta ( fn ( anchor ) , node , 'component' , { componentTag : node . name } ) ) ;
493
488
}
494
489
490
+ memoizer . apply ( ) ;
491
+
495
492
return statements . length > 1 ? b . block ( statements ) : statements [ 0 ] ;
496
493
}
0 commit comments