Skip to content

Stores not honoring contract described in the documentation #15984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mbellgardt opened this issue May 22, 2025 · 1 comment
Open

Stores not honoring contract described in the documentation #15984

mbellgardt opened this issue May 22, 2025 · 1 comment

Comments

@mbellgardt
Copy link

Describe the bug

In https://svelte.dev/docs/svelte/stores#Store-contract the documentations states:

A store may optionally contain a .set method, which [...] synchronously calls all of the store’s active subscription functions.

This is not the behavior I observe from Svelte's built-in stores, as they seem to schedule the calls to the subscriptions till after the calling function is done. I understand that this behavior is probably intended, my main concern is with the documentation.

It would be very helpful to have a proper documentation of how Svelte's stores actually behave.

Reproduction

Consider the following example:

<script lang="ts">
	import { readonly, type Writable, writable } from 'svelte/store'
	let name = 'world';

	const select: Writable<number> = writable(0)
	const select2: Writable<number> = writable($select)
	let i = 0

	$: console.log("select ", $select)
	$: console.log("select2 ", $select2)

	select.subscribe((v) => {
		console.log('select subscribe ', v)
		select2.set(v)
		console.log('after set')
	})

	select2.subscribe((v) => {
		console.log('select 2 subscribe ', v)
		select.set(v)
	})
</script>

<button on:click={() => select.set(++i)}>assign</button>

Which (after clicking the button) results in the output:

select subscribe  1
after set
select 2 subscribe  1
select  1
select2  1

As you can see, the .set method finishes and the surrounding code is executed before the subscriptions are called.

Logs

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 PRO 4750U with Radeon Graphics
    Memory: 12.33 GB / 31.37 GB
  Binaries:
    Node: 22.14.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.22621.3527

Severity

annoyance

@Prinzhorn
Copy link
Contributor

Prinzhorn commented May 22, 2025

You might be confusing synchronously with immediately or instantly. I think what you're seeing is Svelte waiting for the current subscribe to finish before triggering the next subscribers.

Edit: synchronous means that this will always work:

<script>
	import { writable } from 'svelte/store'

	let store = writable('foo');
	let value;

	const unsub = store.subscribe(v => {
		value = v;
	});
	store.set('bar');
        unsub();

	console.log(value);
</script>

https://svelte.dev/playground/hello-world?version=5.32.1#H4sIAAAAAAAAA22PzW6EMAyEX8XKJUGq2Dv7I_XWd1h6SBZTRTIJSgx0hXj3TQKteujNHn8zI6_C6QFFIz6QyMPiA3WgsLOMXSXeRG8Jo2juq-DnmLksJP1wvY9jHWckzprREf_TH94xOk4x4hIfwY58a13Ldhh9YFhhCZa1IYQN-uAHkLvzFNkHlAlNMCFD2eH6yyvZey-r88991jTheedTZ2SYXJxMchRnneZcb1DNcL3BmrmWiysxc8nZ9rjDgKyk0eHoKGmq-tPgCWvyX6pk5MPldDyY3mb8ZtFwmHD7TJu2tFjXiabXFHF7AUdEhs95AQAA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants