Skip to content

Commit 04f57a3

Browse files
committed
WIP
1 parent 25d744c commit 04f57a3

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

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

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
/** @typedef {{ file: string, line: number, column: number }} Location */
22

33
import { STATE_SYMBOL } from '../constants.js';
4+
import { unstate } from '../proxy.js';
45
import { untrack } from '../runtime.js';
6+
import { get_descriptors } from '../utils.js';
57

68
/** @type {Record<string, Array<{ start: Location, end: Location, component: Function }>>} */
79
const boundaries = {};
@@ -98,20 +100,56 @@ export function mark_module_end() {
98100
*/
99101
export function add_owner(object, owner) {
100102
untrack(() => {
101-
add_owner_to_object(object, owner);
103+
var previous_owner = current_owner;
104+
current_owner = owner;
105+
add_owner_to_object(object);
106+
current_owner = previous_owner;
102107
});
103108
}
104109

110+
/** @type {any} */
111+
export var current_owner = null;
112+
105113
/**
106114
* @param {any} object
107-
* @param {Function} owner
115+
* @param {Set<any>} [seen]
108116
*/
109-
function add_owner_to_object(object, owner) {
110-
if (object?.[STATE_SYMBOL]?.o && !object[STATE_SYMBOL].o.has(owner)) {
111-
object[STATE_SYMBOL].o.add(owner);
117+
function add_owner_to_object(object, seen = new Set()) {
118+
if (seen.has(object) || typeof object !== 'object' || object === null) {
119+
return;
120+
}
112121

113-
for (const key in object) {
114-
add_owner_to_object(object[key], owner);
122+
if (object?.[STATE_SYMBOL]?.o) {
123+
object[STATE_SYMBOL].o.add(current_owner);
124+
} else {
125+
seen.add(object);
126+
127+
for (let key in object) {
128+
try {
129+
add_owner_to_object(object[key], seen);
130+
} catch (e) {
131+
// continue
132+
}
133+
}
134+
const proto = Object.getPrototypeOf(object);
135+
if (
136+
proto !== Object.prototype &&
137+
proto !== Array.prototype &&
138+
proto !== Map.prototype &&
139+
proto !== Set.prototype &&
140+
proto !== Date.prototype
141+
) {
142+
const descriptors = get_descriptors(proto);
143+
for (let key in descriptors) {
144+
const get = descriptors[key].get;
145+
if (get) {
146+
try {
147+
get.call(object);
148+
} catch (e) {
149+
// continue
150+
}
151+
}
152+
}
115153
}
116154
}
117155
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
ROOT_EFFECT
2626
} from './constants.js';
2727
import { flush_tasks } from './dom/task.js';
28-
import { add_owner } from './dev/ownership.js';
28+
import { add_owner, current_owner } from './dev/ownership.js';
2929
import { mutate, set, source } from './reactivity/sources.js';
3030
import { update_derived } from './reactivity/deriveds.js';
3131

@@ -758,6 +758,10 @@ export function get(signal) {
758758
}
759759
}
760760

761+
if (current_owner !== null && signal.v?.[STATE_SYMBOL]?.o) {
762+
signal.v[STATE_SYMBOL].o.add(current_owner);
763+
}
764+
761765
return signal.v;
762766
}
763767

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,15 @@ export function map_get(map, key) {
4747
export function is_function(thing) {
4848
return typeof thing === 'function';
4949
}
50+
51+
/** @param {any} object */
52+
export function is_exotic_object(object) {
53+
const proto = Object.getPrototypeOf(object);
54+
return (
55+
proto !== Object.prototype &&
56+
proto !== Array.prototype &&
57+
proto !== Map.prototype &&
58+
proto !== Set.prototype &&
59+
proto !== Date.prototype
60+
);
61+
}

0 commit comments

Comments
 (0)