Skip to content

Commit 71db9ed

Browse files
authored
fix: improve each block item equality for immutable mode (#10537)
* fix: improve each block item equality for immutable mode * alter
1 parent 01b6543 commit 71db9ed

File tree

6 files changed

+46
-8
lines changed

6 files changed

+46
-8
lines changed

.changeset/forty-dogs-divide.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: improve each block item equality for immutable mode

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
DOMBooleanAttributes,
2929
EACH_INDEX_REACTIVE,
3030
EACH_IS_CONTROLLED,
31-
EACH_IS_IMMUTABLE,
31+
EACH_IS_STRICT_EQUALS,
3232
EACH_ITEM_REACTIVE,
3333
EACH_KEYED
3434
} from '../../../../../constants.js';
@@ -2259,8 +2259,8 @@ export const template_visitors = {
22592259
each_type |= EACH_IS_CONTROLLED;
22602260
}
22612261

2262-
if (context.state.analysis.immutable) {
2263-
each_type |= EACH_IS_IMMUTABLE;
2262+
if (context.state.analysis.runes) {
2263+
each_type |= EACH_IS_STRICT_EQUALS;
22642264
}
22652265

22662266
// Find the parent each blocks which contain the arrays to invalidate

packages/svelte/src/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const EACH_KEYED = 1 << 2;
55
/** See EachBlock interface metadata.is_controlled for an explanation what this is */
66
export const EACH_IS_CONTROLLED = 1 << 3;
77
export const EACH_IS_ANIMATED = 1 << 4;
8-
export const EACH_IS_IMMUTABLE = 1 << 6;
8+
export const EACH_IS_STRICT_EQUALS = 1 << 6;
99

1010
export const PROPS_IS_IMMUTABLE = 1;
1111
export const PROPS_IS_RUNES = 1 << 1;

packages/svelte/src/internal/client/each.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
EACH_INDEX_REACTIVE,
33
EACH_IS_ANIMATED,
44
EACH_IS_CONTROLLED,
5-
EACH_IS_IMMUTABLE,
5+
EACH_IS_STRICT_EQUALS,
66
EACH_ITEM_REACTIVE,
77
EACH_KEYED
88
} from '../../constants.js';
@@ -852,9 +852,9 @@ function each_item_block(item, key, index, render_fn, flags) {
852852

853853
const item_value = each_item_not_reactive
854854
? item
855-
: (flags & EACH_IS_IMMUTABLE) === 0
856-
? mutable_source(item)
857-
: source(item);
855+
: (flags & EACH_IS_STRICT_EQUALS) !== 0
856+
? source(item)
857+
: mutable_source(item);
858858

859859
const index_value = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index);
860860
const block = create_each_item_block(item_value, index_value, key);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
immutable: true,
6+
7+
test({ assert, target }) {
8+
const btn = target.querySelector('button');
9+
10+
flushSync(() => {
11+
btn?.click();
12+
});
13+
14+
assert.htmlEqual(target.innerHTML, `<button>Update</button><ul><li>test !!!</li></ul>`);
15+
}
16+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
let items = [{id:1,value: "test"}]
3+
const update = () => {
4+
const clone = items.slice();
5+
clone[0].value += " !!!";
6+
items = clone;
7+
}
8+
</script>
9+
10+
<button on:click={update} >Update</button>
11+
12+
<ul>
13+
{#each items as item (item.id)}
14+
<li>{item.value}</li>
15+
{/each}
16+
</ul>
17+

0 commit comments

Comments
 (0)