tweak implementation

pull/16126/head
Rich Harris 3 months ago
parent 016f02b721
commit 7f4debebcf

@ -18,7 +18,7 @@ import {
import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
import { validate_component_options } from '../validate-options.js';
import { is_reserved, is_svg, is_void } from '../../utils.js';
import { regex_is_valid_identifier } from '../../regexes.js';
import { regex_is_valid_identifier } from '../phases/patterns.js';
const regex_style_tags = /(<style[^>]+>)([\S\s]*?)(<\/style>)/g;
const style_placeholder = '/*$$__STYLE_CONTENT__$$*/';

@ -89,7 +89,11 @@ export function VariableDeclaration(node, context) {
binding.kind === 'bindable_prop' &&
should_proxy(initial, context.state.scope)
) {
initial = b.call('$.proxy', initial, dev && b.literal(id.name));
initial = b.call('$.proxy', initial);
if (dev) {
initial = b.call('$.tag_proxy', initial, b.literal(id.name));
}
}
if (is_prop_source(binding, context.state)) {
@ -132,7 +136,11 @@ export function VariableDeclaration(node, context) {
const is_proxy = should_proxy(value, context.state.scope);
if (rune === '$state' && is_proxy) {
value = b.call('$.proxy', value, dev && b.literal(id.name));
value = b.call('$.proxy', value);
if (dev) {
value = b.call('$.tag_proxy', value, b.literal(id.name));
}
}
if (is_state) {

@ -2,7 +2,7 @@
import { UNINITIALIZED } from '../../../constants.js';
import { snapshot } from '../../shared/clone.js';
import { define_property } from '../../shared/utils.js';
import { DERIVED, STATE_SYMBOL } from '#client/constants';
import { DERIVED, PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';
import { effect_tracking } from '../reactivity/effects.js';
import { active_reaction, captured_signals, set_captured_signals, untrack } from '../runtime.js';
@ -190,6 +190,16 @@ export function tag(source, name) {
return source;
}
/**
* @param {unknown} value
* @param {string} label
*/
export function tag_proxy(value, label) {
// @ts-expect-error
value?.[PROXY_PATH_SYMBOL]?.(label);
return value;
}
/**
* @param {unknown} value
*/

@ -7,7 +7,7 @@ export { add_locations } from './dev/elements.js';
export { hmr } from './dev/hmr.js';
export { create_ownership_validator } from './dev/ownership.js';
export { check_target, legacy_api } from './dev/legacy.js';
export { trace, tag } from './dev/tracing.js';
export { trace, tag, tag_proxy } from './dev/tracing.js';
export { inspect } from './dev/inspect.js';
export { validate_snippet_args } from './dev/validation.js';
export { await_block as await } from './dom/blocks/await.js';

@ -12,7 +12,7 @@ import { state as source, set } from './reactivity/sources.js';
import { PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
import { get_stack, tag } from './dev/tracing.js';
import { get_stack, tag, tag_proxy } from './dev/tracing.js';
import { tracing_mode_flag } from '../flags/index.js';
// TODO move all regexes into shared module?
@ -21,10 +21,9 @@ const regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
/**
* @template T
* @param {T} value
* @param {string} [path]
* @returns {T}
*/
export function proxy(value, path) {
export function proxy(value) {
// if non-proxyable, or is already a proxy, return `value`
if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) {
return value;
@ -39,7 +38,7 @@ export function proxy(value, path) {
/** @type {Map<any, Source<any>>} */
var sources = new Map();
var is_proxied_array = is_array(value);
var version = DEV ? tag(source(0), `${path} version`) : source(0);
var version = source(0);
var stack = DEV && tracing_mode_flag ? get_stack('CreatedAt') : null;
var reaction = active_reaction;
@ -62,10 +61,12 @@ export function proxy(value, path) {
if (is_proxied_array) {
// We need to create the length source eagerly to ensure that
// mutations to the array are properly synced with our proxy
const length_source = source(/** @type {any[]} */ (value).length, stack);
sources.set('length', DEV ? tag(length_source, to_trace_name('length')) : length_source);
sources.set('length', source(/** @type {any[]} */ (value).length, stack));
}
/** Used in dev for $inspect.trace() */
var path = '';
/** @param {string | symbol} prop */
function to_trace_name(prop) {
if (typeof prop === 'symbol') return `${path}[Symbol(${prop.description ?? ''})]`;
@ -84,7 +85,7 @@ export function proxy(value, path) {
var label = to_trace_name(prop);
tag(source, label);
source.v?.[PROXY_PATH_SYMBOL]?.(label);
tag_proxy(source.v, label);
}
}
@ -107,13 +108,18 @@ export function proxy(value, path) {
if (s === undefined) {
s = with_parent(() => source(descriptor.value, stack));
s = DEV && typeof prop === 'string' ? tag(s, to_trace_name(prop)) : s;
sources.set(prop, s);
if (DEV && typeof prop === 'string') {
tag(s, to_trace_name(prop));
}
} else {
set(
s,
with_parent(() => proxy(descriptor.value, to_trace_name(prop)))
);
var p = with_parent(() => proxy(descriptor.value));
set(s, p);
if (DEV) {
tag_proxy(p, to_trace_name(prop));
}
}
return true;
@ -125,8 +131,12 @@ export function proxy(value, path) {
if (s === undefined) {
if (prop in target) {
const s = with_parent(() => source(UNINITIALIZED, stack));
sources.set(prop, DEV ? tag(s, to_trace_name(prop)) : s);
sources.set(prop, s);
update_version(version);
if (DEV) {
tag(s, to_trace_name(prop));
}
}
} else {
// When working with arrays, we need to also ensure we update the length when removing
@ -160,10 +170,19 @@ export function proxy(value, path) {
// 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(() =>
source(proxy(exists ? target[prop] : UNINITIALIZED, to_trace_name(prop)), stack)
);
s = DEV ? tag(s, to_trace_name(prop)) : s;
s = with_parent(() => {
var p = proxy(exists ? target[prop] : UNINITIALIZED);
var s = source(p, stack);
if (DEV) {
var label = to_trace_name(prop);
tag(s, label);
tag_proxy(p, label);
}
return s;
});
sources.set(prop, s);
}
@ -211,10 +230,19 @@ export function proxy(value, path) {
(active_effect !== null && (!has || get_descriptor(target, prop)?.writable))
) {
if (s === undefined) {
s = with_parent(() =>
source(has ? proxy(target[prop], to_trace_name(prop)) : UNINITIALIZED, stack)
);
s = DEV ? tag(s, to_trace_name(prop)) : s;
s = with_parent(() => {
var p = has ? proxy(target[prop]) : UNINITIALIZED;
var s = source(p, stack);
if (DEV) {
var label = to_trace_name(prop);
tag(s, label);
tag_proxy(p, label);
}
return s;
});
sources.set(prop, s);
}
@ -255,12 +283,12 @@ export function proxy(value, path) {
if (s === undefined) {
if (!has || get_descriptor(target, prop)?.writable) {
s = with_parent(() => source(undefined, stack));
var p = with_parent(() => proxy(value, to_trace_name(prop)));
var p = with_parent(() => proxy(value));
if (DEV) {
var label = to_trace_name(prop);
tag(s, label);
p?.[PROXY_PATH_SYMBOL]?.(label);
tag_proxy(p, label);
}
set(s, p);
@ -269,11 +297,10 @@ export function proxy(value, path) {
} else {
has = s.v !== UNINITIALIZED;
p = with_parent(() => proxy(value, to_trace_name(prop)));
p = with_parent(() => proxy(value));
if (DEV) {
label = to_trace_name(prop);
p?.[PROXY_PATH_SYMBOL]?.(label);
tag_proxy(p, to_trace_name(prop));
}
set(s, p);

Loading…
Cancel
Save