Skip to content

Commit e882376

Browse files
authored
Merge branch 'main' into remove-unowned-check
2 parents 64f078d + 3a4dc7d commit e882376

File tree

20 files changed

+265
-124
lines changed

20 files changed

+265
-124
lines changed

.changeset/legal-mangos-peel.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/sixty-comics-bow.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/svelte/CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# svelte
22

3+
## 5.43.4
4+
5+
### Patch Changes
6+
7+
- chore: simplify connection/disconnection logic ([#17105](https://github.com/sveltejs/svelte/pull/17105))
8+
9+
- fix: reconnect deriveds to effect tree when time-travelling ([#17105](https://github.com/sveltejs/svelte/pull/17105))
10+
11+
## 5.43.3
12+
13+
### Patch Changes
14+
15+
- fix: ensure fork always accesses correct values ([#17098](https://github.com/sveltejs/svelte/pull/17098))
16+
17+
- fix: change title only after any pending work has completed ([#17061](https://github.com/sveltejs/svelte/pull/17061))
18+
19+
- fix: preserve symbols when creating derived rest properties ([#17096](https://github.com/sveltejs/svelte/pull/17096))
20+
321
## 5.43.2
422

523
### Patch Changes

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svelte",
33
"description": "Cybernetically enhanced web apps",
44
"license": "MIT",
5-
"version": "5.43.2",
5+
"version": "5.43.4",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ export const BLOCK_EFFECT = 1 << 4;
66
export const BRANCH_EFFECT = 1 << 5;
77
export const ROOT_EFFECT = 1 << 6;
88
export const BOUNDARY_EFFECT = 1 << 7;
9+
/**
10+
* Indicates that a reaction is connected to an effect root — either it is an effect,
11+
* or it is a derived that is depended on by at least one effect. If a derived has
12+
* no dependents, we can disconnect it from the graph, allowing it to either be
13+
* GC'd or reconnected later if an effect comes to depend on it again
14+
*/
15+
export const CONNECTED = 1 << 9;
916
export const CLEAN = 1 << 10;
1017
export const DIRTY = 1 << 11;
1118
export const MAYBE_DIRTY = 1 << 12;
@@ -26,8 +33,6 @@ export const EFFECT_PRESERVED = 1 << 19;
2633
export const USER_EFFECT = 1 << 20;
2734

2835
// Flags exclusive to deriveds
29-
export const UNOWNED = 1 << 8;
30-
export const DISCONNECTED = 1 << 9;
3136
/**
3237
* Tells that we marked this derived and its reactions as visited during the "mark as (maybe) dirty"-phase.
3338
* Will be lifted during execution of the derived and during checking its dirty state (both are necessary

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
DERIVED,
1616
BOUNDARY_EFFECT,
1717
EAGER_EFFECT,
18-
HEAD_EFFECT
18+
HEAD_EFFECT,
19+
ERROR_VALUE
1920
} from '#client/constants';
2021
import { async_mode_flag } from '../../flags/index.js';
2122
import { deferred, define_property } from '../../shared/utils.js';
@@ -285,12 +286,16 @@ export class Batch {
285286
this.previous.set(source, value);
286287
}
287288

288-
this.current.set(source, source.v);
289-
batch_values?.set(source, source.v);
289+
// Don't save errors in `batch_values`, or they won't be thrown in `runtime.js#get`
290+
if ((source.f & ERROR_VALUE) === 0) {
291+
this.current.set(source, source.v);
292+
batch_values?.set(source, source.v);
293+
}
290294
}
291295

292296
activate() {
293297
current_batch = this;
298+
this.apply();
294299
}
295300

296301
deactivate() {
@@ -492,7 +497,7 @@ export class Batch {
492497
}
493498

494499
apply() {
495-
if (!async_mode_flag || batches.size === 1) return;
500+
if (!async_mode_flag || (!this.is_fork && batches.size === 1)) return;
496501

497502
// if there are multiple batches, we are 'time travelling' —
498503
// we need to override values with the ones in this batch...

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ import {
99
EFFECT_PRESERVED,
1010
MAYBE_DIRTY,
1111
STALE_REACTION,
12-
UNOWNED,
1312
ASYNC,
14-
WAS_MARKED
13+
WAS_MARKED,
14+
CONNECTED
1515
} from '#client/constants';
1616
import {
1717
active_reaction,
1818
active_effect,
1919
set_signal_status,
20-
skip_reaction,
2120
update_reaction,
2221
increment_write_version,
2322
set_active_effect,
@@ -27,7 +26,7 @@ import {
2726
import { equals, safe_equals } from './equality.js';
2827
import * as e from '../errors.js';
2928
import * as w from '../warnings.js';
30-
import { async_effect, destroy_effect, teardown } from './effects.js';
29+
import { async_effect, destroy_effect, effect_tracking, teardown } from './effects.js';
3130
import { eager_effects, internal_set, set_eager_effects, source } from './sources.js';
3231
import { get_stack } from '../dev/tracing.js';
3332
import { async_mode_flag, tracing_mode_flag } from '../../flags/index.js';
@@ -61,9 +60,7 @@ export function derived(fn) {
6160
? /** @type {Derived} */ (active_reaction)
6261
: null;
6362

64-
if (active_effect === null || (parent_derived !== null && (parent_derived.f & UNOWNED) !== 0)) {
65-
flags |= UNOWNED;
66-
} else {
63+
if (active_effect !== null) {
6764
// Since deriveds are evaluated lazily, any effects created inside them are
6865
// created too late to ensure that the parent effect is added to the tree
6966
active_effect.f |= EFFECT_PRESERVED;
@@ -368,12 +365,16 @@ export function update_derived(derived) {
368365
return;
369366
}
370367

368+
// During time traveling we don't want to reset the status so that
369+
// traversal of the graph in the other batches still happens
371370
if (batch_values !== null) {
372-
batch_values.set(derived, derived.v);
371+
// only cache the value if we're in a tracking context, otherwise we won't
372+
// clear the cache in `mark_reactions` when dependencies are updated
373+
if (effect_tracking()) {
374+
batch_values.set(derived, derived.v);
375+
}
373376
} else {
374-
var status =
375-
(skip_reaction || (derived.f & UNOWNED) !== 0) && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
376-
377+
var status = (derived.f & CONNECTED) === 0 ? MAYBE_DIRTY : CLEAN;
377378
set_signal_status(derived, status);
378379
}
379380
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import {
3232
EFFECT_PRESERVED,
3333
STALE_REACTION,
3434
USER_EFFECT,
35-
ASYNC
35+
ASYNC,
36+
CONNECTED
3637
} from '#client/constants';
3738
import * as e from '../errors.js';
3839
import { DEV } from 'esm-env';
@@ -47,7 +48,7 @@ import { without_reactive_context } from '../dom/elements/bindings/shared.js';
4748
* @param {'$effect' | '$effect.pre' | '$inspect'} rune
4849
*/
4950
export function validate_effect(rune) {
50-
if (active_effect === null && active_reaction === null) {
51+
if (active_effect === null) {
5152
if (active_reaction === null) {
5253
e.effect_orphan(rune);
5354
}
@@ -102,7 +103,7 @@ function create_effect(type, fn, sync, push = true) {
102103
deps: null,
103104
nodes_start: null,
104105
nodes_end: null,
105-
f: type | DIRTY,
106+
f: type | DIRTY | CONNECTED,
106107
first: null,
107108
fn,
108109
last: null,

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ import {
2323
DIRTY,
2424
BRANCH_EFFECT,
2525
EAGER_EFFECT,
26-
UNOWNED,
2726
MAYBE_DIRTY,
2827
BLOCK_EFFECT,
2928
ROOT_EFFECT,
3029
ASYNC,
31-
WAS_MARKED
30+
WAS_MARKED,
31+
CONNECTED
3232
} from '#client/constants';
3333
import * as e from '../errors.js';
3434
import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js';
3535
import { get_stack, tag_proxy } from '../dev/tracing.js';
3636
import { component_context, is_runes } from '../context.js';
37-
import { Batch, eager_block_effects, schedule_effect } from './batch.js';
37+
import { Batch, batch_values, eager_block_effects, schedule_effect } from './batch.js';
3838
import { proxy } from '../proxy.js';
3939
import { execute_derived } from './deriveds.js';
4040

@@ -211,7 +211,8 @@ export function internal_set(source, value) {
211211
if ((source.f & DIRTY) !== 0) {
212212
execute_derived(/** @type {Derived} */ (source));
213213
}
214-
set_signal_status(source, (source.f & UNOWNED) === 0 ? CLEAN : MAYBE_DIRTY);
214+
215+
set_signal_status(source, (source.f & CONNECTED) !== 0 ? CLEAN : MAYBE_DIRTY);
215216
}
216217

217218
source.wv = increment_write_version();
@@ -333,9 +334,17 @@ function mark_reactions(signal, status) {
333334
}
334335

335336
if ((flags & DERIVED) !== 0) {
337+
var derived = /** @type {Derived} */ (reaction);
338+
339+
batch_values?.delete(derived);
340+
336341
if ((flags & WAS_MARKED) === 0) {
337-
reaction.f |= WAS_MARKED;
338-
mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY);
342+
// Only connected deriveds can be reliably unmarked right away
343+
if (flags & CONNECTED) {
344+
reaction.f |= WAS_MARKED;
345+
}
346+
347+
mark_reactions(derived, MAYBE_DIRTY);
339348
}
340349
} else if (not_dirty) {
341350
if ((flags & BLOCK_EFFECT) !== 0) {

0 commit comments

Comments
 (0)