From 77077da9a3dfc4966d6083a57fb2bbe4b53b26ad Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 24 Nov 2025 14:50:24 -0500 Subject: [PATCH] chore: dedupe stack stuff --- .../svelte/src/internal/client/dev/inspect.js | 2 +- .../svelte/src/internal/client/dev/tracing.js | 38 ----------------- packages/svelte/src/internal/client/proxy.js | 3 +- .../internal/client/reactivity/deriveds.js | 2 +- .../src/internal/client/reactivity/sources.js | 3 +- .../svelte/src/internal/client/runtime.js | 3 +- packages/svelte/src/internal/shared/dev.js | 42 +++++++++++++++---- 7 files changed, 43 insertions(+), 50 deletions(-) diff --git a/packages/svelte/src/internal/client/dev/inspect.js b/packages/svelte/src/internal/client/dev/inspect.js index 34ba508984..953349a5c3 100644 --- a/packages/svelte/src/internal/client/dev/inspect.js +++ b/packages/svelte/src/internal/client/dev/inspect.js @@ -1,8 +1,8 @@ import { UNINITIALIZED } from '../../../constants.js'; import { snapshot } from '../../shared/clone.js'; +import { get_stack } from '../../shared/dev.js'; import { eager_effect, render_effect, validate_effect } from '../reactivity/effects.js'; import { untrack } from '../runtime.js'; -import { get_stack } from './tracing.js'; /** * @param {() => any[]} get_value diff --git a/packages/svelte/src/internal/client/dev/tracing.js b/packages/svelte/src/internal/client/dev/tracing.js index bd11138f66..79e4203e07 100644 --- a/packages/svelte/src/internal/client/dev/tracing.js +++ b/packages/svelte/src/internal/client/dev/tracing.js @@ -130,44 +130,6 @@ export function trace(label, fn) { } } -/** - * @param {string} label - * @returns {Error & { stack: string } | null} - */ -export function get_stack(label) { - return get_infinite_stack(label, (stack) => { - if (!stack) return; - - const lines = stack.split('\n'); - const new_lines = ['\n']; - - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - const posixified = line.replaceAll('\\', '/'); - - if (line === 'Error') { - continue; - } - - if (line.includes('validate_each_keys')) { - return undefined; - } - - if (posixified.includes('svelte/src/internal') || posixified.includes('node_modules/.vite')) { - continue; - } - - new_lines.push(line); - } - - if (new_lines.length === 1) { - return undefined; - } - - return new_lines.join('\n'); - }); -} - /** * @param {Value} source * @param {string} label diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js index 5b028d8d09..d5aac7676d 100644 --- a/packages/svelte/src/internal/client/proxy.js +++ b/packages/svelte/src/internal/client/proxy.js @@ -25,8 +25,9 @@ import { 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 { tag } from './dev/tracing.js'; import { tracing_mode_flag } from '../flags/index.js'; +import { get_stack } from '../shared/dev.js'; // TODO move all regexes into shared module? const regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 7e6f3c6f60..c824de31a7 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -28,7 +28,6 @@ import * as e from '../errors.js'; import * as w from '../warnings.js'; import { async_effect, destroy_effect, effect_tracking, teardown } from './effects.js'; import { eager_effects, internal_set, set_eager_effects, source } from './sources.js'; -import { get_stack } from '../dev/tracing.js'; import { async_mode_flag, tracing_mode_flag } from '../../flags/index.js'; import { Boundary } from '../dom/blocks/boundary.js'; import { component_context } from '../context.js'; @@ -36,6 +35,7 @@ import { UNINITIALIZED } from '../../../constants.js'; import { batch_values, current_batch } from './batch.js'; import { unset_context } from './async.js'; import { deferred } from '../../shared/utils.js'; +import { get_stack } from '../../shared/dev.js'; /** @type {Effect | null} */ export let current_async_effect = null; diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 8ae406b57b..a9106a4cef 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -32,11 +32,12 @@ import { } from '#client/constants'; import * as e from '../errors.js'; import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js'; -import { get_stack, tag_proxy } from '../dev/tracing.js'; +import { tag_proxy } from '../dev/tracing.js'; import { component_context, is_runes } from '../context.js'; import { Batch, batch_values, eager_block_effects, schedule_effect } from './batch.js'; import { proxy } from '../proxy.js'; import { execute_derived } from './deriveds.js'; +import { get_stack } from '../../shared/dev.js'; /** @type {Set} */ export let eager_effects = new Set(); diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 258f6962fa..ca7dbacd27 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -32,7 +32,7 @@ import { update_derived } from './reactivity/deriveds.js'; import { async_mode_flag, tracing_mode_flag } from '../flags/index.js'; -import { tracing_expressions, get_stack } from './dev/tracing.js'; +import { tracing_expressions } from './dev/tracing.js'; import { component_context, dev_current_component_function, @@ -48,6 +48,7 @@ import { handle_error } from './error-handling.js'; import { UNINITIALIZED } from '../../constants.js'; import { captured_signals } from './legacy.js'; import { without_reactive_context } from './dom/elements/bindings/shared.js'; +import { get_stack } from '../shared/dev.js'; export let is_updating_effect = false; diff --git a/packages/svelte/src/internal/shared/dev.js b/packages/svelte/src/internal/shared/dev.js index 546e42461a..3b39113e42 100644 --- a/packages/svelte/src/internal/shared/dev.js +++ b/packages/svelte/src/internal/shared/dev.js @@ -2,23 +2,51 @@ import { define_property } from './utils.js'; /** * @param {string} label - * @param {(stack: string | undefined) => string | undefined} fn * @returns {Error & { stack: string } | null} */ -export function get_infinite_stack(label, fn) { - // @ts-ignore - doesn't exist everywhere +export function get_stack(label) { + // @ts-ignore stackTraceLimit doesn't exist everywhere const limit = Error.stackTraceLimit; - // @ts-ignore - doesn't exist everywhere + + // @ts-ignore Error.stackTraceLimit = Infinity; let error = Error(); - // @ts-ignore - doesn't exist everywhere + + // @ts-ignore Error.stackTraceLimit = limit; - const stack = fn(error.stack); + + const stack = error.stack; if (!stack) return null; + const lines = stack.split('\n'); + const new_lines = ['\n']; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const posixified = line.replaceAll('\\', '/'); + + if (line === 'Error') { + continue; + } + + if (line.includes('validate_each_keys')) { + return null; + } + + if (posixified.includes('svelte/src/internal') || posixified.includes('node_modules/.vite')) { + continue; + } + + new_lines.push(line); + } + + if (new_lines.length === 1) { + return null; + } + define_property(error, 'stack', { - value: stack + value: new_lines.join('\n') }); define_property(error, 'name', {