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

Singletons #71

Closed
dev-guy opened this issue Aug 17, 2023 · 4 comments
Closed

Singletons #71

dev-guy opened this issue Aug 17, 2023 · 4 comments

Comments

@dev-guy
Copy link

dev-guy commented Aug 17, 2023

To avoid wasting memory on features that might not be used, some Svelte frameworks, such as Svelte Skeleton v2, use singleton stores that are intended to be created via top-level SvelteKit files such as +layout.svelte.

<script>
import { initializeStores } from '@skeletonlabs/skeleton';
initializeStores();
</script>

initializeToastStore() does this:

return setContext(TOAST_STORE_KEY, toastStore);

In other words, the Toast store is a singleton that is accessed via a top-level Svelte context that is available to every Svelte component in the application.

A LiveSvelte application needs to initialize the Skeleton toast store somehow. The top-level objects of a Phoenix application are generally app.js and app.html.heex. Of course, using app.js doesn't work because Svelte throws an error when getContext/setContext/hasContext are called outside of component initialization. Apparently, only a .svelte file can initiate a workflow that calls *Context() since contexts are associated with Svelte components.

Heex templates can include Svelte components via LiveSvelte. Can app.html.heex do it? To try, I created a Svelte component that initializes the Toast store. I added the following to the top of app.html.heex: <.svelte name='Toast'>.

Toast.svelte:

<script>
import { initializeStores, Toast } from '@skeletonlabs/skeleton';
initializeStores();
</script>
<Toast />

My application starts fine -- in fact, it works with Svelte Skeleton 1.x so long as you remove the bit about initializeStores. However, this doesn't work with Skeleton 2.x which now uses Svelte contexts. Svelte components must share a common ancestor in order to access the same context instance. Since the above component doesn't have any children, other Svelte components in my application can't access the context singleton created by it. Therefore, they complain that initializeStores has not been called.

Top-level contexts could be established via a parent LiveSvelte component with slots and/or subcomponents. However, such an approach is at odds with creating a Phoenix application that consists of dead views, live views, and LiveSvelte components.

Working with frameworks that require SvelteKit (because of top-level Svelte contexts) would be a huge win because the most interesting parts of the Svelte ecosystem are headed that way.

@woutdp
Copy link
Owner

woutdp commented Aug 17, 2023

If it's just setting the context object it's possible probably. The context right here, https://github.com/woutdp/live_svelte/blob/master/assets/js/live_svelte/hooks.js#L106-L110

Currently there's no way to do it but we can expose this, just like how it's being done with props.

@dev-guy
Copy link
Author

dev-guy commented Aug 29, 2023

At the moment, this is a minor efficiency and start-up speed issue. It could become more of a problem if my application needed a global store for application state which is how a lot of SvelteKit applications behave. This type of application can not be built with Phoenix alone, so IMO this would make LiveSvelte even more compelling for those of us who are working on offline-first apps, don't want to go whole-hog on SPA, and understand the value of Phoenix including OTP and pubsub.

@woutdp
Copy link
Owner

woutdp commented Aug 29, 2023

Ok, leaving this issue in the backlog for now. But feel free to make a PR that integrates this functionality.

@woutdp
Copy link
Owner

woutdp commented Jan 17, 2024

Closing for now as there's not progress on this

@woutdp woutdp closed this as completed Jan 17, 2024
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

2 participants