Skip to content

Commit 6912cd3

Browse files
committed
merge main
2 parents 5c99be3 + 6f0aec5 commit 6912cd3

File tree

5 files changed

+46
-26
lines changed

5 files changed

+46
-26
lines changed

.changeset/eight-walls-mate.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+
chore: simplify reaction/source ownership tracking

.github/workflows/ecosystem-ci-trigger.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
if: github.repository == 'sveltejs/svelte' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
1111
permissions:
1212
issues: write # to add / delete reactions
13-
pull-requests: read # to read PR data
13+
pull-requests: write # to read PR data, and to add labels
1414
actions: read # to check workflow status
1515
contents: read # to clone the repo
1616
steps:

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

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
/** @import { Source } from '#client' */
22
import { DEV } from 'esm-env';
3-
import { get, active_effect, active_reaction, set_active_reaction } from './runtime.js';
3+
import {
4+
get,
5+
active_effect,
6+
update_version,
7+
active_reaction,
8+
set_update_version,
9+
set_active_reaction
10+
} from './runtime.js';
411
import {
512
array_prototype,
613
get_descriptor,
@@ -41,21 +48,31 @@ export function proxy(value) {
4148
var version = source(0);
4249

4350
var stack = DEV && tracing_mode_flag ? get_stack('CreatedAt') : null;
44-
var reaction = active_reaction;
51+
var parent_version = update_version;
4552

4653
/**
4754
* Executes the proxy in the context of the reaction it was originally created in, if any
4855
* @template T
4956
* @param {() => T} fn
5057
*/
5158
var with_parent = (fn) => {
52-
var previous_reaction = active_reaction;
53-
set_active_reaction(reaction);
59+
if (update_version === parent_version) {
60+
return fn();
61+
}
62+
63+
// child source is being created after the initial proxy —
64+
// prevent it from being associated with the current reaction
65+
var reaction = active_reaction;
66+
var version = update_version;
67+
68+
set_active_reaction(null);
69+
set_update_version(parent_version);
5470

55-
/** @type {T} */
5671
var result = fn();
5772

58-
set_active_reaction(previous_reaction);
73+
set_active_reaction(reaction);
74+
set_update_version(version);
75+
5976
return result;
6077
};
6178

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
untrack,
1111
increment_write_version,
1212
update_effect,
13-
source_ownership,
13+
current_sources,
1414
is_dirty,
1515
untracking,
1616
is_destroying_effect,
@@ -141,7 +141,7 @@ export function set(source, value, should_proxy = false) {
141141
(!untracking || (active_reaction.f & INSPECT_EFFECT) !== 0) &&
142142
is_runes() &&
143143
(active_reaction.f & (DERIVED | BLOCK_EFFECT | EFFECT_ASYNC | INSPECT_EFFECT)) !== 0 &&
144-
!(source_ownership?.reaction === active_reaction && source_ownership.sources.includes(source))
144+
!current_sources?.includes(source)
145145
) {
146146
e.state_unsafe_mutation();
147147
}

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,17 @@ export function set_active_effect(effect) {
8787
/**
8888
* When sources are created within a reaction, reading and writing
8989
* them within that reaction should not cause a re-run
90-
* @type {null | { reaction: Reaction, sources: Source[] }}
90+
* @type {null | Source[]}
9191
*/
92-
export let source_ownership = null;
92+
export let current_sources = null;
9393

9494
/** @param {Value} value */
9595
export function push_reaction_value(value) {
9696
if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & DERIVED) !== 0)) {
97-
if (source_ownership === null) {
98-
source_ownership = { reaction: active_reaction, sources: [value] };
97+
if (current_sources === null) {
98+
current_sources = [value];
9999
} else {
100-
source_ownership.sources.push(value);
100+
current_sources.push(value);
101101
}
102102
}
103103
}
@@ -135,6 +135,11 @@ let read_version = 0;
135135

136136
export let update_version = read_version;
137137

138+
/** @param {number} value */
139+
export function set_update_version(value) {
140+
update_version = value;
141+
}
142+
138143
// If we are working with a get() chain that has no active container,
139144
// to prevent memory leaks, we skip adding the reaction.
140145
export let skip_reaction = false;
@@ -239,11 +244,7 @@ function schedule_possible_effect_self_invalidation(signal, effect, root = true)
239244
var reactions = signal.reactions;
240245
if (reactions === null) return;
241246

242-
if (
243-
!async_mode_flag &&
244-
source_ownership?.reaction === active_reaction &&
245-
source_ownership.sources.includes(signal)
246-
) {
247+
if (!async_mode_flag && current_sources?.includes(signal)) {
247248
return;
248249
}
249250

@@ -270,7 +271,7 @@ export function update_reaction(reaction) {
270271
var previous_untracked_writes = untracked_writes;
271272
var previous_reaction = active_reaction;
272273
var previous_skip_reaction = skip_reaction;
273-
var previous_reaction_sources = source_ownership;
274+
var previous_sources = current_sources;
274275
var previous_component_context = component_context;
275276
var previous_untracking = untracking;
276277
var previous_update_version = update_version;
@@ -284,7 +285,7 @@ export function update_reaction(reaction) {
284285
(flags & UNOWNED) !== 0 && (untracking || !is_updating_effect || active_reaction === null);
285286
active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
286287

287-
source_ownership = null;
288+
current_sources = null;
288289
set_component_context(reaction.ctx);
289290
untracking = false;
290291
update_version = ++read_version;
@@ -376,7 +377,7 @@ export function update_reaction(reaction) {
376377
untracked_writes = previous_untracked_writes;
377378
active_reaction = previous_reaction;
378379
skip_reaction = previous_skip_reaction;
379-
source_ownership = previous_reaction_sources;
380+
current_sources = previous_sources;
380381
set_component_context(previous_component_context);
381382
untracking = previous_untracking;
382383
update_version = previous_update_version;
@@ -550,10 +551,7 @@ export function get(signal) {
550551
// we don't add the dependency, because that would create a memory leak
551552
var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;
552553

553-
var is_owned_by_reaction =
554-
source_ownership?.reaction === active_reaction && source_ownership.sources.includes(signal);
555-
556-
if (!destroyed && !is_owned_by_reaction) {
554+
if (!destroyed && !current_sources?.includes(signal)) {
557555
var deps = active_reaction.deps;
558556

559557
if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {

0 commit comments

Comments
 (0)