Skip to content
Open
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/quiet-vue-clients.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/vue-query-devtools": patch
---

Update floating and embedded devtools when the client prop changes, preserving the initially resolved client as the fallback when the override is removed.
81 changes: 81 additions & 0 deletions packages/vue-query-devtools/src/__tests__/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { createApp, h, nextTick, shallowRef } from 'vue'
import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query'
import Devtools from '../devtools.vue'
import DevtoolsPanel from '../devtoolsPanel.vue'
import type { App } from 'vue'

const { setClient, mount, unmount } = vi.hoisted(() => ({
setClient: vi.fn(),
mount: vi.fn(),
unmount: vi.fn(),
}))

vi.mock('@tanstack/query-devtools', () => {
class MockDevtools {
setClient = setClient
mount = mount
unmount = unmount
setButtonPosition = vi.fn()
setPosition = vi.fn()
setInitialIsOpen = vi.fn()
setErrorTypes = vi.fn()
setTheme = vi.fn()
setOnClose = vi.fn()
}
return {
TanstackQueryDevtools: MockDevtools,
TanstackQueryDevtoolsPanel: MockDevtools,
}
})

describe.each([
['floating', Devtools],
['embedded', DevtoolsPanel],
] as const)('%s devtools client', (_, component) => {
let app: App | undefined
let container: HTMLDivElement | undefined

afterEach(() => {
app?.unmount()
container?.remove()
vi.clearAllMocks()
})

it('switches explicit clients without remounting or requiring a provider', async () => {
const first = new QueryClient()
const second = new QueryClient()
const client = shallowRef(first)
container = document.createElement('div')
app = createApp(() => h(component, { client: client.value }))
app.mount(container)

expect(setClient).toHaveBeenLastCalledWith(first)
client.value = second
await nextTick()

expect(setClient).toHaveBeenLastCalledWith(second)
expect(mount).toHaveBeenCalledTimes(1)
expect(unmount).not.toHaveBeenCalled()
})

it('returns to the initial context client after an override is removed', async () => {
const contextClient = new QueryClient()
const override = new QueryClient()
const client = shallowRef<QueryClient>()
container = document.createElement('div')
app = createApp(() => h(component, { client: client.value }))
app.use(VueQueryPlugin, { queryClient: contextClient })
app.mount(container)

expect(setClient).toHaveBeenLastCalledWith(contextClient)
client.value = override
await nextTick()
expect(setClient).toHaveBeenLastCalledWith(override)

client.value = undefined
await nextTick()
expect(setClient).toHaveBeenLastCalledWith(contextClient)
expect(mount).toHaveBeenCalledTimes(1)
})
})
1 change: 1 addition & 0 deletions packages/vue-query-devtools/src/devtools.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const devtools = new TanstackQueryDevtools({
})

watchEffect(() => {
devtools.setClient(props.client || client)
devtools.setButtonPosition(props.buttonPosition || 'bottom-right')
devtools.setPosition(props.position || 'bottom')
devtools.setInitialIsOpen(props.initialIsOpen)
Expand Down
1 change: 1 addition & 0 deletions packages/vue-query-devtools/src/devtoolsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const devtools = new TanstackQueryDevtoolsPanel({
})

watchEffect(() => {
devtools.setClient(props.client || client)
devtools.setOnClose(props.onClose ?? (() => {}))
devtools.setErrorTypes(props.errorTypes || [])
devtools.setTheme(props.theme)
Expand Down