sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.27k stars 1.86k forks source link

Share/Inject functions and object instances in universal loaders without globals/singletons #12455

Open Rican7 opened 4 weeks ago

Rican7 commented 4 weeks ago

Describe the problem

When working with universal loaders (+page.js and +layout.js), there's (seemingly) no way to pass around functions or object instances without resorting to globals or singletons.

On the server-side, you can initialize objects in hooks.server.js and then pass them to server loaders via event.locals (which has it's own oddities of naming/documentation), but there doesn't seem to be an analogous way to pass these kinds of things in a client or universal context.

In components I can use stores/context, or just drill props, but there just doesn't seem to be a way to easily share complex or expensive to initialize objects in client/universal loaders without using globals/singletons.... which comes with all of the negatives of using globals.

Describe the proposed solution

I'd like to, generally, have a way to define a init function (or constructor?) or some way to define dependencies in loaders that isn't just importing globals.

If that's not something that is to be considered, then I'd like to at least see a way for client/universal loaders to share complex data that's similar to the server loaders capabilities.

Alternatives considered

Just using globals/singletons... but that complicates testing and comes with all of the drawbacks of globals/singletons.

Importance

would make my life easier

Additional Information

This may be similar to #6714 or #7107... but from a different functional perspective.

david-plugge commented 4 weeks ago

event.parent is the intended way of doing this, but it is a little annoying as it results in a waterfall. I proposed event.locals for shared load functions and a shared handleLoad hook some time ago. Would be awesome to get this feature for spas!

Rican7 commented 4 weeks ago

event.parent is the intended way of doing this, but it is a little annoying as it results in a waterfall.

Yea, that causes waterfalls and it has to be initiated in a top-level layout or something, which is inconsistent with the way it works with a server (using hooks).

I proposed event.locals for shared load functions and a shared handleLoad hook some time ago. Would be awesome to get this feature for spas!

Yea, honestly that would make things more consistent with how it works for the server. Which, again as I said still isn't the clearest mechanism, but at least that would be consistent. The lack of common "entry-point" or "main" for an SK app makes this all a bit confusing and hard to discover.