Skip to content
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

Feature: Improve passing $stateful values to .svelte.js/ts files #14404

Open
Ocean-OS opened this issue Nov 23, 2024 · 3 comments
Open

Feature: Improve passing $stateful values to .svelte.js/ts files #14404

Ocean-OS opened this issue Nov 23, 2024 · 3 comments

Comments

@Ocean-OS
Copy link
Contributor

Ocean-OS commented Nov 23, 2024

Describe the problem

Imagine this:
You have a .svelte.js/ts file that exports some functions. In these functions, you want to pass a $state or $derived value and use it inside of an $effect, $derived, or something else where you want to keep the reactivity of the value; maybe you want to save the $state's value to a database or external resource as it updates, watch the value for changes and do something when it does change, etc. However, to do that, you have to put the $state value in a callback (or getter/setter object) in the parameters of the function. This feels rather clunky and un-Svelte like. Here's an example of what I mean.

Describe the proposed solution

While there aren't too many good solutions I've thought of, one that stood out to me was to make parameters that accept state values have a name prefixed with a $; the only problem I could see with this is that it may cause some confusion with stores. Examples:
Before
After:

export function watch($value, callback){
    let previous = $value;
    let dispose = $effect.root(()=>{
        $effect(()=>{
            let v = $value;
            callback(v,previous);
            previous = v;
        });
    });
    return dispose;
}
export function syncWithDB($value){
    watch($value,(updated)=>{
        doDatabaseStuffWithNewData(updated);
    })
}

Some other solutions I've thought of, but don't feel would entirely fit Svelte include:

  • Making functions that use $stateful values have a $ prefixing their name
    1. This makes it harder to have a function that takes $stateful values as a few parameters instead of all of its parameters.
    2. This would basically make it possible to create new runes, which, in my opinion, kind of takes away some of the magic and simplicity of runes
  • Stating which values are meant to be $states using types
    1. This just feels wrong if you are using vanilla JS. Using JSDoc (if you don't use TS) wouldn't feel good at all, not to mention it'd probably be difficult to implement in the compiler.
    2. This has basically already been rejected in TS Types for Svelte 5 $state reactivity #11546 and Can we have specific types for reactive state in Svelte 5? #13267
  • Using comments, a la @ts-check/@ts-ignore (example)
    • This feels a little clunky and is also probably difficult to implement in the compiler.
  • Using $state for the default parameters (example: function foo(value=$state()) or function bar(value=$state)
    • This feels somewhat awkward and can be unwanted if the function needs a different default parameter, if the latter option were to be chosen.

Importance

would make my life easier

@Antonio-Bennett
Copy link

Antonio-Bennett commented Nov 23, 2024

I disagree with this proposal. Feels like we’re adding new syntax for no reason other than to be convenient that ends up being confusing. The solution here is documentation if needed in my opinion. Your gripe seems to be with how JavaScript itself works not svelte. Primitives cannot be passed across boundaries magically. I see why people might find it inconvenient but I think this is an area where svelte should stay aligned with Js

@Ocean-OS
Copy link
Contributor Author

Ocean-OS commented Nov 23, 2024

Primitives cannot be passed across boundaries magically. I see why people might find it inconvenient but I think this is an area where svelte should stay aligned with Js

Svelte's runes turn primitives into an object to keep the reference and reactivity; I don't see why we'd have to work around the compiler to maintain that reference behavior.

@Serator
Copy link

Serator commented Nov 23, 2024

@Ocean-OS https://github.com/flakolefluk/dark-runes?tab=readme-ov-file#get - I haven't tried this solution, but it looks like $get from the dark-runes package does what you write about (in a way).

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

No branches or pull requests

3 participants