svelte 5.39.9 → 5.39.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "svelte",
3
3
  "description": "Cybernetically enhanced web apps",
4
4
  "license": "MIT",
5
- "version": "5.39.9",
5
+ "version": "5.39.10",
6
6
  "type": "module",
7
7
  "types": "./types/index.d.ts",
8
8
  "engines": {
@@ -46,6 +46,21 @@ export function VariableDeclarator(node, context) {
46
46
  : path.is_rest
47
47
  ? 'rest_prop'
48
48
  : 'prop';
49
+ if (rune === '$props' && binding.kind === 'rest_prop' && node.id.type === 'ObjectPattern') {
50
+ const { properties } = node.id;
51
+ /** @type {string[]} */
52
+ const exclude_props = [];
53
+ for (const property of properties) {
54
+ if (property.type === 'RestElement') {
55
+ continue;
56
+ }
57
+ const key = /** @type {Identifier | Literal & { value: string | number }} */ (
58
+ property.key
59
+ );
60
+ exclude_props.push(key.type === 'Identifier' ? key.name : key.value.toString());
61
+ }
62
+ (binding.metadata ??= {}).exclude_props = exclude_props;
63
+ }
49
64
  }
50
65
  }
51
66
 
@@ -32,7 +32,11 @@ export function Identifier(node, context) {
32
32
  grand_parent?.type !== 'AssignmentExpression' &&
33
33
  grand_parent?.type !== 'UpdateExpression'
34
34
  ) {
35
- return b.id('$$props');
35
+ const key = /** @type {Identifier} */ (parent.property);
36
+
37
+ if (!binding.metadata?.exclude_props?.includes(key.name)) {
38
+ return b.id('$$props');
39
+ }
36
40
  }
37
41
  }
38
42
 
@@ -99,7 +99,14 @@ export function process_children(nodes, initial, is_element, context) {
99
99
 
100
100
  if (is_static_element(node, context.state)) {
101
101
  skipped += 1;
102
- } else if (node.type === 'EachBlock' && nodes.length === 1 && is_element) {
102
+ } else if (
103
+ node.type === 'EachBlock' &&
104
+ nodes.length === 1 &&
105
+ is_element &&
106
+ // In case it's wrapped in async the async logic will want to skip sibling nodes up until the end, hence we cannot make this controlled
107
+ // TODO switch this around and instead optimize for elements with a single block child and not require extra comments (neither for async nor normally)
108
+ !(node.body.metadata.has_await || node.metadata.expression.has_await)
109
+ ) {
103
110
  node.metadata.is_controlled = true;
104
111
  } else {
105
112
  const id = flush_node(false, node.type === 'RegularElement' ? node.name : 'node');
@@ -23,7 +23,11 @@ export function IfBlock(node, context) {
23
23
  /** @type {Statement} */
24
24
  let statement = b.if(test, consequent, alternate);
25
25
 
26
- if (node.metadata.expression.has_await) {
26
+ if (
27
+ node.metadata.expression.has_await ||
28
+ node.consequent.metadata.has_await ||
29
+ node.alternate?.metadata.has_await
30
+ ) {
27
31
  statement = create_async_block(b.block([statement]));
28
32
  }
29
33
 
@@ -7,11 +7,7 @@ import * as b from '#compiler/builders';
7
7
  * @param {Context} context
8
8
  */
9
9
  export function MemberExpression(node, context) {
10
- if (
11
- context.state.analysis.runes &&
12
- node.object.type === 'ThisExpression' &&
13
- node.property.type === 'PrivateIdentifier'
14
- ) {
10
+ if (context.state.analysis.runes && node.property.type === 'PrivateIdentifier') {
15
11
  const field = context.state.state_fields?.get(`#${node.property.name}`);
16
12
 
17
13
  if (field?.type === '$derived' || field?.type === '$derived.by') {
@@ -122,7 +122,7 @@ export class Binding {
122
122
 
123
123
  /**
124
124
  * Additional metadata, varies per binding type
125
- * @type {null | { inside_rest?: boolean; is_template_declaration?: boolean }}
125
+ * @type {null | { inside_rest?: boolean; is_template_declaration?: boolean; exclude_props?: string[] }}
126
126
  */
127
127
  metadata = null;
128
128
 
@@ -263,6 +263,7 @@ class Evaluation {
263
263
  if (binding.initial?.type === 'SnippetBlock') {
264
264
  this.is_defined = true;
265
265
  this.is_known = false;
266
+ this.values.add(UNKNOWN);
266
267
  break;
267
268
  }
268
269
 
package/src/version.js CHANGED
@@ -4,5 +4,5 @@
4
4
  * The current version, as set in package.json.
5
5
  * @type {string}
6
6
  */
7
- export const VERSION = '5.39.9';
7
+ export const VERSION = '5.39.10';
8
8
  export const PUBLIC_VERSION = '5';