From 48fa6587c9766ef2a5e5892ec1e45afddc1d83ef Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Sat, 8 Jun 2024 14:35:18 +0200 Subject: [PATCH] fix: lazily create sources for Set (#11946) * fix: create sources for initial values of Set * fix: create sources lazily on Set * fix: avoid creating sources if sizes are the same * chore: add test for size of Set * create iterator lazily * tidy up test * oops --------- Co-authored-by: Rich Harris --- .changeset/thin-spoons-float.md | 5 ++ packages/svelte/src/reactivity/set.js | 22 +++++++- .../samples/reactive-set/_config.js | 54 ++++++------------- .../samples/reactive-set/main.svelte | 27 +++++----- 4 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 .changeset/thin-spoons-float.md diff --git a/.changeset/thin-spoons-float.md b/.changeset/thin-spoons-float.md new file mode 100644 index 0000000000..087db3f7b9 --- /dev/null +++ b/.changeset/thin-spoons-float.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: create sources on read for Set diff --git a/packages/svelte/src/reactivity/set.js b/packages/svelte/src/reactivity/set.js index 98d941a07d..3170d0e41e 100644 --- a/packages/svelte/src/reactivity/set.js +++ b/packages/svelte/src/reactivity/set.js @@ -47,6 +47,7 @@ export class ReactiveSet extends Set { for (const method of read_methods) { // @ts-ignore proto[method] = function (...v) { + this.#read_all(); get(this.#version); // @ts-ignore return set_proto[method].apply(this, v); @@ -86,6 +87,23 @@ export class ReactiveSet extends Set { return super.has(value); } + #read_all() { + var sources = this.#sources; + + if (sources.size !== super.size) { + for (let value of super.values()) { + var s = sources.get(value); + + if (s === undefined) { + s = source(true); + sources.set(value, s); + } + + get(s); + } + } + } + /** @param {T} value */ add(value) { var sources = this.#sources; @@ -93,7 +111,6 @@ export class ReactiveSet extends Set { var s = sources.get(value); if (s === undefined) { - sources.set(value, source(true)); set(this.#size, super.size); increment(this.#version); } else { @@ -134,16 +151,19 @@ export class ReactiveSet extends Set { } keys() { + this.#read_all(); get(this.#version); return super.keys(); } values() { + this.#read_all(); get(this.#version); return super.values(); } entries() { + this.#read_all(); get(this.#version); return super.entries(); } diff --git a/packages/svelte/tests/runtime-runes/samples/reactive-set/_config.js b/packages/svelte/tests/runtime-runes/samples/reactive-set/_config.js index b2284071bb..baf2e3df35 100644 --- a/packages/svelte/tests/runtime-runes/samples/reactive-set/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/reactive-set/_config.js @@ -1,50 +1,28 @@ import { flushSync } from '../../../../src/index-client'; -import { test } from '../../test'; +import { ok, test } from '../../test'; export default test({ - html: ``, + html: `

1

0
`, test({ assert, target }) { - const [btn, btn2, btn3] = target.querySelectorAll('button'); + const [btn, btn2, btn3, btn4] = target.querySelectorAll('button'); + const output = target.querySelector('#output'); + ok(output); - flushSync(() => { - btn?.click(); - }); + flushSync(() => btn?.click()); + assert.htmlEqual(output.innerHTML, `

0

`); - assert.htmlEqual( - target.innerHTML, - `
1
` - ); + flushSync(() => btn2?.click()); + assert.htmlEqual(output.innerHTML, `

1

1
`); - flushSync(() => { - btn?.click(); - }); + flushSync(() => btn2?.click()); + flushSync(() => btn2?.click()); + assert.htmlEqual(output.innerHTML, `

3

1
2
3
`); - flushSync(() => { - btn?.click(); - }); + flushSync(() => btn3?.click()); + assert.htmlEqual(output.innerHTML, `

2

1
2
`); - assert.htmlEqual( - target.innerHTML, - `
1
2
3
` - ); - - flushSync(() => { - btn2?.click(); - }); - - assert.htmlEqual( - target.innerHTML, - `
1
2
` - ); - - flushSync(() => { - btn3?.click(); - }); - - assert.htmlEqual( - target.innerHTML, - `` - ); + flushSync(() => btn4?.click()); + assert.htmlEqual(output.innerHTML, `

0

`); } }); diff --git a/packages/svelte/tests/runtime-runes/samples/reactive-set/main.svelte b/packages/svelte/tests/runtime-runes/samples/reactive-set/main.svelte index 523335ced9..1272d28ebe 100644 --- a/packages/svelte/tests/runtime-runes/samples/reactive-set/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/reactive-set/main.svelte @@ -1,21 +1,18 @@ - + + + + - +
+

{state.size}

- - -{#each state as item} -
{item}
-{/each} + {#each state as item} +
{item}
+ {/each} +