svelte 5.55.4 → 5.55.6
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/elements.d.ts +3 -3
- package/package.json +1 -1
- package/src/compiler/phases/1-parse/read/style.js +15 -0
- package/src/compiler/phases/3-transform/client/visitors/DebugTag.js +10 -4
- package/src/compiler/phases/3-transform/server/visitors/Component.js +5 -1
- package/src/compiler/phases/3-transform/server/visitors/DebugTag.js +21 -10
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +2 -2
- package/src/internal/client/constants.js +2 -1
- package/src/internal/client/dev/inspect.js +2 -0
- package/src/internal/client/dom/blocks/async.js +1 -5
- package/src/internal/client/dom/blocks/boundary.js +4 -5
- package/src/internal/client/dom/blocks/svelte-head.js +6 -5
- package/src/internal/client/dom/elements/attributes.js +1 -1
- package/src/internal/client/dom/elements/bindings/this.js +1 -1
- package/src/internal/client/dom/elements/events.js +2 -2
- package/src/internal/client/dom/elements/transitions.js +47 -21
- package/src/internal/client/reactivity/async.js +34 -16
- package/src/internal/client/reactivity/batch.js +294 -127
- package/src/internal/client/reactivity/deriveds.js +30 -29
- package/src/internal/client/reactivity/effects.js +1 -9
- package/src/internal/client/reactivity/props.js +7 -1
- package/src/internal/client/reactivity/sources.js +26 -12
- package/src/internal/server/renderer.js +6 -1
- package/src/version.js +1 -1
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
package/elements.d.ts
CHANGED
|
@@ -2067,9 +2067,9 @@ export interface SvelteHTMLElements {
|
|
|
2067
2067
|
};
|
|
2068
2068
|
'svelte:head': { [name: string]: any };
|
|
2069
2069
|
'svelte:boundary': {
|
|
2070
|
-
onerror?: (error: unknown, reset: () => void) => void;
|
|
2071
|
-
failed?: import('svelte').Snippet<[error: unknown, reset: () => void]
|
|
2072
|
-
pending?: import('svelte').Snippet;
|
|
2070
|
+
onerror?: ((error: unknown, reset: () => void) => void) | null | undefined;
|
|
2071
|
+
failed?: import('svelte').Snippet<[error: unknown, reset: () => void]> | null | undefined;
|
|
2072
|
+
pending?: import('svelte').Snippet | null | undefined;
|
|
2073
2073
|
};
|
|
2074
2074
|
|
|
2075
2075
|
[name: string]: { [name: string]: any };
|
package/package.json
CHANGED
|
@@ -524,6 +524,21 @@ function read_value(parser) {
|
|
|
524
524
|
in_url = true;
|
|
525
525
|
} else if ((char === ';' || char === '{' || char === '}') && !in_url && !quote_mark) {
|
|
526
526
|
return value.trim();
|
|
527
|
+
} else if (
|
|
528
|
+
char === '/' &&
|
|
529
|
+
!in_url &&
|
|
530
|
+
!quote_mark &&
|
|
531
|
+
parser.template[parser.index + 1] === '*'
|
|
532
|
+
) {
|
|
533
|
+
parser.index += 2;
|
|
534
|
+
while (parser.index < parser.template.length) {
|
|
535
|
+
if (parser.template[parser.index] === '*' && parser.template[parser.index + 1] === '/') {
|
|
536
|
+
parser.index += 2;
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
parser.index++;
|
|
540
|
+
}
|
|
541
|
+
continue;
|
|
527
542
|
}
|
|
528
543
|
|
|
529
544
|
value += char;
|
|
@@ -8,6 +8,10 @@ import * as b from '#compiler/builders';
|
|
|
8
8
|
* @param {ComponentContext} context
|
|
9
9
|
*/
|
|
10
10
|
export function DebugTag(node, context) {
|
|
11
|
+
const blockers = node.identifiers
|
|
12
|
+
.map((identifier) => context.state.scope.get(identifier.name)?.blocker)
|
|
13
|
+
.filter((blocker) => blocker != null);
|
|
14
|
+
|
|
11
15
|
const object = b.object(
|
|
12
16
|
node.identifiers.map((identifier) => {
|
|
13
17
|
const visited = b.call('$.snapshot', /** @type {Expression} */ (context.visit(identifier)));
|
|
@@ -20,9 +24,11 @@ export function DebugTag(node, context) {
|
|
|
20
24
|
})
|
|
21
25
|
);
|
|
22
26
|
|
|
23
|
-
const
|
|
27
|
+
const args = [b.thunk(b.block([b.stmt(b.call('console.log', object)), b.debugger]))];
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (blockers.length > 0) {
|
|
30
|
+
args.push(b.array([]), b.array([]), b.array(blockers));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
context.state.init.push(b.stmt(b.call('$.template_effect', ...args)));
|
|
28
34
|
}
|
|
@@ -9,5 +9,9 @@ import { build_inline_component } from './shared/component.js';
|
|
|
9
9
|
* @param {ComponentContext} context
|
|
10
10
|
*/
|
|
11
11
|
export function Component(node, context) {
|
|
12
|
-
build_inline_component(
|
|
12
|
+
build_inline_component(
|
|
13
|
+
node,
|
|
14
|
+
/** @type {Expression} */ (context.visit(b.member_id(node.name))),
|
|
15
|
+
context
|
|
16
|
+
);
|
|
13
17
|
}
|
|
@@ -2,23 +2,34 @@
|
|
|
2
2
|
/** @import { AST } from '#compiler' */
|
|
3
3
|
/** @import { ComponentContext } from '../types.js' */
|
|
4
4
|
import * as b from '#compiler/builders';
|
|
5
|
+
import { create_child_block } from './shared/utils.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @param {AST.DebugTag} node
|
|
8
9
|
* @param {ComponentContext} context
|
|
9
10
|
*/
|
|
10
11
|
export function DebugTag(node, context) {
|
|
12
|
+
const blockers = node.identifiers
|
|
13
|
+
.map((identifier) => context.state.scope.get(identifier.name)?.blocker)
|
|
14
|
+
.filter((blocker) => blocker != null);
|
|
15
|
+
|
|
11
16
|
context.state.template.push(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
b.
|
|
17
|
+
...create_child_block(
|
|
18
|
+
[
|
|
19
|
+
b.stmt(
|
|
20
|
+
b.call(
|
|
21
|
+
'console.log',
|
|
22
|
+
b.object(
|
|
23
|
+
node.identifiers.map((identifier) =>
|
|
24
|
+
b.prop('init', identifier, /** @type {Expression} */ (context.visit(identifier)))
|
|
25
|
+
)
|
|
26
|
+
)
|
|
18
27
|
)
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
),
|
|
29
|
+
b.debugger
|
|
30
|
+
],
|
|
31
|
+
b.array(blockers),
|
|
32
|
+
false
|
|
33
|
+
)
|
|
23
34
|
);
|
|
24
35
|
}
|
|
@@ -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 { has_await_expression } from '../../../../../utils/ast.js';
|
|
15
|
+
import { has_await_expression, save } from '../../../../../utils/ast.js';
|
|
16
16
|
import { ExpressionMetadata } from '../../../../nodes.js';
|
|
17
17
|
|
|
18
18
|
/** Opens an if/each block, so that we can remove nodes in the case of a mismatch */
|
|
@@ -360,7 +360,7 @@ export class PromiseOptimiser {
|
|
|
360
360
|
|
|
361
361
|
return b.const(
|
|
362
362
|
b.array_pattern(this.expressions.map((_, i) => b.id(`$$${i}`))),
|
|
363
|
-
|
|
363
|
+
save(b.call('Promise.all', promises))
|
|
364
364
|
);
|
|
365
365
|
}
|
|
366
366
|
|
|
@@ -48,7 +48,8 @@ export const EFFECT_OFFSCREEN = 1 << 25;
|
|
|
48
48
|
/**
|
|
49
49
|
* Tells that we marked this derived and its reactions as visited during the "mark as (maybe) dirty"-phase.
|
|
50
50
|
* Will be lifted during execution of the derived and during checking its dirty state (both are necessary
|
|
51
|
-
* because a derived might be checked but not executed).
|
|
51
|
+
* because a derived might be checked but not executed). This is a pure performance optimization flag and
|
|
52
|
+
* should not be used for any other purpose!
|
|
52
53
|
*/
|
|
53
54
|
export const WAS_MARKED = 1 << 16;
|
|
54
55
|
|
|
@@ -20,6 +20,8 @@ export function inspect(get_value, inspector, show_stack = false) {
|
|
|
20
20
|
// in an error (an `$inspect(object.property)` will run before the
|
|
21
21
|
// `{#if object}...{/if}` that contains it)
|
|
22
22
|
eager_effect(() => {
|
|
23
|
+
error = UNINITIALIZED;
|
|
24
|
+
|
|
23
25
|
try {
|
|
24
26
|
var value = get_value();
|
|
25
27
|
} catch (e) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { Blocker, TemplateNode, Value } from '#client' */
|
|
2
|
-
import { flatten
|
|
2
|
+
import { flatten } from '../../reactivity/async.js';
|
|
3
3
|
import { get } from '../../runtime.js';
|
|
4
4
|
import {
|
|
5
5
|
hydrate_next,
|
|
@@ -42,8 +42,6 @@ export function async(node, blockers = [], expressions = [], fn) {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const decrement_pending = increment_pending();
|
|
46
|
-
|
|
47
45
|
if (was_hydrating) {
|
|
48
46
|
var previous_hydrate_node = hydrate_node;
|
|
49
47
|
set_hydrate_node(end);
|
|
@@ -64,8 +62,6 @@ export function async(node, blockers = [], expressions = [], fn) {
|
|
|
64
62
|
if (was_hydrating) {
|
|
65
63
|
set_hydrating(false);
|
|
66
64
|
}
|
|
67
|
-
|
|
68
|
-
decrement_pending();
|
|
69
65
|
}
|
|
70
66
|
});
|
|
71
67
|
}
|
|
@@ -35,19 +35,18 @@ import { queue_micro_task } from '../task.js';
|
|
|
35
35
|
import * as e from '../../errors.js';
|
|
36
36
|
import * as w from '../../warnings.js';
|
|
37
37
|
import { DEV } from 'esm-env';
|
|
38
|
-
import { Batch, current_batch
|
|
38
|
+
import { Batch, current_batch } from '../../reactivity/batch.js';
|
|
39
39
|
import { internal_set, source } from '../../reactivity/sources.js';
|
|
40
40
|
import { tag } from '../../dev/tracing.js';
|
|
41
41
|
import { createSubscriber } from '../../../../reactivity/create-subscriber.js';
|
|
42
42
|
import { create_text } from '../operations.js';
|
|
43
43
|
import { defer_effect } from '../../reactivity/utils.js';
|
|
44
|
-
import { set_signal_status } from '../../reactivity/status.js';
|
|
45
44
|
|
|
46
45
|
/**
|
|
47
46
|
* @typedef {{
|
|
48
|
-
* onerror?: (error: unknown, reset: () => void) => void;
|
|
49
|
-
* failed?: (anchor: Node, error: () => unknown, reset: () => () => void) => void;
|
|
50
|
-
* pending?: (anchor: Node) => void;
|
|
47
|
+
* onerror?: ((error: unknown, reset: () => void) => void) | null;
|
|
48
|
+
* failed?: ((anchor: Node, error: () => unknown, reset: () => () => void) => void) | null;
|
|
49
|
+
* pending?: ((anchor: Node) => void) | null;
|
|
51
50
|
* }} BoundaryProps
|
|
52
51
|
*/
|
|
53
52
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** @import { TemplateNode } from '#client' */
|
|
2
2
|
import { hydrate_node, hydrating, set_hydrate_node, set_hydrating } from '../hydration.js';
|
|
3
3
|
import { create_text, get_first_child, get_next_sibling } from '../operations.js';
|
|
4
|
-
import { block } from '../../reactivity/effects.js';
|
|
5
|
-
import { COMMENT_NODE,
|
|
4
|
+
import { block, branch } from '../../reactivity/effects.js';
|
|
5
|
+
import { COMMENT_NODE, HEAD_EFFECT } from '#client/constants';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {string} hash
|
|
@@ -49,9 +49,10 @@ export function head(hash, render_fn) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
block(() => {
|
|
53
|
+
var e = branch(() => render_fn(anchor));
|
|
54
|
+
e.f |= HEAD_EFFECT;
|
|
55
|
+
});
|
|
55
56
|
} finally {
|
|
56
57
|
if (was_hydrating) {
|
|
57
58
|
set_hydrating(true);
|
|
@@ -584,7 +584,7 @@ function get_setters(element) {
|
|
|
584
584
|
var element_proto = Element.prototype;
|
|
585
585
|
|
|
586
586
|
// Stop at Element, from there on there's only unnecessary setters we're not interested in
|
|
587
|
-
// Do not use
|
|
587
|
+
// Do not use constructor.name here as that's unreliable in some browser environments
|
|
588
588
|
while (element_proto !== proto) {
|
|
589
589
|
descriptors = get_descriptors(proto);
|
|
590
590
|
|
|
@@ -40,7 +40,7 @@ export function bind_this(element_or_component = {}, update, get_value, get_part
|
|
|
40
40
|
parts = get_parts?.() || [];
|
|
41
41
|
|
|
42
42
|
untrack(() => {
|
|
43
|
-
if (
|
|
43
|
+
if (!is_bound_this(get_value(...parts), element_or_component)) {
|
|
44
44
|
update(element_or_component, ...parts);
|
|
45
45
|
// If this is an effect rerun (cause: each block context changes), then nullify the binding at
|
|
46
46
|
// the previous position if it isn't already taken over by a different effect.
|
|
@@ -237,9 +237,9 @@ export function handle_event_propagation(event) {
|
|
|
237
237
|
});
|
|
238
238
|
|
|
239
239
|
// This started because of Chromium issue https://chromestatus.com/feature/5128696823545856,
|
|
240
|
-
// where removal or moving of
|
|
240
|
+
// where removal or moving of the DOM can cause sync `blur` events to fire, which can cause logic
|
|
241
241
|
// to run inside the current `active_reaction`, which isn't what we want at all. However, on reflection,
|
|
242
|
-
// it's probably best that all
|
|
242
|
+
// it's probably best that all events handled by Svelte have this behaviour, as we don't really want
|
|
243
243
|
// an event handler to run in the context of another reaction or effect.
|
|
244
244
|
var previous_reaction = active_reaction;
|
|
245
245
|
var previous_effect = active_effect;
|
|
@@ -115,10 +115,17 @@ export function animation(element, get_fn, get_params) {
|
|
|
115
115
|
) {
|
|
116
116
|
const options = get_fn()(this.element, { from, to }, get_params?.());
|
|
117
117
|
|
|
118
|
-
animation = animate(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
animation = animate(
|
|
119
|
+
this.element,
|
|
120
|
+
options,
|
|
121
|
+
undefined,
|
|
122
|
+
1,
|
|
123
|
+
() => {},
|
|
124
|
+
() => {
|
|
125
|
+
animation?.abort();
|
|
126
|
+
animation = undefined;
|
|
127
|
+
}
|
|
128
|
+
);
|
|
122
129
|
}
|
|
123
130
|
},
|
|
124
131
|
fix() {
|
|
@@ -239,15 +246,24 @@ export function transition(flags, element, get_fn, get_params) {
|
|
|
239
246
|
intro?.abort();
|
|
240
247
|
}
|
|
241
248
|
|
|
242
|
-
intro = animate(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
intro = animate(
|
|
250
|
+
element,
|
|
251
|
+
get_options(),
|
|
252
|
+
outro,
|
|
253
|
+
1,
|
|
254
|
+
() => {
|
|
255
|
+
dispatch_event(element, 'introstart');
|
|
256
|
+
},
|
|
257
|
+
() => {
|
|
258
|
+
dispatch_event(element, 'introend');
|
|
259
|
+
|
|
260
|
+
// Ensure we cancel the animation to prevent leaking
|
|
261
|
+
intro?.abort();
|
|
262
|
+
intro = current_options = undefined;
|
|
263
|
+
|
|
264
|
+
element.style.overflow = overflow;
|
|
265
|
+
}
|
|
266
|
+
);
|
|
251
267
|
},
|
|
252
268
|
out(fn) {
|
|
253
269
|
if (!is_outro) {
|
|
@@ -258,10 +274,19 @@ export function transition(flags, element, get_fn, get_params) {
|
|
|
258
274
|
|
|
259
275
|
element.inert = true;
|
|
260
276
|
|
|
261
|
-
outro = animate(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
277
|
+
outro = animate(
|
|
278
|
+
element,
|
|
279
|
+
get_options(),
|
|
280
|
+
intro,
|
|
281
|
+
0,
|
|
282
|
+
() => {
|
|
283
|
+
dispatch_event(element, 'outrostart');
|
|
284
|
+
},
|
|
285
|
+
() => {
|
|
286
|
+
dispatch_event(element, 'outroend');
|
|
287
|
+
fn?.();
|
|
288
|
+
}
|
|
289
|
+
);
|
|
265
290
|
},
|
|
266
291
|
stop: () => {
|
|
267
292
|
intro?.abort();
|
|
@@ -306,10 +331,11 @@ export function transition(flags, element, get_fn, get_params) {
|
|
|
306
331
|
* @param {AnimationConfig | ((opts: { direction: 'in' | 'out' }) => AnimationConfig)} options
|
|
307
332
|
* @param {Animation | undefined} counterpart The corresponding intro/outro to this outro/intro
|
|
308
333
|
* @param {number} t2 The target `t` value — `1` for intro, `0` for outro
|
|
334
|
+
* @param {(() => void)} on_begin Called just before beginning the animation
|
|
309
335
|
* @param {(() => void)} on_finish Called after successfully completing the animation
|
|
310
336
|
* @returns {Animation}
|
|
311
337
|
*/
|
|
312
|
-
function animate(element, options, counterpart, t2, on_finish) {
|
|
338
|
+
function animate(element, options, counterpart, t2, on_begin, on_finish) {
|
|
313
339
|
var is_intro = t2 === 1;
|
|
314
340
|
|
|
315
341
|
if (is_function(options)) {
|
|
@@ -323,7 +349,7 @@ function animate(element, options, counterpart, t2, on_finish) {
|
|
|
323
349
|
queue_micro_task(() => {
|
|
324
350
|
if (aborted) return;
|
|
325
351
|
var o = options({ direction: is_intro ? 'in' : 'out' });
|
|
326
|
-
a = animate(element, o, counterpart, t2, on_finish);
|
|
352
|
+
a = animate(element, o, counterpart, t2, on_begin, on_finish);
|
|
327
353
|
});
|
|
328
354
|
|
|
329
355
|
// ...but we want to do so without using `async`/`await` everywhere, so
|
|
@@ -342,7 +368,7 @@ function animate(element, options, counterpart, t2, on_finish) {
|
|
|
342
368
|
counterpart?.deactivate();
|
|
343
369
|
|
|
344
370
|
if (!options?.duration && !options?.delay) {
|
|
345
|
-
|
|
371
|
+
on_begin();
|
|
346
372
|
on_finish();
|
|
347
373
|
|
|
348
374
|
return {
|
|
@@ -382,7 +408,7 @@ function animate(element, options, counterpart, t2, on_finish) {
|
|
|
382
408
|
// remove dummy animation from the stack to prevent conflict with main animation
|
|
383
409
|
animation.cancel();
|
|
384
410
|
|
|
385
|
-
|
|
411
|
+
on_begin();
|
|
386
412
|
|
|
387
413
|
// for bidirectional transitions, we start from the current position,
|
|
388
414
|
// rather than doing a full intro/outro
|
|
@@ -55,33 +55,38 @@ export function flatten(blockers, sync, async, fn) {
|
|
|
55
55
|
|
|
56
56
|
/** @param {Value[]} values */
|
|
57
57
|
function finish(values) {
|
|
58
|
+
if ((parent.f & DESTROYED) !== 0) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
restore();
|
|
59
63
|
|
|
60
64
|
try {
|
|
61
65
|
fn(values);
|
|
62
66
|
} catch (error) {
|
|
63
|
-
|
|
64
|
-
invoke_error_boundary(error, parent);
|
|
65
|
-
}
|
|
67
|
+
invoke_error_boundary(error, parent);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
unset_context();
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
var decrement_pending = increment_pending();
|
|
74
|
+
|
|
71
75
|
// Fast path: blockers but no async expressions
|
|
72
76
|
if (async.length === 0) {
|
|
73
|
-
/** @type {Promise<any>} */ (blocker_promise)
|
|
77
|
+
/** @type {Promise<any>} */ (blocker_promise)
|
|
78
|
+
.then(() => finish(sync.map(d)))
|
|
79
|
+
.finally(decrement_pending);
|
|
80
|
+
|
|
74
81
|
return;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
|
-
var decrement_pending = increment_pending();
|
|
78
|
-
|
|
79
84
|
// Full path: has async expressions
|
|
80
85
|
function run() {
|
|
81
86
|
Promise.all(async.map((expression) => async_derived(expression)))
|
|
82
87
|
.then((result) => finish([...sync.map(d), ...result]))
|
|
83
88
|
.catch((error) => invoke_error_boundary(error, parent))
|
|
84
|
-
.finally(
|
|
89
|
+
.finally(decrement_pending);
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
if (blocker_promise) {
|
|
@@ -213,22 +218,35 @@ export async function* for_await_track_reactivity_loss(iterable) {
|
|
|
213
218
|
throw new TypeError('value is not async iterable');
|
|
214
219
|
}
|
|
215
220
|
|
|
216
|
-
|
|
217
|
-
let
|
|
221
|
+
// eslint-disable-next-line no-useless-assignment
|
|
222
|
+
let invoke_return = true;
|
|
223
|
+
|
|
218
224
|
try {
|
|
219
225
|
while (true) {
|
|
220
226
|
const { done, value } = (await track_reactivity_loss(iterator.next()))();
|
|
221
227
|
if (done) {
|
|
222
|
-
|
|
228
|
+
invoke_return = false;
|
|
223
229
|
break;
|
|
224
230
|
}
|
|
225
231
|
var prev = reactivity_loss_tracker;
|
|
226
|
-
|
|
232
|
+
try {
|
|
233
|
+
yield value;
|
|
234
|
+
} catch (e) {
|
|
235
|
+
set_reactivity_loss_tracker(prev);
|
|
236
|
+
// If the yield throws, we need to call `return` but not return its value, instead rethrow
|
|
237
|
+
if (iterator.return !== undefined) {
|
|
238
|
+
(await track_reactivity_loss(iterator.return()))();
|
|
239
|
+
}
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
227
242
|
set_reactivity_loss_tracker(prev);
|
|
228
243
|
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
invoke_return = false;
|
|
246
|
+
throw error;
|
|
229
247
|
} finally {
|
|
230
|
-
// If the iterator had an abrupt completion and `return` is defined on the iterator, call it and return the value
|
|
231
|
-
if (
|
|
248
|
+
// If the iterator had an abrupt completion (break) and `return` is defined on the iterator, call it and return the value
|
|
249
|
+
if (invoke_return && iterator.return !== undefined) {
|
|
232
250
|
// eslint-disable-next-line no-unsafe-finally
|
|
233
251
|
return /** @type {TReturn} */ ((await track_reactivity_loss(iterator.return()))().value);
|
|
234
252
|
}
|
|
@@ -310,7 +328,7 @@ export function run(thunks) {
|
|
|
310
328
|
// wait one more tick, so that template effects are
|
|
311
329
|
// guaranteed to run before `$effect(...)`
|
|
312
330
|
.then(() => Promise.resolve())
|
|
313
|
-
.finally(
|
|
331
|
+
.finally(decrement_pending);
|
|
314
332
|
|
|
315
333
|
return blockers;
|
|
316
334
|
}
|
|
@@ -334,8 +352,8 @@ export function increment_pending() {
|
|
|
334
352
|
boundary.update_pending_count(1, batch);
|
|
335
353
|
batch.increment(blocking, effect);
|
|
336
354
|
|
|
337
|
-
return (
|
|
355
|
+
return () => {
|
|
338
356
|
boundary.update_pending_count(-1, batch);
|
|
339
|
-
batch.decrement(blocking, effect
|
|
357
|
+
batch.decrement(blocking, effect);
|
|
340
358
|
};
|
|
341
359
|
}
|