Skip to content

Commit 425e68a

Browse files
committed
Merge branch 'main' into developer-guide
2 parents a64ee32 + 2b85d2a commit 425e68a

File tree

30 files changed

+237
-113
lines changed

30 files changed

+237
-113
lines changed

.changeset/clever-months-clap.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+
perf: run blocks eagerly during flush instead of aborting

.changeset/few-geese-itch.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: destroy dynamic component instance before creating new one

.changeset/itchy-games-guess.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 clone non-proxies in `$inspect`

.changeset/six-shirts-scream.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 recursion error when tagging circular references

packages/svelte/src/internal/client/dev/inspect.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function inspect(get_value, inspector = console.log) {
2626
return;
2727
}
2828

29-
var snap = snapshot(value, true);
29+
var snap = snapshot(value, true, true);
3030
untrack(() => {
3131
inspector(initial ? 'init' : 'update', ...snap);
3232
});

packages/svelte/src/internal/client/dom/blocks/svelte-component.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ export function component(node, get_component, render_fn) {
3434
var pending_effect = null;
3535

3636
function commit() {
37-
if (effect) {
38-
pause_effect(effect);
39-
effect = null;
40-
}
41-
4237
if (offscreen_fragment) {
4338
// remove the anchor
4439
/** @type {Text} */ (offscreen_fragment.lastChild).remove();
@@ -56,6 +51,11 @@ export function component(node, get_component, render_fn) {
5651

5752
var defer = should_defer_append();
5853

54+
if (effect) {
55+
pause_effect(effect);
56+
effect = null;
57+
}
58+
5959
if (component) {
6060
var target = anchor;
6161

packages/svelte/src/internal/client/dom/operations.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { get_descriptor, is_extensible } from '../../shared/utils.js';
66
import { active_effect } from '../runtime.js';
77
import { async_mode_flag } from '../../flags/index.js';
88
import { TEXT_NODE, EFFECT_RAN } from '#client/constants';
9+
import { eager_block_effects } from '../reactivity/batch.js';
910

1011
// export these for reference in the compiled code, making global name deduplication unnecessary
1112
/** @type {Window} */
@@ -214,6 +215,7 @@ export function clear_text_content(node) {
214215
*/
215216
export function should_defer_append() {
216217
if (!async_mode_flag) return false;
218+
if (eager_block_effects !== null) return false;
217219

218220
var flags = /** @type {Effect} */ (active_effect).f;
219221
return (flags & EFFECT_RAN) !== 0;

packages/svelte/src/internal/client/proxy.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ export function proxy(value) {
9393

9494
/** Used in dev for $inspect.trace() */
9595
var path = '';
96-
96+
let updating = false;
9797
/** @param {string} new_path */
9898
function update_path(new_path) {
99+
if (updating) return;
100+
updating = true;
99101
path = new_path;
100102

101103
tag(version, `${path} version`);
@@ -104,6 +106,7 @@ export function proxy(value) {
104106
for (const [prop, source] of sources) {
105107
tag(source, get_label(path, prop));
106108
}
109+
updating = false;
107110
}
108111

109112
return new Proxy(/** @type {any} */ (value), {
@@ -284,13 +287,13 @@ export function proxy(value) {
284287
if (s === undefined) {
285288
if (!has || get_descriptor(target, prop)?.writable) {
286289
s = with_parent(() => source(undefined, stack));
287-
set(s, proxy(value));
288-
289-
sources.set(prop, s);
290290

291291
if (DEV) {
292292
tag(s, get_label(path, prop));
293293
}
294+
set(s, proxy(value));
295+
296+
sources.set(prop, s);
294297
}
295298
} else {
296299
has = s.v !== UNINITIALIZED;

packages/svelte/src/internal/client/reactivity/batch.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,12 @@ export class Batch {
292292
if (!skip && effect.fn !== null) {
293293
if (is_branch) {
294294
effect.f ^= CLEAN;
295+
} else if ((flags & EFFECT) !== 0) {
296+
this.#effects.push(effect);
297+
} else if (async_mode_flag && (flags & RENDER_EFFECT) !== 0) {
298+
this.#render_effects.push(effect);
295299
} else if ((flags & CLEAN) === 0) {
296-
if ((flags & EFFECT) !== 0) {
297-
this.#effects.push(effect);
298-
} else if (async_mode_flag && (flags & RENDER_EFFECT) !== 0) {
299-
this.#render_effects.push(effect);
300-
} else if ((flags & ASYNC) !== 0) {
300+
if ((flags & ASYNC) !== 0) {
301301
var effects = effect.b?.pending ? this.#boundary_async_effects : this.#async_effects;
302302
effects.push(effect);
303303
} else if (is_dirty(effect)) {
@@ -584,6 +584,9 @@ function infinite_loop_guard() {
584584
}
585585
}
586586

587+
/** @type {Effect[] | null} */
588+
export let eager_block_effects = null;
589+
587590
/**
588591
* @param {Array<Effect>} effects
589592
* @returns {void}
@@ -598,7 +601,7 @@ function flush_queued_effects(effects) {
598601
var effect = effects[i++];
599602

600603
if ((effect.f & (DESTROYED | INERT)) === 0 && is_dirty(effect)) {
601-
var n = current_batch ? current_batch.current.size : 0;
604+
eager_block_effects = [];
602605

603606
update_effect(effect);
604607

@@ -619,21 +622,20 @@ function flush_queued_effects(effects) {
619622
}
620623
}
621624

622-
// if state is written in a user effect, abort and re-schedule, lest we run
623-
// effects that should be removed as a result of the state change
624-
if (
625-
current_batch !== null &&
626-
current_batch.current.size > n &&
627-
(effect.f & USER_EFFECT) !== 0
628-
) {
629-
break;
625+
if (eager_block_effects.length > 0) {
626+
// TODO this feels incorrect! it gets the tests passing
627+
old_values.clear();
628+
629+
for (const e of eager_block_effects) {
630+
update_effect(e);
631+
}
632+
633+
eager_block_effects = [];
630634
}
631635
}
632636
}
633637

634-
while (i < length) {
635-
schedule_effect(effects[i++]);
636-
}
638+
eager_block_effects = null;
637639
}
638640

639641
/**

packages/svelte/src/internal/client/reactivity/sources.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import * as e from '../errors.js';
3333
import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js';
3434
import { get_stack, tag_proxy } from '../dev/tracing.js';
3535
import { component_context, is_runes } from '../context.js';
36-
import { Batch, schedule_effect } from './batch.js';
36+
import { Batch, eager_block_effects, schedule_effect } from './batch.js';
3737
import { proxy } from '../proxy.js';
3838
import { execute_derived } from './deriveds.js';
3939

@@ -334,6 +334,12 @@ function mark_reactions(signal, status) {
334334
if ((flags & DERIVED) !== 0) {
335335
mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY);
336336
} else if (not_dirty) {
337+
if ((flags & BLOCK_EFFECT) !== 0) {
338+
if (eager_block_effects !== null) {
339+
eager_block_effects.push(/** @type {Effect} */ (reaction));
340+
}
341+
}
342+
337343
schedule_effect(/** @type {Effect} */ (reaction));
338344
}
339345
}

0 commit comments

Comments
 (0)