tweak implementation

pull/16126/head
Rich Harris 3 months ago
parent 35cbd04ba5
commit 9307ad5e11

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

@ -15,6 +15,9 @@ import * as e from './errors.js';
import { get_stack, tag } from './dev/tracing.js'; import { get_stack, tag } from './dev/tracing.js';
import { tracing_mode_flag } from '../flags/index.js'; import { tracing_mode_flag } from '../flags/index.js';
// TODO move all regexes into shared module?
const regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
/** /**
* @template T * @template T
* @param {T} value * @param {T} value
@ -23,17 +26,11 @@ import { tracing_mode_flag } from '../flags/index.js';
* @returns {T} * @returns {T}
*/ */
export function proxy(value, path, change_path = false) { export function proxy(value, path, change_path = false) {
// if `DEV`, change the proxy `path` since we don't know if its still "owned" by its original source if (DEV && change_path) {
if ( // @ts-expect-error
DEV && value?.[PROXY_PATH_SYMBOL]?.(path);
change_path &&
typeof value === 'object' &&
value !== null &&
STATE_SYMBOL in value &&
PROXY_PATH_SYMBOL in value
) {
value[PROXY_PATH_SYMBOL] = path;
} }
// if non-proxyable, or is already a proxy, return `value` // if non-proxyable, or is already a proxy, return `value`
if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) { if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) {
return value; return value;
@ -52,16 +49,6 @@ export function proxy(value, path, change_path = false) {
var stack = DEV && tracing_mode_flag ? get_stack('CreatedAt') : null; var stack = DEV && tracing_mode_flag ? get_stack('CreatedAt') : null;
var reaction = active_reaction; var reaction = active_reaction;
/** @type {(prop: any) => any} */
var to_trace_name = DEV
? (prop) => {
return typeof prop === 'symbol'
? `${path}[Symbol(${prop.description ?? ''})]`
: typeof prop === 'number' || Number(prop) === Number(prop)
? `${path}[${prop}]`
: `${path}.${prop}`;
}
: (prop) => undefined;
/** /**
* @template T * @template T
@ -85,6 +72,28 @@ export function proxy(value, path, change_path = false) {
sources.set('length', DEV ? tag(length_source, to_trace_name('length')) : length_source); sources.set('length', DEV ? tag(length_source, to_trace_name('length')) : length_source);
} }
/** @param {string | symbol} prop */
function to_trace_name(prop) {
if (typeof prop === 'symbol') return `${path}[Symbol(${prop.description ?? ''})]`;
if (regex_is_valid_identifier.test(prop)) return `${path}.${prop}`;
return /^\d+$/.test(prop) ? `${path}[${prop}]` : `${path}['${prop}']`;
}
/** @param {string} new_path */
function update_path(new_path) {
path = new_path;
tag(version, `${path} version`);
// rename all child sources and child proxies
for (const [prop, source] of sources) {
var label = to_trace_name(prop);
tag(source, label);
source.v?.[PROXY_PATH_SYMBOL]?.(label);
}
}
return new Proxy(/** @type {any} */ (value), { return new Proxy(/** @type {any} */ (value), {
defineProperty(_, prop, descriptor) { defineProperty(_, prop, descriptor) {
if ( if (
@ -147,8 +156,9 @@ export function proxy(value, path, change_path = false) {
if (prop === STATE_SYMBOL) { if (prop === STATE_SYMBOL) {
return value; return value;
} }
if (DEV && prop === PROXY_PATH_SYMBOL) { if (DEV && prop === PROXY_PATH_SYMBOL) {
return path; return update_path;
} }
var s = sources.get(prop); var s = sources.get(prop);
@ -195,7 +205,7 @@ export function proxy(value, path, change_path = false) {
}, },
has(target, prop) { has(target, prop) {
if (prop === STATE_SYMBOL || (DEV && prop === PROXY_PATH_SYMBOL)) { if (prop === STATE_SYMBOL) {
return true; return true;
} }
@ -224,17 +234,6 @@ export function proxy(value, path, change_path = false) {
}, },
set(target, prop, value, receiver) { set(target, prop, value, receiver) {
if (DEV && prop === PROXY_PATH_SYMBOL) {
path = value;
tag(version, `${path} version`);
// rename all child sources and child proxies
for (const [prop, source] of sources) {
tag(source, to_trace_name(prop));
if (typeof source.v === 'object' && source.v !== null && PROXY_PATH_SYMBOL in source.v) {
source.v[PROXY_PATH_SYMBOL] = to_trace_name(prop);
}
}
}
var s = sources.get(prop); var s = sources.get(prop);
var has = prop in target; var has = prop in target;

Loading…
Cancel
Save