Skip to content

Commit 17fd6be

Browse files
committed
Merge branch 'main' into experiment_z2
2 parents 68ad7eb + 8bba70b commit 17fd6be

File tree

22 files changed

+196
-97
lines changed

22 files changed

+196
-97
lines changed

.changeset/clever-cherries-hear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: don't throw for `undefined` non delegated event handlers

.changeset/pink-wolves-search.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: correctly handle `novalidate` attribute casing

.changeset/tasty-pigs-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: avoid double deriveds in component props

packages/svelte/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# svelte
22

3+
## 5.19.2
4+
5+
### Patch Changes
6+
7+
- fix: address regression with untrack ([#15079](https://github.com/sveltejs/svelte/pull/15079))
8+
39
## 5.19.1
410

511
### Patch Changes

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svelte",
33
"description": "Cybernetically enhanced web apps",
44
"license": "MIT",
5-
"version": "5.19.1",
5+
"version": "5.19.2",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

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

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -271,41 +271,6 @@ export function should_proxy(node, scope) {
271271
return true;
272272
}
273273

274-
/**
275-
* @param {Pattern} node
276-
* @param {import('zimmerframe').Context<AST.SvelteNode, ComponentClientTransformState>} context
277-
* @returns {{ id: Pattern, declarations: null | Statement[] }}
278-
*/
279-
export function create_derived_block_argument(node, context) {
280-
if (node.type === 'Identifier') {
281-
context.state.transform[node.name] = { read: get_value };
282-
return { id: node, declarations: null };
283-
}
284-
285-
const pattern = /** @type {Pattern} */ (context.visit(node));
286-
const identifiers = extract_identifiers(node);
287-
288-
const id = b.id('$$source');
289-
const value = b.id('$$value');
290-
291-
const block = b.block([
292-
b.var(pattern, b.call('$.get', id)),
293-
b.return(b.object(identifiers.map((identifier) => b.prop('init', identifier, identifier))))
294-
]);
295-
296-
const declarations = [b.var(value, create_derived(context.state, b.thunk(block)))];
297-
298-
for (const id of identifiers) {
299-
context.state.transform[id.name] = { read: get_value };
300-
301-
declarations.push(
302-
b.var(id, create_derived(context.state, b.thunk(b.member(b.call('$.get', value), id))))
303-
);
304-
}
305-
306-
return { id, declarations };
307-
}
308-
309274
/**
310275
* Svelte legacy mode should use safe equals in most places, runes mode shouldn't
311276
* @param {ComponentClientTransformState} state

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
22
/** @import { AST } from '#compiler' */
3-
/** @import { ComponentContext } from '../types' */
3+
/** @import { ComponentClientTransformState, ComponentContext } from '../types' */
4+
import { extract_identifiers } from '../../../../utils/ast.js';
45
import * as b from '../../../../utils/builders.js';
5-
import { create_derived_block_argument } from '../utils.js';
6+
import { create_derived } from '../utils.js';
7+
import { get_value } from './shared/declarations.js';
68

79
/**
810
* @param {AST.AwaitBlock} node
@@ -65,3 +67,38 @@ export function AwaitBlock(node, context) {
6567
)
6668
);
6769
}
70+
71+
/**
72+
* @param {Pattern} node
73+
* @param {import('zimmerframe').Context<AST.SvelteNode, ComponentClientTransformState>} context
74+
* @returns {{ id: Pattern, declarations: null | Statement[] }}
75+
*/
76+
function create_derived_block_argument(node, context) {
77+
if (node.type === 'Identifier') {
78+
context.state.transform[node.name] = { read: get_value };
79+
return { id: node, declarations: null };
80+
}
81+
82+
const pattern = /** @type {Pattern} */ (context.visit(node));
83+
const identifiers = extract_identifiers(node);
84+
85+
const id = b.id('$$source');
86+
const value = b.id('$$value');
87+
88+
const block = b.block([
89+
b.var(pattern, b.call('$.get', id)),
90+
b.return(b.object(identifiers.map((identifier) => b.prop('init', identifier, identifier))))
91+
]);
92+
93+
const declarations = [b.var(value, create_derived(context.state, b.thunk(block)))];
94+
95+
for (const id of identifiers) {
96+
context.state.transform[id.name] = { read: get_value };
97+
98+
declarations.push(
99+
b.var(id, create_derived(context.state, b.thunk(b.member(b.call('$.get', value), id))))
100+
);
101+
}
102+
103+
return { id, declarations };
104+
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,8 @@ function build_element_attribute_update_assignment(
537537
const is_svg = context.state.metadata.namespace === 'svg' || element.name === 'svg';
538538
const is_mathml = context.state.metadata.namespace === 'mathml';
539539

540-
let { value, has_state } = build_attribute_value(attribute.value, context, (value) =>
541-
get_expression_id(state, value)
540+
let { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
541+
metadata.has_call ? get_expression_id(state, value) : value
542542
);
543543

544544
if (name === 'autofocus') {
@@ -665,8 +665,8 @@ function build_custom_element_attribute_update_assignment(node_id, attribute, co
665665
*/
666666
function build_element_special_value_attribute(element, node_id, attribute, context) {
667667
const state = context.state;
668-
const { value, has_state } = build_attribute_value(attribute.value, context, (value) =>
669-
get_expression_id(state, value)
668+
const { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
669+
metadata.has_call ? get_expression_id(state, value) : value
670670
);
671671

672672
const inner_assignment = b.assignment(

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ export function SlotElement(node, context) {
3030
if (attribute.type === 'SpreadAttribute') {
3131
spreads.push(b.thunk(/** @type {Expression} */ (context.visit(attribute))));
3232
} else if (attribute.type === 'Attribute') {
33-
const { value, has_state } = build_attribute_value(attribute.value, context, (value) =>
34-
memoize_expression(context.state, value)
33+
const { value, has_state } = build_attribute_value(
34+
attribute.value,
35+
context,
36+
(value, metadata) => (metadata.has_call ? memoize_expression(context.state, value) : value)
3537
);
3638

3739
if (attribute.name === 'name') {

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

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import { dev, is_ignored } from '../../../../../state.js';
55
import { get_attribute_chunks, object } from '../../../../../utils/ast.js';
66
import * as b from '../../../../../utils/builders.js';
7-
import { create_derived } from '../../utils.js';
87
import { build_bind_this, memoize_expression, validate_binding } from '../shared/utils.js';
98
import { build_attribute_value } from '../shared/element.js';
109
import { build_event_handler } from './events.js';
@@ -134,9 +133,9 @@ export function build_component(node, component_name, context, anchor = context.
134133
custom_css_props.push(
135134
b.init(
136135
attribute.name,
137-
build_attribute_value(attribute.value, context, (value) =>
136+
build_attribute_value(attribute.value, context, (value, metadata) =>
138137
// TODO put the derived in the local block
139-
memoize_expression(context.state, value)
138+
metadata.has_call ? memoize_expression(context.state, value) : value
140139
).value
141140
)
142141
);
@@ -151,31 +150,29 @@ export function build_component(node, component_name, context, anchor = context.
151150
has_children_prop = true;
152151
}
153152

154-
const { value, has_state } = build_attribute_value(attribute.value, context, (value) =>
155-
memoize_expression(context.state, value)
156-
);
157-
158-
if (has_state) {
159-
let arg = value;
160-
161-
// When we have a non-simple computation, anything other than an Identifier or Member expression,
162-
// then there's a good chance it needs to be memoized to avoid over-firing when read within the
163-
// child component.
164-
const should_wrap_in_derived = get_attribute_chunks(attribute.value).some((n) => {
165-
return (
166-
n.type === 'ExpressionTag' &&
167-
n.expression.type !== 'Identifier' &&
168-
n.expression.type !== 'MemberExpression'
169-
);
170-
});
153+
const { value, has_state } = build_attribute_value(
154+
attribute.value,
155+
context,
156+
(value, metadata) => {
157+
if (!metadata.has_state) return value;
158+
159+
// When we have a non-simple computation, anything other than an Identifier or Member expression,
160+
// then there's a good chance it needs to be memoized to avoid over-firing when read within the
161+
// child component (e.g. `active={i === index}`)
162+
const should_wrap_in_derived = get_attribute_chunks(attribute.value).some((n) => {
163+
return (
164+
n.type === 'ExpressionTag' &&
165+
n.expression.type !== 'Identifier' &&
166+
n.expression.type !== 'MemberExpression'
167+
);
168+
});
171169

172-
if (should_wrap_in_derived) {
173-
const id = b.id(context.state.scope.generate(attribute.name));
174-
context.state.init.push(b.var(id, create_derived(context.state, b.thunk(value))));
175-
arg = b.call('$.get', id);
170+
return should_wrap_in_derived ? memoize_expression(context.state, value) : value;
176171
}
172+
);
177173

178-
push_prop(b.get(attribute.name, [b.return(arg)]));
174+
if (has_state) {
175+
push_prop(b.get(attribute.name, [b.return(value)]));
179176
} else {
180177
push_prop(b.init(attribute.name, value));
181178
}

0 commit comments

Comments
 (0)