Skip to content

Commit 5a9c790

Browse files
committed
fix: ensure async initial store value is noticed
fixes #12341
1 parent 32b55ea commit 5a9c790

File tree

5 files changed

+39
-5
lines changed

5 files changed

+39
-5
lines changed

.changeset/nasty-carrots-develop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure async initial store value is noticed

packages/svelte/src/internal/client/reactivity/sources.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,7 @@ export function set(source, value) {
9797
// reactions as we only allocate and assign the reactions after the signal
9898
// has fully executed. So in the case of ensuring it registers the reaction
9999
// properly for itself, we need to ensure the current effect actually gets
100-
// scheduled. i.e:
101-
//
102-
// $effect(() => x++)
103-
//
104-
// We additionally want to skip this logic when initialising store sources
100+
// scheduled. i.e: `$effect(() => x++)`
105101
if (
106102
is_runes() &&
107103
current_effect !== null &&

packages/svelte/src/internal/client/reactivity/store.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ export function store_get(store, store_name, stores) {
4343
set(entry.source, v);
4444
}
4545
});
46+
47+
// also set initial to false right afterwards in case the store subscription callback is async,
48+
// in which case the `state_unsafe_mutation` check is not relevant anymore and we would instead
49+
// not get notified of the store value change
50+
initial = false;
4651
}
4752
}
4853

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
mode: ['client'],
5+
async test({ assert, target }) {
6+
assert.htmlEqual(target.innerHTML, ' / ');
7+
await new Promise((r) => setTimeout(r, 110));
8+
assert.htmlEqual(target.innerHTML, '42 / 42');
9+
}
10+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
function store() {
3+
return {
4+
subscribe: (cb) => {
5+
setTimeout(() => {
6+
cb(42);
7+
}, 100);
8+
9+
return () => {};
10+
}
11+
};
12+
}
13+
14+
const value = store();
15+
const derivedValue = $derived($value);
16+
</script>
17+
18+
{$value} / {derivedValue}

0 commit comments

Comments
 (0)