1
- /** @import { BlockStatement, Expression, Identifier, Pattern, Statement } from 'estree' */
1
+ /** @import { BlockStatement, Expression, Identifier, Pattern, SequenceExpression, Statement } from 'estree' */
2
2
/** @import { AST, Binding } from '#compiler' */
3
3
/** @import { ComponentContext } from '../types' */
4
4
/** @import { Scope } from '../../../scope' */
@@ -106,16 +106,6 @@ export function EachBlock(node, context) {
106
106
}
107
107
}
108
108
109
- // Legacy mode: find the parent each blocks which contain the arrays to invalidate
110
- const indirect_dependencies = collect_parent_each_blocks ( context ) . flatMap ( ( block ) => {
111
- const array = /** @type {Expression } */ ( context . visit ( block . expression ) ) ;
112
- const transitive_dependencies = build_transitive_dependencies (
113
- block . metadata . expression . dependencies ,
114
- context
115
- ) ;
116
- return [ array , ...transitive_dependencies ] ;
117
- } ) ;
118
-
119
109
/** @type {Identifier | null } */
120
110
let collection_id = null ;
121
111
@@ -129,18 +119,6 @@ export function EachBlock(node, context) {
129
119
}
130
120
}
131
121
132
- if ( collection_id ) {
133
- indirect_dependencies . push ( b . call ( collection_id ) ) ;
134
- } else {
135
- indirect_dependencies . push ( collection ) ;
136
-
137
- const transitive_dependencies = build_transitive_dependencies (
138
- each_node_meta . expression . dependencies ,
139
- context
140
- ) ;
141
- indirect_dependencies . push ( ...transitive_dependencies ) ;
142
- }
143
-
144
122
const child_state = {
145
123
...context . state ,
146
124
transform : { ...context . state . transform } ,
@@ -181,19 +159,51 @@ export function EachBlock(node, context) {
181
159
/** @type {Statement[] } */
182
160
const declarations = [ ] ;
183
161
184
- const invalidate = b . call (
185
- '$.invalidate_inner_signals' ,
186
- b . thunk ( b . sequence ( indirect_dependencies ) )
187
- ) ;
188
-
189
162
const invalidate_store = store_to_invalidate
190
163
? b . call ( '$.invalidate_store' , b . id ( '$$stores' ) , b . literal ( store_to_invalidate ) )
191
164
: undefined ;
192
165
193
166
/** @type {Expression[] } */
194
167
const sequence = [ ] ;
195
- if ( ! context . state . analysis . runes ) sequence . push ( invalidate ) ;
196
- if ( invalidate_store ) sequence . push ( invalidate_store ) ;
168
+
169
+ if ( ! context . state . analysis . runes ) {
170
+ /** @type {Set<Identifier> } */
171
+ const transitive_deps = new Set ( ) ;
172
+
173
+ if ( collection_id ) {
174
+ transitive_deps . add ( collection_id ) ;
175
+ child_state . transform [ collection_id . name ] = { read : b . call } ;
176
+ } else {
177
+ for ( const binding of each_node_meta . transitive_deps ) {
178
+ transitive_deps . add ( binding . node ) ;
179
+ }
180
+ }
181
+
182
+ for ( const block of collect_parent_each_blocks ( context ) ) {
183
+ for ( const binding of block . metadata . transitive_deps ) {
184
+ transitive_deps . add ( binding . node ) ;
185
+ }
186
+ }
187
+
188
+ if ( transitive_deps . size > 0 ) {
189
+ const invalidate = b . call (
190
+ '$.invalidate_inner_signals' ,
191
+ b . thunk (
192
+ b . sequence (
193
+ [ ...transitive_deps ] . map (
194
+ ( node ) => /** @type {Expression } */ ( context . visit ( { ...node } , child_state ) )
195
+ )
196
+ )
197
+ )
198
+ ) ;
199
+
200
+ sequence . push ( invalidate ) ;
201
+ }
202
+ }
203
+
204
+ if ( invalidate_store ) {
205
+ sequence . push ( invalidate_store ) ;
206
+ }
197
207
198
208
if ( node . context ?. type === 'Identifier' ) {
199
209
const binding = /** @type {Binding } */ ( context . state . scope . get ( node . context . name ) ) ;
@@ -329,41 +339,3 @@ export function EachBlock(node, context) {
329
339
function collect_parent_each_blocks ( context ) {
330
340
return /** @type {AST.EachBlock[] } */ ( context . path . filter ( ( node ) => node . type === 'EachBlock' ) ) ;
331
341
}
332
-
333
- /**
334
- * @param {Set<Binding> } references
335
- * @param {ComponentContext } context
336
- */
337
- function build_transitive_dependencies ( references , context ) {
338
- /** @type {Set<Binding> } */
339
- const dependencies = new Set ( ) ;
340
-
341
- for ( const ref of references ) {
342
- const deps = collect_transitive_dependencies ( ref ) ;
343
- for ( const dep of deps ) {
344
- dependencies . add ( dep ) ;
345
- }
346
- }
347
-
348
- return [ ...dependencies ] . map ( ( dep ) => build_getter ( { ...dep . node } , context . state ) ) ;
349
- }
350
-
351
- /**
352
- * @param {Binding } binding
353
- * @param {Set<Binding> } seen
354
- * @returns {Binding[] }
355
- */
356
- function collect_transitive_dependencies ( binding , seen = new Set ( ) ) {
357
- if ( binding . kind !== 'legacy_reactive' ) return [ ] ;
358
-
359
- for ( const dep of binding . legacy_dependencies ) {
360
- if ( ! seen . has ( dep ) ) {
361
- seen . add ( dep ) ;
362
- for ( const transitive_dep of collect_transitive_dependencies ( dep , seen ) ) {
363
- seen . add ( transitive_dep ) ;
364
- }
365
- }
366
- }
367
-
368
- return [ ...seen ] ;
369
- }
0 commit comments