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

Add examples for initializing fetchers and mutators with initial data #8

Open
Todomir opened this issue May 9, 2023 · 4 comments
Open

Comments

@Todomir
Copy link

Todomir commented May 9, 2023

It is a very common pattern to load initial data on the server, pass it to the cache and then have the client take over from there, but I don’t see any example or options for this pattern anywhere. Is it currently possible? If not, is it on the roadmap?

Examples:

@dkzlv
Copy link
Member

dkzlv commented May 25, 2023

We explore a more robust way to implement SSR throughout the whole entirety of nanostores. You can track it in this issue in the core repo.

An honest answer would be that currently we don't really support SSR it in any meaningful way. If you really want to explore this before we finish the work in the upstream libs, you can try to go that way:

  1. provide any nanoquery context a custom cache backend (basically, a new Map())
  2. start rendering the app
  3. wait till allTasks() resolves
  4. serialize the cache, put it into DOM
  5. write a function that will get the cache from the DOM if it's present during module initialization; if not—fall back to new Map() once again.

Nanoquery won't refetch stuff that was fetched on the backend.

@tatarianBarbarian
Copy link

tatarianBarbarian commented Jul 24, 2023

I have a similar case, but my React application is not rendered on the server.
But the server provides some initial data in JSON format right in HTML.

Do I understand correctly that it will be enough to do something like this?

const serializedState = document.querySelector('script[data-state-from-server]')
const deserializedState = JSON.parse(serializedState.textContent)
const cacheKeys = ['key1', 'key2', 'key3']
const initialCache = new Map()

initialCache.set(cacheKeys, deserializedState)

const cache = nanoquery({
  cache: initialCache,
  ...
})

@dkzlv
Copy link
Member

dkzlv commented Jul 24, 2023

@tatarianBarbarian Yeaaah, no, I'm afraid that won't work.

Here's an SB project with a demo. I wrote it for issue #15, but the takeaways are the same, since it doesn't really matter what's the source of "reviving" the cache: it can be SSR, it can be LS, it doesn't matter.

So your idea will work in a sense that it will show the correct initial state, but unfortunately it will refetch everything on mount. The reason is rather simple: everything related to deduplication and cache TTL is stored outside of nanostores right now, and it cannot be received or set from the outside. If it's crucial for your project to avoid refetches, I can come up with some design to allow setting meta (most notably, _lastFetch map) from the outside.

@tatarianBarbarian
Copy link

@tatarianBarbarian Yeaaah, no, I'm afraid that won't work.

Here's an SB project with a demo. I wrote it for issue #15, but the takeaways are the same, since it doesn't really matter what's the source of "reviving" the cache: it can be SSR, it can be LS, it doesn't matter.

So your idea will work in a sense that it will show the correct initial state, but unfortunately it will refetch everything on mount. The reason is rather simple: everything related to deduplication and cache TTL is stored outside of nanostores right now, and it cannot be received or set from the outside. If it's crucial for your project to avoid refetches, I can come up with some design to allow setting meta (most notably, _lastFetch map) from the outside.

Sounds valid to me. Feels like there is no need to fetch data that is already there.
It can also save some server time on larger projects.
(but we'll need some docs on how to use it 😅)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants