Skip to content

Commit 6f937f6

Browse files
committed
breaking: state mutations inside the template are no longer allowed
1 parent b352f08 commit 6f937f6

File tree

5 files changed

+34
-2
lines changed

5 files changed

+34
-2
lines changed

.changeset/wild-chairs-build.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+
breaking: state mutations inside the template are no longer allowed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ export function template_effect(fn) {
325325
value: '{expression}'
326326
});
327327
}
328-
return render_effect(fn);
328+
return block(fn);
329329
}
330330

331331
/**

packages/svelte/src/store/shared/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import { noop, run_all } from '../../internal/shared/utils.js';
44
import { safe_not_equal } from '../../internal/client/reactivity/equality.js';
55
import { subscribe_to_store } from '../utils.js';
6+
import { queue_micro_task } from '../../internal/client/dom/task.js';
7+
import { active_effect } from '../../internal/client/runtime.js';
68

79
/**
810
* @type {Array<SubscribeInvalidateTuple<any> | any>}
@@ -168,7 +170,11 @@ export function derived(stores, fn, initial_value) {
168170
)
169171
);
170172
started = true;
171-
sync();
173+
if (active_effect === null) {
174+
sync();
175+
} else {
176+
queue_micro_task(sync);
177+
}
172178
return function stop() {
173179
run_all(unsubscribers);
174180
cleanup();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
compileOptions: {
6+
dev: true
7+
},
8+
9+
test({ assert, target }) {
10+
const button = target.querySelector('button');
11+
12+
assert.throws(() => {}, /state_unsafe_mutation/);
13+
}
14+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
let items = $state([]);
3+
</script>
4+
5+
<button onclick={() => items.push(3, 2, 1)}>Add</button>
6+
{JSON.stringify(items.sort())}
7+

0 commit comments

Comments
 (0)