Skip to content

Commit da4f0c3

Browse files
committed
alternative approach
1 parent fea1b79 commit da4f0c3

File tree

7 files changed

+61
-26
lines changed

7 files changed

+61
-26
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const LEGACY_DERIVED_PROP = 1 << 17;
2020
export const INSPECT_EFFECT = 1 << 18;
2121
export const HEAD_EFFECT = 1 << 19;
2222
export const EFFECT_HAS_DERIVED = 1 << 20;
23+
export const EFFECT_IS_UPDATING = 1 << 21;
2324

2425
export const STATE_SYMBOL = Symbol('$state');
2526
export const STATE_SYMBOL_METADATA = Symbol('$state metadata');

packages/svelte/src/internal/client/dom/elements/transitions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,11 @@ export function transition(flags, element, get_fn, get_params) {
289289
var run = is_global;
290290

291291
if (!run) {
292-
var block = /** @type {Effect | null} */ (e.p);
292+
var block = /** @type {Effect | null} */ (e.parent);
293293

294294
// skip over transparent blocks (e.g. snippets, else-if blocks)
295295
while (block && (block.f & EFFECT_TRANSPARENT) !== 0) {
296-
while ((block = block.p)) {
296+
while ((block = block.parent)) {
297297
if ((block.f & BLOCK_EFFECT) !== 0) break;
298298
}
299299
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function derived(fn) {
5151
rv: 0,
5252
v: /** @type {V} */ (null),
5353
wv: 0,
54-
p: parent_derived ?? active_effect
54+
parent: parent_derived ?? active_effect
5555
};
5656

5757
if (DEV && tracing_mode_flag) {
@@ -101,12 +101,12 @@ let stack = [];
101101
* @returns {Effect | null}
102102
*/
103103
function get_derived_parent_effect(derived) {
104-
var parent = derived.p;
104+
var parent = derived.parent;
105105
while (parent !== null) {
106106
if ((parent.f & DERIVED) === 0) {
107107
return /** @type {Effect} */ (parent);
108108
}
109-
parent = parent.p;
109+
parent = parent.parent;
110110
}
111111
return null;
112112
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function create_effect(type, fn, sync, push = true) {
8787
if (DEV) {
8888
// Ensure the parent is never an inspect effect
8989
while (parent !== null && (parent.f & INSPECT_EFFECT) !== 0) {
90-
parent = parent.p;
90+
parent = parent.parent;
9191
}
9292
}
9393

@@ -102,7 +102,7 @@ function create_effect(type, fn, sync, push = true) {
102102
fn,
103103
last: null,
104104
next: null,
105-
p: parent,
105+
parent: parent,
106106
prev: null,
107107
teardown: null,
108108
transitions: null,
@@ -393,7 +393,7 @@ export function destroy_effect_children(signal, remove_dom = false) {
393393

394394
if ((effect.f & ROOT_EFFECT) !== 0) {
395395
// this is now an independent root
396-
effect.p = null;
396+
effect.parent = null;
397397
} else {
398398
destroy_effect(effect, remove_dom);
399399
}
@@ -456,7 +456,7 @@ export function destroy_effect(effect, remove_dom = true) {
456456

457457
execute_effect_teardown(effect);
458458

459-
var parent = effect.p;
459+
var parent = effect.parent;
460460

461461
// If the parent doesn't have any children, then skip this work altogether
462462
if (parent !== null && parent.first !== null) {
@@ -486,7 +486,7 @@ export function destroy_effect(effect, remove_dom = true) {
486486
* @param {Effect} effect
487487
*/
488488
export function unlink_effect(effect) {
489-
var parent = effect.p;
489+
var parent = effect.parent;
490490
var prev = effect.prev;
491491
var next = effect.next;
492492

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import {
2525
UNOWNED,
2626
MAYBE_DIRTY,
2727
BLOCK_EFFECT,
28-
ROOT_EFFECT
28+
ROOT_EFFECT,
29+
EFFECT,
30+
EFFECT_IS_UPDATING
2931
} from '../constants.js';
3032
import * as e from '../errors.js';
3133
import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js';
@@ -36,6 +38,14 @@ import { proxy } from '../proxy.js';
3638
export let inspect_effects = new Set();
3739
export const old_values = new Map();
3840

41+
/** @type {Source[] | null} */
42+
export let reaction_sources = null;
43+
44+
/** @param {Source[] | null} v */
45+
export function set_reaction_sources(v) {
46+
reaction_sources = v;
47+
}
48+
3949
/**
4050
* @param {Set<any>} v
4151
*/
@@ -62,6 +72,14 @@ export function source(v, stack) {
6272
wv: 0
6373
};
6474

75+
if (active_reaction !== null && active_reaction.f & EFFECT_IS_UPDATING) {
76+
if (reaction_sources === null) {
77+
reaction_sources = [signal];
78+
} else {
79+
reaction_sources.push(signal);
80+
}
81+
}
82+
6583
if (DEV && tracing_mode_flag) {
6684
signal.created = stack ?? get_stack('CreatedAt');
6785
signal.debug = null;
@@ -118,7 +136,7 @@ export function set(source, value, should_proxy = false) {
118136
!untracking &&
119137
is_runes() &&
120138
(active_reaction.f & (DERIVED | BLOCK_EFFECT)) !== 0 &&
121-
active_reaction !== source.p
139+
!reaction_sources?.includes(source)
122140
) {
123141
e.state_unsafe_mutation();
124142
}

packages/svelte/src/internal/client/reactivity/types.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ export interface Signal {
55
f: number;
66
/** Write version */
77
wv: number;
8-
/** Parent effect or derived */
9-
p: Reaction | null;
108
}
119

1210
export interface Value<V = unknown> extends Signal {
@@ -40,6 +38,8 @@ export interface Derived<V = unknown> extends Value<V>, Reaction {
4038
fn: () => V;
4139
/** Effects created inside this signal */
4240
effects: null | Effect[];
41+
/** Parent effect or derived */
42+
parent: Effect | Derived | null;
4343
}
4444

4545
export interface Effect extends Reaction {
@@ -66,7 +66,7 @@ export interface Effect extends Reaction {
6666
/** Last child effect created inside this signal */
6767
last: null | Effect;
6868
/** Parent effect */
69-
p: Effect | null;
69+
parent: Effect | null;
7070
/** Dev only */
7171
component_function?: any;
7272
}

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

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,16 @@ import {
2222
ROOT_EFFECT,
2323
LEGACY_DERIVED_PROP,
2424
DISCONNECTED,
25-
BOUNDARY_EFFECT
25+
BOUNDARY_EFFECT,
26+
EFFECT_IS_UPDATING
2627
} from './constants.js';
2728
import { flush_tasks } from './dom/task.js';
28-
import { internal_set, old_values } from './reactivity/sources.js';
29+
import {
30+
internal_set,
31+
old_values,
32+
reaction_sources,
33+
set_reaction_sources
34+
} from './reactivity/sources.js';
2935
import { destroy_derived_effects, update_derived } from './reactivity/deriveds.js';
3036
import * as e from './errors.js';
3137
import { FILENAME } from '../../constants.js';
@@ -161,7 +167,7 @@ export function check_dirtiness(reaction) {
161167
// then we need to re-connect the reaction to the dependency
162168
if (is_disconnected || is_unowned_connected) {
163169
var derived = /** @type {Derived} */ (reaction);
164-
var parent = derived.p;
170+
var parent = derived.parent;
165171

166172
for (i = 0; i < length; i++) {
167173
dependency = dependencies[i];
@@ -228,7 +234,7 @@ function propagate_error(error, effect) {
228234
}
229235
}
230236

231-
current = current.p;
237+
current = current.parent;
232238
}
233239

234240
is_throwing_error = false;
@@ -240,7 +246,8 @@ function propagate_error(error, effect) {
240246
*/
241247
function should_rethrow_error(effect) {
242248
return (
243-
(effect.f & DESTROYED) === 0 && (effect.p === null || (effect.p.f & BOUNDARY_EFFECT) === 0)
249+
(effect.f & DESTROYED) === 0 &&
250+
(effect.parent === null || (effect.parent.f & BOUNDARY_EFFECT) === 0)
244251
);
245252
}
246253

@@ -352,7 +359,8 @@ function schedule_possible_effect_self_invalidation(signal, effect, root = true)
352359

353360
for (var i = 0; i < reactions.length; i++) {
354361
var reaction = reactions[i];
355-
if (signal.p === reaction) continue;
362+
363+
if (reaction_sources?.includes(signal)) continue;
356364

357365
if ((reaction.f & DERIVED) !== 0) {
358366
schedule_possible_effect_self_invalidation(/** @type {Derived} */ (reaction), effect, false);
@@ -380,8 +388,11 @@ export function update_reaction(reaction) {
380388
var previous_skip_reaction = skip_reaction;
381389
var previous_component_context = component_context;
382390
var previous_untracking = untracking;
391+
var previous_reaction_sources = reaction_sources;
392+
383393
var flags = reaction.f;
384394

395+
set_reaction_sources(null);
385396
new_deps = /** @type {null | Value[]} */ (null);
386397
skipped_deps = 0;
387398
untracked_writes = null;
@@ -393,6 +404,8 @@ export function update_reaction(reaction) {
393404
untracking = false;
394405
read_version++;
395406

407+
reaction.f |= EFFECT_IS_UPDATING;
408+
396409
try {
397410
var result = /** @type {Function} */ (0, reaction.fn)();
398411
var deps = reaction.deps;
@@ -464,6 +477,9 @@ export function update_reaction(reaction) {
464477
skip_reaction = previous_skip_reaction;
465478
set_component_context(previous_component_context);
466479
untracking = previous_untracking;
480+
set_reaction_sources(previous_reaction_sources);
481+
482+
reaction.f ^= EFFECT_IS_UPDATING;
467483
}
468484
}
469485

@@ -719,8 +735,8 @@ export function schedule_effect(signal) {
719735

720736
var effect = (last_scheduled_effect = signal);
721737

722-
while (effect.p !== null) {
723-
effect = effect.p;
738+
while (effect.parent !== null) {
739+
effect = effect.parent;
724740
var flags = effect.f;
725741

726742
if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
@@ -785,12 +801,12 @@ function process_effects(root) {
785801
}
786802
}
787803

788-
var parent = effect.p;
804+
var parent = effect.parent;
789805
effect = effect.next;
790806

791807
while (effect === null && parent !== null) {
792808
effect = parent.next;
793-
parent = parent.p;
809+
parent = parent.parent;
794810
}
795811
}
796812

@@ -873,7 +889,7 @@ export function get(signal) {
873889
/** @type {Derived} */ (signal).effects === null
874890
) {
875891
var derived = /** @type {Derived} */ (signal);
876-
var parent = derived.p;
892+
var parent = derived.parent;
877893

878894
if (parent !== null && (parent.f & UNOWNED) === 0) {
879895
// If the derived is owned by another derived then mark it as unowned

0 commit comments

Comments
 (0)