From f0576ea01f65c062c3d948475b121620568edd52 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 8 May 2026 10:40:05 -0400 Subject: [PATCH] add test and note-to-self about store behaviour with async --- .../src/internal/client/reactivity/batch.js | 2 +- .../_config.js | 52 +++++++++++++++++++ .../main.svelte | 29 +++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/main.svelte diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index 8f14cb4437..f5f16e101d 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -301,7 +301,7 @@ export class Batch { /** * @type {Effect[]} - * @deprecated when we get rid of legacy mode and stores, we can get rid of this + * @deprecated when we get rid of legacy mode and stores, we can get rid of this, and also early-return in the deferred case */ var updates = (legacy_updates = []); diff --git a/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/_config.js b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/_config.js new file mode 100644 index 0000000000..4a36e05b8c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/_config.js @@ -0,0 +1,52 @@ +import { tick } from 'svelte'; +import { ok, test } from '../../test'; + +// Test that the store is unsubscribed from, even if it's not referenced once the store itself is set to null +export default test({ + async test({ target, assert }) { + assert.htmlEqual( + target.innerHTML, + `

0

` + ); + + target.querySelector('button')?.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + `

1

hello 1 ` + ); + + const input = target.querySelector('input'); + ok(input); + + input.stepUp(); + input.dispatchEvent(new Event('input', { bubbles: true })); + await tick(); + assert.htmlEqual( + target.innerHTML, + `

2

hello 2 ` + ); + + target.querySelector('button')?.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + `

2

` + ); + + input.stepUp(); + input.dispatchEvent(new Event('input', { bubbles: true })); + await tick(); + assert.htmlEqual( + target.innerHTML, + `

2

` + ); + + target.querySelector('button')?.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + `

3

hello 3 ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/main.svelte new file mode 100644 index 0000000000..4abfd3c2f9 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after-2/main.svelte @@ -0,0 +1,29 @@ + + + +

{count}

+ +{#if watcherA} + + {#if true} + {await 'hello'} + {/if} + + {$watcherA} + +{:else} + +{/if}