Skip to content

Commit 5a54ad9

Browse files
authored
fix: ensure SvelteMap reactivity persists through deriveds (#13877)
* fix: ensure SvelteMap reactivity persists through deriveds * fix: ensure SvelteMap reactivity persists through deriveds * fix: ensure SvelteMap reactivity persists through deriveds
1 parent 041e563 commit 5a54ad9

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

.changeset/hungry-dogs-happen.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 SvelteMap reactivity persists through deriveds

packages/svelte/src/reactivity/map.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,22 @@ export class SvelteMap extends Map {
9494
var s = sources.get(key);
9595
var prev_res = super.get(key);
9696
var res = super.set(key, value);
97+
var version = this.#version;
9798

9899
if (s === undefined) {
99100
sources.set(key, source(0));
100101
set(this.#size, super.size);
101-
increment(this.#version);
102+
increment(version);
102103
} else if (prev_res !== value) {
103104
increment(s);
105+
// If no one listening to this property and is listening to the version, or
106+
// the inverse, then we should increment the version to be safe
107+
if (
108+
(s.reactions === null && version.reactions !== null) ||
109+
(s.reactions !== null && version.reactions === null)
110+
) {
111+
increment(version);
112+
}
104113
}
105114

106115
return res;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
html: `Loading`,
6+
7+
async test({ assert, target }) {
8+
await Promise.resolve();
9+
flushSync();
10+
11+
assert.htmlEqual(target.innerHTML, `1`);
12+
}
13+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script>
2+
import { untrack } from 'svelte';
3+
import { SvelteMap } from 'svelte/reactivity';
4+
5+
const cache = new SvelteMap();
6+
7+
function get_async(id) {
8+
const model = cache.get(id);
9+
10+
if (!model) {
11+
const promise = new Promise(async () => {
12+
await Promise.resolve();
13+
cache.set(id, id.toString());
14+
}).then(() => cache.get(id));
15+
16+
untrack(() => {
17+
cache.set(id, promise);
18+
});
19+
20+
return promise;
21+
}
22+
23+
return model;
24+
}
25+
26+
const value = $derived(get_async(1));
27+
</script>
28+
29+
{#if value instanceof Promise}
30+
Loading
31+
{:else}
32+
{value}
33+
{/if}
34+

0 commit comments

Comments
 (0)