Skip to content

chore: use proxy instead of signal in createRoot #9799

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

Merged
merged 6 commits into from
Dec 6, 2023
Merged

Conversation

Rich-Harris
Copy link
Member

This is part of a larger effort to simplify props handling internally, by using proxies rather than signals to represent the props object. In time, this will hopefully enable us to get rid of things like sync_effect.

Just one small change in behaviour — the enumeration order of keys in rest props is different. (I cannot imagine this ever mattering)

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

Copy link

changeset-bot bot commented Dec 5, 2023

⚠️ No Changeset found

Latest commit: cc394ca

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Dec 6, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
svelte-5-preview ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 6, 2023 2:24pm

@Rich-Harris
Copy link
Member Author

This is ready, but we should merge #9801 into this branch first

* use proxies instead of signals for spread/rest

* fix some spread attribute stuff

* remove is_signal calls

* simplify some more

* more

* remove some unnecessary unwrapping

* another

* simplify

* simplify

* simplify

* remove another MaybeSignal

* more

* remove more unwraps

* code-golf, docs

---------

Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Simon Holthausen <[email protected]>
@@ -2616,73 +2621,14 @@ export function spread_props(props) {
* @returns {Exports & { $destroy: () => void; $set: (props: Partial<Props>) => void; }}
*/
export function createRoot(component, options) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change createRoot is basically == mount. I'm wondering if we should therefore should just get rid of createRoot and move the $set/$destroy interface onto mount (in a follow-up PR)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is this:

import { createProps, createRoot } from 'svelte';
import App from './App.svelte';

const props = createProps({ count: 1 });
const destroy = createRoot(App, { props });

// later
props.count += 1;
destroy();

In the case where you didn't need to update the props after creation, it would just be this:

import { createRoot } from 'svelte';
import App from './App.svelte';

const destroy = createRoot(App, { props: { count: 1 } });

// later
destroy();

To me this feels a bit more harmonious than splodging together props with $set and $destroy methods. And it would render accessors unnecessary.

(Obviously we'd still keep that stuff around in compat mode.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's more than accessors, the returned instance can also contain functions etc that are exposed through

<script>
  export function x() {..}
</script>

so we won't be getting away with just destroy.
I also think that getting an object back you can call $set and $destroy on feels like a better API than creating a props object you interact with separately.
Lastly, if it was only mount, we could introduce a corresponding hydrate, with the difference being that mount never sets the hydration flags, which if done right would hopefully enable Rollup etc to treeshake the whole hydration code away, ensuring smaller builds for (for example) web component people.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I have been thinking lately. It would be great if createRoot can be ditched somehow in favor of mount so we have a single API.

@Rich-Harris Rich-Harris merged commit 01a2117 into main Dec 6, 2023
@Rich-Harris Rich-Harris deleted the simplify-props-3 branch December 6, 2023 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants