Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

svelte

Package Overview
Dependencies
Maintainers
0
Versions
819
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte - npm Package Compare versions

Comparing version 5.13.0 to 5.14.0

src/internal/client/dev/tracing.js

2

package.json

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "5.13.0",
"version": "5.14.0",
"type": "module",

@@ -8,0 +8,0 @@ "types": "./types/index.d.ts",

@@ -374,2 +374,21 @@ declare module '*.svelte' {

declare namespace $inspect {
/**
* Tracks which reactive state changes caused an effect to re-run. Must be the first
* statement of a function body. Example:
*
* ```svelte
* <script>
* let count = $state(0);
*
* $effect(() => {
* $inspect.trace('my effect');
*
* count;
* });
* </script>
*/
export function trace(name: string): void;
}
/**

@@ -376,0 +395,0 @@ * Retrieves the `this` reference of the custom element that contains this component. Example:

@@ -210,2 +210,20 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */

/**
* `$inspect.trace(...)` cannot be used inside a generator function
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function inspect_trace_generator(node) {
e(node, "inspect_trace_generator", `\`$inspect.trace(...)\` cannot be used inside a generator function\nhttps://svelte.dev/e/inspect_trace_generator`);
}
/**
* `$inspect.trace(...)` must be the first statement of a function body
* @param {null | number | NodeLike} node
* @returns {never}
*/
export function inspect_trace_invalid_placement(node) {
e(node, "inspect_trace_invalid_placement", `\`$inspect.trace(...)\` must be the first statement of a function body\nhttps://svelte.dev/e/inspect_trace_invalid_placement`);
}
/**
* The arguments keyword cannot be used within the template or at the top level of a component

@@ -212,0 +230,0 @@ * @param {null | number | NodeLike} node

@@ -1,2 +0,2 @@

/** @import { CallExpression, VariableDeclarator } from 'estree' */
/** @import { ArrowFunctionExpression, CallExpression, Expression, FunctionDeclaration, FunctionExpression, Identifier, VariableDeclarator } from 'estree' */
/** @import { AST } from '#compiler' */

@@ -8,3 +8,4 @@ /** @import { Context } from '../types' */

import { is_pure, is_safe_identifier } from './shared/utils.js';
import { mark_subtree_dynamic } from './shared/fragment.js';
import { dev, locate_node, source } from '../../../state.js';
import * as b from '../../../utils/builders.js';

@@ -140,2 +141,41 @@ /**

case '$inspect.trace': {
if (node.arguments.length > 1) {
e.rune_invalid_arguments_length(node, rune, 'zero or one arguments');
}
const grand_parent = context.path.at(-2);
const fn = context.path.at(-3);
if (
parent.type !== 'ExpressionStatement' ||
grand_parent?.type !== 'BlockStatement' ||
!(
fn?.type === 'FunctionDeclaration' ||
fn?.type === 'FunctionExpression' ||
fn?.type === 'ArrowFunctionExpression'
) ||
grand_parent.body[0] !== parent
) {
e.inspect_trace_invalid_placement(node);
}
if (fn.generator) {
e.inspect_trace_generator(node);
}
if (dev) {
if (node.arguments[0]) {
context.state.scope.tracing = b.thunk(/** @type {Expression} */ (node.arguments[0]));
} else {
const label = get_function_label(context.path.slice(0, -2)) ?? 'trace';
const loc = `(${locate_node(fn)})`;
context.state.scope.tracing = b.thunk(b.literal(label + ' ' + loc));
}
}
break;
}
case '$state.snapshot':

@@ -187,1 +227,29 @@ if (node.arguments.length !== 1) {

}
/**
* @param {AST.SvelteNode[]} nodes
*/
function get_function_label(nodes) {
const fn = /** @type {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} */ (
nodes.at(-1)
);
if ((fn.type === 'FunctionDeclaration' || fn.type === 'FunctionExpression') && fn.id != null) {
return fn.id.name;
}
const parent = nodes.at(-2);
if (!parent) return;
if (parent.type === 'CallExpression') {
return source.slice(parent.callee.start, parent.callee.end) + '(...)';
}
if (parent.type === 'Property' && !parent.computed) {
return /** @type {Identifier} */ (parent.key).name;
}
if (parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') {
return parent.id.name;
}
}

@@ -11,3 +11,3 @@ /** @import { Location } from 'locate-character' */

} from '../../../../utils/ast.js';
import { dev, filename, is_ignored, locator } from '../../../../state.js';
import { dev, filename, is_ignored, locate_node, locator } from '../../../../state.js';
import { build_proxy_reassignment, should_proxy } from '../utils.js';

@@ -187,5 +187,2 @@ import { visit_assignment_expression } from '../../shared/assignments.js';

const loc = /** @type {Location} */ (locator(/** @type {number} */ (left.start)));
const location = `${filename}:${loc.line}:${loc.column}`;
return /** @type {Expression} */ (

@@ -202,3 +199,3 @@ context.visit(

right,
b.literal(location)
b.literal(locate_node(left))
)

@@ -205,0 +202,0 @@ )

@@ -1,4 +0,5 @@

/** @import { BlockStatement } from 'estree' */
/** @import { ArrowFunctionExpression, BlockStatement, CallExpression, Expression, FunctionDeclaration, FunctionExpression, Statement } from 'estree' */
/** @import { ComponentContext } from '../types' */
import { add_state_transformers } from './shared/declarations.js';
import * as b from '../../../../utils/builders.js';

@@ -11,3 +12,22 @@ /**

add_state_transformers(context);
const tracing = context.state.scope.tracing;
if (tracing !== null) {
const parent =
/** @type {ArrowFunctionExpression | FunctionDeclaration | FunctionExpression} */ (
context.path.at(-1)
);
const is_async = parent.async;
const call = b.call(
'$.trace',
/** @type {Expression} */ (tracing),
b.thunk(b.block(node.body.map((n) => /** @type {Statement} */ (context.visit(n)))), is_async)
);
return b.block([b.return(is_async ? b.await(call) : call)]);
}
context.next();
}

@@ -23,2 +23,6 @@ /** @import { Expression, ExpressionStatement } from 'estree' */

}
if (rune === '$inspect.trace') {
return b.empty;
}
}

@@ -25,0 +29,0 @@

@@ -30,2 +30,3 @@ /** @import { CallExpression, Expression, Identifier, Literal, VariableDeclaration, VariableDeclarator } from 'estree' */

rune === '$inspect' ||
rune === '$inspect.trace' ||
rune === '$state.snapshot' ||

@@ -32,0 +33,0 @@ rune === '$host'

@@ -13,3 +13,8 @@ /** @import { ExpressionStatement } from 'estree' */

if (rune === '$effect' || rune === '$effect.pre' || rune === '$effect.root') {
if (
rune === '$effect' ||
rune === '$effect.pre' ||
rune === '$effect.root' ||
rune === '$inspect.trace'
) {
return b.empty;

@@ -16,0 +21,0 @@ }

@@ -62,2 +62,8 @@ /** @import { ClassDeclaration, Expression, FunctionDeclaration, Identifier, ImportDeclaration, MemberExpression, Node, Pattern, VariableDeclarator } from 'estree' */

/**
* If tracing of reactive dependencies is enabled for this scope
* @type {null | Expression}
*/
tracing = null;
/**
*

@@ -64,0 +70,0 @@ * @param {ScopeRoot} root

@@ -0,4 +1,6 @@

/** @import { Location } from 'locate-character' */
/** @import { CompileOptions } from './types' */
/** @import { AST, Warning } from '#compiler' */
import { getLocator } from 'locate-character';
import { sanitize_location } from '../utils.js';

@@ -31,2 +33,10 @@ /** @typedef {{ start?: number, end?: number }} NodeLike */

/**
* @param {AST.SvelteNode & { start?: number | undefined }} node
*/
export function locate_node(node) {
const loc = /** @type {Location} */ (locator(/** @type {number} */ (node.start)));
return `${sanitize_location(filename)}:${loc?.line}:${loc.column}`;
}
/** @type {NonNullable<CompileOptions['warningFilter']>} */

@@ -33,0 +43,0 @@ export let warning_filter;

@@ -0,4 +1,4 @@

import { sanitize_location } from '../../../utils.js';
import { untrack } from '../runtime.js';
import * as w from '../warnings.js';
import { sanitize_location } from './location.js';

@@ -5,0 +5,0 @@ /**

@@ -39,2 +39,3 @@ /** @import { EachItem, EachState, Effect, MaybeSource, Source, TemplateNode, TransitionManager, Value } from '#client' */

import { active_effect, active_reaction } from '../../runtime.js';
import { DEV } from 'esm-env';

@@ -195,3 +196,14 @@ /**

var key = get_key(value, i);
item = create_item(hydrate_node, state, prev, null, value, key, i, render_fn, flags);
item = create_item(
hydrate_node,
state,
prev,
null,
value,
key,
i,
render_fn,
flags,
get_collection
);
state.items.set(key, item);

@@ -210,3 +222,12 @@

var effect = /** @type {Effect} */ (active_reaction);
reconcile(array, state, anchor, render_fn, flags, (effect.f & INERT) !== 0, get_key);
reconcile(
array,
state,
anchor,
render_fn,
flags,
(effect.f & INERT) !== 0,
get_key,
get_collection
);
}

@@ -257,5 +278,6 @@

* @param {(value: V, index: number) => any} get_key
* @param {() => V[]} get_collection
* @returns {void}
*/
function reconcile(array, state, anchor, render_fn, flags, is_inert, get_key) {
function reconcile(array, state, anchor, render_fn, flags, is_inert, get_key, get_collection) {
var is_animated = (flags & EACH_IS_ANIMATED) !== 0;

@@ -326,3 +348,4 @@ var should_update = (flags & (EACH_ITEM_REACTIVE | EACH_INDEX_REACTIVE)) !== 0;

render_fn,
flags
flags,
get_collection
);

@@ -494,5 +517,17 @@

* @param {number} flags
* @param {() => V[]} get_collection
* @returns {EachItem}
*/
function create_item(anchor, state, prev, next, value, key, index, render_fn, flags) {
function create_item(
anchor,
state,
prev,
next,
value,
key,
index,
render_fn,
flags,
get_collection
) {
var previous_each_item = current_each_item;

@@ -505,2 +540,12 @@ var reactive = (flags & EACH_ITEM_REACTIVE) !== 0;

if (DEV && reactive) {
// For tracing purposes, we need to link the source signal we create with the
// collection + index so that tracing works as intended
/** @type {Value} */ (v).debug = () => {
var collection_index = typeof i === 'number' ? index : i.v;
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
get_collection()[collection_index];
};
}
/** @type {EachItem} */

@@ -507,0 +552,0 @@ var item = {

@@ -8,7 +8,6 @@ /** @import { Effect, TemplateNode } from '#client' */

import * as w from '../../warnings.js';
import { hash } from '../../../../utils.js';
import { hash, sanitize_location } from '../../../../utils.js';
import { DEV } from 'esm-env';
import { dev_current_component_function } from '../../runtime.js';
import { get_first_child, get_next_sibling } from '../operations.js';
import { sanitize_location } from '../../dev/location.js';

@@ -15,0 +14,0 @@ /**

@@ -15,2 +15,3 @@ export { FILENAME, HMR, NAMESPACE_SVG } from '../../constants.js';

export { check_target, legacy_api } from './dev/legacy.js';
export { trace } from './dev/tracing.js';
export { inspect } from './dev/inspect.js';

@@ -17,0 +18,0 @@ export { await_block as await } from './dom/blocks/await.js';

@@ -16,2 +16,3 @@ /** @import { ProxyMetadata, ProxyStateObject, Source } from '#client' */

import * as e from './errors.js';
import { get_stack } from './dev/tracing.js';

@@ -26,2 +27,7 @@ /**

export function proxy(value, parent = null, prev) {
/** @type {Error | null} */
var stack = null;
if (DEV) {
stack = get_stack('CreatedAt');
}
// if non-proxyable, or is already a proxy, return `value`

@@ -46,3 +52,3 @@ if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) {

// mutations to the array are properly synced with our proxy
sources.set('length', source(/** @type {any[]} */ (value).length));
sources.set('length', source(/** @type {any[]} */ (value).length, stack));
}

@@ -93,3 +99,3 @@

if (s === undefined) {
s = source(descriptor.value);
s = source(descriptor.value, stack);
sources.set(prop, s);

@@ -108,3 +114,3 @@ } else {

if (prop in target) {
sources.set(prop, source(UNINITIALIZED));
sources.set(prop, source(UNINITIALIZED, stack));
}

@@ -143,3 +149,3 @@ } else {

if (s === undefined && (!exists || get_descriptor(target, prop)?.writable)) {
s = source(proxy(exists ? target[prop] : UNINITIALIZED, metadata));
s = source(proxy(exists ? target[prop] : UNINITIALIZED, metadata), stack);
sources.set(prop, s);

@@ -212,3 +218,3 @@ }

if (s === undefined) {
s = source(has ? proxy(target[prop], metadata) : UNINITIALIZED);
s = source(has ? proxy(target[prop], metadata) : UNINITIALIZED, stack);
sources.set(prop, s);

@@ -240,3 +246,3 @@ }

// the value of the original item at that index.
other_s = source(UNINITIALIZED);
other_s = source(UNINITIALIZED, stack);
sources.set(i + '', other_s);

@@ -253,3 +259,3 @@ }

if (!has || get_descriptor(target, prop)?.writable) {
s = source(undefined);
s = source(undefined, stack);
set(s, proxy(value, metadata));

@@ -256,0 +262,0 @@ sources.set(prop, s);

@@ -27,2 +27,3 @@ /** @import { Derived, Effect } from '#client' */

import { inspect_effects, set_inspect_effects } from './sources.js';
import { get_stack } from '../dev/tracing.js';

@@ -65,2 +66,6 @@ /**

if (DEV) {
signal.created = get_stack('CreatedAt');
}
if (parent_derived !== null) {

@@ -67,0 +72,0 @@ (parent_derived.children ??= []).push(signal);

@@ -1,2 +0,2 @@

/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, Reaction, TemplateNode, TransitionManager } from '#client' */
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */
import {

@@ -19,4 +19,3 @@ check_dirtiness,

untrack,
skip_reaction,
capture_signals
skip_reaction
} from '../runtime.js';

@@ -44,3 +43,2 @@ import {

import * as e from '../errors.js';
import * as w from '../warnings.js';
import { DEV } from 'esm-env';

@@ -50,4 +48,2 @@ import { define_property } from '../../shared/utils.js';

import { destroy_derived } from './deriveds.js';
import { FILENAME } from '../../../constants.js';
import { get_location } from '../dev/location.js';

@@ -54,0 +50,0 @@ /**

@@ -36,2 +36,3 @@ /** @import { Derived, Effect, Reaction, Source, Value } from '#client' */

import { legacy_mode_flag } from '../../flags/index.js';
import { get_stack } from '../dev/tracing.js';

@@ -50,6 +51,8 @@ export let inspect_effects = new Set();

* @param {V} v
* @param {Error | null} [stack]
* @returns {Source<V>}
*/
export function source(v) {
return {
export function source(v, stack) {
/** @type {Value} */
var signal = {
f: 0, // TODO ideally we could skip this altogether, but it causes type errors

@@ -61,2 +64,9 @@ v,

};
if (DEV) {
signal.created = stack ?? get_stack('CreatedAt');
signal.debug = null;
}
return signal;
}

@@ -166,2 +176,6 @@

if (DEV) {
source.updated = get_stack('UpdatedAt');
}
mark_reactions(source, DIRTY);

@@ -168,0 +182,0 @@

@@ -17,2 +17,6 @@ import type { ComponentContext, Dom, Equals, TemplateNode, TransitionManager } from '#client';

v: V;
/** Dev only */
created?: Error | null;
updated?: Error | null;
debug?: null | (() => void);
}

@@ -19,0 +23,0 @@

@@ -38,2 +38,3 @@ /** @import { ComponentContext, Derived, Effect, Reaction, Signal, Source, Value } from '#client' */

import { legacy_mode_flag } from '../flags/index.js';
import { tracing_expressions, get_stack } from './dev/tracing.js';

@@ -140,2 +141,7 @@ const FLUSH_MICROTASK = 0;

/** @param {Set<Value> | null} value */
export function set_captured_signals(value) {
captured_signals = value;
}
// Handling runtime component context

@@ -361,3 +367,3 @@ /** @type {ComponentContext | null} */

define_property(error, 'stack', {
value: error.stack + new_lines.join('\n')
value: new_lines.join('\n')
});

@@ -914,2 +920,23 @@ }

if (
DEV &&
tracing_expressions !== null &&
active_reaction !== null &&
tracing_expressions.reaction === active_reaction
) {
// Used when mapping state between special blocks like `each`
if (signal.debug) {
signal.debug();
} else if (signal.created) {
var entry = tracing_expressions.entries.get(signal);
if (entry === undefined) {
entry = { read: [] };
tracing_expressions.entries.set(signal, entry);
}
entry.read.push(get_stack('TracedAt'));
}
}
return signal.v;

@@ -916,0 +943,0 @@ }

@@ -434,2 +434,3 @@ const regex_return_characters = /\r/g;

'$inspect().with',
'$inspect.trace',
'$host'

@@ -453,1 +454,9 @@ ]);

}
/**
* Prevent devtools trying to make `location` a clickable link by inserting a zero-width space
* @param {string | undefined} location
*/
export function sanitize_location(location) {
return location?.replace(/\//g, '/\u200b');
}

@@ -9,3 +9,3 @@ // generated during release, do not modify

*/
export const VERSION = '5.13.0';
export const VERSION = '5.14.0';
export const PUBLIC_VERSION = '5';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc