svelte 5.41.3 → 5.41.4
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/index.js +1 -1
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +2 -2
- package/src/compiler/utils/ast.js +8 -4
- package/src/compiler/utils/builders.js +2 -2
- package/src/internal/client/constants.js +4 -1
- package/src/internal/client/dom/blocks/boundary.js +29 -3
- package/src/internal/client/reactivity/effects.js +9 -1
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import { walk } from 'zimmerframe';
|
|
|
6
6
|
import { parse } from '../1-parse/acorn.js';
|
|
7
7
|
import * as e from '../../errors.js';
|
|
8
8
|
import * as w from '../../warnings.js';
|
|
9
|
-
import { extract_identifiers } from '../../utils/ast.js';
|
|
9
|
+
import { extract_identifiers, has_await_expression } from '../../utils/ast.js';
|
|
10
10
|
import * as b from '#compiler/builders';
|
|
11
11
|
import { Scope, ScopeRoot, create_scopes, get_rune, set_scope } from '../scope.js';
|
|
12
12
|
import check_graph_for_cycles from './utils/check_graph_for_cycles.js';
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import * as b from '#compiler/builders';
|
|
13
13
|
import { sanitize_template_string } from '../../../../../utils/sanitize_template_string.js';
|
|
14
14
|
import { regex_whitespaces_strict } from '../../../../patterns.js';
|
|
15
|
-
import {
|
|
15
|
+
import { has_await_expression } from '../../../../../utils/ast.js';
|
|
16
16
|
|
|
17
17
|
/** Opens an if/each block, so that we can remove nodes in the case of a mismatch */
|
|
18
18
|
export const block_open = b.literal(BLOCK_OPEN);
|
|
@@ -315,7 +315,7 @@ export class PromiseOptimiser {
|
|
|
315
315
|
|
|
316
316
|
const promises = b.array(
|
|
317
317
|
this.expressions.map((expression) => {
|
|
318
|
-
return expression.type === 'AwaitExpression' && !
|
|
318
|
+
return expression.type === 'AwaitExpression' && !has_await_expression(expression.argument)
|
|
319
319
|
? expression.argument
|
|
320
320
|
: b.call(b.thunk(expression, true));
|
|
321
321
|
})
|
|
@@ -611,16 +611,20 @@ export function build_assignment_value(operator, left, right) {
|
|
|
611
611
|
}
|
|
612
612
|
|
|
613
613
|
/**
|
|
614
|
-
* @param {ESTree.
|
|
614
|
+
* @param {ESTree.Node} node
|
|
615
615
|
*/
|
|
616
|
-
export function
|
|
616
|
+
export function has_await_expression(node) {
|
|
617
617
|
let has_await = false;
|
|
618
618
|
|
|
619
|
-
walk(
|
|
619
|
+
walk(node, null, {
|
|
620
620
|
AwaitExpression(_node, context) {
|
|
621
621
|
has_await = true;
|
|
622
622
|
context.stop();
|
|
623
|
-
}
|
|
623
|
+
},
|
|
624
|
+
// don't traverse into these
|
|
625
|
+
FunctionDeclaration() {},
|
|
626
|
+
FunctionExpression() {},
|
|
627
|
+
ArrowFunctionExpression() {}
|
|
624
628
|
});
|
|
625
629
|
|
|
626
630
|
return has_await;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { walk } from 'zimmerframe';
|
|
3
3
|
import { regex_is_valid_identifier } from '../phases/patterns.js';
|
|
4
4
|
import { sanitize_template_string } from './sanitize_template_string.js';
|
|
5
|
-
import {
|
|
5
|
+
import { has_await_expression } from './ast.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {Array<ESTree.Expression | ESTree.SpreadElement | null>} elements
|
|
@@ -451,7 +451,7 @@ export function thunk(expression, async = false) {
|
|
|
451
451
|
export function unthunk(expression) {
|
|
452
452
|
// optimize `async () => await x()`, but not `async () => await x(await y)`
|
|
453
453
|
if (expression.async && expression.body.type === 'AwaitExpression') {
|
|
454
|
-
if (!
|
|
454
|
+
if (!has_await_expression(expression.body.argument)) {
|
|
455
455
|
return unthunk(arrow(expression.params, expression.body.argument));
|
|
456
456
|
}
|
|
457
457
|
}
|
|
@@ -14,7 +14,10 @@ export const DESTROYED = 1 << 14;
|
|
|
14
14
|
|
|
15
15
|
// Flags exclusive to effects
|
|
16
16
|
export const EFFECT_RAN = 1 << 15;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* 'Transparent' effects do not create a transition boundary.
|
|
19
|
+
* This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned
|
|
20
|
+
*/
|
|
18
21
|
export const EFFECT_TRANSPARENT = 1 << 16;
|
|
19
22
|
export const INSPECT_EFFECT = 1 << 17;
|
|
20
23
|
export const HEAD_EFFECT = 1 << 18;
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
skip_nodes,
|
|
31
31
|
set_hydrate_node
|
|
32
32
|
} from '../hydration.js';
|
|
33
|
-
import { get_next_sibling } from '../operations.js';
|
|
34
33
|
import { queue_micro_task } from '../task.js';
|
|
35
34
|
import * as e from '../../errors.js';
|
|
36
35
|
import * as w from '../../warnings.js';
|
|
@@ -39,6 +38,7 @@ import { Batch, effect_pending_updates } from '../../reactivity/batch.js';
|
|
|
39
38
|
import { internal_set, source } from '../../reactivity/sources.js';
|
|
40
39
|
import { tag } from '../../dev/tracing.js';
|
|
41
40
|
import { createSubscriber } from '../../../../reactivity/create-subscriber.js';
|
|
41
|
+
import { create_text } from '../operations.js';
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* @typedef {{
|
|
@@ -93,6 +93,9 @@ export class Boundary {
|
|
|
93
93
|
/** @type {DocumentFragment | null} */
|
|
94
94
|
#offscreen_fragment = null;
|
|
95
95
|
|
|
96
|
+
/** @type {TemplateNode | null} */
|
|
97
|
+
#pending_anchor = null;
|
|
98
|
+
|
|
96
99
|
#local_pending_count = 0;
|
|
97
100
|
#pending_count = 0;
|
|
98
101
|
|
|
@@ -156,8 +159,10 @@ export class Boundary {
|
|
|
156
159
|
this.#hydrate_resolved_content();
|
|
157
160
|
}
|
|
158
161
|
} else {
|
|
162
|
+
var anchor = this.#get_anchor();
|
|
163
|
+
|
|
159
164
|
try {
|
|
160
|
-
this.#main_effect = branch(() => children(
|
|
165
|
+
this.#main_effect = branch(() => children(anchor));
|
|
161
166
|
} catch (error) {
|
|
162
167
|
this.error(error);
|
|
163
168
|
}
|
|
@@ -168,6 +173,10 @@ export class Boundary {
|
|
|
168
173
|
this.#pending = false;
|
|
169
174
|
}
|
|
170
175
|
}
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
this.#pending_anchor?.remove();
|
|
179
|
+
};
|
|
171
180
|
}, flags);
|
|
172
181
|
|
|
173
182
|
if (hydrating) {
|
|
@@ -195,9 +204,11 @@ export class Boundary {
|
|
|
195
204
|
this.#pending_effect = branch(() => pending(this.#anchor));
|
|
196
205
|
|
|
197
206
|
Batch.enqueue(() => {
|
|
207
|
+
var anchor = this.#get_anchor();
|
|
208
|
+
|
|
198
209
|
this.#main_effect = this.#run(() => {
|
|
199
210
|
Batch.ensure();
|
|
200
|
-
return branch(() => this.#children(
|
|
211
|
+
return branch(() => this.#children(anchor));
|
|
201
212
|
});
|
|
202
213
|
|
|
203
214
|
if (this.#pending_count > 0) {
|
|
@@ -212,6 +223,19 @@ export class Boundary {
|
|
|
212
223
|
});
|
|
213
224
|
}
|
|
214
225
|
|
|
226
|
+
#get_anchor() {
|
|
227
|
+
var anchor = this.#anchor;
|
|
228
|
+
|
|
229
|
+
if (this.#pending) {
|
|
230
|
+
this.#pending_anchor = create_text();
|
|
231
|
+
this.#anchor.before(this.#pending_anchor);
|
|
232
|
+
|
|
233
|
+
anchor = this.#pending_anchor;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return anchor;
|
|
237
|
+
}
|
|
238
|
+
|
|
215
239
|
/**
|
|
216
240
|
* Returns `true` if the effect exists inside a boundary whose pending snippet is shown
|
|
217
241
|
* @returns {boolean}
|
|
@@ -253,6 +277,7 @@ export class Boundary {
|
|
|
253
277
|
|
|
254
278
|
if (this.#main_effect !== null) {
|
|
255
279
|
this.#offscreen_fragment = document.createDocumentFragment();
|
|
280
|
+
this.#offscreen_fragment.append(/** @type {TemplateNode} */ (this.#pending_anchor));
|
|
256
281
|
move_effect(this.#main_effect, this.#offscreen_fragment);
|
|
257
282
|
}
|
|
258
283
|
|
|
@@ -402,6 +427,7 @@ export class Boundary {
|
|
|
402
427
|
if (failed) {
|
|
403
428
|
queue_micro_task(() => {
|
|
404
429
|
this.#failed_effect = this.#run(() => {
|
|
430
|
+
Batch.ensure();
|
|
405
431
|
this.#is_creating_fallback = true;
|
|
406
432
|
|
|
407
433
|
try {
|
|
@@ -149,6 +149,9 @@ function create_effect(type, fn, sync, push = true) {
|
|
|
149
149
|
(e.f & EFFECT_PRESERVED) === 0
|
|
150
150
|
) {
|
|
151
151
|
e = e.first;
|
|
152
|
+
if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {
|
|
153
|
+
e.f |= EFFECT_TRANSPARENT;
|
|
154
|
+
}
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
if (e !== null) {
|
|
@@ -604,7 +607,12 @@ export function pause_children(effect, transitions, local) {
|
|
|
604
607
|
|
|
605
608
|
while (child !== null) {
|
|
606
609
|
var sibling = child.next;
|
|
607
|
-
var transparent =
|
|
610
|
+
var transparent =
|
|
611
|
+
(child.f & EFFECT_TRANSPARENT) !== 0 ||
|
|
612
|
+
// If this is a branch effect without a block effect parent,
|
|
613
|
+
// it means the parent block effect was pruned. In that case,
|
|
614
|
+
// transparency information was transferred to the branch effect.
|
|
615
|
+
((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0);
|
|
608
616
|
// TODO we don't need to call pause_children recursively with a linked list in place
|
|
609
617
|
// it's slightly more involved though as we have to account for `transparent` changing
|
|
610
618
|
// through the tree.
|
package/src/version.js
CHANGED