|
|
|
|
@ -46,64 +46,17 @@ export function proxy(value, parent = null, prev) {
|
|
|
|
|
const prototype = get_prototype_of(value);
|
|
|
|
|
|
|
|
|
|
if (prototype === object_prototype || prototype === array_prototype) {
|
|
|
|
|
const proxy = new Proxy(value, state_proxy_handler);
|
|
|
|
|
|
|
|
|
|
define_property(value, STATE_SYMBOL, {
|
|
|
|
|
value: /** @type {ProxyMetadata} */ ({
|
|
|
|
|
let metadata = /** @type {ProxyMetadata} */ ({
|
|
|
|
|
s: new Map(),
|
|
|
|
|
v: source(0),
|
|
|
|
|
a: is_array(value),
|
|
|
|
|
p: proxy,
|
|
|
|
|
p: /** @type {any} */ (null),
|
|
|
|
|
t: value
|
|
|
|
|
}),
|
|
|
|
|
writable: true,
|
|
|
|
|
enumerable: false
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
value[STATE_SYMBOL].parent = parent;
|
|
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
|
// Reuse owners from previous state; necessary because reassignment is not guaranteed to have correct component context.
|
|
|
|
|
// If no previous proxy exists we play it safe and assume ownerless state
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
const prev_owners = prev?.v?.[STATE_SYMBOL]?.owners;
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
value[STATE_SYMBOL].owners = prev_owners ? new Set(prev_owners) : null;
|
|
|
|
|
} else {
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
value[STATE_SYMBOL].owners =
|
|
|
|
|
parent === null
|
|
|
|
|
? current_component_context !== null
|
|
|
|
|
? new Set([current_component_context.function])
|
|
|
|
|
: null
|
|
|
|
|
: new Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return proxy;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {Source<number>} signal
|
|
|
|
|
* @param {1 | -1} [d]
|
|
|
|
|
*/
|
|
|
|
|
function update_version(signal, d = 1) {
|
|
|
|
|
set(signal, signal.v + d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @type {ProxyHandler<ProxyStateObject<any>>} */
|
|
|
|
|
const state_proxy_handler = {
|
|
|
|
|
const p = new Proxy(/** @type {any} */ (value), {
|
|
|
|
|
defineProperty(target, prop, descriptor) {
|
|
|
|
|
if (descriptor.value) {
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
|
|
|
|
|
const s = metadata.s.get(prop);
|
|
|
|
|
if (s !== undefined) set(s, proxy(descriptor.value, metadata));
|
|
|
|
|
}
|
|
|
|
|
@ -112,8 +65,6 @@ const state_proxy_handler = {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
deleteProperty(target, prop) {
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
const s = metadata.s.get(prop);
|
|
|
|
|
const is_array = metadata.a;
|
|
|
|
|
const boolean = delete target[prop];
|
|
|
|
|
@ -131,6 +82,7 @@ const state_proxy_handler = {
|
|
|
|
|
set(ls, length);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s !== undefined) set(s, UNINITIALIZED);
|
|
|
|
|
|
|
|
|
|
if (boolean) {
|
|
|
|
|
@ -142,11 +94,9 @@ const state_proxy_handler = {
|
|
|
|
|
|
|
|
|
|
get(target, prop, receiver) {
|
|
|
|
|
if (prop === STATE_SYMBOL) {
|
|
|
|
|
return Reflect.get(target, STATE_SYMBOL);
|
|
|
|
|
return metadata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
let s = metadata.s.get(prop);
|
|
|
|
|
|
|
|
|
|
// create a source, but only if it's an own property and not a prototype property
|
|
|
|
|
@ -165,9 +115,8 @@ const state_proxy_handler = {
|
|
|
|
|
|
|
|
|
|
getOwnPropertyDescriptor(target, prop) {
|
|
|
|
|
const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
|
|
|
|
|
|
|
|
if (descriptor && 'value' in descriptor) {
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
const s = metadata.s.get(prop);
|
|
|
|
|
|
|
|
|
|
if (s) {
|
|
|
|
|
@ -182,8 +131,7 @@ const state_proxy_handler = {
|
|
|
|
|
if (prop === STATE_SYMBOL) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
|
|
|
|
|
const has = Reflect.has(target, prop);
|
|
|
|
|
|
|
|
|
|
let s = metadata.s.get(prop);
|
|
|
|
|
@ -204,8 +152,6 @@ const state_proxy_handler = {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
set(target, prop, value, receiver) {
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
let s = metadata.s.get(prop);
|
|
|
|
|
// If we haven't yet created a source for this property, we need to ensure
|
|
|
|
|
// we do so otherwise if we read it later, then the write won't be tracked and
|
|
|
|
|
@ -267,18 +213,49 @@ const state_proxy_handler = {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
ownKeys(target) {
|
|
|
|
|
/** @type {ProxyMetadata} */
|
|
|
|
|
const metadata = target[STATE_SYMBOL];
|
|
|
|
|
|
|
|
|
|
get(metadata.v);
|
|
|
|
|
return Reflect.ownKeys(target);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
state_proxy_handler.setPrototypeOf = () => {
|
|
|
|
|
setPrototypeOf() {
|
|
|
|
|
e.state_prototype_fixed();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
metadata.p = p;
|
|
|
|
|
|
|
|
|
|
if (DEV) {
|
|
|
|
|
metadata.parent = parent;
|
|
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
|
// Reuse owners from previous state; necessary because reassignment is not guaranteed to have correct component context.
|
|
|
|
|
// If no previous proxy exists we play it safe and assume ownerless state
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
const prev_owners = prev?.v?.[STATE_SYMBOL]?.owners;
|
|
|
|
|
metadata.owners = prev_owners ? new Set(prev_owners) : null;
|
|
|
|
|
} else {
|
|
|
|
|
metadata.owners =
|
|
|
|
|
parent === null
|
|
|
|
|
? current_component_context !== null
|
|
|
|
|
? new Set([current_component_context.function])
|
|
|
|
|
: null
|
|
|
|
|
: new Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {Source<number>} signal
|
|
|
|
|
* @param {1 | -1} [d]
|
|
|
|
|
*/
|
|
|
|
|
function update_version(signal, d = 1) {
|
|
|
|
|
set(signal, signal.v + d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -288,7 +265,7 @@ export function get_proxied_value(value) {
|
|
|
|
|
if (value !== null && typeof value === 'object' && STATE_SYMBOL in value) {
|
|
|
|
|
var metadata = value[STATE_SYMBOL];
|
|
|
|
|
if (metadata) {
|
|
|
|
|
return metadata.p;
|
|
|
|
|
return metadata.t;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
|