fix: ensure legacy run utility does not cause cycles (#13643)

* fix: ensure legacy run utility does not cause cycles

* add warning

* add warning

* lint

* feedback

* lint

* lint
pull/13648/head
Dominic Gannaway 3 weeks ago committed by GitHub
parent ffa2af7549
commit 139114bdcb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure legacy run utility does not cause cycles

@ -56,6 +56,12 @@ Hydration failed because the initial UI does not match what was rendered on the
The `render` function passed to `createRawSnippet` should return HTML for a single element
```
### legacy_recursive_reactive_block
```
Detected a migrated `$:` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
```
### lifecycle_double_unmount
```

@ -36,6 +36,10 @@ The easiest way to log a value as it changes over time is to use the [`$inspect`
> The `render` function passed to `createRawSnippet` should return HTML for a single element
## legacy_recursive_reactive_block
> Detected a migrated `$:` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
## lifecycle_double_unmount
> Tried to unmount a component that was not mounted

@ -99,6 +99,18 @@ export function invalid_raw_snippet_render() {
}
}
/**
* Detected a migrated `$:` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an `$effect`.
*/
export function legacy_recursive_reactive_block() {
if (DEV) {
console.warn(`%c[svelte] legacy_recursive_reactive_block\n%cDetected a migrated \`$:\` reactive block that both accesses and updates the same reactive value. This may cause recursive updates when converted to an \`$effect\`.`, bold, normal);
} else {
// TODO print a link to the documentation
console.warn("legacy_recursive_reactive_block");
}
}
/**
* Tried to unmount a component that was not mounted
*/

@ -1,10 +1,18 @@
/** @import { ComponentConstructorOptions, ComponentType, SvelteComponent, Component } from 'svelte' */
import { DIRTY, MAYBE_DIRTY } from '../internal/client/constants.js';
import { user_pre_effect } from '../internal/client/reactivity/effects.js';
import { mutable_source, set } from '../internal/client/reactivity/sources.js';
import { hydrate, mount, unmount } from '../internal/client/render.js';
import { component_context, flush_sync, get } from '../internal/client/runtime.js';
import {
active_effect,
component_context,
flush_sync,
get,
set_signal_status
} from '../internal/client/runtime.js';
import { lifecycle_outside_component } from '../internal/shared/errors.js';
import { define_property, is_array } from '../internal/shared/utils.js';
import * as w from '../internal/client/warnings.js';
/**
* Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.
@ -169,7 +177,15 @@ class Svelte4Component {
* @returns {void}
*/
export function run(fn) {
user_pre_effect(fn);
user_pre_effect(() => {
fn();
var effect = /** @type {import('#client').Effect} */ (active_effect);
// If the effect is immediately made dirty again, mark it as maybe dirty to emulate legacy behaviour
if ((effect.f & DIRTY) !== 0) {
w.legacy_recursive_reactive_block();
set_signal_status(effect, MAYBE_DIRTY);
}
});
}
/**

Loading…
Cancel
Save