snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
autofix.ci / autofix (push) Failing after 4s
Release / Release (push) Has been skipped
GitHub Actions Security Analysis / Run zizmor (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-16 01:13:08 +05:00
commit 3a013ccdfe
3570 changed files with 490194 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
{
"ignoreRules": ["no-resolution"]
}

View File

@@ -0,0 +1,380 @@
# @tanstack/react-query-devtools
## 5.102.8
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.8
- @tanstack/react-query@5.102.8
## 5.102.7
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.7
- @tanstack/react-query@5.102.7
## 5.102.6
### Patch Changes
- Updated dependencies [[`ac2b612`](https://github.com/TanStack/query/commit/ac2b61230ea35b90b177ba35dc030598bac9c9a6)]:
- @tanstack/react-query@5.102.6
- @tanstack/query-devtools@5.102.6
## 5.102.5
### Patch Changes
- Updated dependencies [[`ef1eff1`](https://github.com/TanStack/query/commit/ef1eff1b62a657d6ff6f2af819c1cb8b73ad2af5)]:
- @tanstack/query-devtools@5.102.5
- @tanstack/react-query@5.102.5
## 5.102.4
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.4
- @tanstack/react-query@5.102.4
## 5.102.3
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.3
- @tanstack/react-query@5.102.3
## 5.102.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.2
- @tanstack/react-query@5.102.2
## 5.102.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.102.1
- @tanstack/react-query@5.102.1
## 5.102.0
### Patch Changes
- Updated dependencies [[`37127db`](https://github.com/TanStack/query/commit/37127dbe479a4892dbbe28ac8ceabf8832b5f1a3), [`6e3d521`](https://github.com/TanStack/query/commit/6e3d521fe54f78624e53c1c6f9cadd678504bee8), [`294d4e6`](https://github.com/TanStack/query/commit/294d4e62c4f7d674574a4903eef2a1bc3dd1413b), [`cb6c9d3`](https://github.com/TanStack/query/commit/cb6c9d3725db0fed94fb5133820e41b7c326d2ef), [`2215bb0`](https://github.com/TanStack/query/commit/2215bb031139cdc8a84751b37a485c38ca9d2b6e), [`1ef4208`](https://github.com/TanStack/query/commit/1ef42087c9a266c2137d2ef645cbcc662f60ac93), [`fb6c3fa`](https://github.com/TanStack/query/commit/fb6c3fabda4cb6b291cccc6651ed88a7db901915), [`8834267`](https://github.com/TanStack/query/commit/88342670eca6e4949416aab832b1f81cc7b881f8), [`b866a95`](https://github.com/TanStack/query/commit/b866a95adde7e8465462526df5870ebc12340b36), [`e546d03`](https://github.com/TanStack/query/commit/e546d03bef116c66a05dbf42ccfd70b6d8600a8f), [`e674826`](https://github.com/TanStack/query/commit/e6748265c86294704f6c872e6f435d9ec5a92b28)]:
- @tanstack/react-query@5.102.0
- @tanstack/query-devtools@5.102.0
## 5.101.4
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.101.4
- @tanstack/react-query@5.101.4
## 5.101.3
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.101.3
- @tanstack/react-query@5.101.3
## 5.101.2
### Patch Changes
- Updated dependencies [[`f5bf180`](https://github.com/TanStack/query/commit/f5bf180d933d8b8d9d9e7b845e55b26a3a413b07), [`25cdd97`](https://github.com/TanStack/query/commit/25cdd975fed4703d2ca5b600ca5ccd2b600b3dd8), [`ecd89c8`](https://github.com/TanStack/query/commit/ecd89c8faf7acc226f00633ea3a761d3ab842c1d), [`01c7634`](https://github.com/TanStack/query/commit/01c763444e3cf3dfa9744f13911aa1533cac3c29), [`49012db`](https://github.com/TanStack/query/commit/49012dbd5192dfe483d3b108b72ffaa7f2849e0f)]:
- @tanstack/query-devtools@5.101.2
- @tanstack/react-query@5.101.2
## 5.101.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.101.1
- @tanstack/react-query@5.101.1
## 5.101.0
### Patch Changes
- Updated dependencies [[`3042860`](https://github.com/TanStack/query/commit/3042860e3c8731c94ca4dec0e277e415d0484fce), [`e631dc3`](https://github.com/TanStack/query/commit/e631dc3fa17bff71f413246b7a770a730016d346)]:
- @tanstack/query-devtools@5.101.0
- @tanstack/react-query@5.101.0
## 5.100.14
### Patch Changes
- Updated dependencies [[`ed20b6d`](https://github.com/TanStack/query/commit/ed20b6d7541c908033acfcad92b0cd112930d1c3)]:
- @tanstack/react-query@5.100.14
- @tanstack/query-devtools@5.100.14
## 5.100.13
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.13
- @tanstack/react-query@5.100.13
## 5.100.12
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.12
- @tanstack/react-query@5.100.12
## 5.100.11
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.11
- @tanstack/react-query@5.100.11
## 5.100.10
### Patch Changes
- Updated dependencies [[`4d130b9`](https://github.com/TanStack/query/commit/4d130b992d2ac396d75f921bfc530dd3a9d50577)]:
- @tanstack/query-devtools@5.100.10
- @tanstack/react-query@5.100.10
## 5.100.9
### Patch Changes
- Updated dependencies [[`3d21cac`](https://github.com/TanStack/query/commit/3d21cacdec3028b700c4c2e3e0ff8dbe7a235e8c)]:
- @tanstack/query-devtools@5.100.9
- @tanstack/react-query@5.100.9
## 5.100.8
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.8
- @tanstack/react-query@5.100.8
## 5.100.7
### Patch Changes
- docs(devtools): align logo, panel, and 'buttonPosition' union descriptions across docs and JSDoc ([#10617](https://github.com/TanStack/query/pull/10617))
- Updated dependencies []:
- @tanstack/query-devtools@5.100.7
- @tanstack/react-query@5.100.7
## 5.100.6
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.6
- @tanstack/react-query@5.100.6
## 5.100.5
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.5
- @tanstack/react-query@5.100.5
## 5.100.4
### Patch Changes
- fix(devtools): change onClose callback type from () => unknown to () => void ([#10118](https://github.com/TanStack/query/pull/10118))
- Updated dependencies [[`3d1a62e`](https://github.com/TanStack/query/commit/3d1a62e63bd864359e369bb21356fa80d043f2ba)]:
- @tanstack/query-devtools@5.100.4
- @tanstack/react-query@5.100.4
## 5.100.3
### Patch Changes
- Updated dependencies [[`f85d825`](https://github.com/TanStack/query/commit/f85d825e02efbbff02e2081528ed28f5e5382f7a)]:
- @tanstack/react-query@5.100.3
- @tanstack/query-devtools@5.100.3
## 5.100.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.2
- @tanstack/react-query@5.100.2
## 5.100.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.1
- @tanstack/react-query@5.100.1
## 5.100.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.100.0
- @tanstack/react-query@5.100.0
## 5.99.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.99.2
- @tanstack/react-query@5.99.2
## 5.99.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.99.1
- @tanstack/react-query@5.99.1
## 5.99.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.99.0
- @tanstack/react-query@5.99.0
## 5.98.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.98.0
- @tanstack/react-query@5.98.0
## 5.97.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.97.0
- @tanstack/react-query@5.97.0
## 5.96.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.96.2
- @tanstack/react-query@5.96.2
## 5.96.1
### Patch Changes
- fix(build): exclude config files from production DTS rollup to prevent `@types/node` type pollution ([#10358](https://github.com/TanStack/query/pull/10358))
- Updated dependencies []:
- @tanstack/query-devtools@5.96.1
- @tanstack/react-query@5.96.1
## 5.96.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.96.0
- @tanstack/react-query@5.96.0
## 5.95.2
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.95.2
- @tanstack/react-query@5.95.2
## 5.95.1
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.95.1
- @tanstack/react-query@5.95.1
## 5.95.0
### Patch Changes
- Updated dependencies []:
- @tanstack/query-devtools@5.95.0
- @tanstack/react-query@5.95.0
## 5.94.5
### Patch Changes
- fix(\*): resolve issue about excluded build directory ([#10312](https://github.com/TanStack/query/pull/10312))
- Updated dependencies [[`4b6536d`](https://github.com/TanStack/query/commit/4b6536dfce99036f4e37f52943c6fed3ad0e0a18)]:
- @tanstack/query-devtools@5.94.5
- @tanstack/react-query@5.94.5
## 5.94.4
### Patch Changes
- chore: fixed version ([#10064](https://github.com/TanStack/query/pull/10064))
- Updated dependencies [[`4c75210`](https://github.com/TanStack/query/commit/4c75210ce8235fe3d39b67e1029eff11278927cc)]:
- @tanstack/query-devtools@5.94.4
- @tanstack/react-query@5.94.4
## 5.91.3
### Patch Changes
- Updated dependencies [[`83366c4`](https://github.com/TanStack/query/commit/83366c46a6825b5c591399c705d8128743c527dd)]:
- @tanstack/query-devtools@5.93.0
## 5.91.2
### Patch Changes
- Updated dependencies [[`f9fc56a`](https://github.com/TanStack/query/commit/f9fc56a9b8724bcfae46f8f6cb229123478eb4db), [`0b29b6f`](https://github.com/TanStack/query/commit/0b29b6f877d4b3a6d05b1c85fb9cb1e6ea736291)]:
- @tanstack/query-devtools@5.92.0
- @tanstack/react-query@5.90.14
## 5.91.1
### Patch Changes
- Updated dependencies [[`b261b6f`](https://github.com/TanStack/query/commit/b261b6f29eee2a9bdbe1bc20035fe9b83b15376b)]:
- @tanstack/query-devtools@5.91.1
## 5.91.0
### Minor Changes
- feat(devtools): allow passing a theme via prop ([#9887](https://github.com/TanStack/query/pull/9887))
### Patch Changes
- Updated dependencies [[`0e9d5b5`](https://github.com/TanStack/query/commit/0e9d5b565276f0de2a1a14ffbb079b5988581c27)]:
- @tanstack/query-devtools@5.91.0

View File

@@ -0,0 +1,22 @@
// @ts-check
import pluginReact from '@eslint-react/eslint-plugin'
import reactHooks from 'eslint-plugin-react-hooks'
import rootConfig from './root.eslint.config.js'
export default [
...rootConfig,
// @ts-expect-error wtf
...reactHooks.configs['recommended-latest'],
{
files: ['**/*.{ts,tsx}'],
...pluginReact.configs.recommended,
rules: {
'@eslint-react/no-context-provider': 'off', // We need to be React 18 compatible
'react-hooks/exhaustive-deps': 'error',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/unsupported-syntax': 'error',
'react-hooks/incompatible-library': 'error',
},
},
]

View File

@@ -0,0 +1,94 @@
{
"name": "@tanstack/react-query-devtools",
"version": "5.102.8",
"description": "Developer tools to interact with and visualize the TanStack/react-query cache",
"author": "tannerlinsley",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/TanStack/query.git",
"directory": "packages/react-query-devtools"
},
"homepage": "https://tanstack.com/query",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"scripts": {
"clean": "premove ./build ./coverage ./dist-ts ./.cache/test-types",
"compile": "tsc --project tsconfig.json",
"test:eslint": "eslint --concurrency=auto ./src",
"test:types": "npm-run-all --serial test:types:*",
"test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts56 --tsBuildInfoFile .cache/test-types/ts56.tsbuildinfo",
"test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts57 --tsBuildInfoFile .cache/test-types/ts57.tsbuildinfo",
"test:types:ts58": "node ../../node_modules/typescript58/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts58 --tsBuildInfoFile .cache/test-types/ts58.tsbuildinfo",
"test:types:ts59": "node ../../node_modules/typescript59/lib/tsc.js --project tsconfig.legacy.json --outDir .cache/test-types/ts59 --tsBuildInfoFile .cache/test-types/ts59.tsbuildinfo",
"test:types:tscurrent": "tsc --project tsconfig.json --outDir .cache/test-types/tscurrent --tsBuildInfoFile .cache/test-types/tscurrent.tsbuildinfo",
"test:types:ts70": "node ../../node_modules/typescript70/lib/tsc.js --project tsconfig.json --outDir .cache/test-types/ts70 --tsBuildInfoFile .cache/test-types/ts70.tsbuildinfo",
"test:lib": "vitest",
"test:lib:dev": "pnpm run test:lib --watch",
"test:build": "publint --strict && attw --pack",
"build": "tsdown --tsconfig tsconfig.prod.json",
"build:dev": "tsdown --watch"
},
"type": "module",
"types": "build/legacy/index.d.ts",
"main": "build/legacy/index.cjs",
"module": "build/legacy/index.js",
"exports": {
".": {
"@tanstack/custom-condition": "./src/index.ts",
"import": {
"types": "./build/modern/index.d.ts",
"default": "./build/modern/index.js"
},
"require": {
"types": "./build/modern/index.d.cts",
"default": "./build/modern/index.cjs"
}
},
"./production": {
"import": {
"types": "./build/modern/production.d.ts",
"default": "./build/modern/production.js"
},
"require": {
"types": "./build/modern/production.d.cts",
"default": "./build/modern/production.cjs"
}
},
"./build/modern/production.js": {
"import": {
"types": "./build/modern/production.d.ts",
"default": "./build/modern/production.js"
},
"require": {
"types": "./build/modern/production.d.cts",
"default": "./build/modern/production.cjs"
}
},
"./package.json": "./package.json"
},
"sideEffects": false,
"files": [
"build",
"src",
"!src/__tests__"
],
"dependencies": {
"@tanstack/query-devtools": "workspace:*"
},
"devDependencies": {
"@tanstack/react-query": "workspace:*",
"@testing-library/react": "^16.1.0",
"@types/react": "^19.2.7",
"@vitejs/plugin-react": "^4.3.4",
"npm-run-all2": "^5.0.0",
"react": "^19.2.1"
},
"peerDependencies": {
"@tanstack/react-query": "workspace:^",
"@types/react": "^18 || ^19",
"react": "^18 || ^19"
}
}

View File

@@ -0,0 +1 @@
../../eslint.config.js

View File

@@ -0,0 +1 @@
../../scripts/getTsdownConfig.js

View File

@@ -0,0 +1,128 @@
'use client'
import * as React from 'react'
import { onlineManager, useQueryClient } from '@tanstack/react-query'
import { TanstackQueryDevtools } from '@tanstack/query-devtools'
import type {
DevtoolsButtonPosition,
DevtoolsErrorType,
DevtoolsPosition,
Theme,
} from '@tanstack/query-devtools'
import type { QueryClient } from '@tanstack/react-query'
export interface DevtoolsOptions {
/**
* Set this true if you want the dev tools to default to being open
*/
initialIsOpen?: boolean
/**
* The position of the TanStack logo to open and close the devtools panel.
* 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'relative'
* Defaults to 'bottom-right'.
*/
buttonPosition?: DevtoolsButtonPosition
/**
* The position of the React Query devtools panel.
* 'top' | 'bottom' | 'left' | 'right'
* Defaults to 'bottom'.
*/
position?: DevtoolsPosition
/**
* Custom instance of QueryClient
*/
client?: QueryClient
/**
* Use this so you can define custom errors that can be shown in the devtools.
*/
errorTypes?: Array<DevtoolsErrorType>
/**
* Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles.
*/
styleNonce?: string
/**
* Use this so you can attach the devtool's styles to specific element in the DOM.
*/
shadowDOMTarget?: ShadowRoot
/**
* Set this to true to hide disabled queries from the devtools panel.
*/
hideDisabledQueries?: boolean
/**
* Set this to 'light', 'dark', or 'system' to change the theme of the devtools panel.
* Defaults to 'system'.
*/
theme?: Theme
}
export function ReactQueryDevtools(
props: DevtoolsOptions,
): React.ReactElement | null {
const queryClient = useQueryClient(props.client)
const ref = React.useRef<HTMLDivElement>(null)
const {
buttonPosition,
position,
initialIsOpen,
errorTypes,
styleNonce,
shadowDOMTarget,
hideDisabledQueries,
theme,
} = props
const [devtools] = React.useState(
new TanstackQueryDevtools({
client: queryClient,
queryFlavor: 'React Query',
version: '5',
onlineManager,
buttonPosition,
position,
initialIsOpen,
errorTypes,
styleNonce,
shadowDOMTarget,
hideDisabledQueries,
theme,
}),
)
React.useEffect(() => {
devtools.setClient(queryClient)
}, [queryClient, devtools])
React.useEffect(() => {
if (buttonPosition) {
devtools.setButtonPosition(buttonPosition)
}
}, [buttonPosition, devtools])
React.useEffect(() => {
if (position) {
devtools.setPosition(position)
}
}, [position, devtools])
React.useEffect(() => {
devtools.setInitialIsOpen(initialIsOpen || false)
}, [initialIsOpen, devtools])
React.useEffect(() => {
devtools.setErrorTypes(errorTypes || [])
}, [errorTypes, devtools])
React.useEffect(() => {
devtools.setTheme(theme)
}, [theme, devtools])
React.useEffect(() => {
if (ref.current) {
devtools.mount(ref.current)
}
return () => {
devtools.unmount()
}
}, [devtools])
return <div dir="ltr" className="tsqd-parent-container" ref={ref}></div>
}

View File

@@ -0,0 +1,112 @@
'use client'
import * as React from 'react'
import { onlineManager, useQueryClient } from '@tanstack/react-query'
import { TanstackQueryDevtoolsPanel } from '@tanstack/query-devtools'
import type { DevtoolsErrorType, Theme } from '@tanstack/query-devtools'
import type { QueryClient } from '@tanstack/react-query'
export interface DevtoolsPanelOptions {
/**
* Custom instance of QueryClient
*/
client?: QueryClient
/**
* Use this so you can define custom errors that can be shown in the devtools.
*/
errorTypes?: Array<DevtoolsErrorType>
/**
* Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles.
*/
styleNonce?: string
/**
* Use this so you can attach the devtool's styles to specific element in the DOM.
*/
shadowDOMTarget?: ShadowRoot
/**
* Custom styles for the devtools panel
* @default { height: '500px' }
* @example { height: '100%' }
* @example { height: '100%', width: '100%' }
*/
style?: React.CSSProperties
/**
* Callback function that is called when the devtools panel is closed
*/
onClose?: () => void
/**
* Set this to true to hide disabled queries from the devtools panel.
*/
hideDisabledQueries?: boolean
/**
* Set this to 'light', 'dark', or 'system' to change the theme of the devtools panel.
* Defaults to 'system'.
*/
theme?: Theme
}
export function ReactQueryDevtoolsPanel(
props: DevtoolsPanelOptions,
): React.ReactElement | null {
const queryClient = useQueryClient(props.client)
const ref = React.useRef<HTMLDivElement>(null)
const {
errorTypes,
styleNonce,
shadowDOMTarget,
hideDisabledQueries,
theme,
} = props
const [devtools] = React.useState(
new TanstackQueryDevtoolsPanel({
client: queryClient,
queryFlavor: 'React Query',
version: '5',
onlineManager,
buttonPosition: 'bottom-left',
position: 'bottom',
initialIsOpen: true,
errorTypes,
styleNonce,
shadowDOMTarget,
onClose: props.onClose,
hideDisabledQueries,
theme,
}),
)
React.useEffect(() => {
devtools.setClient(queryClient)
}, [queryClient, devtools])
React.useEffect(() => {
devtools.setOnClose(props.onClose ?? (() => {}))
}, [props.onClose, devtools])
React.useEffect(() => {
devtools.setErrorTypes(errorTypes || [])
}, [errorTypes, devtools])
React.useEffect(() => {
devtools.setTheme(theme)
}, [theme, devtools])
React.useEffect(() => {
if (ref.current) {
devtools.mount(ref.current)
}
return () => {
devtools.unmount()
}
}, [devtools])
return (
<div
style={{ height: '500px', ...props.style }}
className="tsqd-parent-container"
ref={ref}
></div>
)
}

View File

@@ -0,0 +1,233 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { render } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { TanstackQueryDevtools } from '@tanstack/query-devtools'
import type { ReactQueryDevtools as ReactQueryDevtoolsComponent } from '../ReactQueryDevtools'
const mountMock = vi.fn()
const unmountMock = vi.fn()
const setClientMock = vi.fn()
const setButtonPositionMock = vi.fn()
const setPositionMock = vi.fn()
const setInitialIsOpenMock = vi.fn()
const setErrorTypesMock = vi.fn()
const setThemeMock = vi.fn()
vi.mock('@tanstack/query-devtools', () => ({
TanstackQueryDevtools: vi.fn(function (this: TanstackQueryDevtools) {
this.mount = mountMock
this.unmount = unmountMock
this.setClient = setClientMock
this.setButtonPosition = setButtonPositionMock
this.setPosition = setPositionMock
this.setInitialIsOpen = setInitialIsOpenMock
this.setErrorTypes = setErrorTypesMock
this.setTheme = setThemeMock
}),
}))
describe('ReactQueryDevtools', () => {
let ReactQueryDevtools: typeof ReactQueryDevtoolsComponent
let queryClient: QueryClient
beforeEach(async () => {
vi.clearAllMocks()
;({ ReactQueryDevtools } = await import('../ReactQueryDevtools'))
queryClient = new QueryClient()
})
it('should throw an error if no query client has been set', () => {
expect(() => render(<ReactQueryDevtools />)).toThrow(
'No QueryClient set, use QueryClientProvider to set one',
)
})
it('should not throw an error if query client is provided via context', () => {
expect(() =>
render(
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools />
</QueryClientProvider>,
),
).not.toThrow()
expect(mountMock).toHaveBeenCalled()
})
it('should not throw an error if query client is provided via props', () => {
expect(() =>
render(<ReactQueryDevtools client={queryClient} />),
).not.toThrow()
expect(mountMock).toHaveBeenCalled()
})
it('should forward "buttonPosition" to the devtools instance', () => {
render(
<ReactQueryDevtools client={queryClient} buttonPosition="top-left" />,
)
expect(setButtonPositionMock).toHaveBeenCalledWith('top-left')
})
it('should forward "position" to the devtools instance', () => {
render(<ReactQueryDevtools client={queryClient} position="left" />)
expect(setPositionMock).toHaveBeenCalledWith('left')
})
it('should forward "initialIsOpen" to the devtools instance', () => {
render(<ReactQueryDevtools client={queryClient} initialIsOpen={true} />)
expect(setInitialIsOpenMock).toHaveBeenCalledWith(true)
})
it('should default "initialIsOpen" to "false" when the prop is omitted', () => {
render(<ReactQueryDevtools client={queryClient} />)
expect(setInitialIsOpenMock).toHaveBeenCalledWith(false)
})
it('should forward "errorTypes" to the devtools instance', () => {
const errorTypes = [
{ name: 'Network', initializer: () => new Error('Network') },
]
render(<ReactQueryDevtools client={queryClient} errorTypes={errorTypes} />)
expect(setErrorTypesMock).toHaveBeenCalledWith(errorTypes)
})
it('should default "errorTypes" to an empty array when the prop is omitted', () => {
render(<ReactQueryDevtools client={queryClient} />)
expect(setErrorTypesMock).toHaveBeenCalledWith([])
})
it('should forward "theme" to the devtools instance', () => {
render(<ReactQueryDevtools client={queryClient} theme="dark" />)
expect(setThemeMock).toHaveBeenCalledWith('dark')
})
it('should forward the resolved "QueryClient" via "setClient"', () => {
render(<ReactQueryDevtools client={queryClient} />)
expect(setClientMock).toHaveBeenCalledWith(queryClient)
})
it('should forward "styleNonce" to the devtools constructor', () => {
render(<ReactQueryDevtools client={queryClient} styleNonce="abc" />)
expect(TanstackQueryDevtools).toHaveBeenCalledWith(
expect.objectContaining({ styleNonce: 'abc' }),
)
})
it('should forward "shadowDOMTarget" to the devtools constructor', () => {
const shadowDOMTarget = document
.createElement('div')
.attachShadow({ mode: 'open' })
render(
<ReactQueryDevtools
client={queryClient}
shadowDOMTarget={shadowDOMTarget}
/>,
)
expect(TanstackQueryDevtools).toHaveBeenCalledWith(
expect.objectContaining({ shadowDOMTarget }),
)
})
it('should forward "hideDisabledQueries" to the devtools constructor', () => {
render(
<ReactQueryDevtools client={queryClient} hideDisabledQueries={true} />,
)
expect(TanstackQueryDevtools).toHaveBeenCalledWith(
expect.objectContaining({ hideDisabledQueries: true }),
)
})
it('should forward a "buttonPosition" change to the devtools instance after mount', () => {
const { rerender } = render(
<ReactQueryDevtools client={queryClient} buttonPosition="bottom-right" />,
)
setButtonPositionMock.mockClear()
rerender(
<ReactQueryDevtools client={queryClient} buttonPosition="top-left" />,
)
expect(setButtonPositionMock).toHaveBeenCalledWith('top-left')
})
it('should forward a "position" change to the devtools instance after mount', () => {
const { rerender } = render(
<ReactQueryDevtools client={queryClient} position="bottom" />,
)
setPositionMock.mockClear()
rerender(<ReactQueryDevtools client={queryClient} position="top" />)
expect(setPositionMock).toHaveBeenCalledWith('top')
})
it('should forward an "initialIsOpen" change to the devtools instance after mount', () => {
const { rerender } = render(
<ReactQueryDevtools client={queryClient} initialIsOpen={false} />,
)
setInitialIsOpenMock.mockClear()
rerender(<ReactQueryDevtools client={queryClient} initialIsOpen={true} />)
expect(setInitialIsOpenMock).toHaveBeenCalledWith(true)
})
it('should forward an "errorTypes" change to the devtools instance after mount', () => {
const { rerender } = render(
<ReactQueryDevtools client={queryClient} errorTypes={[]} />,
)
setErrorTypesMock.mockClear()
const errorTypes = [
{ name: 'Network', initializer: () => new Error('Network') },
]
rerender(
<ReactQueryDevtools client={queryClient} errorTypes={errorTypes} />,
)
expect(setErrorTypesMock).toHaveBeenCalledWith(errorTypes)
})
it('should forward a "theme" change to the devtools instance after mount', () => {
const { rerender } = render(
<ReactQueryDevtools client={queryClient} theme="light" />,
)
setThemeMock.mockClear()
rerender(<ReactQueryDevtools client={queryClient} theme="dark" />)
expect(setThemeMock).toHaveBeenCalledWith('dark')
})
it('should call "unmount" on the devtools instance when the component unmounts', () => {
const { unmount } = render(<ReactQueryDevtools client={queryClient} />)
unmount()
expect(unmountMock).toHaveBeenCalled()
})
it('should return null in non-development environments', async () => {
vi.stubEnv('NODE_ENV', 'production')
vi.resetModules()
try {
const { ReactQueryDevtools: ProductionDevtools } = await import('..')
expect(ProductionDevtools({})).toBeNull()
} finally {
vi.unstubAllEnvs()
vi.resetModules()
}
})
})

View File

@@ -0,0 +1,193 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { render } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { TanstackQueryDevtoolsPanel } from '@tanstack/query-devtools'
import type { ReactQueryDevtoolsPanel as ReactQueryDevtoolsPanelComponent } from '../ReactQueryDevtoolsPanel'
const mountMock = vi.fn()
const unmountMock = vi.fn()
const setClientMock = vi.fn()
const setOnCloseMock = vi.fn()
const setErrorTypesMock = vi.fn()
const setThemeMock = vi.fn()
vi.mock('@tanstack/query-devtools', () => ({
TanstackQueryDevtoolsPanel: vi.fn(function (
this: TanstackQueryDevtoolsPanel,
) {
this.mount = mountMock
this.unmount = unmountMock
this.setClient = setClientMock
this.setOnClose = setOnCloseMock
this.setErrorTypes = setErrorTypesMock
this.setTheme = setThemeMock
}),
}))
describe('ReactQueryDevtoolsPanel', () => {
let ReactQueryDevtoolsPanel: typeof ReactQueryDevtoolsPanelComponent
let queryClient: QueryClient
beforeEach(async () => {
vi.clearAllMocks()
;({ ReactQueryDevtoolsPanel } = await import('../ReactQueryDevtoolsPanel'))
queryClient = new QueryClient()
})
it('should throw an error if no query client has been set', () => {
expect(() => render(<ReactQueryDevtoolsPanel />)).toThrow(
'No QueryClient set, use QueryClientProvider to set one',
)
})
it('should not throw an error if query client is provided via context', () => {
expect(() =>
render(
<QueryClientProvider client={queryClient}>
<ReactQueryDevtoolsPanel />
</QueryClientProvider>,
),
).not.toThrow()
expect(mountMock).toHaveBeenCalled()
})
it('should not throw an error if query client is provided via props', () => {
expect(() =>
render(<ReactQueryDevtoolsPanel client={queryClient} />),
).not.toThrow()
expect(mountMock).toHaveBeenCalled()
})
it('should forward "onClose" to the devtools instance', () => {
const onClose = vi.fn()
render(<ReactQueryDevtoolsPanel client={queryClient} onClose={onClose} />)
expect(setOnCloseMock).toHaveBeenCalledWith(onClose)
})
it('should default "onClose" to a no-op function when the prop is omitted', () => {
render(<ReactQueryDevtoolsPanel client={queryClient} />)
const forwarded = setOnCloseMock.mock.calls[0]?.[0]
expect(forwarded).toBeInstanceOf(Function)
expect(forwarded()).toBeUndefined()
})
it('should forward "errorTypes" to the devtools instance', () => {
const errorTypes = [
{ name: 'Network', initializer: () => new Error('Network') },
]
render(
<ReactQueryDevtoolsPanel client={queryClient} errorTypes={errorTypes} />,
)
expect(setErrorTypesMock).toHaveBeenCalledWith(errorTypes)
})
it('should default "errorTypes" to an empty array when the prop is omitted', () => {
render(<ReactQueryDevtoolsPanel client={queryClient} />)
expect(setErrorTypesMock).toHaveBeenCalledWith([])
})
it('should forward "theme" to the devtools instance', () => {
render(<ReactQueryDevtoolsPanel client={queryClient} theme="dark" />)
expect(setThemeMock).toHaveBeenCalledWith('dark')
})
it('should forward the resolved "QueryClient" via "setClient"', () => {
render(<ReactQueryDevtoolsPanel client={queryClient} />)
expect(setClientMock).toHaveBeenCalledWith(queryClient)
})
it('should forward "styleNonce" to the devtools constructor', () => {
render(<ReactQueryDevtoolsPanel client={queryClient} styleNonce="abc" />)
expect(TanstackQueryDevtoolsPanel).toHaveBeenCalledWith(
expect.objectContaining({ styleNonce: 'abc' }),
)
})
it('should forward "shadowDOMTarget" to the devtools constructor', () => {
const shadowDOMTarget = document
.createElement('div')
.attachShadow({ mode: 'open' })
render(
<ReactQueryDevtoolsPanel
client={queryClient}
shadowDOMTarget={shadowDOMTarget}
/>,
)
expect(TanstackQueryDevtoolsPanel).toHaveBeenCalledWith(
expect.objectContaining({ shadowDOMTarget }),
)
})
it('should forward "hideDisabledQueries" to the devtools constructor', () => {
render(
<ReactQueryDevtoolsPanel
client={queryClient}
hideDisabledQueries={true}
/>,
)
expect(TanstackQueryDevtoolsPanel).toHaveBeenCalledWith(
expect.objectContaining({ hideDisabledQueries: true }),
)
})
it('should preserve the default container height when "style" omits "height"', () => {
const { container } = render(
<ReactQueryDevtoolsPanel
client={queryClient}
style={{ width: '300px' }}
/>,
)
expect(container.querySelector('.tsqd-parent-container')).toHaveStyle({
height: '500px',
width: '300px',
})
})
it('should let "style" override the default container height on the rendered element', () => {
const { container } = render(
<ReactQueryDevtoolsPanel
client={queryClient}
style={{ width: '300px', height: '300px' }}
/>,
)
expect(container.querySelector('.tsqd-parent-container')).toHaveStyle({
height: '300px',
width: '300px',
})
})
it('should call "unmount" on the devtools instance when the component unmounts', () => {
const { unmount } = render(<ReactQueryDevtoolsPanel client={queryClient} />)
unmount()
expect(unmountMock).toHaveBeenCalled()
})
it('should return null in non-development environments', async () => {
vi.stubEnv('NODE_ENV', 'production')
vi.resetModules()
try {
const { ReactQueryDevtoolsPanel: ProductionDevtoolsPanel } =
await import('..')
expect(ProductionDevtoolsPanel({})).toBeNull()
} finally {
vi.unstubAllEnvs()
vi.resetModules()
}
})
})

View File

@@ -0,0 +1,20 @@
'use client'
import * as Devtools from './ReactQueryDevtools'
import * as DevtoolsPanel from './ReactQueryDevtoolsPanel'
export const ReactQueryDevtools: (typeof Devtools)['ReactQueryDevtools'] =
process.env.NODE_ENV !== 'development'
? function () {
return null
}
: Devtools.ReactQueryDevtools
export const ReactQueryDevtoolsPanel: (typeof DevtoolsPanel)['ReactQueryDevtoolsPanel'] =
process.env.NODE_ENV !== 'development'
? function () {
return null
}
: DevtoolsPanel.ReactQueryDevtoolsPanel
export type DevtoolsPanelOptions = DevtoolsPanel.DevtoolsPanelOptions

View File

@@ -0,0 +1,7 @@
'use client'
import * as Devtools from './ReactQueryDevtools'
import * as DevtoolsPanel from './ReactQueryDevtoolsPanel'
export const ReactQueryDevtools = Devtools.ReactQueryDevtools
export const ReactQueryDevtoolsPanel = DevtoolsPanel.ReactQueryDevtoolsPanel

View File

@@ -0,0 +1,12 @@
import '@testing-library/jest-dom/vitest'
import { act, cleanup } from '@testing-library/react'
import { afterEach } from 'vitest'
import { notifyManager } from '@tanstack/react-query'
// https://testing-library.com/docs/react-testing-library/api#cleanup
afterEach(() => cleanup())
// Wrap notifications with act to make sure React knows about React Query updates
notifyManager.setNotifyFunction((fn) => {
act(fn)
})

View File

@@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist-ts",
"rootDir": ".",
"jsx": "react-jsx"
},
"include": [
"src",
"test-setup.ts",
"*.config.ts",
"*.config.js",
"package.json"
],
"references": [{ "path": "../query-devtools" }, { "path": "../react-query" }]
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"outDir": "./dist-ts/legacy"
},
"include": ["src"],
"exclude": ["src/__tests__"],
"references": [{ "path": "../query-devtools" }, { "path": "../react-query" }]
}

View File

@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"incremental": false,
"composite": false,
"rootDir": "../../",
"customConditions": []
},
"include": ["src"],
"exclude": ["src/__tests__"]
}

View File

@@ -0,0 +1,7 @@
import { defineConfig } from 'tsdown'
import { legacyConfig, modernConfig } from './root.tsdown.config.js'
export default defineConfig([
modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
legacyConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
])

View File

@@ -0,0 +1,34 @@
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import packageJson from './package.json'
export default defineConfig({
plugins: [react()],
// fix from https://github.com/vitest-dev/vitest/issues/6992#issuecomment-2509408660
resolve: {
conditions: ['@tanstack/custom-condition'],
},
environments: {
ssr: {
resolve: {
conditions: ['@tanstack/custom-condition'],
},
},
},
test: {
name: packageJson.name,
dir: './src',
watch: false,
environment: 'jsdom',
setupFiles: ['test-setup.ts'],
coverage: {
enabled: !!process.env.CI,
provider: 'istanbul',
include: ['src/**/*'],
exclude: ['src/__tests__/**'],
},
typecheck: { enabled: true },
restoreMocks: true,
},
})