|
|
|
@ -34,9 +34,13 @@ const regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
|
|
|
|
|
/**
|
|
|
|
|
* @template T
|
|
|
|
|
* @param {T} value
|
|
|
|
|
* @param {WeakSet<Source>} [owned_sources]
|
|
|
|
|
* @returns {T}
|
|
|
|
|
*/
|
|
|
|
|
export function proxy(value) {
|
|
|
|
|
export function proxy(value, owned_sources) {
|
|
|
|
|
if (DEV) {
|
|
|
|
|
owned_sources ??= new WeakSet();
|
|
|
|
|
}
|
|
|
|
|
// if non-proxyable, or is already a proxy, return `value`
|
|
|
|
|
if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) {
|
|
|
|
|
return value;
|
|
|
|
@ -94,8 +98,15 @@ export function proxy(value) {
|
|
|
|
|
/** Used in dev for $inspect.trace() */
|
|
|
|
|
var path = '';
|
|
|
|
|
|
|
|
|
|
/** @param {string} new_path */
|
|
|
|
|
function update_path(new_path) {
|
|
|
|
|
/**
|
|
|
|
|
* @param {string} new_path
|
|
|
|
|
* @param {Source} updater the source causing the path update
|
|
|
|
|
*/
|
|
|
|
|
function update_path(new_path, updater) {
|
|
|
|
|
// there's a circular reference somewhere, don't update the path to avoid recursion
|
|
|
|
|
if (owned_sources?.has(updater)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
path = new_path;
|
|
|
|
|
|
|
|
|
|
tag(version, `${path} version`);
|
|
|
|
@ -127,6 +138,7 @@ export function proxy(value) {
|
|
|
|
|
sources.set(prop, s);
|
|
|
|
|
if (DEV && typeof prop === 'string') {
|
|
|
|
|
tag(s, get_label(path, prop));
|
|
|
|
|
owned_sources?.add(s);
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
});
|
|
|
|
@ -148,6 +160,7 @@ export function proxy(value) {
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
tag(s, get_label(path, prop));
|
|
|
|
|
owned_sources?.add(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -173,11 +186,12 @@ export function proxy(value) {
|
|
|
|
|
// create a source, but only if it's an own property and not a prototype property
|
|
|
|
|
if (s === undefined && (!exists || get_descriptor(target, prop)?.writable)) {
|
|
|
|
|
s = with_parent(() => {
|
|
|
|
|
var p = proxy(exists ? target[prop] : UNINITIALIZED);
|
|
|
|
|
var p = proxy(exists ? target[prop] : UNINITIALIZED, DEV ? owned_sources : undefined);
|
|
|
|
|
var s = source(p, stack);
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
tag(s, get_label(path, prop));
|
|
|
|
|
owned_sources?.add(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
@ -231,11 +245,12 @@ export function proxy(value) {
|
|
|
|
|
) {
|
|
|
|
|
if (s === undefined) {
|
|
|
|
|
s = with_parent(() => {
|
|
|
|
|
var p = has ? proxy(target[prop]) : UNINITIALIZED;
|
|
|
|
|
var p = has ? proxy(target[prop], DEV ? owned_sources : undefined) : UNINITIALIZED;
|
|
|
|
|
var s = source(p, stack);
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
tag(s, get_label(path, prop));
|
|
|
|
|
owned_sources?.add(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
@ -272,6 +287,7 @@ export function proxy(value) {
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
tag(other_s, get_label(path, i));
|
|
|
|
|
owned_sources?.add(other_s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -284,18 +300,19 @@ export function proxy(value) {
|
|
|
|
|
if (s === undefined) {
|
|
|
|
|
if (!has || get_descriptor(target, prop)?.writable) {
|
|
|
|
|
s = with_parent(() => source(undefined, stack));
|
|
|
|
|
set(s, proxy(value));
|
|
|
|
|
set(s, proxy(value, DEV ? owned_sources : undefined));
|
|
|
|
|
|
|
|
|
|
sources.set(prop, s);
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
tag(s, get_label(path, prop));
|
|
|
|
|
owned_sources?.add(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
has = s.v !== UNINITIALIZED;
|
|
|
|
|
|
|
|
|
|
var p = with_parent(() => proxy(value));
|
|
|
|
|
var p = with_parent(() => proxy(value, DEV ? owned_sources : undefined));
|
|
|
|
|
set(s, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|