feat: allow effects to return AbortController

effect-abort
Dominic Gannaway 4 weeks ago
parent 2bfdd1b436
commit e4e799bad2

@ -234,7 +234,7 @@ declare namespace $derived {
* https://svelte.dev/docs/svelte/$effect * https://svelte.dev/docs/svelte/$effect
* @param fn The function to execute * @param fn The function to execute
*/ */
declare function $effect(fn: () => void | (() => void)): void; declare function $effect(fn: () => void | (() => void) | AbortController): void;
declare namespace $effect { declare namespace $effect {
/** /**
@ -253,7 +253,7 @@ declare namespace $effect {
* https://svelte.dev/docs/svelte/$effect#$effect.pre * https://svelte.dev/docs/svelte/$effect#$effect.pre
* @param fn The function to execute * @param fn The function to execute
*/ */
export function pre(fn: () => void | (() => void)): void; export function pre(fn: () => void | (() => void) | AbortController): void;
/** /**
* The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template. * The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template.

@ -381,7 +381,11 @@ export function execute_effect_teardown(effect) {
set_is_destroying_effect(true); set_is_destroying_effect(true);
set_active_reaction(null); set_active_reaction(null);
try { try {
teardown.call(null); if (typeof teardown === 'function') {
teardown.call(null);
} else {
teardown.abort('effect destroyed');
}
} finally { } finally {
set_is_destroying_effect(previously_destroying_effect); set_is_destroying_effect(previously_destroying_effect);
set_active_reaction(previous_reaction); set_active_reaction(previous_reaction);

@ -52,7 +52,7 @@ export interface Effect extends Reaction {
/** The effect function */ /** The effect function */
fn: null | (() => void | (() => void)); fn: null | (() => void | (() => void));
/** The teardown function returned from the effect function */ /** The teardown function returned from the effect function */
teardown: null | (() => void); teardown: null | (() => void) | AbortController;
/** Transition managers created with `$.transition` */ /** Transition managers created with `$.transition` */
transitions: null | TransitionManager[]; transitions: null | TransitionManager[];
/** Next sibling child effect created inside the parent signal */ /** Next sibling child effect created inside the parent signal */

@ -524,8 +524,12 @@ export function update_effect(effect) {
destroy_effect_deriveds(effect); destroy_effect_deriveds(effect);
execute_effect_teardown(effect); execute_effect_teardown(effect);
var teardown = update_reaction(effect); var teardown = update_reaction(effect) ?? null;
effect.teardown = typeof teardown === 'function' ? teardown : null; // Avoid doing an instanceof check on the hot-path
effect.teardown =
teardown === null || typeof teardown === 'function' || teardown instanceof AbortController
? teardown
: null;
effect.version = current_version; effect.version = current_version;
if (DEV) { if (DEV) {

@ -2892,7 +2892,7 @@ declare namespace $derived {
* https://svelte.dev/docs/svelte/$effect * https://svelte.dev/docs/svelte/$effect
* @param fn The function to execute * @param fn The function to execute
*/ */
declare function $effect(fn: () => void | (() => void)): void; declare function $effect(fn: () => void | (() => void) | AbortController): void;
declare namespace $effect { declare namespace $effect {
/** /**
@ -2911,7 +2911,7 @@ declare namespace $effect {
* https://svelte.dev/docs/svelte/$effect#$effect.pre * https://svelte.dev/docs/svelte/$effect#$effect.pre
* @param fn The function to execute * @param fn The function to execute
*/ */
export function pre(fn: () => void | (() => void)): void; export function pre(fn: () => void | (() => void) | AbortController): void;
/** /**
* The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template. * The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template.

Loading…
Cancel
Save