chore: unify pre effects (#10933)

* breaking: always run pre effects synchronously

* unify pre effects
pull/10947/head
Rich Harris 12 months ago committed by GitHub
parent f2cca537a3
commit 7adc14e24c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -371,7 +371,7 @@ export const javascript_visitors_runes = {
const func = context.visit(node.expression.arguments[0]);
return {
...node,
expression: b.call('$.pre_effect', /** @type {import('estree').Expression} */ (func))
expression: b.call('$.user_pre_effect', /** @type {import('estree').Expression} */ (func))
};
}
}

@ -231,7 +231,7 @@ function setup_select_synchronization(value_binding, context) {
context.state.init.push(
b.stmt(
b.call(
'$.invalidate_effect',
'$.pre_effect',
b.thunk(
b.block([
b.stmt(
@ -747,7 +747,7 @@ function serialize_inline_component(node, component_name, context) {
binding_initializers.push(
b.stmt(
b.call(
b.id('$.pre_effect'),
b.id('$.user_pre_effect'),
b.thunk(b.call(b.id('$.add_owner'), expression, b.id(component_name)))
)
)

@ -1,5 +1,5 @@
import { run } from '../../../common.js';
import { pre_effect, user_effect } from '../../reactivity/effects.js';
import { user_pre_effect, user_effect } from '../../reactivity/effects.js';
import {
current_component_context,
deep_read_state,
@ -19,7 +19,7 @@ export function init() {
// beforeUpdate
if (callbacks.b.length) {
pre_effect(() => {
user_pre_effect(() => {
observe_all(context);
callbacks.b.forEach(run);
// beforeUpdate might change state that affects rendering, ensure the render effects following from it

@ -108,6 +108,24 @@ export function user_effect(fn) {
return effect;
}
/**
* Internal representation of `$effect.pre(...)`
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function user_pre_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '')
);
}
return pre_effect(fn);
}
/**
* Internal representation of `$effect.root(...)`
* @param {() => void | (() => void)} fn
@ -128,24 +146,6 @@ export function effect(fn) {
return create_effect(EFFECT, fn, false);
}
/**
* Internal representation of `$effect.pre(...)`
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function pre_effect(fn) {
if (current_effect === null) {
throw new Error(
'ERR_SVELTE_ORPHAN_EFFECT' +
(DEV
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
: '')
);
}
return create_effect(PRE_EFFECT, fn, true);
}
/**
* Internal representation of `$: ..`
* @param {() => any} deps
@ -157,19 +157,15 @@ export function legacy_pre_effect(deps, fn) {
current_component_context
);
const token = {};
return create_effect(
PRE_EFFECT,
() => {
deps();
if (component_context.l1.includes(token)) {
return;
}
component_context.l1.push(token);
set(component_context.l2, true);
return untrack(fn);
},
true
);
return pre_effect(() => {
deps();
if (component_context.l1.includes(token)) {
return;
}
component_context.l1.push(token);
set(component_context.l2, true);
return untrack(fn);
});
}
export function legacy_pre_effect_reset() {
@ -186,13 +182,10 @@ export function legacy_pre_effect_reset() {
}
/**
* This effect is used to ensure binding are kept in sync. We use a pre effect to ensure we run before the
* bindings which are in later effects. However, we don't use a pre_effect directly as we don't want to flush anything.
*
* @param {() => void | (() => void)} fn
* @returns {import('#client').Effect}
*/
export function invalidate_effect(fn) {
export function pre_effect(fn) {
return create_effect(PRE_EFFECT, fn, true);
}

@ -8,7 +8,7 @@ import {
object_prototype
} from './utils.js';
import { unstate } from './proxy.js';
import { destroy_effect, pre_effect } from './reactivity/effects.js';
import { destroy_effect, user_pre_effect } from './reactivity/effects.js';
import {
EFFECT,
PRE_EFFECT,
@ -1201,7 +1201,7 @@ let warned_inspect_changed = false;
export function inspect(get_value, inspect = console.log) {
let initial = true;
pre_effect(() => {
user_pre_effect(() => {
const fn = () => {
const value = untrack(() => get_value().map((v) => deep_unstate(v)));
if (value.length === 2 && typeof value[1] === 'function' && !warned_inspect_changed) {

Loading…
Cancel
Save