-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
breaking: overhaul proxies, remove $state.is
#12916
Conversation
🦋 Changeset detectedLatest commit: 689d367 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
descriptor.enumerable === false || | ||
descriptor.writable === false | ||
) { | ||
e.state_descriptors_fixed(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be good to have a comment here explaining why we have this restriction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment - reading up on the invariants, can we relax/change this validation? IIUC we only need to disallow non-configurable properties, because they need to appear as such on the target, too. On the other hand, we cannot allow it at all if the target is no extensible and doesn't contain this property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The invariant is correct. We also can’t support non enumerable properties or non-writable because then we need extra overhead to store the extra descriptor info per lookup. See the pr that this came from for context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough - for future reference, this is where it original came up: #12847 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for that, was on mobile earlier so couldn't link it.
Hello! Question: What is the new way of checking if an object is equal to a reactive object now that |
Either avoid doing that (curious to know why you need it) or use |
Write your code in such a way that you don't need to compare a proxy with a non-proxy. The original motivation was to solve cases like this... <script>
let items = [...];
let selected = $state(items[0]); // oops, we just proxified `items[0]`
</script>
{#each items as item}
<!-- this comparison will fail, need to use `$state.is(selected, item)` instead -->
<div class:selected={selected === item}>...</div>
{/each} ...but since then we introduced <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} |
Hello! I do have this case on a component that renders nav link items in a Bootstrap navbar:
Then the |
Right, so it sounds like |
Indeed, Rich. I'll schedule some time later in the week to do the change and test. Thank you all for the kind explanations. Rich, the docs page still lists $state.is. Unsure if the PR needed to have the docs changed or not. |
ah whoops, good catch — fixed in #12927 |
How can I combine |
Can you illustrate why you need to? (Also, if there's an issue here, then please open a new one as it's very easy to lose closed threads) |
I have implemented a |
That's not an illustration. Please provide a https://svelte-5-preview.vercel.app repro link showing the problem |
Reduced demo showing the problem. Not sure if it is an issue or if I am simply using it wrong. The demo is very reduced. My real component allows a property to fetch possible items/options by an async function. It's also possible to provide mappings from options to a value (i.e. to bind just the ID of the selected option). |
Nooo, don't tell me that bindable props are an issue? I have exactly that. I neglected to correctly specify my props before. In reality, I have: let {
items,
activeItem = $bindable(),
} = $props(); This is so the clicking of the nav-link element can inform about the active item, and so the active item can be set externally. Both ways are necessary. What's the problem with |
Exteded the demo a bit for comparison with |
-let selected = $state();
+let selected = $state.raw(); |
Indeed, as Rich states, binding to a raw variable makes the comparison works. However, would this suffice long term? For example, I find myself easily forwarding properties from one control to another. For the case of Bootstrap, I have a Dropdown component, which is used as the base of DropdownMenu component, which is used as base to the Autocomplete component. For the DropdownMenu/Autocomplete relation, both have an |
I miss "state.is" I use new Object to create a uniquie id inside script: Now, I do this on mount: But without state.is - I can not run this code on destroy: Same happen in my keydown event - missing state.is: |
@dm-de We don't use the object you pass into |
Thank you.... Symbol fixes it! this combination works now:
|
This builds on #12912, with the following changes brought over from #12847:
$state.is
defineProperty
with non-basic descriptorsIt also removes the
is_frozen
check.To recap: this simplifies the internals a decent amount, gets rid of the weird
STATE_SYMBOL
property on proxied objects (it's accessible via the proxy, but doesn't exist on the original object), removes the weird abstraction leak around frozen objects, and makes stuff a lot more future-proof.Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint