Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cold-islands-move.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@tanstack/vue-query': minor
---

add new imperitive methods to QueryClient proxy
37 changes: 36 additions & 1 deletion packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { dataTagSymbol } from '@tanstack/query-core'
import { reactive } from 'vue-demi'
import { reactive, unref } from 'vue-demi'
import { queryKey } from '@tanstack/query-test-utils'
import { infiniteQueryOptions } from '../infiniteQueryOptions'
import { QueryClient } from '../queryClient'
Expand DownExpand Up@@ -49,6 +49,41 @@ describe('infiniteQueryOptions', () => {
InfiniteData<string, unknown> | undefined
>()
})
it('should work when passed to infiniteQuery', async () => {
const options = infiniteQueryOptions({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
})

const data = await new QueryClient().infiniteQuery({
...unref(options),
enabled: true,
staleTime: 0,
pages: 1,
})

expectTypeOf(data).toEqualTypeOf<InfiniteData<string, number>>()
})
it('should work when passed to infiniteQuery with select', async () => {
const options = infiniteQueryOptions({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
select: (data) => data.pages,
})

const data = await new QueryClient().infiniteQuery({
...unref(options),
enabled: true,
staleTime: 0,
pages: 1,
})

expectTypeOf(data).toEqualTypeOf<Array<string>>()
})
it('should tag the queryKey with the result type of the QueryFn', () => {
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
Expand Down
106 changes: 106 additions & 0 deletions packages/vue-query/src/__tests__/queryClient.test-d.ts
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { skipToken } from '@tanstack/query-core'
import { queryKey } from '@tanstack/query-test-utils'
import { QueryClient } from '../queryClient'
import type { DataTag, InfiniteData } from '@tanstack/query-core'
Expand DownExpand Up@@ -151,3 +152,108 @@ describe('fetchInfiniteQuery', () => {
])
})
})

describe('query', () => {
it('should return the selected type', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
select: (data) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken and enabled false', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
enabled: false,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})

it('should infer select type with skipToken and enabled true', () => {
const result = new QueryClient().query({
queryKey: ['key'],
queryFn: skipToken,
enabled: true,
select: (data: string) => data.length,
})

expectTypeOf(result).toEqualTypeOf<Promise<number>>()
})
})

describe('infiniteQuery', () => {
it('should return infinite data', async () => {
const data = await new QueryClient().infiniteQuery({
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
})

expectTypeOf(data).toEqualTypeOf<InfiniteData<string, number>>()
})

it('should return the selected type', () => {
const result = new QueryClient().infiniteQuery({
queryKey: ['key'],
queryFn: () => Promise.resolve({ count: 1 }),
getNextPageParam: () => 2,
initialPageParam: 1,
select: (data) => data.pages.map((page) => page.count),
})

expectTypeOf(result).toEqualTypeOf<Promise<Array<number>>>()
})

it('should allow passing pages with getNextPageParam', () => {
assertType<Parameters<QueryClient['infiniteQuery']>>([
{
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
initialPageParam: 1,
getNextPageParam: () => 1,
pages: 5,
},
])
})

it('should not allow passing pages without getNextPageParam', () => {
assertType<Parameters<QueryClient['infiniteQuery']>>([
// @ts-expect-error Property 'getNextPageParam' is missing
{
queryKey: ['key'],
queryFn: () => Promise.resolve('string'),
initialPageParam: 1,
pages: 5,
},
])
})

it('should preserve page param inference', () => {
new QueryClient().infiniteQuery({
queryKey: ['key'],
queryFn: ({ pageParam }) => {
expectTypeOf(pageParam).toEqualTypeOf<number>()
return Promise.resolve(pageParam.toString())
},
initialPageParam: 1,
getNextPageParam: () => undefined,
})
})
})
128 changes: 127 additions & 1 deletion packages/vue-query/src/__tests__/queryClient.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue-demi'
import { ref, unref } from 'vue-demi'
import { QueryClient as QueryClientOrigin } from '@tanstack/query-core'
import { QueryClient } from '../queryClient'
import { infiniteQueryOptions } from '../infiniteQueryOptions'
import { queryOptions } from '../queryOptions'

vi.mock('@tanstack/query-core', async () => {
const actual = await vi.importActual<{
Expand DownExpand Up@@ -340,6 +341,57 @@ describe('QueryCache', () => {
})
})

describe('query', () => {
it('should properly unwrap queryKey', () => {
const queryClient = new QueryClient()

queryClient.query({
queryKey: queryKeyRef,
})

expect(QueryClientOrigin.prototype.query).toBeCalledWith({
queryKey: queryKeyUnref,
})
})

it('should properly unwrap enabled, staleTime, and select', () => {
const queryClient = new QueryClient()
const enabled = () => false
const staleTime = () => 1000
const select = (data: string) => data.length

queryClient.query({
queryKey: queryKeyRef,
enabled: ref(enabled),
staleTime: ref(staleTime),
select: ref(select),
})

expect(QueryClientOrigin.prototype.query).toBeCalledWith({
queryKey: queryKeyUnref,
enabled,
staleTime,
select,
})
})

it('should properly unwrap queryOptions getter', () => {
const queryClient = new QueryClient()

const options = queryOptions(() => ({
queryKey: queryKeyRef,
queryFn: fn,
}))

queryClient.query(options)

expect(QueryClientOrigin.prototype.query).toBeCalledWith({
queryKey: queryKeyUnref,
queryFn: fn,
})
})
})

describe('prefetchQuery', () => {
it('should properly unwrap parameters', () => {
const queryClient = new QueryClient()
Expand DownExpand Up@@ -393,6 +445,80 @@ describe('QueryCache', () => {
})
})

describe('infiniteQuery', () => {
it('should properly unwrap queryKey, initialPageParam, pages, and select', () => {
const queryClient = new QueryClient()
const getNextPageParam = () => 1
const select = (data: { pages: Array<string> }) => data.pages.length

queryClient.infiniteQuery({
queryKey: queryKeyRef,
initialPageParam: ref(0),
pages: ref(2),
getNextPageParam: ref(getNextPageParam),
select: ref(select),
})

expect(QueryClientOrigin.prototype.infiniteQuery).toBeCalledWith(
expect.objectContaining({
queryKey: queryKeyUnref,
initialPageParam: 0,
pages: 2,
getNextPageParam,
select,
}),
)
})

it('should properly unwrap getNextPageParam when using infiniteQueryOptions', () => {
const queryClient = new QueryClient()
const getNextPageParam = () => 12

const options = infiniteQueryOptions({
queryKey: queryKeyRef,
initialPageParam: ref(0),
getNextPageParam: ref(getNextPageParam),
})

queryClient.infiniteQuery({
...unref(options),
enabled: true,
staleTime: 0,
pages: 1,
})

expect(QueryClientOrigin.prototype.infiniteQuery).toBeCalledWith(
expect.objectContaining({
queryKey: queryKeyUnref,
initialPageParam: 0,
pages: 1,
getNextPageParam,
}),
)
})

it('should properly unwrap options getter', () => {
const queryClient = new QueryClient()
const getNextPageParam = () => 12

queryClient.infiniteQuery(() => ({
queryKey: queryKeyRef,
initialPageParam: ref(0),
pages: ref(1),
getNextPageParam: ref(getNextPageParam),
}))

expect(QueryClientOrigin.prototype.infiniteQuery).toBeCalledWith(
expect.objectContaining({
queryKey: queryKeyUnref,
initialPageParam: 0,
pages: 1,
getNextPageParam,
}),
)
})
})

describe('prefetchInfiniteQuery', () => {
it('should properly unwrap parameters', () => {
const queryClient = new QueryClient()
Expand Down
24 changes: 23 additions & 1 deletion packages/vue-query/src/__tests__/queryOptions.test-d.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,25 @@ describe('queryOptions', () => {
const { data } = reactive(useQuery(options))
expectTypeOf(data).toEqualTypeOf<number | undefined>()
})
it('should work when passed to query', async () => {
const options = queryOptions({
queryKey: ['key'],
queryFn: () => Promise.resolve(5),
})

const data = await new QueryClient().query(options)
expectTypeOf(data).toEqualTypeOf<number>()
})
it('should work when passed to query with select', async () => {
const options = queryOptions({
queryKey: ['key'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
})

const data = await new QueryClient().query(options)
expectTypeOf(data).toEqualTypeOf<string>()
})
it('should tag the queryKey with the result type of the QueryFn', () => {
const key = queryKey()
const { queryKey: tagged } = queryOptions({
Expand DownExpand Up@@ -132,10 +151,13 @@ describe('queryOptions', () => {
// Should not error
const data = queryClient.invalidateQueries(options)
// Should not error
const data2 = queryClient.fetchQuery(options)
const data2 = queryClient.query(options)
// Should not error
const data3 = queryClient.fetchQuery(options)

expectTypeOf(data).toEqualTypeOf<Promise<void>>()
expectTypeOf(data2).toEqualTypeOf<Promise<number>>()
expectTypeOf(data3).toEqualTypeOf<Promise<number>>()
})

it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
Expand Down
Loading