chore: unify pre effects (#10933)

* breaking: always run pre effects synchronously

* unify pre effects
pull/10947/head
Rich Harris 1 year 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]); const func = context.visit(node.expression.arguments[0]);
return { return {
...node, ...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( context.state.init.push(
b.stmt( b.stmt(
b.call( b.call(
'$.invalidate_effect', '$.pre_effect',
b.thunk( b.thunk(
b.block([ b.block([
b.stmt( b.stmt(
@ -747,7 +747,7 @@ function serialize_inline_component(node, component_name, context) {
binding_initializers.push( binding_initializers.push(
b.stmt( b.stmt(
b.call( b.call(
b.id('$.pre_effect'), b.id('$.user_pre_effect'),
b.thunk(b.call(b.id('$.add_owner'), expression, b.id(component_name))) b.thunk(b.call(b.id('$.add_owner'), expression, b.id(component_name)))
) )
) )

@ -1,5 +1,5 @@
import { run } from '../../../common.js'; 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 { import {
current_component_context, current_component_context,
deep_read_state, deep_read_state,
@ -19,7 +19,7 @@ export function init() {
// beforeUpdate // beforeUpdate
if (callbacks.b.length) { if (callbacks.b.length) {
pre_effect(() => { user_pre_effect(() => {
observe_all(context); observe_all(context);
callbacks.b.forEach(run); callbacks.b.forEach(run);
// beforeUpdate might change state that affects rendering, ensure the render effects following from it // 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; 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(...)` * Internal representation of `$effect.root(...)`
* @param {() => void | (() => void)} fn * @param {() => void | (() => void)} fn
@ -128,24 +146,6 @@ export function effect(fn) {
return create_effect(EFFECT, fn, false); 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 `$: ..` * Internal representation of `$: ..`
* @param {() => any} deps * @param {() => any} deps
@ -157,19 +157,15 @@ export function legacy_pre_effect(deps, fn) {
current_component_context current_component_context
); );
const token = {}; const token = {};
return create_effect( return pre_effect(() => {
PRE_EFFECT, deps();
() => { if (component_context.l1.includes(token)) {
deps(); return;
if (component_context.l1.includes(token)) { }
return; component_context.l1.push(token);
} set(component_context.l2, true);
component_context.l1.push(token); return untrack(fn);
set(component_context.l2, true); });
return untrack(fn);
},
true
);
} }
export function legacy_pre_effect_reset() { 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 * @param {() => void | (() => void)} fn
* @returns {import('#client').Effect} * @returns {import('#client').Effect}
*/ */
export function invalidate_effect(fn) { export function pre_effect(fn) {
return create_effect(PRE_EFFECT, fn, true); return create_effect(PRE_EFFECT, fn, true);
} }

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

Loading…
Cancel
Save