Skip to content

Commit abeb31a

Browse files
committed
widen ownership if assigning different state proxies to one another
1 parent e1c79ba commit abeb31a

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

packages/svelte/src/internal/client/dev/ownership.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,27 @@ export function add_owner(object, owner, global = false) {
125125
add_owner_to_object(object, owner);
126126
}
127127

128+
/**
129+
* @param {import('#client').ProxyMetadata | null} from
130+
* @param {import('#client').ProxyMetadata} to
131+
*/
132+
export function widen_ownership(from, to) {
133+
if (to.owners === null) {
134+
return;
135+
}
136+
137+
while (from) {
138+
if (from.owners === null) {
139+
to.owners = null;
140+
break;
141+
}
142+
for (const owner of from.owners) {
143+
to.owners.add(owner);
144+
}
145+
from = from.parent;
146+
}
147+
}
148+
128149
/**
129150
* @param {any} object
130151
* @param {Function} owner

packages/svelte/src/internal/client/proxy.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
is_frozen,
1717
object_prototype
1818
} from './utils.js';
19-
import { check_ownership } from './dev/ownership.js';
19+
import { check_ownership, widen_ownership } from './dev/ownership.js';
2020
import { mutable_source, source, set } from './reactivity/sources.js';
2121
import { STATE_SYMBOL } from './constants.js';
2222
import { UNINITIALIZED } from '../../constants.js';
@@ -280,6 +280,11 @@ const state_proxy_handler = {
280280
const not_has = !(prop in target);
281281

282282
if (DEV) {
283+
/** @type {import('#client').ProxyMetadata | undefined} */
284+
const prop_metadata = value?.[STATE_SYMBOL];
285+
if (prop_metadata && prop_metadata?.parent !== metadata) {
286+
widen_ownership(metadata, prop_metadata);
287+
}
283288
check_ownership(metadata);
284289
}
285290

packages/svelte/tests/runtime-runes/samples/non-local-mutation-inherited-owner/main.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import Counter from './Counter.svelte';
33
import { global } from './state.svelte.js';
44
5-
global.object = { count: 0 };
5+
let object = $state({ count: 0 });
6+
global.object = object;
67
</script>
78

89
<Counter />

0 commit comments

Comments
 (0)