DEV Community

Using Sharable Runes with TypeScript in Svelte5

Jonathan Gamble on April 28, 2024

I don't know about you, but I don't like using Runes with $state in Svelte 5. Sure, they're easier to set data in your component, but I don't write...
Collapse
 
brugh profile image
brugh

I have an application that has a service.ts with an eventhandler that impacts the store. I cannot use useRune() or any runelike actions in a service file since you can only use runes in components, how can i get the store defined like this to update from an eventhandler?

Collapse
 
jdgamble555 profile image
Jonathan Gamble

This is a Svelte 5 limitation. You would need to rename service.ts to service.svelte.ts, generally speaking.

Collapse
 
brugh profile image
brugh

yes, that's true. if you add a
const docState = $state( {value: null} )
it will let you do that.
but if you set
const docState = useRune('docstate')
it will error out with a Svelte error: lifecycle_outside_component

i dont see a way to circumvent that...

Thread Thread
 
jdgamble555 profile image
Jonathan Gamble

Are you using shared.svelte.ts for the useRune()? Also, I'm not sure where you're putting that, so an example repo would help.

Thread Thread
 
brugh profile image
brugh • Edited

I made 2 thinking errors; first, if you're using a rune in a service.svelte.ts, you don't need a context for children objects to access it. you can simply export const store=$state({}).
Secondly, I got confused while testing because I used a const store=$state<Map<string,string>>(new Map()); which didn't work; not because of contexts as I thought, but because a Map change doesn't seem to trigger a change in svelte. When i used a normal object of type { [k: string]: string } it worked like a charm.. old javascript habits ...

Thread Thread
 
jdgamble555 profile image
Jonathan Gamble

You still want to use context. While it can work, there is a chance it could leak in SSR. See my first post about this and the issue - github.com/sveltejs/kit/discussion....

Collapse
 
jamesforan profile image
James Foran

This is the post I have been looking for. Thanks. I am a very part-time programmer and am struggling a little with runes, and sharing state across my app.

I agree with your point about, "should be standard in libraries/frameworks".

Collapse
 
slidenerd profile image
slidenerd

but how will you access this inside +layout.ts when running in the browser. Both getContext and setContext throw an error. Use case infinite scrolling. Scroll 3 pages, click on the 31st item. It calls +layout.ts that attempts to navigate to this item which doesnt exist, somehow these items have to be shared between +layout.ts and +layout.svelte

Collapse
 
jdgamble555 profile image
Jonathan Gamble

Read my other posts, you shouldn't use context inside +page.ts or +layout.ts. Context is meant for sharing in components. You can share data in a loader differently by returning the data.