Skip to content

Commit 17b55ef

Browse files
Handle api.provided state changes in RTKQ 2.6.2 (#1848)
* Handle api.provided state changes in RTKQ 2.6.2 * Create little-melons-grow.md --------- Co-authored-by: Nathan Bierema <[email protected]>
1 parent 73a01cc commit 17b55ef

File tree

4 files changed

+64
-10
lines changed

4 files changed

+64
-10
lines changed

.changeset/little-melons-grow.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@redux-devtools/rtk-query-monitor': minor
3+
---
4+
5+
Handle api.provided state changes in RTKQ 2.6.2

packages/redux-devtools-rtk-query-monitor/src/selectors.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import {
66
RtkQueryApiState,
77
RtkQueryTag,
88
SelectorsSource,
9-
RtkQueryProvided,
9+
RtkQueryProvidedTagsState,
1010
QueryPreviewTabs,
1111
RtkResourceInfo,
12+
RtkQuery262ProvidedState,
1213
} from './types';
1314
import { Comparator, queryComparators } from './utils/comparators';
1415
import { FilterList, queryListFilters } from './utils/filters';
@@ -216,7 +217,7 @@ export function createInspectorSelectors<S>(): InspectorSelectors<S> {
216217

217218
const selectProvidedOfCurrentQuery: InspectorSelector<
218219
S,
219-
null | RtkQueryProvided
220+
null | RtkQueryProvidedTagsState | RtkQuery262ProvidedState
220221
> = (selectorsSource: SelectorsSource<S>) => {
221222
return selectApiOfCurrentQuery(selectorsSource)?.provided ?? null;
222223
};

packages/redux-devtools-rtk-query-monitor/src/types.ts

+36-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import type { LiftedAction, LiftedState } from '@redux-devtools/core';
2-
import type { createApi, QueryStatus } from '@reduxjs/toolkit/query';
2+
import type {
3+
createApi,
4+
QueryCacheKey,
5+
QueryStatus,
6+
} from '@reduxjs/toolkit/query';
37
import type { Action, AnyAction, Dispatch } from '@reduxjs/toolkit';
48
import type { ComponentType } from 'react';
59
import { base16Themes } from 'react-base16-styling';
@@ -52,7 +56,37 @@ export type RtkMutationState = NonNullable<
5256

5357
export type RtkQueryApiConfig = RtkQueryApiState['config'];
5458

55-
export type RtkQueryProvided = RtkQueryApiState['provided'];
59+
export type FullTagDescription<TagType> = {
60+
type: TagType;
61+
id?: number | string;
62+
};
63+
64+
// This is the actual tags structure, and was the entire `api.provided`
65+
// field up through 2.6.1
66+
export type RtkQueryProvidedTagsState = {
67+
[x: string]: {
68+
[id: string]: QueryCacheKey[];
69+
[id: number]: QueryCacheKey[];
70+
};
71+
};
72+
73+
// As of 2.6.2, the `api.provided` field is split into `tags` and `keys` fields,
74+
// with the old data nested in `tags`.
75+
export type RtkQuery262ProvidedState = {
76+
keys: Record<QueryCacheKey, FullTagDescription<any>[]>;
77+
tags: RtkQueryProvidedTagsState;
78+
};
79+
80+
export function isRtkQuery262Provided(
81+
provided: Record<string, unknown>,
82+
): provided is RtkQuery262ProvidedState {
83+
return (
84+
'tags' in provided &&
85+
'keys' in provided &&
86+
typeof provided.tags === 'object' &&
87+
typeof provided.keys === 'object'
88+
);
89+
}
5690

5791
export interface ExternalProps<S, A extends Action<string>> {
5892
dispatch: Dispatch<Action | LiftedAction<S, A, RtkQueryMonitorState>>;

packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Action, AnyAction, isAllOf, isPlainObject } from '@reduxjs/toolkit';
2-
import { QueryStatus } from '@reduxjs/toolkit/query';
2+
import { QueryCacheKey, QueryStatus } from '@reduxjs/toolkit/query';
33
import {
44
QueryInfo,
55
RtkQueryMonitorState,
@@ -11,14 +11,16 @@ import {
1111
MutationInfo,
1212
ApiStats,
1313
QueryTally,
14-
RtkQueryProvided,
14+
RtkQueryProvidedTagsState,
15+
RtkQuery262ProvidedState,
1516
ApiTimings,
1617
QueryTimings,
1718
SelectorsSource,
1819
RtkMutationState,
1920
RtkResourceInfo,
2021
RtkRequest,
2122
RtkRequestTiming,
23+
isRtkQuery262Provided,
2224
} from '../types';
2325
import { missingTagId } from '../monitor-config';
2426
import { Comparator, compareJSONPrimitive } from './comparators';
@@ -529,24 +531,36 @@ export function getProvidedOf(
529531

530532
export function getQueryTagsOf(
531533
resInfo: RtkResourceInfo | null,
532-
provided: RtkQueryProvided | null,
534+
provided: RtkQueryProvidedTagsState | RtkQuery262ProvidedState | null,
533535
): RtkQueryTag[] {
534536
if (!resInfo || resInfo.type === 'mutation' || !provided) {
535537
return emptyArray;
536538
}
537539

538-
const tagTypes = Object.keys(provided);
540+
// Handle `api.provided` schema change with RTK Query tag handling.
541+
// Originally, `api.provided` was a `Record<string, Record<string, string[]>>`,
542+
// directly containing the tag names.
543+
// With https://github.com/reduxjs/redux-toolkit/pull/4910 , that changes to
544+
// change the top level to be `{tags, keys}`, with `tags` containing the tag names.
545+
// Handle the newer structure by extracting the right field if it exists.
546+
const actualProvided: RtkQueryProvidedTagsState = isRtkQuery262Provided(
547+
provided,
548+
)
549+
? provided.tags
550+
: provided;
551+
552+
const tagTypes = Object.keys(actualProvided);
539553

540554
if (tagTypes.length < 1) {
541555
return emptyArray;
542556
}
543557

544558
const output: RtkQueryTag[] = [];
545559

546-
for (const [type, tagIds] of Object.entries(provided)) {
560+
for (const [type, tagIds] of Object.entries(actualProvided)) {
547561
if (tagIds) {
548562
for (const [id, queryKeys] of Object.entries(tagIds)) {
549-
if ((queryKeys as unknown[]).includes(resInfo.queryKey)) {
563+
if (queryKeys.includes(resInfo.queryKey as QueryCacheKey)) {
550564
const tag: RtkQueryTag = { type };
551565

552566
if (id !== missingTagId) {

0 commit comments

Comments
 (0)