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

feat(ensureQueryData): add 'revalidateIfStale' option #6996

Merged
merged 21 commits into from
Mar 13, 2024
Merged

feat(ensureQueryData): add 'revalidateIfStale' option #6996

merged 21 commits into from
Mar 13, 2024

Conversation

andredewaard
Copy link
Contributor

add a prefetchWhenStale property to the fetchQuery function.
This allows the function to work like useQuery.

  • if data is fresh, return it immediately
  • if data is stale, return it immediately and call prefetchQuery() in the background for the next consumer
  • if there is no data in the cache (either first hit or after gcTime), await the fetch and return that

As discussed here: https://discord.com/channels/719702312431386674/1212427380912820315

Please feel free to give feedback about how to better implement this feature.

Copy link

vercel bot commented Feb 29, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
query ⬜️ Ignored (Inspect) Visit Preview Mar 13, 2024 8:23am

Copy link

codesandbox-ci bot commented Feb 29, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 90aa502:

Sandbox Source
@tanstack/query-example-angular-basic Configuration
@tanstack/query-example-react-basic-typescript Configuration
@tanstack/query-example-solid-basic-typescript Configuration
@tanstack/query-example-svelte-basic Configuration
@tanstack/query-example-vue-basic Configuration

Copy link

nx-cloud bot commented Mar 3, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 90aa502. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


✅ Successfully ran 2 targets

Sent with 💌 from NxCloud.

@TkDodo
Copy link
Collaborator

TkDodo commented Mar 3, 2024

Thanks for this. I thought about it for some time, and while I think there are ways to combine ensureQueryData / fetchQuery / prefetchQuery for a streamlined API, this would require a major version change, so I'll "defer" that decision for now.


I think the better API would be to add this option to ensureQueryData and keep fetchQuery as it is. ensureQueryData will right now:

  • always return data if it exists in the cache
  • if there is no data in the cache, it will fetch and wait for it, then return it.

what's missing is the piece in between: data exists, but is stale. I think we could just add a revalidateIfStale: boolean option here that defaults to false (current behaviour). If set to true, it would return stale data immediately, but trigger void queryClient.prefetchQuery() to make a background update to the cache for the next consumer.

Since your use-case is also router related, and we recommend using ensureQueryData in route loaders, I think this would align nicely. What do you think ?

@andredewaard
Copy link
Contributor Author

alright that also makes sense, i added it to fetchQuery so it would be more aligned with how useQuery already works and since they are both kinda the same function but useQuery is for components i thought it would be better to add there.

But ensureQueryData would be better indeed. will revert my changes and try to implement the changes.

packages/query-core/src/types.ts Show resolved Hide resolved
packages/query-core/src/queryClient.ts Outdated Show resolved Hide resolved
packages/query-core/src/queryClient.ts Outdated Show resolved Hide resolved
@TkDodo
Copy link
Collaborator

TkDodo commented Mar 4, 2024

can you also add some tests for this please ?

@andredewaard
Copy link
Contributor Author

can you also add some tests for this please ?

Will do

@andredewaard
Copy link
Contributor Author

Test added. At first the test needs to return cached data which is 'old', we wait for the promise to resolve which will let the new call return 'new'

@github-actions github-actions bot added documentation Improvements or additions to documentation package: query-core labels Mar 9, 2024
@TkDodo
Copy link
Collaborator

TkDodo commented Mar 11, 2024

please fix prettier

@TkDodo TkDodo changed the title feat(fetchQuery): add 'prefetchWhenStale' option feat(ensureQueryData): add 'prefetchWhenStale' option Mar 11, 2024
@TkDodo TkDodo changed the title feat(ensureQueryData): add 'prefetchWhenStale' option feat(ensureQueryData): add 'revalidateIfStale' option Mar 11, 2024
@TkDodo TkDodo merged commit e34bf4d into TanStack:main Mar 13, 2024
5 checks passed
@andredewaard
Copy link
Contributor Author

@TkDodo For me it seems like the build is not build properly. in queryClient.d.ts the ensureQueryData looks like

ensureQueryData<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>): Promise<TData>;
    ensureQueryData<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: MaybeRefDeep<FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>>): Promise<TData>;

where it should be

ensureQueryData<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: EnsureQueryDataOptions<TQueryFnData, TError, TData, TQueryKey>): Promise<TData>;
    ensureQueryData<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: MaybeRefDeep<EnsureQueryDataOptions<TQueryFnData, TError, TData, TQueryKey>>): Promise<TData>;

@TkDodo
Copy link
Collaborator

TkDodo commented Mar 14, 2024

@andredewaard
Copy link
Contributor Author

andredewaard commented Mar 14, 2024

its inside the vue-query plugin, not in core
https://unpkg.com/browse/@tanstack/[email protected]/build/modern/queryClient.d.ts

@TkDodo
Copy link
Collaborator

TkDodo commented Mar 14, 2024

ooh, that's because vue has it's own wrapper around the core because of this unref things, and we didn't update the types there:

ensureQueryData<
TQueryFnData,
TError = DefaultError,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
>(
options: MaybeRefDeep<
FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>
>,
): Promise<TData> {
return super.ensureQueryData(cloneDeepUnref(options))
}

can you do another PR to fix this please ?

@andredewaard
Copy link
Contributor Author

A alright, yes will do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation package: query-core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants