run rescheduled block effects eagerly

pull/16631/head
Rich Harris 1 month ago
parent 8e2cc027a3
commit 5d6b081747

@ -6,6 +6,7 @@ import { get_descriptor, is_extensible } from '../../shared/utils.js';
import { active_effect } from '../runtime.js'; import { active_effect } from '../runtime.js';
import { async_mode_flag } from '../../flags/index.js'; import { async_mode_flag } from '../../flags/index.js';
import { TEXT_NODE, EFFECT_RAN } from '#client/constants'; import { TEXT_NODE, EFFECT_RAN } from '#client/constants';
import { eager_block_effects } from '../reactivity/batch.js';
// export these for reference in the compiled code, making global name deduplication unnecessary // export these for reference in the compiled code, making global name deduplication unnecessary
/** @type {Window} */ /** @type {Window} */
@ -214,6 +215,7 @@ export function clear_text_content(node) {
*/ */
export function should_defer_append() { export function should_defer_append() {
if (!async_mode_flag) return false; if (!async_mode_flag) return false;
if (eager_block_effects !== null) return false;
var flags = /** @type {Effect} */ (active_effect).f; var flags = /** @type {Effect} */ (active_effect).f;
return (flags & EFFECT_RAN) !== 0; return (flags & EFFECT_RAN) !== 0;

@ -28,7 +28,7 @@ import * as e from '../errors.js';
import { flush_tasks } from '../dom/task.js'; import { flush_tasks } from '../dom/task.js';
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { invoke_error_boundary } from '../error-handling.js'; import { invoke_error_boundary } from '../error-handling.js';
import { old_values, schedule_version } from './sources.js'; import { old_values } from './sources.js';
import { unlink_effect } from './effects.js'; import { unlink_effect } from './effects.js';
import { unset_context } from './async.js'; import { unset_context } from './async.js';
@ -601,8 +601,6 @@ function flush_queued_effects(effects) {
var effect = effects[i++]; var effect = effects[i++];
if ((effect.f & (DESTROYED | INERT)) === 0 && is_dirty(effect)) { if ((effect.f & (DESTROYED | INERT)) === 0 && is_dirty(effect)) {
var sv = schedule_version;
eager_block_effects = []; eager_block_effects = [];
update_effect(effect); update_effect(effect);
@ -625,26 +623,19 @@ function flush_queued_effects(effects) {
} }
if (eager_block_effects.length > 0) { if (eager_block_effects.length > 0) {
// TODO this feels incorrect! it gets the tests passing
old_values.clear();
for (const e of eager_block_effects) { for (const e of eager_block_effects) {
update_effect(e); update_effect(e);
} }
eager_block_effects = []; eager_block_effects = [];
} }
// if a state change in a user effect invalidates a _different_ effect,
// abort and reschedule in case that effect now needs to be destroyed
if (schedule_version > sv && (effect.f & USER_EFFECT) !== 0) {
// break;
}
} }
} }
eager_block_effects = null; eager_block_effects = null;
while (i < length) {
schedule_effect(effects[i++]);
}
} }
/** /**

@ -299,12 +299,6 @@ export function increment(source) {
set(source, source.v + 1); set(source, source.v + 1);
} }
/**
* We increment this value when a block effect is scheduled as a result of a state change,
* as its currently-scheduled child effects may need to be destroyed
*/
export let schedule_version = 0;
/** /**
* @param {Value} signal * @param {Value} signal
* @param {number} status should be DIRTY or MAYBE_DIRTY * @param {number} status should be DIRTY or MAYBE_DIRTY
@ -344,7 +338,6 @@ function mark_reactions(signal, status) {
if (eager_block_effects !== null) { if (eager_block_effects !== null) {
eager_block_effects.push(/** @type {Effect} */ (reaction)); eager_block_effects.push(/** @type {Effect} */ (reaction));
} }
schedule_version += 1;
} }
schedule_effect(/** @type {Effect} */ (reaction)); schedule_effect(/** @type {Effect} */ (reaction));

Loading…
Cancel
Save