From 1e81913a50dc1cc8b2d96561ec4ec466c2aaa446 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 13 Nov 2023 11:18:16 +0000 Subject: [PATCH] Fix runtime effect issues --- .../phases/3-transform/client/utils.js | 2 ++ .../svelte/src/internal/client/runtime.js | 15 +++++++++++-- .../_config.js | 13 +++++++++++ .../main.svelte | 14 ++++++++++++ .../_config.js | 13 +++++++++++ .../main.svelte | 22 +++++++++++++++++++ .../samples/effect-cleanup/_config.js | 19 ++++++++++++++++ .../samples/effect-cleanup/main.svelte | 17 ++++++++++++++ 8 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/main.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/main.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/effect-cleanup/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/effect-cleanup/main.svelte diff --git a/packages/svelte/src/compiler/phases/3-transform/client/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/utils.js index eed663846b..1194cffcde 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/utils.js @@ -251,6 +251,8 @@ export const function_visitor = (node, context) => { const in_constructor = parent.type === 'MethodDefinition' && parent.kind === 'constructor'; state = { ...context.state, in_constructor }; + } else { + state = { ...context.state, in_constructor: false }; } if (metadata?.hoistable === true) { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index b5fddc4489..1a217c5626 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -343,7 +343,13 @@ function destroy_references(signal) { if (references !== null) { let i; for (i = 0; i < references.length; i++) { - destroy_signal(references[i]); + const reference = references[i]; + if ((reference.flags & IS_EFFECT) !== 0) { + destroy_signal(reference); + } else { + remove_consumer(reference, 0, true); + reference.dependencies = null; + } } } } @@ -710,7 +716,7 @@ export function exposable(fn) { export function get(signal) { const flags = signal.flags; if ((flags & DESTROYED) !== 0) { - return /** @type {V} */ (UNINITIALIZED); + return signal.value; } if (is_signal_exposed && current_should_capture_signal) { @@ -1156,6 +1162,11 @@ export function managed_pre_effect(init, sync) { * @returns {import('./types.js').EffectSignal} */ export function pre_effect(init) { + if (current_effect === null) { + throw new Error( + 'The Svelte $effect.pre rune can only be used during component initialisation.' + ); + } const sync = current_effect !== null && (current_effect.flags & RENDER_EFFECT) !== 0; return internal_create_effect( PRE_EFFECT, diff --git a/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/_config.js b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/_config.js new file mode 100644 index 0000000000..dd847ce2f2 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: ``, + ssrHtml: ``, + + async test({ assert, target }) { + flushSync(); + + assert.htmlEqual(target.innerHTML, ``); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/main.svelte b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/main.svelte new file mode 100644 index 0000000000..88b0398943 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure-private/main.svelte @@ -0,0 +1,14 @@ + + + diff --git a/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/_config.js b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/_config.js new file mode 100644 index 0000000000..dd847ce2f2 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: ``, + ssrHtml: ``, + + async test({ assert, target }) { + flushSync(); + + assert.htmlEqual(target.innerHTML, ``); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/main.svelte b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/main.svelte new file mode 100644 index 0000000000..fe7fcf1aa3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/class-state-constructor-closure/main.svelte @@ -0,0 +1,22 @@ + + + diff --git a/packages/svelte/tests/runtime-runes/samples/effect-cleanup/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-cleanup/_config.js new file mode 100644 index 0000000000..ee690418d6 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-cleanup/_config.js @@ -0,0 +1,19 @@ +import { test } from '../../test'; +import { flushSync } from 'svelte'; + +export default test({ + get props() { + return { log: [] }; + }, + + async test({ assert, target, component }) { + const [b1] = target.querySelectorAll('button'); + flushSync(() => { + b1.click(); + }); + flushSync(() => { + b1.click(); + }); + assert.deepEqual(component.log, ['init 0', 'cleanup 2', 'init 2', 'cleanup 4', 'init 4']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-cleanup/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-cleanup/main.svelte new file mode 100644 index 0000000000..7c84aeddff --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-cleanup/main.svelte @@ -0,0 +1,17 @@ + + +