File tree 4 files changed +40
-5
lines changed
src/internal/client/proxy
tests/runtime-runes/samples/proxy-array-length
4 files changed +40
-5
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ ' svelte ' : patch
3
+ ---
4
+
5
+ fix: ensure proxied array length is updated
Original file line number Diff line number Diff line change @@ -139,23 +139,34 @@ const handler = {
139
139
target [ READONLY_SYMBOL ] = value ;
140
140
return true ;
141
141
}
142
-
143
142
const metadata = target [ STATE_SYMBOL ] ;
144
-
145
143
const s = metadata . s . get ( prop ) ;
146
144
if ( s !== undefined ) set ( s , proxy ( value ) ) ;
145
+ const is_array = metadata . a ;
146
+ const not_has = ! ( prop in target ) ;
147
147
148
- if ( metadata . a && prop === 'length' ) {
148
+ if ( is_array && prop === 'length' ) {
149
149
for ( let i = value ; i < target . length ; i += 1 ) {
150
150
const s = metadata . s . get ( i + '' ) ;
151
151
if ( s !== undefined ) set ( s , UNINITIALIZED ) ;
152
152
}
153
153
}
154
-
155
- if ( ! ( prop in target ) ) increment ( metadata . v ) ;
154
+ if ( not_has ) {
155
+ increment ( metadata . v ) ;
156
+ }
156
157
// @ts -ignore
157
158
target [ prop ] = value ;
158
159
160
+ // If we have mutated an array directly, we might need to
161
+ // signal that length has also changed too.
162
+ if ( is_array && not_has ) {
163
+ const ls = metadata . s . get ( 'length' ) ;
164
+ const length = target . length ;
165
+ if ( ls !== undefined && ls . v !== length ) {
166
+ set ( ls , length ) ;
167
+ }
168
+ }
169
+
159
170
return true ;
160
171
} ,
161
172
Original file line number Diff line number Diff line change
1
+ import { flushSync } from 'svelte' ;
2
+ import { test } from '../../test' ;
3
+
4
+ export default test ( {
5
+ skip_if_ssr : 'permanent' ,
6
+ html : `
7
+ <input><input><input><div>3</div>
8
+ `
9
+ } ) ;
Original file line number Diff line number Diff line change
1
+ <script >
2
+ let values = $state ([' foo' , ' bar' , ' baz' ]);
3
+ let elements = $state ([]);
4
+ let nums = $state ([1 ,2 ,3 ]);
5
+ </script >
6
+
7
+ {#each values as value , i }
8
+ <input bind:this ={elements [i ]} bind:value ={values [i ]} />
9
+ {/each }
10
+ <div >{elements .length }</div >
You can’t perform that action at this time.
0 commit comments