Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

svelte

Package Overview
Dependencies
Maintainers
3
Versions
1083
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.56.0
to
5.56.1
+1
-1
package.json

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

"license": "MIT",
"version": "5.56.0",
"version": "5.56.1",
"type": "module",

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

@@ -8,3 +8,2 @@ /** @import { Comment, Program, Statement } from 'estree' */

import * as e from '../../errors.js';
import { find_matching_bracket } from './utils/bracket.js';

@@ -110,34 +109,22 @@ const JSParser = acorn.Parser;

export function parse_statement_at(parser, source, index) {
const acorn = parser.ts ? TSParser : JSParser;
let end = find_matching_bracket(source, index, '{');
if (end === undefined) e.unexpected_eof(source.length);
// cast to `any`: acorn's Parser constructor and parseStatement/nextToken aren't in its public types
const acorn = /** @type {any} */ (parser.ts ? TSParser : JSParser);
const { onComment, add_comments } = get_comment_handlers(source, parser.root.comments, index);
while (source[end - 1] === ';') {
end -= 1;
}
const padded_source = `${' '.repeat(index)}${source.slice(index, end)}`;
const { onComment, add_comments } = get_comment_handlers(
padded_source,
parser.root.comments,
index
);
try {
const ast = acorn.parse(padded_source, {
onComment,
sourceType: 'module',
ecmaVersion: 16,
locations: true
});
add_comments(ast);
const statement = /** @type {Statement} */ (
/** @type {unknown} */ (/** @type {Program} */ (ast).body[0])
// This is like parseExpressionAt but for statements
const p = new acorn(
{ onComment, sourceType: 'module', ecmaVersion: 16, locations: true },
source,
index
);
statement.end = Math.min(/** @type {number} */ (statement.end), end);
p.nextToken();
const statement = /** @type {Statement} */ (p.parseStatement(null, true, Object.create(null)));
add_comments(/** @type {acorn.Node} */ (statement));
return statement;
} catch (e) {
handle_parse_error(e);
} catch (err) {
// A statement that runs to the end of the source (e.g. an unterminated declaration tag)
// is an EOF, not a stray token; preserve the friendlier `unexpected_eof` diagnostic.
if (/** @type {any} */ (err).pos === source.length) e.unexpected_eof(source.length);
handle_parse_error(err);
}

@@ -144,0 +131,0 @@ }

@@ -15,5 +15,5 @@ /** @import { ArrowFunctionExpression, Expression, Identifier, Pattern, VariableDeclaration } from 'estree' */

const regex_supported_declaration = /(?:let|const)\b/y;
// All except `type` are reserved keywords and cannot be used as variable names.
// For type we check if it's not something like `type .x` / `type ()` / `type % 2` / ...
const regex_unsupported_declaration = /(?:(?:var|interface|enum)\b)|(?:type\s+[^?.(`<[&|%^}])/y;
const regex_unsupported_declaration = /(?:var|interface|enum)\b/y;
// `type` is a contextual keyword; this is just a shape hint, confirmed by parsing.
const regex_maybe_type_declaration = /type\b/y;

@@ -81,6 +81,13 @@ const pointy_bois = { '<': '>' };

if (!parser.match_regex(regex_supported_declaration)) {
if (
!parser.match_regex(regex_supported_declaration) &&
// `type` is special, since it is not a reserved keyword and can be used
// as part of a valid expression. We gotta parse first and then see what it is.
!parser.match_regex(regex_maybe_type_declaration)
) {
return null;
}
const initial_comment_count = parser.root.comments.length;
/** @type {import('estree').Statement | import('estree').VariableDeclaration} */

@@ -122,6 +129,12 @@ let declaration;

if (declaration.type !== 'VariableDeclaration') {
e.declaration_tag_invalid_type({
start: declaration.start ?? start,
end: declaration.end ?? parser.index
});
if (declaration.type === 'ExpressionStatement') {
parser.root.comments.length = initial_comment_count; // Else they show up duplicated
return null;
} else {
// This is a TSTypeAliasDeclaration
e.declaration_tag_invalid_type({
start: declaration.start ?? start,
end: declaration.end ?? parser.index
});
}
}

@@ -128,0 +141,0 @@

@@ -42,3 +42,5 @@ /** @import { Parser } from '../index.js' */

function find_regex_end(string, search_start_index) {
return find_unescaped_char(string, search_start_index, '/');
const slash = find_unescaped_char(string, search_start_index, '/');
const eol = find_unescaped_char(string, search_start_index, '\n');
return slash < eol ? slash : Infinity;
}

@@ -109,3 +111,7 @@

const next_char = template[i + 1];
if (!next_char) continue;
if (!next_char) {
// `/` is the last character; advance past it so we don't loop forever
i++;
continue;
}
if (next_char === '/') {

@@ -119,3 +125,8 @@ i = infinity_if_negative(template.indexOf('\n', i + 1)) + '\n'.length;

}
i = find_regex_end(template, i + 1) + '/'.length;
const end = find_regex_end(template, i + 1) + '/'.length;
if (end === Infinity) {
i++;
} else {
i = end;
}
continue;

@@ -122,0 +133,0 @@ }

@@ -5,3 +5,3 @@ /** @import { AST } from '#compiler' */

import * as e from '../../../errors.js';
import { validate_opening_tag } from './shared/utils.js';
import { extract_identifiers } from '../../../utils/ast.js';

@@ -13,3 +13,2 @@ /**

export function DeclarationTag(node, context) {
validate_opening_tag(node, context.state, node.declaration.kind[0]);
if (!context.state.analysis.runes && !context.state.analysis.maybe_runes) {

@@ -19,5 +18,19 @@ e.declaration_tag_no_legacy_mode(node);

const is_top_level = context.path.length === 1 && context.path[0].type === 'Fragment';
if (is_top_level) {
const duplicate = node.declaration.declarations
.flatMap((declaration) => extract_identifiers(declaration.id))
.find((id) => context.state.analysis.instance.scope.declarations.has(id.name));
if (duplicate) {
e.declaration_duplicate(duplicate, duplicate.name);
}
}
context.visit(node.declaration, {
...context.state,
in_declaration_tag: true,
// the declaration lives in the fragment scope, which is one level deeper than the
// `function_depth` we're tracking here (`set_scope` doesn't update `function_depth`).
// align them so that `state_referenced_locally` warnings are calculated correctly
function_depth: context.state.scope.function_depth,
expression: node.metadata.expression

@@ -24,0 +37,0 @@ });

@@ -28,16 +28,21 @@ /** @import { AST, Binding } from '#compiler' */

const can_hoist =
context.path.length === 1 &&
context.path[0].type === 'Fragment' &&
can_hoist_snippet(context.state.scope, context.state.scopes);
const is_top_level = context.path.length === 1 && context.path[0].type === 'Fragment';
const name = node.expression.name;
if (is_top_level) {
const name = node.expression.name;
if (can_hoist) {
const binding = /** @type {Binding} */ (context.state.scope.get(name));
context.state.analysis.module.scope.declarations.set(name, binding);
if (context.state.analysis.instance.scope.declarations.has(name)) {
e.declaration_duplicate(node.expression, name);
}
node.metadata.can_hoist =
is_top_level && can_hoist_snippet(context.state.scope, context.state.scopes);
if (node.metadata.can_hoist) {
const name = node.expression.name;
const binding = /** @type {Binding} */ (context.state.scope.get(name));
context.state.analysis.module.scope.declarations.set(name, binding);
}
}
node.metadata.can_hoist = can_hoist;
const { path } = context;

@@ -44,0 +49,0 @@ const parent = path.at(-2);

@@ -13,4 +13,6 @@ /** @import { Expression, Identifier, Pattern, Statement, ExpressionStatement, VariableDeclaration } from 'estree' */

export function DeclarationTag(node, context) {
// register the transformers _before_ visiting the declaration, so that
// later declarators can reference earlier ones (e.g. `{let a = $state(0), b = $derived(a * 2)}`)
add_state_transformers(context);
const declaration = /** @type {Statement | undefined} */ (context.visit(node.declaration));
add_state_transformers(context);

@@ -17,0 +19,0 @@ if (

@@ -346,3 +346,3 @@ /** @import { Expression, Identifier, Node, Statement, BlockStatement, ArrayExpression } from 'estree' */

check_blockers(metadata) {
for (const binding of metadata.dependencies) {
for (const binding of metadata.references) {
if (binding.blocker) {

@@ -349,0 +349,0 @@ this.#blockers.add(binding.blocker);

@@ -206,3 +206,5 @@ /** @import { EachItem, EachOutroGroup, EachState, Effect, EffectNodes, MaybeSource, Source, TemplateNode, TransitionManager, Value } from '#client' */

return is_array(collection) ? collection : collection == null ? [] : array_from(collection);
return /** @type {V[]} */ (
is_array(collection) ? collection : collection == null ? [] : array_from(collection)
);
});

@@ -209,0 +211,0 @@

@@ -335,2 +335,11 @@ /** @import { Blocker, Effect } from '#client' */

if (element.nodeName === INPUT_TAG && 'type' in next && ('value' in next || '__value' in next)) {
var type = next.type;
if (type !== current.type || (type === undefined && element.hasAttribute('type'))) {
current.type = type;
set_attribute(element, 'type', type, skip_warning);
}
}
// since key is captured we use const

@@ -337,0 +346,0 @@ for (const key in next) {

@@ -10,3 +10,2 @@ /** @import { Batch } from '../../../reactivity/batch.js' */

import { tick, untrack } from '../../../runtime.js';
import { is_runes } from '../../../context.js';
import { current_batch, previous_batch } from '../../../reactivity/batch.js';

@@ -13,0 +12,0 @@ import { async_mode_flag } from '../../../../flags/index.js';

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

/** @import { Blocker, Effect, Value } from '#client' */
/** @import { Blocker, Effect, Source, Value } from '#client' */
import { DESTROYED, STALE_REACTION } from '#client/constants';

@@ -41,4 +41,18 @@ import { DEV } from 'esm-env';

var deriveds = sync.map(d);
if (DEV) {
deriveds.forEach((d, i) => {
// TODO this is kinda useful for debugging but a lousy implementation —
// maybe the compiler could pass through the template string
d.label = sync[i]
.toString()
.replace('() => ', '')
.replaceAll('$.eager(() => ', '$state.eager(')
.replace(/\$\.get\((.+?)\)/g, (_, id) => id);
});
}
if (async.length === 0 && pending.length === 0) {
fn(sync.map(d));
fn(deriveds);
return;

@@ -57,4 +71,6 @@ }

/** @param {Value[]} values */
function finish(values) {
/**
* @param {Source[]} async
*/
function finish(async) {
if ((parent.f & DESTROYED) !== 0) {

@@ -67,3 +83,3 @@ return;

try {
fn(values);
fn([...deriveds, ...async]);
} catch (error) {

@@ -80,6 +96,3 @@ invoke_error_boundary(error, parent);

if (async.length === 0) {
/** @type {Promise<any>} */ (blocker_promise)
.then(() => finish(sync.map(d)))
.finally(decrement_pending);
/** @type {Promise<any>} */ (blocker_promise).then(() => finish([])).finally(decrement_pending);
return;

@@ -91,3 +104,3 @@ }

Promise.all(async.map((expression) => async_derived(expression)))
.then((result) => finish([...sync.map(d), ...result]))
.then(finish)
.catch((error) => invoke_error_boundary(error, parent))

@@ -94,0 +107,0 @@ .finally(decrement_pending);

@@ -390,3 +390,5 @@ /** @import { Blocker, ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */

flatten(blockers, sync, async, (values) => {
create_effect(RENDER_EFFECT, () => fn(...values.map(get)));
create_effect(RENDER_EFFECT, () => {
fn(...values.map(get));
});
});

@@ -522,3 +524,3 @@ }

set_signal_status(effect, DESTROYING);
effect.f |= DESTROYING;
destroy_effect_children(effect, remove_dom && !removed);

@@ -525,0 +527,0 @@ remove_reactions(effect, 0);

@@ -135,7 +135,8 @@ import { DEV } from 'esm-env';

set(name, value) {
var previous = super.getAll(name).join('');
var previous = super.getAll(name);
super.set(name, value);
// can't use has(name, value), because for something like https://svelte.dev?foo=1&bar=2&foo=3
// if you set `foo` to 1, then foo=3 gets deleted whilst `has("foo", "1")` returns true
if (previous !== super.getAll(name).join('')) {
var current = super.getAll(name);
if (previous.length !== current.length || previous.some((value, i) => value !== current[i])) {
this.#update_url();

@@ -142,0 +143,0 @@ increment(this.#version);

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

*/
export const VERSION = '5.56.0';
export const VERSION = '5.56.1';
export const PUBLIC_VERSION = '5';

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