Skip to content

Commit be1300e

Browse files
committed
add microtask queue handling
1 parent 6af3fc4 commit be1300e

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ let current_queued_effects = [];
5050

5151
/** @type {Array<() => void>} */
5252
let current_queued_tasks = [];
53+
/** @type {Array<() => void>} */
54+
let current_queued_microtasks = [];
5355
let flush_count = 0;
5456
// Handle signal reactivity tree dependencies and consumer
5557

@@ -579,6 +581,11 @@ function flush_queued_effects(effects) {
579581

580582
function process_microtask() {
581583
is_micro_task_queued = false;
584+
if (current_queued_microtasks.length > 0) {
585+
const tasks = current_queued_microtasks.slice();
586+
current_queued_microtasks = [];
587+
run_all(tasks);
588+
}
582589
if (flush_count > 101) {
583590
return;
584591
}
@@ -637,6 +644,18 @@ export function schedule_task(fn) {
637644
current_queued_tasks.push(fn);
638645
}
639646

647+
/**
648+
* @param {() => void} fn
649+
* @returns {void}
650+
*/
651+
export function schedule_microtask(fn) {
652+
if (!is_micro_task_queued) {
653+
is_micro_task_queued = true;
654+
queueMicrotask(process_microtask);
655+
}
656+
current_queued_microtasks.push(fn);
657+
}
658+
640659
/**
641660
* @returns {void}
642661
*/
@@ -697,6 +716,9 @@ export function flushSync(fn) {
697716
if (current_queued_pre_and_render_effects.length > 0 || effects.length > 0) {
698717
flushSync();
699718
}
719+
if (is_micro_task_queued) {
720+
process_microtask();
721+
}
700722
if (is_task_queued) {
701723
process_task();
702724
}

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

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
managed_effect,
2222
managed_pre_effect,
2323
mark_subtree_inert,
24-
schedule_task,
24+
schedule_microtask,
2525
untrack
2626
} from './runtime.js';
2727
import { raf } from './timing.js';
@@ -357,11 +357,15 @@ function create_transition(dom, init, direction, effect) {
357357
cancelled = false;
358358
create_animation();
359359
}
360-
dispatch_event(dom, 'introstart');
361-
if (needs_reverse) {
362-
/** @type {Animation | TickAnimation} */ (animation).reverse();
360+
if (animation === null) {
361+
transition.x();
362+
} else {
363+
dispatch_event(dom, 'introstart');
364+
if (needs_reverse) {
365+
/** @type {Animation | TickAnimation} */ (animation).reverse();
366+
}
367+
/** @type {Animation | TickAnimation} */ (animation).play();
363368
}
364-
/** @type {Animation | TickAnimation} */ (animation).play();
365369
},
366370
// out
367371
o() {
@@ -371,11 +375,15 @@ function create_transition(dom, init, direction, effect) {
371375
cancelled = false;
372376
create_animation();
373377
}
374-
dispatch_event(dom, 'outrostart');
375-
if (needs_reverse) {
376-
/** @type {Animation | TickAnimation} */ (animation).reverse();
378+
if (animation === null) {
379+
transition.x();
377380
} else {
378-
/** @type {Animation | TickAnimation} */ (animation).play();
381+
dispatch_event(dom, 'outrostart');
382+
if (needs_reverse) {
383+
/** @type {Animation | TickAnimation} */ (animation).reverse();
384+
} else {
385+
/** @type {Animation | TickAnimation} */ (animation).play();
386+
}
379387
}
380388
},
381389
// cancel
@@ -424,7 +432,6 @@ function is_transition_block(block) {
424432
export function bind_transition(dom, get_transition_fn, props_fn, direction, global) {
425433
const transition_effect = /** @type {import('./types.js').EffectSignal} */ (current_effect);
426434
const block = current_block;
427-
const is_key_animation = direction === 'key';
428435

429436
let can_show_intro_on_mount = true;
430437
let can_apply_lazy_transitions = false;
@@ -472,7 +479,7 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
472479
const init = (from) =>
473480
untrack(() => {
474481
const props = props_fn === null ? {} : props_fn();
475-
return is_key_animation
482+
return direction === 'key'
476483
? /** @type {import('./types.js').AnimateFn<any>} */ (transition_fn)(
477484
dom,
478485
{ from: /** @type {DOMRect} */ (from), to: dom.getBoundingClientRect() },
@@ -489,17 +496,13 @@ export function bind_transition(dom, get_transition_fn, props_fn, direction, glo
489496
const show_intro = !can_show_intro_on_mount && (is_intro || direction === 'both');
490497

491498
if (show_intro) {
492-
transition.p = transition.i() || null;
499+
transition.p = transition.i();
493500
}
494501

495502
const effect = managed_pre_effect(() => {
496503
destroy_signal(effect);
497504
dom.inert = false;
498505

499-
if (transition.p === null && !is_key_animation) {
500-
return;
501-
}
502-
503506
if (show_intro) {
504507
transition.in();
505508
}
@@ -679,7 +682,7 @@ function each_item_animate(block, transitions, index, index_is_reactive) {
679682
transition.c();
680683
}
681684
}
682-
queueMicrotask(() => {
685+
schedule_microtask(() => {
683686
trigger_transitions(transitions, 'key', from);
684687
});
685688
}

packages/svelte/tests/runtime-runes/samples/if-transition-undefined/main.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
let animate = $state(false);
66
77
function maybe(node, animate) {
8-
console.log('maybe - animate?', animate);
98
if (animate) return fade(node);
109
}
1110
</script>

0 commit comments

Comments
 (0)