From 28ba45a994ba60798f3ce6760b9eb09cbadfe0cb Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Thu, 13 Jul 2023 15:10:31 +0800 Subject: [PATCH 1/5] feat: support invoke in vue `runWithContext()` --- packages/vue-query/src/useQueryClient.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vue-query/src/useQueryClient.ts b/packages/vue-query/src/useQueryClient.ts index 4662d1b12d..f4562f6da8 100644 --- a/packages/vue-query/src/useQueryClient.ts +++ b/packages/vue-query/src/useQueryClient.ts @@ -4,16 +4,16 @@ import type { QueryClient } from './queryClient' import { getClientKey } from './utils' export function useQueryClient(id = ''): QueryClient { - const vm = getCurrentInstance()?.proxy - - if (!vm) { - throw new Error('vue-query hooks can only be used inside setup() function.') - } - const key = getClientKey(id) const queryClient = inject(key) if (!queryClient) { + const vm = getCurrentInstance()?.proxy + + if (!vm) { + throw new Error('vue-query hooks can only be used inside setup() function.') + } + throw new Error( "No 'queryClient' found in Vue context, use 'VueQueryPlugin' to properly initialize the library.", ) From 0f8263bfff5c0f3b0f78f02bda868c5ec2e4b2c3 Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Thu, 13 Jul 2023 15:38:19 +0800 Subject: [PATCH 2/5] chore: run prettier --- packages/vue-query/src/useQueryClient.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vue-query/src/useQueryClient.ts b/packages/vue-query/src/useQueryClient.ts index f4562f6da8..7440c4fccc 100644 --- a/packages/vue-query/src/useQueryClient.ts +++ b/packages/vue-query/src/useQueryClient.ts @@ -11,7 +11,9 @@ export function useQueryClient(id = ''): QueryClient { const vm = getCurrentInstance()?.proxy if (!vm) { - throw new Error('vue-query hooks can only be used inside setup() function.') + throw new Error( + 'vue-query hooks can only be used inside setup() function.', + ) } throw new Error( From 75ba2c82217a6a25f713220c725304e01a57ed9b Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Mon, 21 Aug 2023 18:44:11 +0800 Subject: [PATCH 3/5] feat(vue-qury): add a second parameter to inject to avoid vue warning --- packages/vue-query/src/useQueryClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vue-query/src/useQueryClient.ts b/packages/vue-query/src/useQueryClient.ts index 7440c4fccc..2776182379 100644 --- a/packages/vue-query/src/useQueryClient.ts +++ b/packages/vue-query/src/useQueryClient.ts @@ -5,7 +5,7 @@ import { getClientKey } from './utils' export function useQueryClient(id = ''): QueryClient { const key = getClientKey(id) - const queryClient = inject(key) + const queryClient = inject(key, null) if (!queryClient) { const vm = getCurrentInstance()?.proxy From 479e146df176fc8ca44df3ad2dff6c3c1b26e455 Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Mon, 21 Aug 2023 19:09:14 +0800 Subject: [PATCH 4/5] test: update test --- packages/vue-query/src/__tests__/useQueryClient.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vue-query/src/__tests__/useQueryClient.test.ts b/packages/vue-query/src/__tests__/useQueryClient.test.ts index 27861adf0e..becde82cc4 100644 --- a/packages/vue-query/src/__tests__/useQueryClient.test.ts +++ b/packages/vue-query/src/__tests__/useQueryClient.test.ts @@ -18,7 +18,7 @@ describe('useQueryClient', () => { expect(queryClient).toStrictEqual(queryClientMock) expect(injectSpy).toHaveBeenCalledTimes(1) - expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT) + expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT, null) }) test('should throw an error when queryClient does not exist in the context', () => { @@ -26,7 +26,7 @@ describe('useQueryClient', () => { expect(useQueryClient).toThrowError() expect(injectSpy).toHaveBeenCalledTimes(1) - expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT) + expect(injectSpy).toHaveBeenCalledWith(VUE_QUERY_CLIENT, null) }) test('should throw an error when used outside of setup function', () => { @@ -44,6 +44,6 @@ describe('useQueryClient', () => { useQueryClient(queryClientKey) - expect(injectSpy).toHaveBeenCalledWith(expectedKeyParameter) + expect(injectSpy).toHaveBeenCalledWith(expectedKeyParameter, null) }) }) From f67e7960429bd507694c22851dee761111c83d93 Mon Sep 17 00:00:00 2001 From: Damian Osipiuk Date: Wed, 23 Aug 2023 09:10:03 +0200 Subject: [PATCH 5/5] fix: add warning about potential memory leak --- packages/vue-query/src/useBaseQuery.ts | 9 +++++++++ packages/vue-query/src/useIsFetching.ts | 17 ++++++++++++++++- packages/vue-query/src/useIsMutating.ts | 17 ++++++++++++++++- packages/vue-query/src/useMutation.ts | 9 +++++++++ packages/vue-query/src/useQueries.ts | 17 ++++++++++++++++- 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/packages/vue-query/src/useBaseQuery.ts b/packages/vue-query/src/useBaseQuery.ts index 7dea6e351c..ecafa426c4 100644 --- a/packages/vue-query/src/useBaseQuery.ts +++ b/packages/vue-query/src/useBaseQuery.ts @@ -1,5 +1,6 @@ import { computed, + getCurrentScope, onScopeDispose, reactive, readonly, @@ -58,6 +59,14 @@ export function useBaseQuery< | UseQueryOptionsGeneric = {}, arg3: UseQueryOptionsGeneric = {}, ): UseQueryReturnType { + if (process.env.NODE_ENV === 'development') { + if (!getCurrentScope()) { + console.warn( + 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.', + ) + } + } + const options = computed(() => parseQueryArgs(arg1, arg2, arg3)) const queryClient = diff --git a/packages/vue-query/src/useIsFetching.ts b/packages/vue-query/src/useIsFetching.ts index 4a09f5b6fe..1e4c4c3bf5 100644 --- a/packages/vue-query/src/useIsFetching.ts +++ b/packages/vue-query/src/useIsFetching.ts @@ -1,4 +1,11 @@ -import { computed, onScopeDispose, ref, unref, watch } from 'vue-demi' +import { + computed, + getCurrentScope, + onScopeDispose, + ref, + unref, + watch, +} from 'vue-demi' import { useQueryClient } from './useQueryClient' import { cloneDeepUnref, isQueryKey } from './utils' import type { Ref } from 'vue-demi' @@ -17,6 +24,14 @@ export function useIsFetching( arg1?: MaybeRef | QueryFilters, arg2?: Omit, ): Ref { + if (process.env.NODE_ENV === 'development') { + if (!getCurrentScope()) { + console.warn( + 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.', + ) + } + } + const filters = computed(() => parseFilterArgs(arg1, arg2)) const queryClient = filters.value.queryClient ?? useQueryClient(filters.value.queryClientKey) diff --git a/packages/vue-query/src/useIsMutating.ts b/packages/vue-query/src/useIsMutating.ts index 3a25c092ec..9e42ec3954 100644 --- a/packages/vue-query/src/useIsMutating.ts +++ b/packages/vue-query/src/useIsMutating.ts @@ -1,4 +1,11 @@ -import { computed, onScopeDispose, ref, unref, watch } from 'vue-demi' +import { + computed, + getCurrentScope, + onScopeDispose, + ref, + unref, + watch, +} from 'vue-demi' import { useQueryClient } from './useQueryClient' import { cloneDeepUnref, isQueryKey } from './utils' import type { Ref } from 'vue-demi' @@ -17,6 +24,14 @@ export function useIsMutating( arg1?: MaybeRef | MutationFilters, arg2?: Omit, ): Ref { + if (process.env.NODE_ENV === 'development') { + if (!getCurrentScope()) { + console.warn( + 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.', + ) + } + } + const filters = computed(() => parseFilterArgs(arg1, arg2)) const queryClient = filters.value.queryClient ?? useQueryClient(filters.value.queryClientKey) diff --git a/packages/vue-query/src/useMutation.ts b/packages/vue-query/src/useMutation.ts index 97805b5a65..5e75dc1d0d 100644 --- a/packages/vue-query/src/useMutation.ts +++ b/packages/vue-query/src/useMutation.ts @@ -1,5 +1,6 @@ import { computed, + getCurrentScope, onScopeDispose, reactive, readonly, @@ -148,6 +149,14 @@ export function useMutation< VueMutationObserverOptions >, ): UseMutationReturnType { + if (process.env.NODE_ENV === 'development') { + if (!getCurrentScope()) { + console.warn( + 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.', + ) + } + } + const options = computed(() => { return parseMutationArgs(arg1, arg2, arg3) }) diff --git a/packages/vue-query/src/useQueries.ts b/packages/vue-query/src/useQueries.ts index b6af074d19..50e47dbc1a 100644 --- a/packages/vue-query/src/useQueries.ts +++ b/packages/vue-query/src/useQueries.ts @@ -1,6 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { QueriesObserver } from '@tanstack/query-core' -import { computed, onScopeDispose, reactive, readonly, watch } from 'vue-demi' +import { + computed, + getCurrentScope, + onScopeDispose, + reactive, + readonly, + watch, +} from 'vue-demi' import { useQueryClient } from './useQueryClient' import { cloneDeepUnref } from './utils' import type { Ref } from 'vue-demi' @@ -133,6 +140,14 @@ export function useQueries({ queries: Ref> | UseQueriesOptionsArg queryClient?: QueryClient }): Readonly> { + if (process.env.NODE_ENV === 'development') { + if (!getCurrentScope()) { + console.warn( + 'vue-query composables like "uesQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.', + ) + } + } + const unreffedQueries = computed( () => cloneDeepUnref(queries) as UseQueriesOptionsArg, )