@@ -33,10 +33,17 @@ export function proxy(value, parent = null, prev) {
33
33
return value ;
34
34
}
35
35
36
+ /** @type {Map<any, Source<any>> } */
36
37
var sources = new Map ( ) ;
37
38
var is_proxied_array = is_array ( value ) ;
38
39
var version = source ( 0 ) ;
39
40
41
+ if ( is_proxied_array ) {
42
+ // We need to create the length source eagerly to ensure that
43
+ // mutations to the array are properly synced with our proxy
44
+ sources . set ( 'length' , source ( /** @type {any[] } */ ( value ) . length ) ) ;
45
+ }
46
+
40
47
/** @type {ProxyMetadata } */
41
48
var metadata ;
42
49
@@ -187,6 +194,22 @@ export function proxy(value, parent = null, prev) {
187
194
var s = sources . get ( prop ) ;
188
195
var has = prop in target ;
189
196
197
+ // variable.length = value -> clear all signals with index >= value
198
+ if ( is_proxied_array && prop === 'length' ) {
199
+ for ( var i = value ; i < /** @type {Source<number> } */ ( s ) . v ; i += 1 ) {
200
+ var other_s = sources . get ( i + '' ) ;
201
+ if ( other_s !== undefined ) {
202
+ set ( other_s , UNINITIALIZED ) ;
203
+ } else if ( i in target ) {
204
+ // If the item exists in the original, we need to create a uninitialized source,
205
+ // else a later read of the property would result in a source being created with
206
+ // the value of the original item at that index.
207
+ other_s = source ( UNINITIALIZED ) ;
208
+ sources . set ( i + '' , other_s ) ;
209
+ }
210
+ }
211
+ }
212
+
190
213
// If we haven't yet created a source for this property, we need to ensure
191
214
// we do so otherwise if we read it later, then the write won't be tracked and
192
215
// the heuristics of effects will be different vs if we had read the proxied
@@ -211,14 +234,6 @@ export function proxy(value, parent = null, prev) {
211
234
check_ownership ( metadata ) ;
212
235
}
213
236
214
- // variable.length = value -> clear all signals with index >= value
215
- if ( is_proxied_array && prop === 'length' ) {
216
- for ( var i = value ; i < target . length ; i += 1 ) {
217
- var other_s = sources . get ( i + '' ) ;
218
- if ( other_s !== undefined ) set ( other_s , UNINITIALIZED ) ;
219
- }
220
- }
221
-
222
237
var descriptor = Reflect . getOwnPropertyDescriptor ( target , prop ) ;
223
238
224
239
// Set the new value before updating any signals so that any listeners get the new value
@@ -232,14 +247,11 @@ export function proxy(value, parent = null, prev) {
232
247
// to ensure that iterating over the array as a result of a metadata update
233
248
// will not cause the length to be out of sync.
234
249
if ( is_proxied_array && typeof prop === 'string' ) {
235
- var ls = sources . get ( 'length' ) ;
236
-
237
- if ( ls !== undefined ) {
238
- var n = Number ( prop ) ;
250
+ var ls = /** @type {Source<number> } */ ( sources . get ( 'length' ) ) ;
251
+ var n = Number ( prop ) ;
239
252
240
- if ( Number . isInteger ( n ) && n >= ls . v ) {
241
- set ( ls , n + 1 ) ;
242
- }
253
+ if ( Number . isInteger ( n ) && n >= ls . v ) {
254
+ set ( ls , n + 1 ) ;
243
255
}
244
256
}
245
257
0 commit comments