Description
Describe the bug
In a situation like this (see complete code in "Reproduction"):
<script>
import { createPressWatcher } from './pressWatcher.svelte.js';
const pressWatcher = createPressWatcher();
</script>
<button onmousedown={pressWatcher.onmousedown} onmouseup={pressWatcher.onmouseup}>
Pressed: {pressWatcher.pressed}
</button>
it is tempting to refactor the code like this:
<script>
import { createPressWatcher } from './pressWatcher.svelte.js';
const { pressed, ...events } = createPressWatcher();
</script>
<button {...events}>
Pressed: {pressed}
</button>
to reduce boilerplate.
But this breaks the app (events are working just fine, but pressed state is broken). As I understand it's because no dot-accessing is used and thus no getters are called, but this is not something a regular dev, who just copied reactivity pattern from docs and applied a common practice of destructuring, would immediately think about.
It is kinda of addressed in the docs with:
Note that we're using a get property in the returned object, so that
counter.count
always refers to the current value rather than the value at the time the createCounter function was called.
But the focus in this sentence seems to be on the fact of how we created not on the fact that we should consume this only with dot-access if we want to save reactivity. The user may start to look for a bug in "Universal reactivity module" but it's accessing code that should be changed.
Proposal
Clearly state that for such universal reactivity case only dot-accessing works reactively
Reproduction
Working reactivity before destructuring
Broken reactivity after destructuring
Logs
No response
System Info
svelte@5.0.0-next.90
Severity
annoyance