sveltejs / svelte

web development for the rest of us
https://svelte.dev
MIT License
80.25k stars 4.27k forks source link

Feature: Improve passing `$state`ful values to `.svelte.js/ts` files #14404

Open Ocean-OS opened 1 week ago

Ocean-OS commented 1 week ago

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:

Importance

would make my life easier

Antonio-Bennett commented 6 days ago

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 commented 6 days ago

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 commented 6 days ago

@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).