From 6403d554d7fc17c7cf7998e1a938c76e37a43f0c Mon Sep 17 00:00:00 2001 From: Matt Sutkowski Date: Sat, 15 Jan 2022 12:39:11 -0800 Subject: [PATCH 1/4] Pass baseQueryMeta into calculateProvidedBy --- .../toolkit/src/query/core/buildThunks.ts | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/toolkit/src/query/core/buildThunks.ts b/packages/toolkit/src/query/core/buildThunks.ts index 58496877aa..19e2ed6ec8 100644 --- a/packages/toolkit/src/query/core/buildThunks.ts +++ b/packages/toolkit/src/query/core/buildThunks.ts @@ -5,9 +5,8 @@ import type { BaseQueryError, QueryReturnValue, } from '../baseQueryTypes' -import { BaseQueryArg } from '../baseQueryTypes' import type { RootState, QueryKeys, QuerySubstateIdentifier } from './apiState' -import { QueryStatus, CombinedState } from './apiState' +import { QueryStatus } from './apiState' import type { StartQueryActionCreatorOptions } from './buildInitiate' import type { AssertTagTypes, @@ -18,10 +17,11 @@ import type { QueryDefinition, ResultTypeFrom, } from '../endpointDefinitions' -import { calculateProvidedBy, FullTagDescription } from '../endpointDefinitions' +import { calculateProvidedBy } from '../endpointDefinitions' import type { AsyncThunkPayloadCreator, Draft } from '@reduxjs/toolkit' import { isAllOf, + isAnyOf, isFulfilled, isPending, isRejected, @@ -500,20 +500,30 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".` } } +type CalculatableAction = UnwrapPromise< + ReturnType> | ReturnType> +> export function calculateProvidedByThunk( - action: UnwrapPromise< - ReturnType> | ReturnType> - >, + action: CalculatableAction, type: 'providesTags' | 'invalidatesTags', endpointDefinitions: EndpointDefinitions, assertTagType: AssertTagTypes ) { + const isQuery = (action: CalculatableAction) => + action.meta.arg.type === 'query' + const isFulfilledQuery = (action: any): action is QueryThunk => + isQuery(action) + const isFulfilledMutation = (action: any): action is MutationThunk => + !isQuery(action) + return calculateProvidedBy( endpointDefinitions[action.meta.arg.endpointName][type], isFulfilled(action) ? action.payload : undefined, isRejectedWithValue(action) ? action.payload : undefined, action.meta.arg.originalArgs, - action.meta, + isAnyOf(isRejected, isFulfilledQuery, isFulfilledMutation)(action) + ? action.meta.baseQueryMeta + : undefined, assertTagType ) } From c4a859b56d70bd59db1fda4631554b4f6deb3186 Mon Sep 17 00:00:00 2001 From: Matt Sutkowski Date: Sat, 15 Jan 2022 19:03:50 -0800 Subject: [PATCH 2/4] Assert that baseQueryMeta is available for invalidation mechanisms --- .../toolkit/src/query/tests/createApi.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/toolkit/src/query/tests/createApi.test.ts b/packages/toolkit/src/query/tests/createApi.test.ts index 90c9acb772..a7c1fbbcb8 100644 --- a/packages/toolkit/src/query/tests/createApi.test.ts +++ b/packages/toolkit/src/query/tests/createApi.test.ts @@ -5,6 +5,8 @@ import type { QueryDefinition, } from '@reduxjs/toolkit/query' import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query' +import type { FetchBaseQueryMeta } from '@reduxjs/toolkit/dist/query/fetchBaseQuery' + import { ANY, expectType, @@ -722,3 +724,42 @@ describe('query endpoint lifecycles - onStart, onSuccess, onError', () => { expect(storeRef.store.getState().testReducer.count).toBe(1) }) }) + +test('providesTags and invalidatesTags can use baseQueryMeta', async () => { + let _meta: FetchBaseQueryMeta | undefined + + type SuccessResponse = { value: 'success' } + + const api = createApi({ + baseQuery: fetchBaseQuery({ baseUrl: 'http://example.com' }), + tagTypes: ['success'], + endpoints: (build) => ({ + query: build.query({ + query: () => '/success', + providesTags: (_result, _error, _arg, meta) => { + _meta = meta + return ['success'] + }, + }), + mutation: build.mutation({ + query: () => ({ url: '/success', method: 'POST' }), + invalidatesTags: (_result, _error, _arg, meta) => { + _meta = meta + return ['success'] + }, + }), + }), + }) + + const storeRef = setupApiStore(api) + + await storeRef.store.dispatch(api.endpoints.query.initiate()) + + expect('request' in _meta! && 'response' in _meta!).toBe(true) + + _meta = undefined + + await storeRef.store.dispatch(api.endpoints.mutation.initiate()) + + expect('request' in _meta! && 'response' in _meta!).toBe(true) +}) From 20245730415d2b3affdc59b929873009c01b82d9 Mon Sep 17 00:00:00 2001 From: Lenz Weber Date: Fri, 21 Jan 2022 11:42:15 +0100 Subject: [PATCH 3/4] simplify type guards --- packages/toolkit/src/query/core/buildThunks.ts | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/toolkit/src/query/core/buildThunks.ts b/packages/toolkit/src/query/core/buildThunks.ts index 19e2ed6ec8..0c505bc322 100644 --- a/packages/toolkit/src/query/core/buildThunks.ts +++ b/packages/toolkit/src/query/core/buildThunks.ts @@ -500,30 +500,20 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".` } } -type CalculatableAction = UnwrapPromise< - ReturnType> | ReturnType> -> export function calculateProvidedByThunk( - action: CalculatableAction, + action: UnwrapPromise< + ReturnType> | ReturnType> + >, type: 'providesTags' | 'invalidatesTags', endpointDefinitions: EndpointDefinitions, assertTagType: AssertTagTypes ) { - const isQuery = (action: CalculatableAction) => - action.meta.arg.type === 'query' - const isFulfilledQuery = (action: any): action is QueryThunk => - isQuery(action) - const isFulfilledMutation = (action: any): action is MutationThunk => - !isQuery(action) - return calculateProvidedBy( endpointDefinitions[action.meta.arg.endpointName][type], isFulfilled(action) ? action.payload : undefined, isRejectedWithValue(action) ? action.payload : undefined, action.meta.arg.originalArgs, - isAnyOf(isRejected, isFulfilledQuery, isFulfilledMutation)(action) - ? action.meta.baseQueryMeta - : undefined, + 'baseQueryMeta' in action.meta ? action.meta.baseQueryMeta : undefined, assertTagType ) } From 8a94e0536cc4c67938b272576025fe223855e6c8 Mon Sep 17 00:00:00 2001 From: Lenz Weber Date: Fri, 21 Jan 2022 11:45:07 +0100 Subject: [PATCH 4/4] remove unused import --- packages/toolkit/src/query/core/buildThunks.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/toolkit/src/query/core/buildThunks.ts b/packages/toolkit/src/query/core/buildThunks.ts index 0c505bc322..04f6e06ce9 100644 --- a/packages/toolkit/src/query/core/buildThunks.ts +++ b/packages/toolkit/src/query/core/buildThunks.ts @@ -21,7 +21,6 @@ import { calculateProvidedBy } from '../endpointDefinitions' import type { AsyncThunkPayloadCreator, Draft } from '@reduxjs/toolkit' import { isAllOf, - isAnyOf, isFulfilled, isPending, isRejected,