Skip to content

Commit 26173de

Browse files
committed
init
1 parent b5fcd11 commit 26173de

File tree

7 files changed

+83
-23
lines changed

7 files changed

+83
-23
lines changed

packages/svelte/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,17 @@ export function VariableDeclaration(node, context) {
128128
const binding = /** @type {import('#compiler').Binding} */ (
129129
context.state.scope.get(id.name)
130130
);
131-
if (rune === '$state' && should_proxy(value, context.state.scope)) {
132-
value = b.call('$.proxy', value);
131+
const is_state = is_state_source(binding, context.state.analysis);
132+
const is_proxy = should_proxy(value, context.state.scope);
133+
if (rune === '$state' && is_proxy) {
134+
value = b.call('$.proxy', value, dev ? b.literal(id.name) : undefined);
133135
}
134-
if (is_state_source(binding, context.state.analysis)) {
136+
if (is_state) {
135137
value = b.call('$.state', value);
136138
}
139+
if (dev && is_state) {
140+
value = b.call('$.tag_source', value, b.literal(id.name));
141+
}
137142
return value;
138143
};
139144

@@ -154,7 +159,11 @@ export function VariableDeclaration(node, context) {
154159
context.state.transform[id.name] = { read: get_value };
155160

156161
const expression = /** @type {Expression} */ (context.visit(b.thunk(value)));
157-
return b.declarator(id, b.call('$.derived', expression));
162+
const call = b.call('$.derived', expression);
163+
return b.declarator(
164+
id,
165+
dev ? b.call('$.tag_source', call, b.literal(id.name)) : call
166+
);
158167
}),
159168
...paths.map((path) => {
160169
const value = /** @type {Expression} */ (context.visit(path.expression));
@@ -176,8 +185,13 @@ export function VariableDeclaration(node, context) {
176185
if (declarator.id.type === 'Identifier') {
177186
let expression = /** @type {Expression} */ (context.visit(value));
178187
if (rune === '$derived') expression = b.thunk(expression);
179-
180-
declarations.push(b.declarator(declarator.id, b.call('$.derived', expression)));
188+
const call = b.call('$.derived', expression);
189+
declarations.push(
190+
b.declarator(
191+
declarator.id,
192+
dev ? b.call('$.tag_source', call, b.literal(declarator.id.name)) : call
193+
)
194+
);
181195
} else {
182196
const init = /** @type {CallExpression} */ (declarator.init);
183197

@@ -205,7 +219,19 @@ export function VariableDeclaration(node, context) {
205219

206220
for (const path of paths) {
207221
const expression = /** @type {Expression} */ (context.visit(path.expression));
208-
declarations.push(b.declarator(path.node, b.call('$.derived', b.thunk(expression))));
222+
const call = b.call('$.derived', b.thunk(expression));
223+
declarations.push(
224+
b.declarator(
225+
path.node,
226+
dev
227+
? b.call(
228+
'$.tag_source',
229+
call,
230+
b.literal(/** @type {Identifier} */ (path.node).name)
231+
)
232+
: call
233+
)
234+
);
209235
}
210236
}
211237

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export const EFFECT_IS_UPDATING = 1 << 21;
2525
export const STATE_SYMBOL = Symbol('$state');
2626
export const LEGACY_PROPS = Symbol('legacy props');
2727
export const LOADING_ATTR_SYMBOL = Symbol('');
28+
export const PROXY_PATH_SYMBOL = Symbol('proxy path');

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ function log_entry(signal, entry) {
4343
const type = (signal.f & DERIVED) !== 0 ? '$derived' : '$state';
4444
const current_reaction = /** @type {Reaction} */ (active_reaction);
4545
const dirty = signal.wv > current_reaction.wv || current_reaction.wv === 0;
46-
46+
const { trace_name: name } = signal;
47+
const style = dirty
48+
? 'color: CornflowerBlue; font-weight: bold'
49+
: 'color: grey; font-weight: bold';
4750
// eslint-disable-next-line no-console
4851
console.groupCollapsed(
49-
`%c${type}`,
50-
dirty ? 'color: CornflowerBlue; font-weight: bold' : 'color: grey; font-weight: bold',
52+
typeof name === 'string' ? `%c${name}${type}` : `%c${type}`,
53+
style,
5154
typeof value === 'object' && value !== null && STATE_SYMBOL in value
5255
? snapshot(value, true)
5356
: value
@@ -92,11 +95,9 @@ export function trace(label, fn) {
9295
var previously_tracing_expressions = tracing_expressions;
9396
try {
9497
tracing_expressions = { entries: new Map(), reaction: active_reaction };
95-
9698
var start = performance.now();
9799
var value = fn();
98100
var time = (performance.now() - start).toFixed(2);
99-
100101
if (!effect_tracking()) {
101102
// eslint-disable-next-line no-console
102103
console.log(`${label()} %cran outside of an effect (${time}ms)`, 'color: grey');
@@ -177,3 +178,12 @@ export function get_stack(label) {
177178
}
178179
return error;
179180
}
181+
182+
/**
183+
* @param {Value} source
184+
* @param {string} name
185+
*/
186+
export function tag_source(source, name) {
187+
source.trace_name = name;
188+
return source;
189+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export { add_locations } from './dev/elements.js';
77
export { hmr } from './dev/hmr.js';
88
export { create_ownership_validator } from './dev/ownership.js';
99
export { check_target, legacy_api } from './dev/legacy.js';
10-
export { trace } from './dev/tracing.js';
10+
export { trace, tag_source } from './dev/tracing.js';
1111
export { inspect } from './dev/inspect.js';
1212
export { validate_snippet_args } from './dev/validation.js';
1313
export { await_block as await } from './dom/blocks/await.js';

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

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ import { state as source, set } from './reactivity/sources.js';
1212
import { STATE_SYMBOL } from '#client/constants';
1313
import { UNINITIALIZED } from '../../constants.js';
1414
import * as e from './errors.js';
15-
import { get_stack } from './dev/tracing.js';
15+
import { get_stack, tag_source } from './dev/tracing.js';
1616
import { tracing_mode_flag } from '../flags/index.js';
1717

1818
/**
1919
* @template T
2020
* @param {T} value
21+
* @param {string} [path]
2122
* @returns {T}
2223
*/
23-
export function proxy(value) {
24+
export function proxy(value, path) {
2425
// if non-proxyable, or is already a proxy, return `value`
2526
if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) {
2627
return value;
@@ -39,6 +40,16 @@ export function proxy(value) {
3940

4041
var stack = DEV && tracing_mode_flag ? get_stack('CreatedAt') : null;
4142
var reaction = active_reaction;
43+
/** @type {(prop: any) => any} */
44+
var to_trace_name = DEV
45+
? (prop) => {
46+
return typeof prop === 'symbol'
47+
? `${path}[unique symbol]`
48+
: typeof prop === 'number' || Number(prop) === Number(prop)
49+
? `${path}[${prop}]`
50+
: `${path}.${prop}`;
51+
}
52+
: (prop) => undefined;
4253

4354
/**
4455
* @template T
@@ -58,7 +69,8 @@ export function proxy(value) {
5869
if (is_proxied_array) {
5970
// We need to create the length source eagerly to ensure that
6071
// mutations to the array are properly synced with our proxy
61-
sources.set('length', source(/** @type {any[]} */ (value).length, stack));
72+
const length_source = source(/** @type {any[]} */ (value).length, stack);
73+
sources.set('length', DEV ? tag_source(length_source, to_trace_name('length')) : length_source);
6274
}
6375

6476
return new Proxy(/** @type {any} */ (value), {
@@ -80,11 +92,12 @@ export function proxy(value) {
8092

8193
if (s === undefined) {
8294
s = with_parent(() => source(descriptor.value, stack));
95+
s = DEV && typeof prop === 'string' ? tag_source(s, to_trace_name(prop)) : s;
8396
sources.set(prop, s);
8497
} else {
8598
set(
8699
s,
87-
with_parent(() => proxy(descriptor.value))
100+
with_parent(() => proxy(descriptor.value, to_trace_name(prop)))
88101
);
89102
}
90103

@@ -96,9 +109,10 @@ export function proxy(value) {
96109

97110
if (s === undefined) {
98111
if (prop in target) {
112+
const s = with_parent(() => source(UNINITIALIZED, stack));
99113
sources.set(
100114
prop,
101-
with_parent(() => source(UNINITIALIZED, stack))
115+
DEV && typeof prop === 'string' ? tag_source(s, to_trace_name(prop)) : s
102116
);
103117
update_version(version);
104118
}
@@ -130,7 +144,10 @@ export function proxy(value) {
130144

131145
// create a source, but only if it's an own property and not a prototype property
132146
if (s === undefined && (!exists || get_descriptor(target, prop)?.writable)) {
133-
s = with_parent(() => source(proxy(exists ? target[prop] : UNINITIALIZED), stack));
147+
s = with_parent(() =>
148+
source(proxy(exists ? target[prop] : UNINITIALIZED, to_trace_name(prop)), stack)
149+
);
150+
s = DEV && typeof prop === 'string' ? tag_source(s, to_trace_name(prop)) : s;
134151
sources.set(prop, s);
135152
}
136153

@@ -178,7 +195,10 @@ export function proxy(value) {
178195
(active_effect !== null && (!has || get_descriptor(target, prop)?.writable))
179196
) {
180197
if (s === undefined) {
181-
s = with_parent(() => source(has ? proxy(target[prop]) : UNINITIALIZED, stack));
198+
s = with_parent(() =>
199+
source(has ? proxy(target[prop], to_trace_name(prop)) : UNINITIALIZED, stack)
200+
);
201+
s = DEV && typeof prop === 'string' ? tag_source(s, to_trace_name(prop)) : s;
182202
sources.set(prop, s);
183203
}
184204

@@ -206,6 +226,7 @@ export function proxy(value) {
206226
// else a later read of the property would result in a source being created with
207227
// the value of the original item at that index.
208228
other_s = with_parent(() => source(UNINITIALIZED, stack));
229+
other_s = DEV ? tag_source(other_s, to_trace_name(i)) : other_s;
209230
sources.set(i + '', other_s);
210231
}
211232
}
@@ -218,17 +239,18 @@ export function proxy(value) {
218239
if (s === undefined) {
219240
if (!has || get_descriptor(target, prop)?.writable) {
220241
s = with_parent(() => source(undefined, stack));
242+
s = DEV && typeof prop === 'string' ? tag_source(s, to_trace_name(prop)) : s;
221243
set(
222244
s,
223-
with_parent(() => proxy(value))
245+
with_parent(() => proxy(value, to_trace_name(prop)))
224246
);
225247
sources.set(prop, s);
226248
}
227249
} else {
228250
has = s.v !== UNINITIALIZED;
229251
set(
230252
s,
231-
with_parent(() => proxy(value))
253+
with_parent(() => proxy(value, to_trace_name(prop)))
232254
);
233255
}
234256

packages/svelte/src/internal/client/reactivity/sources.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export function set(source, value, should_proxy = false) {
139139
e.state_unsafe_mutation();
140140
}
141141

142-
let new_value = should_proxy ? proxy(value) : value;
142+
let new_value = should_proxy ? proxy(value, DEV ? source.trace_name : undefined) : value;
143143

144144
return internal_set(source, new_value);
145145
}

packages/svelte/src/internal/client/reactivity/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface Value<V = unknown> extends Signal {
2121
updated?: Error | null;
2222
trace_need_increase?: boolean;
2323
trace_v?: V;
24+
trace_name?: string;
2425
debug?: null | (() => void);
2526
}
2627

0 commit comments

Comments
 (0)