Skip to content

Bring back $state.is runeΒ #13582

@kwangure

Description

@kwangure

Describe the problem

The $state.is() rune was removed with the argument that $state.raw makes it not needed. In #12916 (comment) Rich says:

Write your code in such a way that you don't need to compare a proxy with a non-proxy...
....
$state.raw is a much better approach:

<script>
  let items = [...];
- let selected = $state(items[0]);
+ let selected = $state.raw(items[0]);
</script>
{#each items as item}
<div class:selected={selected === item}>...</div>
{/each}
  1. This "fix" is fine in a single component but not in a sizable application where data is crossing several boundaries where anything could proxify it. (e.g item[0] being passed to ListItem and then createListItem() where I want to do const active = $derived(myRootComponent.value === item) and return { get foo() { return item.deep.value.foo; }
  2. 90% of state starts as $state only for you to later realize you need to compare it with something downstream.
  3. In the context of Rich's example, the particular use case I'm interested in is where you want items[0] to be a reactive signal/proxy...but also compare it with selected.

Expecting someone to just "Write your code in such a way that you don't need to compare a proxy with a non-proxy" is not a reasonable request because:
a) It needs engineering time to refactor the entire state & component tree that touches a piece of data potentially proxying it while $state.is would otherwise suffice.
b) There's no easy way to enforce that distant up-stream or down-stream consumers not to proxy data.
c) I now need to document and recall arguments/props that should not be deep proxies as I'm passing them to places that do comparison...and I need to actually know if they do comparison
d) Probably most importantly, my data is already proxied, I want it to be deeply reactive, but I also want to compare it. What can we do about it?

Describe the proposed solution

Bring $state.is back. Alternatively, some other solution that allows dealing with proxied data after the fact and preserves object identity (e.g $state.unproxify) is also welcome.

Importance

i cannot use svelte without it

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions