kit icon indicating copy to clipboard operation
kit copied to clipboard

Feature request: Partial load/invalidation

Open Hugos68 opened this issue 1 year ago • 2 comments

Describe the problem

Whenever having 2 data fetches in a load function and want to for example only invalidate the first you cannot do that, yeah you can use untrack but then you lose the automatic dependency tracking, you cannot currently manually invalidate 1 "part" of a load function.

Describe the proposed solution

The solution would be similar to how hooks in sveltekit works where you can define multiple hooks, my proposal introduces multiple load functions and being able to "sequence" them, for example:

// routes/products/+page.ts
import { multiple } from '@sveltejs/kit';

async function loadProfile({ depends, fetch }) {
  depends('foo:profile');
  const res = await fetch(...);
  const profile = await res.json();
  return { profile };
};

async function loadProducts({ depends, fetch }) {
  depends('foo:products');
  const res = await fetch(...);
  const products= await res.json();
  return { products};
};

export const load = multiple(loadProfile, loadProducts);
<!-- routes/products/+page.svelte -->
<script>
  import { invalidate } from '$app/navigation';
  export let data;
</script>

<p>{data.profile.name}</p>

{#each data.products as product}
  <p>{product.name}</p>
{/each}

<button on:click={() => invalidate('foo:profile')}>Invalidate profile</button>
<button on:click={() => invalidate('foo:products')}>Invalidate products</button>

If you return the same prop from 2 load functions that latter one takes presedence but it should probably warn you if you are returning a prop with the same name from both functions.

If function A gets invalidated it should invalidate function A and keep the current data from function B.

Alternatives considered

You could also just export any function from the +page or +page.server with some sort of special prefix but that doesn't sound very nice, for example:

export async function _loadProfile() { ... }; // This would count as a load function

export async function _loadProducts() { ... }; // This would count as a load function

export async function loadFooBar() { ... }; // This would NOT count as a load function because it doesn't have the ``_load`` prefix

Importance

would make my life easier

Additional Information

This is pretty crucial because each time you invalidate because you need to invalidate only a partial piece of the load function you are making more network requests to your backend, and although caching helps with this, you shouldn't have to be forced to rerun everything inside your load function when only a small part needs to be invalidated.

Hugos68 avatar Jan 02 '24 11:01 Hugos68

I like this multiple() syntax. Also gives me the ability to generate full load functions from my api backend to reduce boilerplate even more.

dukesteen avatar Jan 02 '24 12:01 dukesteen

This will make it so much easier. The only alternative I see is to use:enhance and do updates yourself via fetch calls for the specific parts that need to be updated from the load function.

joetifa2003 avatar Jun 08 '24 09:06 joetifa2003

Alternative solution, not sure about this: you can add another file +page.server.ts in your path folder

But it would be difficult to keep track of which one is for which purpose without naming them like +products.server.ts and +profile.server.js.

Izobov avatar Jul 12 '24 09:07 Izobov

@Izobov I don't think that makes much sense because all exports like form actions, prerender, ssr and csr are all part of a +page.server.ts

Hugos68 avatar Jul 12 '24 09:07 Hugos68