kit: invalidate: callback not called for server load, invalidate never reloads server endpoints

Describe the bug

I’m not really sure if this is intentional or a bug, but anyway:

invalidateAll correctly triggers all load functions including calling the server side equivalents (+layout.server.ts, +page.server.ts).

Accordingly, I would expect the callback passed to invalidate to be called with some URL that represents the server side load functions to selectively trigger a refetch of those resources. However, it is only called for URLs used in explicit fetch or depends calls in load functions. As a consequence, invalidate( () => true) does not behave like invalidateAll. I realize it’s not documented to behave the same, but intuitively I’d expect it to.

As a corollary, there is no URL that can be passed to invalidate (the non-callback version) that would reload the server side endpoints. The only way to trigger server side page/layout endpoints to reload is by using invalidateAll.

Reproduction

See https://stackblitz.com/edit/sveltejs-kit-template-default-zrzasd?terminal=dev

The page shows the timestamp of the data coming from different layers (server side layout load, layout load, server side page load, page load).

The button “Test invalidate” invokes invalidate and collects all URLs passed to the callback (note that the callback always returns false - we do not actually need to refresh anything for this test). The page shows the list of URLs that were passed to invalidate.

Note that the explicit dependencies “app://layout-load” and “app://page-load” show up in the list, but nothing more.

“Test invalidate with refresh” does the same but returns true from the callback. This causes the two load functions to run, but does NOT invoke the server side endpoints to be called. As a result, the server side data is missing from $page.data.

“Invalidate all” calls invalidateAll which refreshes all data as expected.

Logs

No response

System Info

(Stackblitz)
  System:
    OS: Linux 5.0 undefined
    CPU: (4) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.73 
    @sveltejs/kit: next => 1.0.0-next.481 
    svelte: ^3.46.0 => 3.50.1 
    vite: ^3.1.0 => 3.1.0

Severity

serious, but I can work around it

Additional Information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 15 (11 by maintainers)

Most upvoted comments

Filed the bug as #6929

The stackblitz in my original post does not reflect what I said in my later posts.

Here’s an example that shows different scenarios for invalidate: https://stackblitz.com/edit/sveltekit-selective-invalidation?file=src%2Froutes%2F%2Bpage.svelte

(Note that I wrote earlier that triggering a server side load would not trigger the shared/isomorphic load if both are present, but that’s not true. The shared load - if present - is always called when the server side load is called - which makes sense, because the server side data always has to pass through the shared load function and is not automatically merged into PageData.)

BTW: yes “isomorphic load” refers to +page.ts or +layout.ts whereas “server load” refers to +page.server.ts and +layout.server.ts.

BUT: I just realized that the typescript types are not complete - depends is not defined in ServerLoadEvent but is actually passed in (and works, see the stackblitz). I’ll file an issue.

This is intended behaviour. If you need to invalidate a specific load function (server or shared) you can use depends with a custom identifier. This is already documented in the depends and invalidate docs, I’m not sure that there’s more we can do?