@@ -123,7 +123,7 @@ export function add_owner(object, owner, global = false) {
123
123
}
124
124
}
125
125
126
- add_owner_to_object ( object , owner ) ;
126
+ add_owner_to_object ( object , owner , new Set ( ) ) ;
127
127
}
128
128
129
129
/**
@@ -140,18 +140,21 @@ export function widen_ownership(from, to) {
140
140
to . owners = null ;
141
141
break ;
142
142
}
143
+
143
144
for ( const owner of from . owners ) {
144
145
to . owners . add ( owner ) ;
145
146
}
147
+
146
148
from = from . parent ;
147
149
}
148
150
}
149
151
150
152
/**
151
153
* @param {any } object
152
154
* @param {Function } owner
155
+ * @param {Set<any> } seen
153
156
*/
154
- function add_owner_to_object ( object , owner ) {
157
+ function add_owner_to_object ( object , owner , seen ) {
155
158
const metadata = /** @type {import('#client').ProxyMetadata } */ ( object ?. [ STATE_SYMBOL ] ) ;
156
159
157
160
if ( metadata ) {
@@ -160,6 +163,9 @@ function add_owner_to_object(object, owner) {
160
163
metadata . owners . add ( owner ) ;
161
164
}
162
165
} else if ( object && typeof object === 'object' ) {
166
+ if ( seen . has ( object ) ) return ;
167
+ seen . add ( object ) ;
168
+
163
169
if ( object [ ADD_OWNER ] ) {
164
170
// this is a class with state fields. we put this in a render effect
165
171
// so that if state is replaced (e.g. `instance.name = { first, last }`)
@@ -173,12 +179,12 @@ function add_owner_to_object(object, owner) {
173
179
if ( proto === Object . prototype ) {
174
180
// recurse until we find a state proxy
175
181
for ( const key in object ) {
176
- add_owner_to_object ( object [ key ] , owner ) ;
182
+ add_owner_to_object ( object [ key ] , owner , seen ) ;
177
183
}
178
184
} else if ( proto === Array . prototype ) {
179
185
// recurse until we find a state proxy
180
186
for ( let i = 0 ; i < object . length ; i += 1 ) {
181
- add_owner_to_object ( object [ i ] , owner ) ;
187
+ add_owner_to_object ( object [ i ] , owner , seen ) ;
182
188
}
183
189
}
184
190
}
0 commit comments