svelte 5.39.8 → 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/compiler/index.js +1 -1
- package/package.json +1 -1
- package/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js +15 -0
- package/src/compiler/phases/3-transform/client/visitors/Identifier.js +5 -1
- package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +8 -1
- package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +5 -1
- package/src/compiler/phases/3-transform/server/visitors/MemberExpression.js +1 -5
- package/src/compiler/phases/scope.js +2 -1
- package/src/internal/client/dom/blocks/boundary.js +7 -0
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
|
|
@@ -285,6 +285,13 @@ export class Boundary {
|
|
|
285
285
|
this.#anchor.before(this.#offscreen_fragment);
|
|
286
286
|
this.#offscreen_fragment = null;
|
|
287
287
|
}
|
|
288
|
+
|
|
289
|
+
// TODO this feels like a little bit of a kludge, but until we
|
|
290
|
+
// overhaul the boundary/batch relationship it's probably
|
|
291
|
+
// the most pragmatic solution available to us
|
|
292
|
+
queue_micro_task(() => {
|
|
293
|
+
Batch.ensure().flush();
|
|
294
|
+
});
|
|
288
295
|
}
|
|
289
296
|
}
|
|
290
297
|
|
package/src/version.js
CHANGED