Description
Describe the problem
Reactive state is cool. We need to work with it and yadayada. I'm really glad that Svelte exists and it is saving more time for me compared to frameworks I used previously. But, reactive states being based on Proxies results in the fact that every non-primitive value you put into reactive state is not ===
to itself from inside the reactive state.
There are several use cases where one needs to work with a clean, unproxified value:
WeakMap
s. When logically the same object comes from different sets (arrays, Maps, Sets, as a property, etc.), you cannot use it as a key of a WeakMap to update/remove the same value from different places. And adding artificial primitive identifiers to your object defeats the purpose of theWeakMap
.- Identifying objects in various subsets. REPL. Say, you have several subsets where if you delete an object, you must delete it from every one of it. E.g.
filesAll
andfilesFiltered
in a file browser component (and filtering is hecking expensive (it's just an example, my use case is different anyways so don't teach me$derived
, duh)). Naive indexOf+splice fails, and… artificially tagging them to use withfindIndex
is:- Dumb if it is in my own codebase — why must I change my data model for the GUI framework?
- Hacky if it is about objects coming from a 3rdparty and sometimes impossible if public values don't have something that would make objects distinguishable, and objects come from some 3rdparty method or whatnot.
- $state.snapshot cause object prototype to be lost #15022 shows that the current tools for unproxifying are lacking.
Additional grudge: In a TypeScript project, you can't distinguish when a reactive proxy or a plain value is used. Having a generic that tags states as reactive would help to make typeguards in methods that disallow/require the use of reactive state, and just to help me lose less hairs when I bump into one of the issues above. The current $state
return type makes things look deceptively easy when they are nuanced af.
Describe the proposed solution
- Expose
get_proxied_value
from src/internal/client/proxy.js as$state.unwrap
- Bring back
$state.is
as usage of$state.raw
is not scalable; it requires writing non-obvious hacks for each individual case. - Describe both as last-resort tools to spook newbies looking for easy but bad solutions to some problems they might have. Both
$state.unwrap
and$state.is
are advanced tools.
Previous relevant discussions:
Importance
would make my life easier