Skip to content

Commit 5df0149

Browse files
committed
move signal init logic into create_effect
1 parent ed2981d commit 5df0149

File tree

3 files changed

+85
-75
lines changed

3 files changed

+85
-75
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import {
77
destroy_children,
88
execute_effect,
99
get,
10+
is_flushing_effect,
1011
remove_reactions,
1112
schedule_effect,
13+
set_is_flushing_effect,
1214
set_signal_status,
1315
untrack
1416
} from '../runtime.js';
@@ -20,7 +22,9 @@ import {
2022
PRE_EFFECT,
2123
DESTROYED,
2224
INERT,
23-
IS_ELSEIF
25+
IS_ELSEIF,
26+
CLEAN,
27+
EFFECT_RAN
2428
} from '../constants.js';
2529
import { set } from './sources.js';
2630
import { noop } from '../../common.js';
@@ -63,7 +67,19 @@ function create_effect(type, fn, sync, init = true) {
6367
}
6468

6569
if (init) {
66-
schedule_effect(signal, sync);
70+
if (sync) {
71+
const previously_flushing_effect = is_flushing_effect;
72+
try {
73+
set_is_flushing_effect(true);
74+
execute_effect(signal);
75+
set_signal_status(signal, CLEAN);
76+
signal.f |= EFFECT_RAN;
77+
} finally {
78+
set_is_flushing_effect(previously_flushing_effect);
79+
}
80+
} else {
81+
schedule_effect(signal);
82+
}
6783
}
6884

6985
return signal;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export function set(signal, value) {
135135
) {
136136
if (current_dependencies !== null && current_dependencies.includes(signal)) {
137137
set_signal_status(current_effect, DIRTY);
138-
schedule_effect(current_effect, false);
138+
schedule_effect(current_effect);
139139
} else {
140140
if (current_untracked_writes === null) {
141141
set_current_untracked_writes([signal]);

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

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ const FLUSH_SYNC = 1;
3636
let current_scheduler_mode = FLUSH_MICROTASK;
3737
// Used for handling scheduling
3838
let is_micro_task_queued = false;
39-
let is_flushing_effect = false;
39+
export let is_flushing_effect = false;
40+
41+
/** @param {boolean} value */
42+
export function set_is_flushing_effect(value) {
43+
is_flushing_effect = value;
44+
}
45+
4046
// Used for $inspect
4147
export let is_batching_effect = false;
4248
let is_inspecting_signal = false;
@@ -466,85 +472,73 @@ function process_microtask() {
466472

467473
/**
468474
* @param {import('./types.js').Effect} signal
469-
* @param {boolean} sync
470475
* @returns {void}
471476
*/
472-
export function schedule_effect(signal, sync) {
477+
export function schedule_effect(signal) {
473478
const flags = signal.f;
474-
if (sync) {
475-
const previously_flushing_effect = is_flushing_effect;
476-
try {
477-
is_flushing_effect = true;
478-
execute_effect(signal);
479-
set_signal_status(signal, CLEAN);
480-
} finally {
481-
is_flushing_effect = previously_flushing_effect;
479+
480+
if (current_scheduler_mode === FLUSH_MICROTASK) {
481+
if (!is_micro_task_queued) {
482+
is_micro_task_queued = true;
483+
queueMicrotask(process_microtask);
482484
}
483-
} else {
484-
if (current_scheduler_mode === FLUSH_MICROTASK) {
485-
if (!is_micro_task_queued) {
486-
is_micro_task_queued = true;
487-
queueMicrotask(process_microtask);
488-
}
485+
}
486+
487+
if ((flags & EFFECT) !== 0) {
488+
current_queued_effects.push(signal);
489+
// Prevent any nested user effects from potentially triggering
490+
// before this effect is scheduled. We know they will be destroyed
491+
// so we can make them inert to avoid having to find them in the
492+
// queue and remove them.
493+
if ((flags & MANAGED) === 0) {
494+
mark_subtree_children_inert(signal, true);
489495
}
490-
if ((flags & EFFECT) !== 0) {
491-
current_queued_effects.push(signal);
492-
// Prevent any nested user effects from potentially triggering
493-
// before this effect is scheduled. We know they will be destroyed
494-
// so we can make them inert to avoid having to find them in the
495-
// queue and remove them.
496-
if ((flags & MANAGED) === 0) {
497-
mark_subtree_children_inert(signal, true);
498-
}
499-
} else {
500-
// We need to ensure we insert the signal in the right topological order. In other words,
501-
// we need to evaluate where to insert the signal based off its level and whether or not it's
502-
// a pre-effect and within the same block. By checking the signals in the queue in reverse order
503-
// we can find the right place quickly. TODO: maybe opt to use a linked list rather than an array
504-
// for these operations.
505-
const length = current_queued_pre_and_render_effects.length;
506-
let should_append = length === 0;
507-
508-
if (!should_append) {
509-
const target_level = signal.l;
510-
const is_pre_effect = (flags & PRE_EFFECT) !== 0;
511-
let target_signal;
512-
let target_signal_level;
513-
let is_target_pre_effect;
514-
let i = length;
515-
while (true) {
516-
target_signal = current_queued_pre_and_render_effects[--i];
517-
target_signal_level = target_signal.l;
518-
if (target_signal_level <= target_level) {
519-
if (i + 1 === length) {
520-
should_append = true;
521-
} else {
522-
is_target_pre_effect = (target_signal.f & PRE_EFFECT) !== 0;
523-
if (
524-
target_signal_level < target_level ||
525-
target_signal !== signal ||
526-
(is_target_pre_effect && !is_pre_effect)
527-
) {
528-
i++;
529-
}
530-
current_queued_pre_and_render_effects.splice(i, 0, signal);
496+
} else {
497+
// We need to ensure we insert the signal in the right topological order. In other words,
498+
// we need to evaluate where to insert the signal based off its level and whether or not it's
499+
// a pre-effect and within the same block. By checking the signals in the queue in reverse order
500+
// we can find the right place quickly. TODO: maybe opt to use a linked list rather than an array
501+
// for these operations.
502+
const length = current_queued_pre_and_render_effects.length;
503+
let should_append = length === 0;
504+
505+
if (!should_append) {
506+
const target_level = signal.l;
507+
const is_pre_effect = (flags & PRE_EFFECT) !== 0;
508+
let target_signal;
509+
let target_signal_level;
510+
let is_target_pre_effect;
511+
let i = length;
512+
while (true) {
513+
target_signal = current_queued_pre_and_render_effects[--i];
514+
target_signal_level = target_signal.l;
515+
if (target_signal_level <= target_level) {
516+
if (i + 1 === length) {
517+
should_append = true;
518+
} else {
519+
is_target_pre_effect = (target_signal.f & PRE_EFFECT) !== 0;
520+
if (
521+
target_signal_level < target_level ||
522+
target_signal !== signal ||
523+
(is_target_pre_effect && !is_pre_effect)
524+
) {
525+
i++;
531526
}
532-
break;
533-
}
534-
if (i === 0) {
535-
current_queued_pre_and_render_effects.unshift(signal);
536-
break;
527+
current_queued_pre_and_render_effects.splice(i, 0, signal);
537528
}
529+
break;
530+
}
531+
if (i === 0) {
532+
current_queued_pre_and_render_effects.unshift(signal);
533+
break;
538534
}
539535
}
536+
}
540537

541-
if (should_append) {
542-
current_queued_pre_and_render_effects.push(signal);
543-
}
538+
if (should_append) {
539+
current_queued_pre_and_render_effects.push(signal);
544540
}
545541
}
546-
547-
signal.f |= EFFECT_RAN;
548542
}
549543

550544
/**
@@ -696,7 +690,7 @@ export function get(signal) {
696690
current_untracked_writes.includes(signal)
697691
) {
698692
set_signal_status(current_effect, DIRTY);
699-
schedule_effect(current_effect, false);
693+
schedule_effect(current_effect);
700694
}
701695
}
702696

@@ -772,7 +766,7 @@ export function mark_subtree_inert(signal, inert) {
772766
if (is_already_inert !== inert) {
773767
signal.f ^= INERT;
774768
if (!inert && (flags & CLEAN) === 0) {
775-
schedule_effect(signal, false);
769+
schedule_effect(signal);
776770
}
777771
}
778772

@@ -819,7 +813,7 @@ export function mark_reactions(signal, to_status, force_schedule) {
819813
force_schedule
820814
);
821815
} else {
822-
schedule_effect(/** @type {import('#client').Effect} */ (reaction), false);
816+
schedule_effect(/** @type {import('#client').Effect} */ (reaction));
823817
}
824818
}
825819
}
@@ -1075,7 +1069,7 @@ export function pop(component) {
10751069
if (effects !== null) {
10761070
context_stack_item.e = null;
10771071
for (let i = 0; i < effects.length; i++) {
1078-
schedule_effect(effects[i], false);
1072+
schedule_effect(effects[i]);
10791073
}
10801074
}
10811075
current_component_context = context_stack_item.p;

0 commit comments

Comments
 (0)