diff --git a/packages/svelte/src/internal/client/dev/tracing.js b/packages/svelte/src/internal/client/dev/tracing.js
index 65c6379625..5834f5bffd 100644
--- a/packages/svelte/src/internal/client/dev/tracing.js
+++ b/packages/svelte/src/internal/client/dev/tracing.js
@@ -26,23 +26,6 @@ function log_entry(signal, entry) {
return;
}
- if (signal.trace) {
- var previous_captured_signals = captured_signals;
- var captured = new Set();
- set_captured_signals(captured);
-
- try {
- untrack(signal.trace);
- } finally {
- set_captured_signals(previous_captured_signals);
- }
-
- if (captured.size > 0) {
- for (const dep of captured) log_entry(dep);
- return;
- }
- }
-
const type = (signal.f & DERIVED) !== 0 ? '$derived' : '$state';
const current_reaction = /** @type {Reaction} */ (active_reaction);
const dirty = signal.wv > current_reaction.wv || current_reaction.wv === 0;
@@ -103,19 +86,25 @@ export function trace(label, fn) {
var value = fn();
var time = (performance.now() - start).toFixed(2);
+ var prefix = untrack(label);
+
if (!effect_tracking()) {
// eslint-disable-next-line no-console
- console.log(`${label()} %cran outside of an effect (${time}ms)`, 'color: grey');
+ console.log(`${prefix} %cran outside of an effect (${time}ms)`, 'color: grey');
} else if (tracing_expressions.entries.size === 0) {
// eslint-disable-next-line no-console
- console.log(`${label()} %cno reactive dependencies (${time}ms)`, 'color: grey');
+ console.log(`${prefix} %cno reactive dependencies (${time}ms)`, 'color: grey');
} else {
// eslint-disable-next-line no-console
- console.group(`${label()} %c(${time}ms)`, 'color: grey');
+ console.group(`${prefix} %c(${time}ms)`, 'color: grey');
- for (const [signal, traces] of tracing_expressions.entries) {
- log_entry(signal, traces);
- }
+ var entries = tracing_expressions.entries;
+
+ untrack(() => {
+ for (const [signal, traces] of entries) {
+ log_entry(signal, traces);
+ }
+ });
tracing_expressions = null;
diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js
index c06705ce24..9544060959 100644
--- a/packages/svelte/src/internal/client/runtime.js
+++ b/packages/svelte/src/internal/client/runtime.js
@@ -39,6 +39,7 @@ import {
set_dev_current_component_function
} from './context.js';
import { handle_error, invoke_error_boundary } from './error-handling.js';
+import { snapshot } from '../shared/clone.js';
let is_flushing = false;
@@ -769,6 +770,7 @@ export function get(signal) {
if (
DEV &&
tracing_mode_flag &&
+ !untracking &&
tracing_expressions !== null &&
active_reaction !== null &&
tracing_expressions.reaction === active_reaction
diff --git a/packages/svelte/tests/runtime-legacy/shared.ts b/packages/svelte/tests/runtime-legacy/shared.ts
index c0d1177a82..11ea9f6dda 100644
--- a/packages/svelte/tests/runtime-legacy/shared.ts
+++ b/packages/svelte/tests/runtime-legacy/shared.ts
@@ -3,7 +3,7 @@ import { setImmediate } from 'node:timers/promises';
import { globSync } from 'tinyglobby';
import { createClassComponent } from 'svelte/legacy';
import { proxy } from 'svelte/internal/client';
-import { flushSync, hydrate, mount, unmount } from 'svelte';
+import { flushSync, hydrate, mount, unmount, untrack } from 'svelte';
import { render } from 'svelte/server';
import { afterAll, assert, beforeAll } from 'vitest';
import { compile_directory, fragments } from '../helpers.js';
diff --git a/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/Entry.svelte b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/Entry.svelte
new file mode 100644
index 0000000000..a22f006dcc
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/Entry.svelte
@@ -0,0 +1,8 @@
+
diff --git a/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/_config.js b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/_config.js
new file mode 100644
index 0000000000..94cd9d8aaf
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/_config.js
@@ -0,0 +1,40 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+import { normalise_trace_logs } from '../../../helpers.js';
+
+export default test({
+ compileOptions: {
+ dev: true
+ },
+
+ test({ assert, target, logs }) {
+ assert.deepEqual(normalise_trace_logs(logs), [
+ { log: 'effect' },
+ { log: '$state', highlighted: true },
+ { log: 'array', highlighted: false },
+ { log: [{ id: 1, hi: true }] },
+ // this _doesn't_ appear in the browser, but it does appear during tests
+ // and i cannot for the life of me figure out why. this does at least
+ // test that we don't log `array[0].id` etc
+ { log: '$state', highlighted: true },
+ { log: 'array[0]', highlighted: false },
+ { log: { id: 1, hi: true } }
+ ]);
+
+ logs.length = 0;
+
+ const button = target.querySelector('button');
+ button?.click();
+ flushSync();
+
+ assert.deepEqual(normalise_trace_logs(logs), [
+ { log: 'effect' },
+ { log: '$state', highlighted: true },
+ { log: 'array', highlighted: false },
+ { log: [{ id: 1, hi: false }] },
+ { log: '$state', highlighted: false },
+ { log: 'array[0]', highlighted: false },
+ { log: { id: 1, hi: false } }
+ ]);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/main.svelte b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/main.svelte
new file mode 100644
index 0000000000..e89ee7d9bc
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/inspect-trace-each/main.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+{#each array as entry (entry.id)}
+
+{/each}